feat(ahbot): Add item level scaling for AH equipment

- Add 5 new config options for item level scaling:
  - AuctionHouseBot.Items.Scaling.Enabled (default: 0)
  - AuctionHouseBot.Items.Scaling.MinItemLevel (default: 200)
  - AuctionHouseBot.Items.Scaling.MaxItemLevel (default: 500)
  - AuctionHouseBot.Items.Scaling.Chance (default: 75)
  - AuctionHouseBot.Items.Scaling.EquipmentOnly (default: 1)

- Implement scaling logic in AuctionHouseBotSeller::AddNewAuctions()
  - Uses ItemBonusMgr::GetItemBonusListForItemLevelDelta() for scaling
  - Random target ilvl within configured range
  - Respects chance and equipment-only filters

- Update SetPricesOfItem() to use scaled item level for pricing
  - 2% price increase per item level gained

- Add .ahbot stats [equipment] GM command for item level analysis
  - Shows distribution, avg/min/max ilvl, scaling config status

- Add MCP console_command support for ahbot commands
  - ahbot status, rebuild, reload, stats

Tested: Avg equipment ilvl increased from ~35 to 367.9 with default config
This commit is contained in:
2025-12-15 08:20:21 -05:00
parent cf2d839748
commit 6bb035cfc3
7 changed files with 379 additions and 6 deletions

View File

@@ -25,7 +25,11 @@
#include "DatabaseEnv.h"
#include "GameTime.h"
#include "DB2Stores.h"
#include "AuctionHouseBot.h"
#include "AuctionHouseMgr.h"
#include "Item.h"
#include <sstream>
#include <map>
namespace Araxia
{
@@ -440,6 +444,168 @@ void RegisterSpawnTools()
};
}
}
// AHBot commands - useful for managing auction house bot without a player
// These mirror the .ahbot GM commands but work from MCP console
else if (cmd == "ahbot")
{
std::string subcmd;
iss >> subcmd;
if (subcmd == "status")
{
// Get AHBot status info
std::unordered_map<AuctionHouseType, AuctionHouseBotStatusInfoPerType> statusInfo;
sAuctionBot->PrepareStatusInfos(statusInfo);
return {
{"success", true},
{"command", "ahbot status"},
{"alliance", {
{"itemCount", statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount}
}},
{"horde", {
{"itemCount", statusInfo[AUCTION_HOUSE_HORDE].ItemsCount}
}},
{"neutral", {
{"itemCount", statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount}
}},
{"total", statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount +
statusInfo[AUCTION_HOUSE_HORDE].ItemsCount +
statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount}
};
}
else if (subcmd == "rebuild")
{
std::string arg;
iss >> arg;
bool all = (arg == "all");
sAuctionBot->Rebuild(all);
return {
{"success", true},
{"command", "ahbot rebuild"},
{"all", all},
{"message", all ? "Rebuilding all auction house items" : "Rebuilding auction house items"}
};
}
else if (subcmd == "reload")
{
sAuctionBot->ReloadAllConfig();
return {
{"success", true},
{"command", "ahbot reload"},
{"message", "AHBot configuration reloaded"}
};
}
else if (subcmd == "stats")
{
// Item level statistics - mirrors the new .ahbot stats command
std::string arg;
iss >> arg;
bool equipmentOnly = (arg == "equipment");
std::map<uint32, uint32> itemLevelBuckets;
uint32 totalItems = 0;
uint32 equipmentItems = 0;
uint32 minItemLevel = UINT32_MAX;
uint32 maxItemLevel = 0;
uint64 totalItemLevel = 0;
std::vector<uint32> auctionHouseIds = { 1, 2, 6, 7 };
for (uint32 ahId : auctionHouseIds)
{
AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsById(ahId);
if (!auctionHouse)
continue;
for (auto itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr)
{
AuctionPosting& auction = itr->second;
for (Item* item : auction.Items)
{
if (!item)
continue;
ItemTemplate const* proto = item->GetTemplate();
if (!proto)
continue;
bool isEquipment = (proto->GetClass() == ITEM_CLASS_WEAPON || proto->GetClass() == ITEM_CLASS_ARMOR);
if (equipmentOnly && !isEquipment)
continue;
if (isEquipment)
++equipmentItems;
uint32 itemLevel = Item::GetItemLevel(proto, *item->GetBonus(), 90, 0, 0, 0, 0, false, 0);
++totalItems;
totalItemLevel += itemLevel;
if (itemLevel < minItemLevel)
minItemLevel = itemLevel;
if (itemLevel > maxItemLevel)
maxItemLevel = itemLevel;
uint32 bucket = (itemLevel / 50) * 50;
itemLevelBuckets[bucket]++;
}
}
}
if (totalItems == 0)
{
return {
{"success", true},
{"command", "ahbot stats"},
{"message", "No items found in auction house"},
{"totalItems", 0}
};
}
json distribution = json::array();
for (auto const& [bucket, count] : itemLevelBuckets)
{
distribution.push_back({
{"minLevel", bucket},
{"maxLevel", bucket + 49},
{"count", count},
{"percentage", (static_cast<float>(count) / totalItems) * 100.0f}
});
}
return {
{"success", true},
{"command", "ahbot stats"},
{"equipmentOnly", equipmentOnly},
{"totalItems", totalItems},
{"equipmentItems", equipmentItems},
{"minItemLevel", minItemLevel},
{"maxItemLevel", maxItemLevel},
{"avgItemLevel", static_cast<float>(totalItemLevel) / totalItems},
{"distribution", distribution},
{"scalingConfig", {
{"enabled", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_ENABLED)},
{"minTargetLevel", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_MIN_ITEM_LEVEL)},
{"maxTargetLevel", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_MAX_ITEM_LEVEL)},
{"chance", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_CHANCE)},
{"equipmentOnly", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_EQUIPMENT_ONLY)}
}}
};
}
else
{
return {
{"success", false},
{"error", "Unknown ahbot subcommand"},
{"subcommand", subcmd},
{"supported", {"status", "rebuild [all]", "reload", "stats [equipment]"}}
};
}
}
return {
{"success", false},
@@ -448,7 +614,11 @@ void RegisterSpawnTools()
{"supported", {
"server info",
"reload creature [entry]",
"reload creature_spawns (requires restart)"
"reload creature_spawns (requires restart)",
"ahbot status",
"ahbot rebuild [all]",
"ahbot reload",
"ahbot stats [equipment]"
}}
};
}

View File

@@ -167,6 +167,11 @@ void AuctionBotConfig::GetConfigFromFile()
SetConfig(CONFIG_AHBOT_ITEMS_LOOT, "AuctionHouseBot.Items.Loot", true);
SetConfig(CONFIG_AHBOT_ITEMS_MISC, "AuctionHouseBot.Items.Misc", false);
// AHBot Item Level Scaling - applies random item level bonuses to equipment
// Uses ItemBonusMgr::GetItemBonusListForItemLevelDelta() (same system as Timewalking/Remix)
SetConfig(CONFIG_AHBOT_ITEM_SCALING_ENABLED, "AuctionHouseBot.Items.Scaling.Enabled", false);
SetConfig(CONFIG_AHBOT_ITEM_SCALING_EQUIPMENT_ONLY, "AuctionHouseBot.Items.Scaling.EquipmentOnly", true);
SetConfig(CONFIG_AHBOT_BIND_NO, "AuctionHouseBot.Bind.No", true);
SetConfig(CONFIG_AHBOT_BIND_PICKUP, "AuctionHouseBot.Bind.Pickup", false);
SetConfig(CONFIG_AHBOT_BIND_EQUIP, "AuctionHouseBot.Bind.Equip", true);
@@ -181,6 +186,10 @@ void AuctionBotConfig::GetConfigFromFile()
SetConfig(CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL, "AuctionHouseBot.Items.ItemLevel.Min", 0);
SetConfig(CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL, "AuctionHouseBot.Items.ItemLevel.Max", 0);
// Item level scaling range and chance (only used when scaling is enabled)
SetConfig(CONFIG_AHBOT_ITEM_SCALING_MIN_ITEM_LEVEL, "AuctionHouseBot.Items.Scaling.MinItemLevel", 0);
SetConfig(CONFIG_AHBOT_ITEM_SCALING_MAX_ITEM_LEVEL, "AuctionHouseBot.Items.Scaling.MaxItemLevel", 550);
SetConfigMax(CONFIG_AHBOT_ITEM_SCALING_CHANCE, "AuctionHouseBot.Items.Scaling.Chance", 50, 100);
SetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL, "AuctionHouseBot.Items.ReqLevel.Min", 0);
SetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL, "AuctionHouseBot.Items.ReqLevel.Max", 0);
SetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK, "AuctionHouseBot.Items.ReqSkill.Min", 0);

View File

@@ -64,6 +64,9 @@ enum AuctionBotConfigUInt32Values
CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO,
CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL,
CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL,
CONFIG_AHBOT_ITEM_SCALING_MIN_ITEM_LEVEL,
CONFIG_AHBOT_ITEM_SCALING_MAX_ITEM_LEVEL,
CONFIG_AHBOT_ITEM_SCALING_CHANCE,
CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL,
CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL,
CONFIG_AHBOT_ITEM_MIN_SKILL_RANK,
@@ -171,6 +174,7 @@ enum AuctionBotConfigBoolValues
CONFIG_AHBOT_ITEMS_VENDOR,
CONFIG_AHBOT_ITEMS_LOOT,
CONFIG_AHBOT_ITEMS_MISC,
CONFIG_AHBOT_ITEM_SCALING_ENABLED,
CONFIG_AHBOT_BIND_NO,
CONFIG_AHBOT_BIND_PICKUP,
CONFIG_AHBOT_BIND_EQUIP,
@@ -180,6 +184,7 @@ enum AuctionBotConfigBoolValues
CONFIG_AHBOT_SELLER_ENABLED,
CONFIG_AHBOT_BUYER_ENABLED,
CONFIG_AHBOT_LOCKBOX_ENABLED,
CONFIG_AHBOT_ITEM_SCALING_EQUIPMENT_ONLY,
CONFIG_AHBOT_CLASS_CONSUMABLE_ALLOW_ZERO,
CONFIG_AHBOT_CLASS_CONTAINER_ALLOW_ZERO,
CONFIG_AHBOT_CLASS_WEAPON_ALLOW_ZERO,

View File

@@ -21,6 +21,7 @@
#include "DB2Stores.h"
#include "GameTime.h"
#include "Item.h"
#include "ItemBonusMgr.h"
#include "Log.h"
#include "Containers.h"
#include "ObjectMgr.h"
@@ -586,7 +587,9 @@ bool AuctionBotSeller::GetItemsToSell(SellerConfiguration& config, ItemsToSellAr
}
// Set items price. All important value are passed by address.
void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyout, uint32& bid, uint32 stackCount)
// scaledItemLevel: If non-zero, use this item level for price calculation instead of base level
// This ensures scaled items are priced appropriately for their actual power level
void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyout, uint32& bid, uint32 stackCount, uint32 scaledItemLevel /*= 0*/)
{
uint32 classRatio = config.GetPriceRatioPerClass(ItemClass(itemProto->GetClass()));
uint32 qualityRatio = config.GetPriceRatioPerQuality(AuctionQuality(itemProto->GetQuality()));
@@ -595,6 +598,9 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
float buyPrice = itemProto->GetBuyPrice();
float sellPrice = itemProto->GetSellPrice();
// Use scaled item level if provided, otherwise use base item level
float effectiveItemLevel = scaledItemLevel > 0 ? static_cast<float>(scaledItemLevel) : static_cast<float>(itemProto->GetBaseItemLevel());
if (buyPrice == 0)
{
if (sellPrice > 0)
@@ -602,12 +608,21 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
else
{
float divisor = ((itemProto->GetClass() == ITEM_CLASS_WEAPON || itemProto->GetClass() == ITEM_CLASS_ARMOR) ? 284.0f : 80.0f);
float tempLevel = (itemProto->GetBaseItemLevel() == 0 ? 1.0f : itemProto->GetBaseItemLevel());
float tempLevel = (effectiveItemLevel == 0 ? 1.0f : effectiveItemLevel);
float tempQuality = (itemProto->GetQuality() == 0 ? 1.0f : itemProto->GetQuality());
buyPrice = tempLevel * tempQuality * static_cast<float>(GetBuyModifier(itemProto))* tempLevel / divisor;
}
}
// If item has a buy price but was scaled, apply a multiplier based on item level increase
else if (scaledItemLevel > 0 && scaledItemLevel > itemProto->GetBaseItemLevel())
{
// Scale price proportionally: higher ilvl = higher price
// Formula: basePrice * (1 + (deltaLevel * 0.02)) - 2% increase per item level
float deltaLevel = static_cast<float>(scaledItemLevel - itemProto->GetBaseItemLevel());
float scalingFactor = 1.0f + (deltaLevel * 0.02f);
buyPrice *= scalingFactor;
}
if (sellPrice == 0)
sellPrice = (buyPrice > 10 ? buyPrice / GetSellModifier(itemProto) : buyPrice);
@@ -869,11 +884,47 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
// Ex: Notched Shortsword of Stamina will only generate as a Notched Shortsword without this.
item->SetItemRandomBonusList(GenerateItemRandomBonusListId(itemId));
// AHBot Item Level Scaling: Apply random item level bonus to equipment items
// Uses the same ItemBonusMgr system as Timewalking/Remix for item level deltas
// This allows AH to stock gear at varied item levels for players at all progression stages
uint32 scaledItemLevel = prototype->GetBaseItemLevel();
if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_ENABLED))
{
// Check if we should scale this item (equipment-only filter and chance roll)
bool isEquipment = (prototype->GetClass() == ITEM_CLASS_WEAPON || prototype->GetClass() == ITEM_CLASS_ARMOR);
bool shouldScale = !sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_EQUIPMENT_ONLY) || isEquipment;
if (shouldScale && urand(0, 99) < sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_CHANCE))
{
uint32 minLevel = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_MIN_ITEM_LEVEL);
uint32 maxLevel = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_MAX_ITEM_LEVEL);
uint32 targetLevel = urand(minLevel, maxLevel);
// Only scale up, not down - if target is below base level, skip scaling
if (targetLevel > prototype->GetBaseItemLevel())
{
int16 delta = static_cast<int16>(targetLevel - prototype->GetBaseItemLevel());
if (uint32 bonusListId = ItemBonusMgr::GetItemBonusListForItemLevelDelta(delta))
{
item->AddBonuses(bonusListId);
scaledItemLevel = targetLevel;
TC_LOG_DEBUG("ahbot", "AHBot: Scaled item {} from ilvl {} to {} (delta: {}, bonus: {})",
itemId, prototype->GetBaseItemLevel(), targetLevel, delta, bonusListId);
}
else
{
TC_LOG_DEBUG("ahbot", "AHBot: No bonus list found for item {} delta {} - keeping base ilvl {}",
itemId, delta, prototype->GetBaseItemLevel());
}
}
}
}
uint32 buyoutPrice;
uint32 bidPrice = 0;
// Price of items are set here
SetPricesOfItem(prototype, config, buyoutPrice, bidPrice, stackCount);
// Price of items are set here - pass scaled item level for price calculation
SetPricesOfItem(prototype, config, buyoutPrice, bidPrice, stackCount, scaledItemLevel);
// Deposit time
uint32 etime = urand(1, 3);

View File

@@ -142,7 +142,7 @@ private:
void LoadSellerValues(SellerConfiguration& config);
uint32 SetStat(SellerConfiguration& config);
bool GetItemsToSell(SellerConfiguration& config, ItemsToSellArray& itemsToSellArray, AllItemsArray const& addedItem);
void SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyout, uint32& bid, uint32 stackcnt);
void SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyout, uint32& bid, uint32 stackcnt, uint32 scaledItemLevel = 0);
uint32 GetStackSizeForItem(ItemTemplate const* itemProto, SellerConfiguration& config) const;
void LoadItemsQuantity(SellerConfiguration& config);
static uint32 GetBuyModifier(ItemTemplate const* prototype);

View File

@@ -17,10 +17,13 @@
#include "ScriptMgr.h"
#include "AuctionHouseBot.h"
#include "AuctionHouseMgr.h"
#include "Chat.h"
#include "ChatCommand.h"
#include "Item.h"
#include "Language.h"
#include "RBAC.h"
#include <map>
using namespace Trinity::ChatCommands;
@@ -69,6 +72,7 @@ public:
{ "rebuild", HandleAHBotRebuildCommand, rbac::RBAC_PERM_COMMAND_AHBOT_REBUILD, Console::Yes },
{ "reload", HandleAHBotReloadCommand, rbac::RBAC_PERM_COMMAND_AHBOT_RELOAD, Console::Yes },
{ "status", HandleAHBotStatusCommand, rbac::RBAC_PERM_COMMAND_AHBOT_STATUS, Console::Yes },
{ "stats", HandleAHBotStatsCommand, rbac::RBAC_PERM_COMMAND_AHBOT_STATUS, Console::Yes },
};
static ChatCommandTable commandTable =
@@ -188,6 +192,105 @@ public:
return true;
}
// AHBot Stats Command - Reports item level distribution for auction house items
// This is useful for analyzing the effectiveness of item level scaling
// Usage: .ahbot stats [equipment] - shows item level distribution
// equipment flag filters to only weapons/armor
static bool HandleAHBotStatsCommand(ChatHandler* handler, Optional<EXACT_SEQUENCE("equipment")> equipmentOnly)
{
// Item level buckets for distribution analysis
std::map<uint32, uint32> itemLevelBuckets; // bucket -> count
uint32 totalItems = 0;
uint32 equipmentItems = 0;
uint32 minItemLevel = UINT32_MAX;
uint32 maxItemLevel = 0;
uint64 totalItemLevel = 0;
// Iterate through all three auction houses
// AuctionHouseIds: 1=Alliance, 2=Neutral (Goblin), 6=Horde, 7=Neutral (Blackwater)
std::vector<uint32> auctionHouseIds = { 1, 2, 6, 7 };
for (uint32 ahId : auctionHouseIds)
{
AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsById(ahId);
if (!auctionHouse)
continue;
for (auto itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr)
{
AuctionPosting& auction = itr->second;
for (Item* item : auction.Items)
{
if (!item)
continue;
ItemTemplate const* proto = item->GetTemplate();
if (!proto)
continue;
bool isEquipment = (proto->GetClass() == ITEM_CLASS_WEAPON || proto->GetClass() == ITEM_CLASS_ARMOR);
// Skip non-equipment if filter is active
if (equipmentOnly.has_value() && !isEquipment)
continue;
if (isEquipment)
++equipmentItems;
// Get item level from bonus data (includes any scaling bonuses)
// Use static GetItemLevel with minimal parameters since AHBot items have no owner
uint32 itemLevel = Item::GetItemLevel(proto, *item->GetBonus(), 90, 0, 0, 0, 0, false, 0);
++totalItems;
totalItemLevel += itemLevel;
if (itemLevel < minItemLevel)
minItemLevel = itemLevel;
if (itemLevel > maxItemLevel)
maxItemLevel = itemLevel;
// Bucket by 50 item levels for readable output
uint32 bucket = (itemLevel / 50) * 50;
itemLevelBuckets[bucket]++;
}
}
}
if (totalItems == 0)
{
handler->SendSysMessage("AHBot Stats: No items found in auction house.");
return true;
}
// Output results
handler->PSendSysMessage("=== AHBot Item Level Statistics ===");
handler->PSendSysMessage("Total items analyzed: %u", totalItems);
if (!equipmentOnly.has_value())
handler->PSendSysMessage("Equipment items (weapons/armor): %u", equipmentItems);
handler->PSendSysMessage("Item level range: %u - %u", minItemLevel, maxItemLevel);
handler->PSendSysMessage("Average item level: %.1f", static_cast<float>(totalItemLevel) / totalItems);
handler->SendSysMessage("--- Distribution by Item Level ---");
for (auto const& [bucket, count] : itemLevelBuckets)
{
float percentage = (static_cast<float>(count) / totalItems) * 100.0f;
handler->PSendSysMessage(" ilvl %u-%u: %u items (%.1f%%)", bucket, bucket + 49, count, percentage);
}
// Show scaling config status
handler->SendSysMessage("--- Scaling Configuration ---");
handler->PSendSysMessage("Scaling Enabled: %s", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_ENABLED) ? "Yes" : "No");
if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_ENABLED))
{
handler->PSendSysMessage(" Min Target ilvl: %u", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_MIN_ITEM_LEVEL));
handler->PSendSysMessage(" Max Target ilvl: %u", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_MAX_ITEM_LEVEL));
handler->PSendSysMessage(" Scaling Chance: %u%%", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_CHANCE));
handler->PSendSysMessage(" Equipment Only: %s", sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_SCALING_EQUIPMENT_ONLY) ? "Yes" : "No");
}
return true;
}
};
template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GRAY>(ChatHandler* handler, uint32 amount);

View File

@@ -3779,6 +3779,41 @@ AuctionHouseBot.Class.Glyph.Price.Ratio = 100
AuctionHouseBot.Items.ItemLevel.Min = 0
AuctionHouseBot.Items.ItemLevel.Max = 0
#
# AuctionHouseBot.Items.Scaling.*
# Description: Item level scaling for AHBot items. When enabled, equipment items
# posted by AHBot can receive random item level bonuses, allowing
# the AH to stock gear suitable for all player progression levels.
# Uses the same ItemBonusMgr system as Timewalking/Remix scaling.
#
# AuctionHouseBot.Items.Scaling.Enabled
# Description: Enable item level scaling for AHBot items
# Default: 0 - (Disabled, items use base item level)
# 1 - (Enabled, items may receive random item level bonuses)
#
# AuctionHouseBot.Items.Scaling.MinItemLevel
# Description: Minimum target item level for scaled items
# Default: 0 - (Use item's base level as minimum)
#
# AuctionHouseBot.Items.Scaling.MaxItemLevel
# Description: Maximum target item level for scaled items
# Default: 550 - (MoP raid gear level)
#
# AuctionHouseBot.Items.Scaling.Chance
# Description: Percentage chance (0-100) for each item to be scaled
# Default: 50 - (50% of eligible items get scaled)
#
# AuctionHouseBot.Items.Scaling.EquipmentOnly
# Description: Only scale equipment (weapons/armor), not consumables/materials
# Default: 1 - (Only equipment is scaled)
# 0 - (All item types can be scaled)
AuctionHouseBot.Items.Scaling.Enabled = 0
AuctionHouseBot.Items.Scaling.MinItemLevel = 0
AuctionHouseBot.Items.Scaling.MaxItemLevel = 550
AuctionHouseBot.Items.Scaling.Chance = 50
AuctionHouseBot.Items.Scaling.EquipmentOnly = 1
#
# AuctionHouseBot.Items.ReqLevel.*
# Description: Prevent seller from listing items below/above this required level