Compare commits

..

24 Commits

Author SHA1 Message Date
NathanHandley
55a403133e Re-enable common weapons and armor
This should be managed by listing proportions anyway.  Added some invalid item IDs to purge a few bad items.
2026-01-06 08:52:36 -06:00
NathanHandley
9bd64af3a9 Update comments about the 25% random spread 2026-01-06 08:44:19 -06:00
NathanHandley
dcb615212d Add ability to filter items by use or equip level 2026-01-06 08:41:32 -06:00
Nathan Handley
5561885b8b Merge pull request #49 from zeb139/issue-47
Fixed handling of null UseDropRates.<Category>.AffectedQualities configs. Improved module disablement
2025-11-11 22:01:32 -06:00
zeb
41fd346a6e improved module disablement when AuctionHouseBot.GUIDs is not configured 2025-11-11 22:33:33 -05:00
zeb
8038fec2db fixed handling of null UseDropRates.<Category>.AffectedQualities configs 2025-11-11 22:22:29 -05:00
Nathan Handley
7db32506d2 Update README.md 2025-11-11 18:09:35 -06:00
Nathan Handley
a2f55d3df0 Merge pull request #48 from zeb139/issue-46
Added mod-ah-bot backwards compatible script loader
2025-11-11 18:07:05 -06:00
zeb
c2e3be9e57 added mod-ah-bot backwards compatible script loader 2025-11-11 19:03:31 -05:00
Nathan Handley
a3385f09be Update README.md 2025-11-11 17:19:04 -06:00
Nathan Handley
d5ad1f9020 Add note about repository rename 2025-11-09 15:33:26 -06:00
Nathan Handley
d197c00963 Merge pull request #45 from zeb139/master
Fix build error: undefined reference to `Addmod_ah_bot_plusScripts()'
2025-11-09 15:10:07 -06:00
zeb
4863229bb6 fixed new name build error 2025-11-09 15:26:48 -05:00
Nathan Handley
c35954cc21 Update README.md 2025-11-09 07:18:48 -06:00
Nathan Handley
6fd491277a Remove old text block about professions 2025-11-09 07:13:16 -06:00
Nathan Handley
43e82355b4 Clarify comments on exclusion 2025-11-08 23:44:04 -06:00
Nathan Handley
1df870435a Merge pull request #44 from zeb139/issue-43
Improved logging for some cases of ParseNumberListToSet, Fixed erroneous duplicate entries error logging
2025-11-07 19:47:45 -06:00
zeb
cd2d0146bb improved logging for some cases of ParseNumberListToSet, fixed erroneous duplicate entries error logging 2025-11-07 14:23:54 -05:00
Nathan Handley
f326bee515 Merge pull request #41 from zeb139/development
Add Advanced_Pricing_Calculator spreadsheet tool
2025-10-25 15:10:31 -05:00
zeb
8079160ef5 added Advanced_Pricing_Calculator spreadsheet tool 2025-10-24 14:00:23 -04:00
Nathan Handley
b6a7c651c5 Merge pull request #40 from zeb139/development
Improved UseDropRates item selection logic, Removed duplicates from ItemTiersByClassAndQuality
2025-10-17 19:29:13 -05:00
zeb
f935be7b88 improved UseDropRates item selection logic, removed duplicates from ItemTiersByClassAndQuality 2025-10-15 11:53:45 -04:00
Nathan Handley
6c4195b102 Merge pull request #39 from zeb139/add-usedroprates-minrate
Added UseDropRates.MinDropRate + other fixes
2025-10-14 08:53:26 -05:00
zeb
00e1fe1988 Added UseDropRates.MinDropRate 2025-10-14 08:28:43 -04:00
8 changed files with 206 additions and 62 deletions

View File

@@ -1,4 +1,4 @@
## Description
## Auction Bot Plus
This is a fork of the auction house bot for AzerothCore. This fork gives a much more blizzlike experience in the offerings on the auction house, and it is built with the following ethos: "Maximum understandable customization in the hands of admins via non-SQL configurations". Here are some of the feature highlights:
- All configuration is done via config files, with no SQL configuration needed
@@ -27,7 +27,6 @@ Requires an AzerothCore version that is caught up to at least change set 3f46e05
Notes:
- These accounts do not need any security level and can be a player accounts.
- The characters used by the ahbot are not meant to be used ingame. If you use it to browse the auction house, you might have issues like "Searching for items..." displaying forever.
- Important! By default, most player crafted items (except glyphs, bolts, maybe a few other things) are disabled from showing up in the auction house in order to encourage player crafting on lower pop servers. If you want different behavior, alter the config variable "AuctionHouseBot.DisabledCraftedItemIDs" by deleting IDs you wish to show up. Note that fish are also disabled to encourage fishing, and that's also managed by disabled lists.
- It takes a few hours for the auction house to fully populate, as only 75 items gets added by default every 'tick'. You can change this in the config with the AuctionHouseBot.ItemsPerCycle variable.
- All price multpliers (along with the advanced pricing, see config) are applied multiplicative. Example: A Category of 1.5x, Quality of 2x, and CategoryQuality of 1.4x would make the multiplier 4.2 (1.5 x 2 x 1.4). The advanced pricing would then multiply that value further. Using item level price multpliers, which create a multiplier of itemlevel x value, is also multiplicitive along with the others. You cannot use item level price multipliers and advanced pricing, as advanced pricing will take priority between the two.
- Bot-listed prices will not exceed 100k gold buyout. This can be reduced via the configuration if you want.
@@ -46,11 +45,17 @@ The AuctionHouseBot module adds the following in-game commands (for GMs only):
## Buying Bot Behavior
1. **Determining Items to Buy:** Every minute the buyer bot will select (BuyCandidatesPerBuyCycle) items currently up for auction which are listed by players as potential purchase items.
2. **Price Willing to Pay:** The buyer bot will use the same item price calculation the seller bot uses, including the random +/- 25%, and that calculated price is then multiplied by (AcceptablePriceModifier) which then becomes the price the buyer will be willing to spend.
2. **Price Willing to Pay:** The buyer bot will use the same item price calculation the seller bot uses, including the random +/- 25% (configurable), and that calculated price is then multiplied by (AcceptablePriceModifier) which then becomes the price the buyer will be willing to spend.
3. **Buying it:** If the price calculated is higher than the buy out price, then the bot will buy it out. If not, it will test to see if it has been bidded on by a bot and if not, if the bid price is below the price it is willing to pay. If so, it will bid (outbid, so just over current bid).
The above behavior is replicated on each enabled auction house. If left to default settings, 1 item in each auction house will attempt to be bought from, if the price calculation seems favorable. Note that any item buy attempt, even items above buying price, consumes a buy candidate. That means that too many overpriced items can drown out potential sales.
## Additional Resources
[Advanced Pricing Calculator](tools/AdvancedPricingCalculator/Advanced_Pricing_Calculator.xlsx) - If `AuctionHouseBot.AdvancedPricing.<Category>.<Subclass>.Enabled` is enabled, this spreadsheet can help quickly visualize how config settings affect in-game prices.
## Credits
- NathanHandley: Created this rewrite of the one that was ported to AzerothCore

File diff suppressed because one or more lines are too long

View File

@@ -68,8 +68,11 @@ AuctionHouseBot::AuctionHouseBot() :
DisabledRecipeProducedItemFilterEnabled(false),
ListedItemLevelRestrictedEnabled(false),
ListedItemLevelRestrictedUseCraftedItemForCalculation(true),
ListedItemLevelMax(999),
ListedItemLevelMin(0),
ListedItemLevelMax(999),
ListedItemUseOrEquipRestrictedEnabled(false),
ListedItemUseOrEquipRestrictMinLevel(0),
ListedItemUseOrEquipRestrictMaxLevel(999),
RandomStackRatioConsumable(1),
RandomStackRatioContainer(1),
RandomStackRatioWeapon(1),
@@ -161,6 +164,7 @@ AuctionHouseBot::AuctionHouseBot() :
AdvancedListingRuleUseDropRatesWeaponEnabled(true),
AdvancedListingRuleUseDropRatesArmorEnabled(true),
AdvancedListingRuleUseDropRatesRecipeEnabled(true),
AdvancedListingRuleUseDropRatesMinDropRate(0.005),
LastBuyCycleCount(0),
LastSellCycleCount(0),
ActiveListMultipleItemID(0),
@@ -727,6 +731,29 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
}
}
// If there is a use/equip level exception, honor it
if (ListedItemUseOrEquipRestrictedEnabled == true)
{
// Only test if it's not an exception
if (ListedItemUseOrEquipExceptionItems.find(itr->second.ItemId) == ListedItemUseOrEquipExceptionItems.end())
{
uint32 useOrEquipLevelCompare = itr->second.RequiredLevel;
if (useOrEquipLevelCompare > 0 && useOrEquipLevelCompare < ListedItemUseOrEquipRestrictMinLevel)
{
if (debug_Out_Filters)
LOG_ERROR("module", "AuctionHouseBot: Item {} disabled since item use or equip level is lower than EquipItemUseOrEquipLevelRestrict.MinItemLevel", itr->second.ItemId);
continue;
}
if (useOrEquipLevelCompare > 0 && useOrEquipLevelCompare > ListedItemUseOrEquipRestrictMaxLevel)
{
if (debug_Out_Filters)
LOG_ERROR("module", "AuctionHouseBot: Item {} disabled since item use or equip level is higher than EquipItemUseOrEquipLevelRestrict.MaxItemLevel", itr->second.ItemId);
continue;
}
}
}
// Disabled items by Id
if (DisabledItems.find(itr->second.ItemId) != DisabledItems.end())
{
@@ -823,7 +850,8 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
itr->second.Name1.find("]") != std::string::npos ||
itr->second.Name1.find("D'Sak") != std::string::npos ||
itr->second.Name1.find("(") != std::string::npos ||
itr->second.Name1.find("OLD") != std::string::npos))
itr->second.Name1.find("OLD") != std::string::npos ||
itr->second.Name1.find("PVP") != std::string::npos))
{
if (debug_Out_Filters)
LOG_ERROR("module", "AuctionHouseBot: Item {} disabled item with a temp or unused item name", itr->second.ItemId);
@@ -849,22 +877,6 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
continue;
}
// Disable common weapons
if (itr->second.Quality == ITEM_QUALITY_NORMAL && itr->second.Class == ITEM_CLASS_WEAPON)
{
if (debug_Out_Filters)
LOG_ERROR("module", "AuctionHouseBot: Item {} disabled common weapon", itr->second.ItemId);
continue;
}
// Disable common armor
if (itr->second.Quality == ITEM_QUALITY_NORMAL && itr->second.Class == ITEM_CLASS_ARMOR)
{
if (debug_Out_Filters)
LOG_ERROR("module", "AuctionHouseBot: Item {} disabled common non-misc armor", itr->second.ItemId);
continue;
}
// Store the item ID
ItemCandidatesByItemClassAndQuality[itr->second.Class][itr->second.Quality].push_back(itr->second.ItemId);
}
@@ -1100,10 +1112,10 @@ bool AuctionHouseBot::HandleAdvancedListingRuleUseDropRates(ItemTemplate const*&
double r = 100.0 * (urand(0, INT32_MAX) / static_cast<double>(INT32_MAX));
int tier = GetItemDropChanceTier(r);
// If chosen tier is empty, search rarer tiers until not empty
// If chosen tier is empty, search more common tiers until not empty
auto& tierBuckets = ItemTiersByClassAndQuality[proto->Class][proto->Quality];
while (tierBuckets[tier].empty() && tier < 10) {
tier++;
while (tierBuckets[tier].empty() && tier > 0) {
tier--;
}
// Pull a random item from selected rarity tier
@@ -1196,11 +1208,11 @@ void AuctionHouseBot::PopulateItemDropChances()
for (size_t k = 0; k < tiers.size(); ++k)
{
const auto& items = tiers[k];
if (i == 2)
LOG_INFO("module", "Armor Count: {} Tier {} has {} items", GetQualityName((ItemQualities)j), k, items.size());
if (i == 4)
if (i == ITEM_CLASS_WEAPON)
LOG_INFO("module", "Weapon Count: {} Tier {} has {} items", GetQualityName((ItemQualities)j), k, items.size());
if (i == 9)
if (i == ITEM_CLASS_ARMOR)
LOG_INFO("module", "Armor Count: {} Tier {} has {} items", GetQualityName((ItemQualities)j), k, items.size());
if (i == ITEM_CLASS_RECIPE)
LOG_INFO("module", "Recipe Count: {} Tier {} has {} items", GetQualityName((ItemQualities)j), k, items.size());
}
}
@@ -1210,6 +1222,14 @@ void AuctionHouseBot::PopulateItemDropChances()
void AuctionHouseBot::PopulateItemDropChancesForCategoryAndQuality(ItemClass category, std::string qualities)
{
if (qualities.empty())
{
LOG_ERROR("module", "AuctionHouseBot: PopulateItemDropChancesForCategoryAndQuality() qualities are not set. "
"Verify that mod_ahbot.conf has values for AdvancedListingRules.UseDropRates.<Category>.AffectedQualities. "
"Defaulting to '2,3,4,5' to prevent crash.");
qualities = "2,3,4,5";
}
// Search creature loot templates, referenced loot_loot_template, group_loot tables, and object_loot tables for items' drop rates
std::string directDropString = R"SQL(
with chances AS (
@@ -1292,7 +1312,7 @@ void AuctionHouseBot::PopulateItemDropChancesForCategoryAndQuality(ItemClass cat
SELECT itemID,
0 AS direct_chance,
AVG(reference_chance) AS reference_chance
MIN(reference_chance) AS reference_chance
FROM chances
GROUP BY itemID
)SQL";
@@ -1347,7 +1367,7 @@ void AuctionHouseBot::PopulateItemDropChancesForCategoryAndQuality(ItemClass cat
}
// Add drop rate of all results to CachedItemDropRates
auto parseResults = [this](QueryResult result)
auto parseResults = [this](QueryResult result, bool overwriteDropRate)
{
do {
Field* fields = result->Fetch();
@@ -1359,12 +1379,17 @@ void AuctionHouseBot::PopulateItemDropChancesForCategoryAndQuality(ItemClass cat
if (IsItemQuestReward(itemID) || IsItemCrafted(itemID))
continue;
if (CachedItemDropRates.contains(itemID) && !overwriteDropRate)
continue;
if (!fields[1].IsNull())
directDropChance = fields[1].Get<double>();
if (!fields[2].IsNull())
referenceDropChance = fields[2].Get<double>();
// Choose higher of two rates (one is normally 0), then raise to MinDropRate if less than
double higherDropChance = (directDropChance > referenceDropChance) ? directDropChance : referenceDropChance;
higherDropChance = (higherDropChance < AdvancedListingRuleUseDropRatesMinDropRate) ? AdvancedListingRuleUseDropRatesMinDropRate : higherDropChance;
if (CachedItemDropRates[itemID] < higherDropChance)
CachedItemDropRates[itemID] = higherDropChance;
@@ -1372,11 +1397,11 @@ void AuctionHouseBot::PopulateItemDropChancesForCategoryAndQuality(ItemClass cat
} while (result->NextRow());
};
parseResults(directResult);
parseResults(referenceResult);
parseResults(danglingReferenceResult);
parseResults(groupResult);
parseResults(objectsDropResult);
parseResults(directResult, true);
parseResults(referenceResult, true);
parseResults(danglingReferenceResult, false);
parseResults(groupResult, true);
parseResults(objectsDropResult, true);
// Populate drop rates Tiers
for (auto& [classID, qualityGroups] : ItemCandidatesByItemClassAndQuality)
@@ -1399,6 +1424,14 @@ void AuctionHouseBot::PopulateItemDropChancesForCategoryAndQuality(ItemClass cat
}
}
}
// Remove duplicates
for (auto& byClass : ItemTiersByClassAndQuality)
for (auto& byQuality : byClass)
for (auto& byTier : byQuality) {
std::sort(byTier.begin(), byTier.end());
byTier.erase(std::unique(byTier.begin(), byTier.end()), byTier.end());
}
}
void AuctionHouseBot::InitializeAdvancedListingRuleUseDropRatesTiers()
@@ -1706,8 +1739,6 @@ void AuctionHouseBot::Update()
if (AHCharacters.empty() == true)
return;
CleanupExpiredAuctionItems();
if ((SellingBotEnabled == false) && (BuyingBotEnabled == false))
return;
@@ -1787,24 +1818,30 @@ void AuctionHouseBot::Update()
ObjectAccessor::RemoveObject(player.get());
}
bool AuctionHouseBot::IsModuleEnabled()
{
bool sellerEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.EnableSeller", false);
bool buyerEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.Buyer.Enabled", false);
if (sellerEnabled == false && buyerEnabled == false)
return false;
string charString = sConfigMgr->GetOption<std::string>("AuctionHouseBot.GUIDs", "0");
if (charString == "0" || charString.empty())
{
LOG_INFO("module", "AuctionHouseBot: AuctionHouseBot.GUIDs is not configured so this module will be disabled");
return false;
}
return true;
}
void AuctionHouseBot::InitializeConfiguration()
{
debug_Out = sConfigMgr->GetOption<bool>("AuctionHouseBot.DEBUG", false);
debug_Out_Filters = sConfigMgr->GetOption<bool>("AuctionHouseBot.DEBUG_FILTERS", false);
// Bot enablement
SellingBotEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.EnableSeller", false);
BuyingBotEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.Buyer.Enabled", false);
if (SellingBotEnabled == false && BuyingBotEnabled == false)
return;
string charString = sConfigMgr->GetOption<std::string>("AuctionHouseBot.GUIDs", "0");
if (charString == "0")
{
BuyingBotEnabled = false;
SellingBotEnabled = false;
LOG_INFO("module", "AuctionHouseBot: AuctionHouseBot.GUIDs is '0' so this module will be disabled");
return;
}
AddCharacters(charString);
// Buyer & Seller core properties
@@ -1815,9 +1852,14 @@ void AuctionHouseBot::InitializeConfiguration()
AdvancedListingRuleUseDropRatesWeaponEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Weapon", true);
AdvancedListingRuleUseDropRatesArmorEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Armor", true);
AdvancedListingRuleUseDropRatesRecipeEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Recipe", true);
ParseNumberListToSet(AdvancedListingRuleUseDropRatesWeaponAffectedQualities, sConfigMgr->GetOption<std::string>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Weapon.AffectedQualities", "2,3,4,5"), "");
ParseNumberListToSet(AdvancedListingRuleUseDropRatesArmorAffectedQualities, sConfigMgr->GetOption<std::string>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Armor.AffectedQualities", "2,3,4,5"), "");
ParseNumberListToSet(AdvancedListingRuleUseDropRatesRecipeAffectedQualities, sConfigMgr->GetOption<std::string>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Recipe.AffectedQualities", "2,3,4,5"), "");
AdvancedListingRuleUseDropRatesMinDropRate = sConfigMgr->GetOption<float>("AuctionHouseBot.AdvancedListingRules.UseDropRates.MinDropRate", 0.005);
if (AdvancedListingRuleUseDropRatesMinDropRate < 0 || AdvancedListingRuleUseDropRatesMinDropRate > 100) AdvancedListingRuleUseDropRatesMinDropRate = 0.005;
AdvancedListingRuleUseDropRatesWeaponAffectedQualities.clear();
AdvancedListingRuleUseDropRatesArmorAffectedQualities.clear();
AdvancedListingRuleUseDropRatesRecipeAffectedQualities.clear();
ParseNumberListToSet(AdvancedListingRuleUseDropRatesWeaponAffectedQualities, sConfigMgr->GetOption<std::string>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Weapon.AffectedQualities", "2,3,4,5"), "AdvancedListingRules.UseDropRates.Weapon.AffectedQualities");
ParseNumberListToSet(AdvancedListingRuleUseDropRatesArmorAffectedQualities, sConfigMgr->GetOption<std::string>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Armor.AffectedQualities", "2,3,4,5"), "AdvancedListingRules.UseDropRates.Armor.AffectedQualities");
ParseNumberListToSet(AdvancedListingRuleUseDropRatesRecipeAffectedQualities, sConfigMgr->GetOption<std::string>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Recipe.AffectedQualities", "2,3,4,5"), "AdvancedListingRules.UseDropRates.Recipe.AffectedQualities");
AdvancedListingRuleUseDropRatesExceptionItems.clear();
ParseNumberListToSet(AdvancedListingRuleUseDropRatesExceptionItems, sConfigMgr->GetOption<std::string>("AuctionHouseBot.AdvancedListingRules.UseDropRates.DisabledItemIDs", ""), "AdvancedListingRules.UseDropRates.DisabledItemIDs");
MaxBuyoutPriceInCopper = sConfigMgr->GetOption<uint32>("AuctionHouseBot.MaxBuyoutPriceInCopper", 1000000000);
@@ -2017,6 +2059,13 @@ void AuctionHouseBot::InitializeConfiguration()
ListedItemIDExceptionItems.clear();
ParseNumberListToSet(ListedItemIDExceptionItems, sConfigMgr->GetOption<std::string>("AuctionHouseBot.ListedItemIDRestrict.ExceptionItemIDs", ""), "ListedItemIDRestrict.ExceptionItemIDs");
// Equip or use restrictions
ListedItemUseOrEquipRestrictedEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.EquipItemUseOrEquipLevelRestrict.Enabled", false);
ListedItemUseOrEquipRestrictMinLevel = sConfigMgr->GetOption("AuctionHouseBot.EquipItemUseOrEquipLevelRestrict.MinLevel", 0);
ListedItemUseOrEquipRestrictMaxLevel = sConfigMgr->GetOption("AuctionHouseBot.EquipItemUseOrEquipLevelRestrict.MaxLevel", 999);
ListedItemUseOrEquipExceptionItems.clear();
ParseNumberListToSet(ListedItemUseOrEquipExceptionItems, sConfigMgr->GetOption<std::string>("AuctionHouseBot.EquipItemUseOrEquipLevelRestrict.ExceptionItemIDs", ""), "EquipItemUseOrEquipLevelRestrict.ExceptionItemIDs");
// Disabled Items
DisabledItemTextFilter = sConfigMgr->GetOption<bool>("AuctionHouseBot.DisabledItemTextFilter", true);
DisabledRecipeProducedItemFilterEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.DisabledRecipeProducedItemFilterEnabled", false);

View File

@@ -159,9 +159,13 @@ private:
std::set<uint32> DisabledItems;
bool ListedItemLevelRestrictedEnabled;
bool ListedItemLevelRestrictedUseCraftedItemForCalculation;
uint32 ListedItemLevelMax;
uint32 ListedItemLevelMin;
uint32 ListedItemLevelMax;
std::set<uint32> ListedItemLevelExceptionItems;
bool ListedItemUseOrEquipRestrictedEnabled;
uint32 ListedItemUseOrEquipRestrictMinLevel;
uint32 ListedItemUseOrEquipRestrictMaxLevel;
std::set<uint32> ListedItemUseOrEquipExceptionItems;
uint32 RandomStackRatioConsumable;
uint32 RandomStackRatioContainer;
uint32 RandomStackRatioWeapon;
@@ -289,6 +293,7 @@ private:
std::set<uint32> AdvancedListingRuleUseDropRatesWeaponAffectedQualities;
std::set<uint32> AdvancedListingRuleUseDropRatesArmorAffectedQualities;
std::set<uint32> AdvancedListingRuleUseDropRatesRecipeAffectedQualities;
float AdvancedListingRuleUseDropRatesMinDropRate;
std::unordered_set<uint32> QuestRewardItemIDs;
FactionSpecificAuctionHouseConfig AllianceConfig;
@@ -312,6 +317,7 @@ public:
~AuctionHouseBot();
void Update();
bool IsModuleEnabled();
void InitializeConfiguration();
void EmptyAuctionHouses();
uint32 GetRandomStackValue(std::string configKeyString, uint32 defaultValue);

View File

@@ -20,13 +20,16 @@ public:
void OnAfterConfigLoad(bool /*reload*/) override
{
if (!auctionbot->IsModuleEnabled())
return;
auctionbot->InitializeConfiguration();
if (HasPerformedStartup == true)
{
LOG_INFO("server.loading", "AuctionHouseBot: (Re)populating item candidate lists ...");
auctionbot->PopulateItemCandidatesAndProportions();
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled", true))
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled", false))
{
auctionbot->PopulateQuestRewardItemIDs();
auctionbot->PopulateItemDropChances();
@@ -36,9 +39,12 @@ public:
void OnStartup() override
{
if (!auctionbot->IsModuleEnabled())
return;
LOG_INFO("server.loading", "AuctionHouseBot: (Re)populating item candidate lists ...");
auctionbot->PopulateItemCandidatesAndProportions();
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled", true))
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled", false))
{
auctionbot->PopulateQuestRewardItemIDs();
auctionbot->PopulateItemDropChances();
@@ -169,6 +175,8 @@ public:
LOG_INFO("module", "AuctionHouseBot: Updating Auction House...");
handler->PSendSysMessage("AuctionHouseBot: Updating Auction House...");
AuctionHouseBot::instance()->Update();
LOG_INFO("module", "AuctionHouseBot: Auction House Updated.");
handler->PSendSysMessage("AuctionHouseBot: Auction House Updated.");
return true;
}
@@ -198,6 +206,9 @@ public:
LOG_INFO("module", "AuctionHouseBot: Emptying Auction House...");
handler->PSendSysMessage("AuctionHouseBot: Emptying Auction House...");
AuctionHouseBot::instance()->EmptyAuctionHouses();
AuctionHouseBot::instance()->CleanupExpiredAuctionItems(); // Must go after EmptyAuctionHouses()
LOG_INFO("module", "AuctionHouseBot: Auction Houses Emptied.");
handler->PSendSysMessage("AuctionHouseBot: Auction Houses Emptied.");
return true;
}

View File

@@ -8,6 +8,11 @@
void AddAHBotScripts();
// Add all
void Addmod_ah_bot_plusScripts()
{
AddAHBotScripts();
}
void Addmod_ah_botScripts()
{
AddAHBotScripts();

View File

@@ -0,0 +1,22 @@
## mod-ah-bot Advanced Pricing Calculator
This spreadsheet helps show the buy and sell prices that the Bot(s) will use based on your configuration when `AuctionHouseBot.AdvancedPricing.<Category>.<Subclass>.Enabled` is `true` .
### How to Use
**Edit only the “Config” tab**
- This tab contains many adjustable settings from the modules config file
- Change these values to match your servers setup
- Items in other tabs reference the `Config` tab, so values will update immediately
<br>
**You shouldnt need to modify anything outside the Config sheet unless you know what you're doing.**
*There are hidden columns in each tab that can show items' Quality, Vendor Price, and Item Level (according to the database).
If you make custom changes to your database info, consider updating these as well for accurate pricing.*
### Notes
- The spreadsheet does not consider the following settings:
- AuctionHouseBot.Buyer.AcceptablePriceModifier
- AuctionHouseBot.BidVariationHighReducePercent
- AuctionHouseBot.BidVariationLowReducePercent
- AuctionHouseBot.BuyoutBelowVendorVariationAddPercentEnabled
- AuctionHouseBot.BuyoutBelowVendorVariationAddPercent