From 67ac281e60ec1ad10c16c24e8e819f7cd05fb10d Mon Sep 17 00:00:00 2001 From: NathanHandley Date: Tue, 16 Sep 2025 18:57:06 -0500 Subject: [PATCH] Add categories for item level multipliers --- conf/mod_ahbot.conf.dist | 21 +++++++- src/AuctionHouseBot.cpp | 100 +++++++++++++++++++++++++++++---------- src/AuctionHouseBot.h | 16 ++++++- 3 files changed, 110 insertions(+), 27 deletions(-) diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index a66224e..25e51f5 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -224,6 +224,8 @@ AuctionHouseBot.AdvancedPricing.Misc.Mount.Enabled = 1 # Multiplier applied to item level when determining auction price # Final multiplier = itemLevel * this value. Set to 0 (or less) to disable. # Default: 0 (Disabled) +# Note: This will be ignored if AdvancedPricing is enabled (above), but this +# will apply in combination with other price multipliers # # AuctionHouseBot.PriceMultiplier.Category*.Quality* # Category-and-Quality- modifier values for the prices of items. @@ -238,6 +240,7 @@ AuctionHouseBot.AdvancedPricing.Misc.Mount.Enabled = 1 # (above) would then multiply that value further. ############################################################################### +# Broad category multipliers AuctionHouseBot.PriceMultiplier.Category.Consumable = 1 AuctionHouseBot.PriceMultiplier.Category.Container = 1 AuctionHouseBot.PriceMultiplier.Category.Weapon = 1 @@ -254,6 +257,7 @@ AuctionHouseBot.PriceMultiplier.Category.Key = 1 AuctionHouseBot.PriceMultiplier.Category.Misc = 1 AuctionHouseBot.PriceMultiplier.Category.Glyph = 1 +# Broad quality multipliers AuctionHouseBot.PriceMultiplier.Quality.Poor = 1 AuctionHouseBot.PriceMultiplier.Quality.Normal = 1 AuctionHouseBot.PriceMultiplier.Quality.Uncommon = 1.8 @@ -263,7 +267,22 @@ AuctionHouseBot.PriceMultiplier.Quality.Legendary = 3 AuctionHouseBot.PriceMultiplier.Quality.Artifact = 3 AuctionHouseBot.PriceMultiplier.Quality.Heirloom = 3 -AuctionHouseBot.PriceMultiplier.ItemLevel = 0 +# Category item level multiplier (item itemlevel x this value, 0 = disabled) +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Consumable = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Container = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Weapon = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Gem = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Armor = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Reagent = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Projectile = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.TradeGood = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Generic = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Recipe = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Quiver = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Quest = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Key = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Misc = 0 +AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Glyph = 0 # Consumable AuctionHouseBot.PriceMultiplier.CategoryConsumable.QualityPoor = 1.0 diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index 1e65715..d9970a3 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -111,6 +111,21 @@ AuctionHouseBot::AuctionHouseBot() : PriceMultiplierCategoryKey(1), PriceMultiplierCategoryMisc(1), PriceMultiplierCategoryGlyph(1), + PriceMultiplierItemLevelCategoryConsumable(0), + PriceMultiplierItemLevelCategoryContainer(0), + PriceMultiplierItemLevelCategoryWeapon(0), + PriceMultiplierItemLevelCategoryGem(0), + PriceMultiplierItemLevelCategoryArmor(0), + PriceMultiplierItemLevelCategoryReagent(0), + PriceMultiplierItemLevelCategoryProjectile(0), + PriceMultiplierItemLevelCategoryTradeGood(0), + PriceMultiplierItemLevelCategoryGeneric(0), + PriceMultiplierItemLevelCategoryRecipe(0), + PriceMultiplierItemLevelCategoryQuiver(0), + PriceMultiplierItemLevelCategoryQuest(0), + PriceMultiplierItemLevelCategoryKey(0), + PriceMultiplierItemLevelCategoryMisc(0), + PriceMultiplierItemLevelCategoryGlyph(0), PriceMultiplierQualityPoor(1), PriceMultiplierQualityNormal(1), PriceMultiplierQualityUncommon(1), @@ -134,7 +149,6 @@ AuctionHouseBot::AuctionHouseBot() : PriceMinimumCenterBaseKey(1), PriceMinimumCenterBaseMisc(1), PriceMinimumCenterBaseGlyph(1), - ItemLevelPriceMultiplier(1), ListedItemIDRestrictedEnabled(false), ListedItemIDMin(0), ListedItemIDMax(200000), @@ -277,7 +291,7 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& */ // Try to approximate real world prices for Trade Goods based on subclass and item level - double subclassPriceMultiplier = 1.0f; + double advancedPriceingMultiplier = 1.0f; if (itemProto->Class == ITEM_CLASS_TRADE_GOODS) { switch (itemProto->SubClass) @@ -287,7 +301,7 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& if (!AdvancedPricingTradeGoodClothEnabled) break; double clothMultiplierHelper = std::log(1.0 + (itemProto->ItemLevel)); - subclassPriceMultiplier = ((std::pow(clothMultiplierHelper,2.0)) / (1 + (0.8 * clothMultiplierHelper))) + (0.001 * std::pow(clothMultiplierHelper,3.5)) - 0.3; + advancedPriceingMultiplier = ((std::pow(clothMultiplierHelper,2.0)) / (1 + (0.8 * clothMultiplierHelper))) + (0.001 * std::pow(clothMultiplierHelper,3.5)) - 0.3; break; } case ITEM_SUBCLASS_HERB: @@ -295,7 +309,7 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& if (!AdvancedPricingTradeGoodHerbEnabled) break; double herbMultiplierHelper = std::log(1.0 + (5.0 * itemProto->ItemLevel)); - subclassPriceMultiplier = (std::pow(herbMultiplierHelper,3.0) / (1 + (1.8 * herbMultiplierHelper))) - 4.2; + advancedPriceingMultiplier = (std::pow(herbMultiplierHelper,3.0) / (1 + (1.8 * herbMultiplierHelper))) - 4.2; break; } case ITEM_SUBCLASS_METAL_STONE: @@ -303,7 +317,7 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& if (!AdvancedPricingTradeGoodMetalStoneEnabled) break; double metalMultiplierHelper = std::log(1.0 + (75.0 * itemProto->ItemLevel)); - subclassPriceMultiplier = ((std::pow(metalMultiplierHelper,3.0)) / (1 + (7.0 * metalMultiplierHelper))) + (0.001 * std::pow(metalMultiplierHelper,3.5)) - 5.2; + advancedPriceingMultiplier = ((std::pow(metalMultiplierHelper,3.0)) / (1 + (7.0 * metalMultiplierHelper))) + (0.001 * std::pow(metalMultiplierHelper,3.5)) - 5.2; break; } case ITEM_SUBCLASS_LEATHER: @@ -311,7 +325,7 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& if (!AdvancedPricingTradeGoodLeatherEnabled) break; double leatherMultiplierHelper = std::log(1.0 + (0.25 * itemProto->ItemLevel)); - subclassPriceMultiplier = ((std::pow(leatherMultiplierHelper,0.15)) / (1 + (2.0 * leatherMultiplierHelper))) + (0.4 * std::pow(leatherMultiplierHelper,3.0)) - 0.2; + advancedPriceingMultiplier = ((std::pow(leatherMultiplierHelper,0.15)) / (1 + (2.0 * leatherMultiplierHelper))) + (0.4 * std::pow(leatherMultiplierHelper,3.0)) - 0.2; break; } case ITEM_SUBCLASS_ENCHANTING: @@ -319,14 +333,14 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& if (!AdvancedPricingTradeGoodEnchantingEnabled) break; double enchantingMultiplierHelper = std::log(1.0 + (0.25 * itemProto->ItemLevel)); - subclassPriceMultiplier = ((std::pow(enchantingMultiplierHelper,0.15)) / (1 + (2.0 * enchantingMultiplierHelper))) + (0.4 * std::pow(enchantingMultiplierHelper,3.0)) - 0.2; + advancedPriceingMultiplier = ((std::pow(enchantingMultiplierHelper,0.15)) / (1 + (2.0 * enchantingMultiplierHelper))) + (0.4 * std::pow(enchantingMultiplierHelper,3.0)) - 0.2; break; } case ITEM_SUBCLASS_ELEMENTAL: { if (!AdvancedPricingTradeGoodElementalEnabled) break; - subclassPriceMultiplier = 85 - (itemProto->ItemLevel / 0.97); + advancedPriceingMultiplier = 85 - (itemProto->ItemLevel / 0.97); break; } default: @@ -343,7 +357,7 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& if (!AdvancedPricingMiscJunkEnabled) break; double miscMultiplierHelper = std::log(1.0 + (0.12 * itemProto->ItemLevel)); - subclassPriceMultiplier = (std::pow(miscMultiplierHelper,3.2) / (1 + miscMultiplierHelper)); + advancedPriceingMultiplier = (std::pow(miscMultiplierHelper,3.2) / (1 + miscMultiplierHelper)); break; } case ITEM_SUBCLASS_JUNK_MOUNT: @@ -352,14 +366,14 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& break; switch (itemProto->Quality) { - case ITEM_QUALITY_POOR: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityPoor; break; - case ITEM_QUALITY_NORMAL: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityNormal; break; - case ITEM_QUALITY_UNCOMMON: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityUncommon; break; - case ITEM_QUALITY_RARE: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityRare; break; - case ITEM_QUALITY_EPIC: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityEpic; break; - case ITEM_QUALITY_LEGENDARY: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityLegendary; break; - case ITEM_QUALITY_ARTIFACT: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityArtifact; break; - case ITEM_QUALITY_HEIRLOOM: subclassPriceMultiplier = PriceMultiplierCategoryMountQualityHeirloom; break; + case ITEM_QUALITY_POOR: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityPoor; break; + case ITEM_QUALITY_NORMAL: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityNormal; break; + case ITEM_QUALITY_UNCOMMON: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityUncommon; break; + case ITEM_QUALITY_RARE: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityRare; break; + case ITEM_QUALITY_EPIC: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityEpic; break; + case ITEM_QUALITY_LEGENDARY: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityLegendary; break; + case ITEM_QUALITY_ARTIFACT: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityArtifact; break; + case ITEM_QUALITY_HEIRLOOM: advancedPriceingMultiplier = PriceMultiplierCategoryMountQualityHeirloom; break; default: break; } break; @@ -409,18 +423,40 @@ void AuctionHouseBot::calculateItemValue(ItemTemplate const* itemProto, uint64& qualityPriceMultplier = 1.0f; if (classQualityPriceMultiplier <= 0.0f) classQualityPriceMultiplier = 1.0f; - if (subclassPriceMultiplier <= 0.0f) - subclassPriceMultiplier = 1.0f; - + if (advancedPriceingMultiplier <= 0.0f) + advancedPriceingMultiplier = 1.0f; + + // Grab any item level price multipliers + float itemLevelPriceMultplier = 0.0f; + switch (itemProto->Class) + { + case ITEM_CLASS_CONSUMABLE: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryConsumable; break; + case ITEM_CLASS_CONTAINER: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryContainer; break; + case ITEM_CLASS_WEAPON: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryWeapon; break; + case ITEM_CLASS_GEM: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryGem; break; + case ITEM_CLASS_REAGENT: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryReagent; break; + case ITEM_CLASS_ARMOR: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryArmor; break; + case ITEM_CLASS_PROJECTILE: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryProjectile; break; + case ITEM_CLASS_TRADE_GOODS: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryTradeGood; break; + case ITEM_CLASS_GENERIC: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryGeneric; break; + case ITEM_CLASS_RECIPE: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryRecipe; break; + case ITEM_CLASS_QUIVER: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryQuiver; break; + case ITEM_CLASS_QUEST: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryQuest; break; + case ITEM_CLASS_KEY: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryKey; break; + case ITEM_CLASS_MISC: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryMisc; break; + case ITEM_CLASS_GLYPH: itemLevelPriceMultplier = PriceMultiplierItemLevelCategoryGlyph; break; + default: break; + } + // Multiply the price based on multipliers outBuyoutPrice *= qualityPriceMultplier; outBuyoutPrice *= classPriceMultiplier; outBuyoutPrice *= classQualityPriceMultiplier; - outBuyoutPrice *= static_cast(subclassPriceMultiplier); + outBuyoutPrice *= static_cast(advancedPriceingMultiplier); - // Apply item level multiplier. Only if no subclass multiplier was applied - if (ItemLevelPriceMultiplier > 0.0f && itemProto->ItemLevel > 0 && subclassPriceMultiplier == 1.0f) - outBuyoutPrice *= itemProto->ItemLevel * ItemLevelPriceMultiplier; + // Only apply item level multiplier if set, and no advanced pricing has been enabled + if (itemLevelPriceMultplier > 0.0f && itemProto->ItemLevel > 0 && advancedPriceingMultiplier == 1.0f) + outBuyoutPrice *= itemProto->ItemLevel * itemLevelPriceMultplier; // If a vendor sells this item, make the price at least that high if (itemProto->SellPrice > outBuyoutPrice) @@ -1217,6 +1253,21 @@ void AuctionHouseBot::InitializeConfiguration() PriceMultiplierCategoryKey = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Category.Key", 1); PriceMultiplierCategoryMisc = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Category.Misc", 1); PriceMultiplierCategoryGlyph = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Category.Glyph", 1); + PriceMultiplierItemLevelCategoryConsumable = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Consumable", 0); + PriceMultiplierItemLevelCategoryContainer = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Container", 0); + PriceMultiplierItemLevelCategoryWeapon = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Weapon", 0); + PriceMultiplierItemLevelCategoryGem = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Gem", 0); + PriceMultiplierItemLevelCategoryArmor = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Armor", 0); + PriceMultiplierItemLevelCategoryReagent = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Reagent", 0); + PriceMultiplierItemLevelCategoryProjectile = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Projectile", 0); + PriceMultiplierItemLevelCategoryTradeGood = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.TradeGood", 0); + PriceMultiplierItemLevelCategoryGeneric = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Generic", 0); + PriceMultiplierItemLevelCategoryRecipe = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Recipe", 0); + PriceMultiplierItemLevelCategoryQuiver = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Quiver", 0); + PriceMultiplierItemLevelCategoryQuest = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Quest", 0); + PriceMultiplierItemLevelCategoryKey = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Key", 0); + PriceMultiplierItemLevelCategoryMisc = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Misc", 0); + PriceMultiplierItemLevelCategoryGlyph = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel.Category.Glyph", 0); PriceMultiplierQualityPoor = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Quality.Poor", 1); PriceMultiplierQualityNormal = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Quality.Normal", 1); PriceMultiplierQualityUncommon = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Quality.Uncommon", 1.8); @@ -1225,7 +1276,6 @@ void AuctionHouseBot::InitializeConfiguration() PriceMultiplierQualityLegendary = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Quality.Legendary", 3); PriceMultiplierQualityArtifact = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Quality.Artifact", 3); PriceMultiplierQualityHeirloom = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.Quality.Heirloom", 3); - ItemLevelPriceMultiplier = sConfigMgr->GetOption("AuctionHouseBot.PriceMultiplier.ItemLevel", 0); for (int category = 0; category < MAX_ITEM_CLASS; category++) { for (int quality = 0; quality < MAX_ITEM_QUALITY; quality++) diff --git a/src/AuctionHouseBot.h b/src/AuctionHouseBot.h index 6adee46..bdc3f49 100644 --- a/src/AuctionHouseBot.h +++ b/src/AuctionHouseBot.h @@ -197,6 +197,21 @@ private: float PriceMultiplierCategoryKey; float PriceMultiplierCategoryMisc; float PriceMultiplierCategoryGlyph; + float PriceMultiplierItemLevelCategoryConsumable; + float PriceMultiplierItemLevelCategoryContainer; + float PriceMultiplierItemLevelCategoryWeapon; + float PriceMultiplierItemLevelCategoryGem; + float PriceMultiplierItemLevelCategoryArmor; + float PriceMultiplierItemLevelCategoryReagent; + float PriceMultiplierItemLevelCategoryProjectile; + float PriceMultiplierItemLevelCategoryTradeGood; + float PriceMultiplierItemLevelCategoryGeneric; + float PriceMultiplierItemLevelCategoryRecipe; + float PriceMultiplierItemLevelCategoryQuiver; + float PriceMultiplierItemLevelCategoryQuest; + float PriceMultiplierItemLevelCategoryKey; + float PriceMultiplierItemLevelCategoryMisc; + float PriceMultiplierItemLevelCategoryGlyph; float PriceMultiplierQualityPoor; float PriceMultiplierQualityNormal; float PriceMultiplierQualityUncommon; @@ -238,7 +253,6 @@ private: uint32 PriceMinimumCenterBaseMisc; uint32 PriceMinimumCenterBaseGlyph; std::unordered_map PriceMinimumCenterBaseOverridesByItemID; - float ItemLevelPriceMultiplier; bool ListedItemIDRestrictedEnabled; uint32 ListedItemIDMin; uint32 ListedItemIDMax;