diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index 4722973..21b7c5c 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -94,6 +94,16 @@ # Set to 1 to restore that behaviour. # Default 5 # +# AuctionHouseBot.BinItemShare +# Percentage of each cycle's candidate list reserved for items that have no +# row in "mod_auctionhousebot_priceOverride". The seller only ever works +# through the first AuctionHouseBot.ItemsPerCycle entries of that list, and +# the price override items alone number in the thousands, so without a +# reserved share those items are never reached and never listed. +# Set to 0 to append them after the price override items instead (they will +# then effectively never be listed). +# Default 25 +# # AuctionHouseBot.DivisibleStacks # Sell items in stack sizes which depends on the maximum amount per stack. # For example, an item with max stack size 20 will be sold in 5, 10 15 and 20 stacks, and not at random. @@ -131,6 +141,7 @@ AuctionHouseBot.ItemsPerCycle = 200 AuctionHouseBot.ConsiderOnlyBotAuctions = 0 AuctionHouseBot.DuplicatesCount = 0 AuctionHouseBot.RestockBatchSize = 5 +AuctionHouseBot.BinItemShare = 25 AuctionHouseBot.DivisibleStacks = 0 AuctionHouseBot.ElapsingTimeClass = 1 AuctionHouseBot.MaxItems = 15000 diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index 22a6ef8..7df70d1 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -1319,11 +1319,18 @@ std::vector AuctionHouseBot::GetItemsToSell(AHBConfig* config, ObjectGui // Queue every stack an item is short of, keeping the copies adjacent so a // sold out item is restocked as a batch instead of one stack per cycle. + // Blocks 1 and 2 (price override items) and blocks 3 and 4 (bin items) are + // collected separately so they can be woven together at the end. Concatenating + // them starved the bin items: a cycle only ever consumes the first + // ItemsPerCycle entries, and the override blocks alone are thousands long. + std::vector priorityItems; + std::vector binOnlyItems; + auto appendMissingStacks = [&](const std::vector& items) { for (auto const& itemID : items) { - allItemIDs.insert(allItemIDs.end(), missingStacks(itemID), itemID); + priorityItems.insert(priorityItems.end(), missingStacks(itemID), itemID); } }; @@ -1362,7 +1369,7 @@ std::vector AuctionHouseBot::GetItemsToSell(AHBConfig* config, ObjectGui itemsWithOverrides.push_back(itemID); } std::shuffle(itemsWithOverrides.begin(), itemsWithOverrides.end(), std::mt19937(std::random_device()())); - allItemIDs.insert(allItemIDs.end(), itemsWithOverrides.begin(), itemsWithOverrides.end()); + priorityItems.insert(priorityItems.end(), itemsWithOverrides.begin(), itemsWithOverrides.end()); // 3. Items without overrides that are not in the auction house (randomized order) addItems(greyItemsBin, true); @@ -1375,7 +1382,7 @@ std::vector AuctionHouseBot::GetItemsToSell(AHBConfig* config, ObjectGui // Randomize the collected items std::shuffle(tempItemIDs.begin(), tempItemIDs.end(), std::mt19937(std::random_device()())); - allItemIDs.insert(allItemIDs.end(), tempItemIDs.begin(), tempItemIDs.end()); + binOnlyItems.insert(binOnlyItems.end(), tempItemIDs.begin(), tempItemIDs.end()); // 4. Random items without price overrides (randomized order) tempItemIDs.clear(); @@ -1393,9 +1400,40 @@ std::vector AuctionHouseBot::GetItemsToSell(AHBConfig* config, ObjectGui allItemIDs.insert(allItemIDs.end(), tempItemIDs.begin(), tempItemIDs.end()); */ + // Weave the two sources together so that, over any stretch of the list, + // BinItemShare percent of the slots belong to items that have no price + // override. At 0 the bin items simply follow the priority ones, which is the + // old concatenation order. + uint32 share = std::min(config->BinItemShare, 100); + size_t nextPriority = 0; + size_t nextBin = 0; + uint32 credit = 0; + + allItemIDs.reserve(priorityItems.size() + binOnlyItems.size()); + + while (nextPriority < priorityItems.size() || nextBin < binOnlyItems.size()) + { + credit += share; + + if (credit >= 100 && nextBin < binOnlyItems.size()) + { + credit -= 100; + allItemIDs.push_back(binOnlyItems[nextBin++]); + } + else if (nextPriority < priorityItems.size()) + { + allItemIDs.push_back(priorityItems[nextPriority++]); + } + else if (nextBin < binOnlyItems.size()) + { + allItemIDs.push_back(binOnlyItems[nextBin++]); + } + } + // Log the number of items to sell if(config->TraceSeller) { + LOG_INFO("module", "AHBot [{}]: {} price override and {} bin only candidates woven at {}%", _id, priorityItems.size(), binOnlyItems.size(), share); LOG_INFO("module", "AHBot [{}]: restocking {} sold out and {} understocked price override items", _id, itemsWithOverridesNotListed.size(), itemsWithOverridesBelowTarget.size()); LOG_INFO("module", "AHBot [{}]: GetItemsToSell returning {} items", _id, allItemIDs.size()); } diff --git a/src/AuctionHouseBotConfig.cpp b/src/AuctionHouseBotConfig.cpp index 954998c..4eca72f 100644 --- a/src/AuctionHouseBotConfig.cpp +++ b/src/AuctionHouseBotConfig.cpp @@ -222,6 +222,7 @@ AHBConfig::AHBConfig(uint32 ahid, AHBConfig* conf) Bind_Quest_Item = conf->Bind_Quest_Item; DuplicatesCount = conf->DuplicatesCount; RestockBatchSize = conf->RestockBatchSize; + BinItemShare = conf->BinItemShare; ElapsingTimeClass = conf->ElapsingTimeClass; DivisibleStacks = conf->DivisibleStacks; DisablePermEnchant = conf->DisablePermEnchant; @@ -532,6 +533,7 @@ void AHBConfig::Reset() Bind_Quest_Item = false; DuplicatesCount = 0; RestockBatchSize = 5; + BinItemShare = 25; ElapsingTimeClass = 1; DivisibleStacks = false; @@ -2049,6 +2051,7 @@ void AHBConfig::InitializeFromFile() MarketResetThreshold = sConfigMgr->GetOption("AuctionHouseBot.MarketResetThreshold" , 25); DuplicatesCount = sConfigMgr->GetOption("AuctionHouseBot.DuplicatesCount" , 0); RestockBatchSize = sConfigMgr->GetOption("AuctionHouseBot.RestockBatchSize" , 5); + BinItemShare = sConfigMgr->GetOption("AuctionHouseBot.BinItemShare" , 25); DivisibleStacks = sConfigMgr->GetOption ("AuctionHouseBot.DivisibleStacks" , false); ElapsingTimeClass = sConfigMgr->GetOption("AuctionHouseBot.ElapsingTimeClass" , 1); ConsiderOnlyBotAuctions = sConfigMgr->GetOption ("AuctionHouseBot.ConsiderOnlyBotAuctions", false); diff --git a/src/AuctionHouseBotConfig.h b/src/AuctionHouseBotConfig.h index 0222d1a..cb928ff 100644 --- a/src/AuctionHouseBotConfig.h +++ b/src/AuctionHouseBotConfig.h @@ -203,6 +203,7 @@ class AHBConfig uint32 DuplicatesCount; uint32 RestockBatchSize; + uint32 BinItemShare; uint32 ElapsingTimeClass; bool DivisibleStacks;