mirror of
https://github.com/NathanHandley/mod-ah-bot-plus.git
synced 2026-01-13 09:17:21 +00:00
separated buy and sell cycles
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -41,9 +41,12 @@ AuctionHouseBot::AuctionHouseBot() :
|
|||||||
debug_Out_Filters(false),
|
debug_Out_Filters(false),
|
||||||
SellingBotEnabled(false),
|
SellingBotEnabled(false),
|
||||||
BuyingBotEnabled(false),
|
BuyingBotEnabled(false),
|
||||||
CyclesBetweenBuyOrSellMin(1),
|
CyclesBetweenBuyActionMin(1),
|
||||||
CyclesBetweenBuyOrSell(1),
|
CyclesBetweenBuyAction(1),
|
||||||
CyclesBetweenBuyOrSellMax(1),
|
CyclesBetweenBuyActionMax(1),
|
||||||
|
CyclesBetweenSellActionMin(1),
|
||||||
|
CyclesBetweenSellAction(1),
|
||||||
|
CyclesBetweenSellActionMax(1),
|
||||||
MaxBuyoutPriceInCopper(1000000000),
|
MaxBuyoutPriceInCopper(1000000000),
|
||||||
BuyoutVariationReducePercent(0.15f),
|
BuyoutVariationReducePercent(0.15f),
|
||||||
BuyoutVariationAddPercent(0.25f),
|
BuyoutVariationAddPercent(0.25f),
|
||||||
@@ -151,7 +154,8 @@ AuctionHouseBot::AuctionHouseBot() :
|
|||||||
ListedItemIDRestrictedEnabled(false),
|
ListedItemIDRestrictedEnabled(false),
|
||||||
ListedItemIDMin(0),
|
ListedItemIDMin(0),
|
||||||
ListedItemIDMax(200000),
|
ListedItemIDMax(200000),
|
||||||
LastCycleCount(0),
|
LastBuyCycleCount(0),
|
||||||
|
LastSellCycleCount(0),
|
||||||
ActiveListMultipleItemID(0),
|
ActiveListMultipleItemID(0),
|
||||||
RemainingListMultipleCount(0)
|
RemainingListMultipleCount(0)
|
||||||
{
|
{
|
||||||
@@ -360,7 +364,7 @@ void AuctionHouseBot::CalculateItemValue(ItemTemplate const* itemProto, uint64&
|
|||||||
float sellVarianceBidPriceBottomPercent = 1.0f - BidVariationLowReducePercent;
|
float sellVarianceBidPriceBottomPercent = 1.0f - BidVariationLowReducePercent;
|
||||||
outBidPrice = urand(sellVarianceBidPriceBottomPercent * outBuyoutPrice, sellVarianceBidPriceTopPercent * outBuyoutPrice);
|
outBidPrice = urand(sellVarianceBidPriceBottomPercent * outBuyoutPrice, sellVarianceBidPriceTopPercent * outBuyoutPrice);
|
||||||
|
|
||||||
// If variance brought price below sell price, bring it back up to avoid making money off vendoring AH newItemsToListCount
|
// If variance brought price below sell price, bring it back up to avoid making money off vendoring AH items
|
||||||
if (outBuyoutPrice < itemProto->SellPrice)
|
if (outBuyoutPrice < itemProto->SellPrice)
|
||||||
{
|
{
|
||||||
float minLowPriceAddVariancePercent = 1.0f + BuyoutBelowVendorVariationAddPercent;
|
float minLowPriceAddVariancePercent = 1.0f + BuyoutBelowVendorVariationAddPercent;
|
||||||
@@ -393,7 +397,7 @@ float AuctionHouseBot::GetAdvancedPricingMultiplier(ItemTemplate const* itemProt
|
|||||||
Notes:
|
Notes:
|
||||||
- This formula produces a multiplier that grows logarithmically with ItemLevel (uses natural log, not base10)
|
- This formula produces a multiplier that grows logarithmically with ItemLevel (uses natural log, not base10)
|
||||||
- The first term (before '+') heavily influences low item levels, the second term adds some fine-tuning for higher levels.
|
- The first term (before '+') heavily influences low item levels, the second term adds some fine-tuning for higher levels.
|
||||||
- The subtraction of 'r' can help ensure low-level newItemsToListCount don't get inflated excessively. Sometimes it isn't necessary
|
- The subtraction of 'r' can help ensure low-level items don't get inflated excessively. Sometimes it isn't necessary
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Try to approximate real world prices for Trade Goods based on subclass and item level
|
// Try to approximate real world prices for Trade Goods based on subclass and item level
|
||||||
@@ -669,7 +673,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
{
|
{
|
||||||
uint32 itemLevelToCompare = itr->second.ItemLevel;
|
uint32 itemLevelToCompare = itr->second.ItemLevel;
|
||||||
|
|
||||||
// Recipes might need to consider produced newItemsToListCount
|
// Recipes might need to consider produced items
|
||||||
if (ListedItemLevelRestrictedUseCraftedItemForCalculation == true && itr->second.Class == ITEM_CLASS_RECIPE)
|
if (ListedItemLevelRestrictedUseCraftedItemForCalculation == true && itr->second.Class == ITEM_CLASS_RECIPE)
|
||||||
{
|
{
|
||||||
ItemTemplate const* producedItemTemplate = GetProducedItemFromRecipe(&itr->second);
|
ItemTemplate const* producedItemTemplate = GetProducedItemFromRecipe(&itr->second);
|
||||||
@@ -717,7 +721,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disabled newItemsToListCount by Id
|
// Disabled items by Id
|
||||||
if (DisabledItems.find(itr->second.ItemId) != DisabledItems.end())
|
if (DisabledItems.find(itr->second.ItemId) != DisabledItems.end())
|
||||||
{
|
{
|
||||||
if (debug_Out_Filters)
|
if (debug_Out_Filters)
|
||||||
@@ -736,14 +740,14 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These newItemsToListCount should be included and would otherwise be skipped due to conditions below
|
// These items should be included and would otherwise be skipped due to conditions below
|
||||||
if (includeItemIDExecptions.find(itr->second.ItemId) != includeItemIDExecptions.end())
|
if (includeItemIDExecptions.find(itr->second.ItemId) != includeItemIDExecptions.end())
|
||||||
{
|
{
|
||||||
ItemCandidatesByItemClassAndQuality[itr->second.Class][itr->second.Quality].push_back(itr->second.ItemId);
|
ItemCandidatesByItemClassAndQuality[itr->second.Class][itr->second.Quality].push_back(itr->second.ItemId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip any BOP newItemsToListCount
|
// Skip any BOP items
|
||||||
if (itr->second.Bonding == BIND_WHEN_PICKED_UP || itr->second.Bonding == BIND_QUEST_ITEM)
|
if (itr->second.Bonding == BIND_WHEN_PICKED_UP || itr->second.Bonding == BIND_QUEST_ITEM)
|
||||||
{
|
{
|
||||||
if (debug_Out_Filters)
|
if (debug_Out_Filters)
|
||||||
@@ -755,7 +759,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
if (itr->second.Quality == 0 || itr->second.Quality > 6)
|
if (itr->second.Quality == 0 || itr->second.Quality > 6)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Disable conjured newItemsToListCount
|
// Disable conjured items
|
||||||
if (itr->second.IsConjuredConsumable())
|
if (itr->second.IsConjuredConsumable())
|
||||||
{
|
{
|
||||||
if (debug_Out_Filters)
|
if (debug_Out_Filters)
|
||||||
@@ -779,7 +783,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable newItemsToListCount with duration
|
// Disable items with duration
|
||||||
if (itr->second.Duration > 0)
|
if (itr->second.Duration > 0)
|
||||||
{
|
{
|
||||||
if (debug_Out_Filters)
|
if (debug_Out_Filters)
|
||||||
@@ -795,7 +799,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable normal class 'book' recipies, since they are junk
|
// Disable normal class 'book' recipes, since they are junk
|
||||||
if (itr->second.Class == ITEM_CLASS_RECIPE && itr->second.SubClass == ITEM_SUBCLASS_BOOK && itr->second.Quality <= ITEM_QUALITY_NORMAL)
|
if (itr->second.Class == ITEM_CLASS_RECIPE && itr->second.SubClass == ITEM_SUBCLASS_BOOK && itr->second.Quality <= ITEM_QUALITY_NORMAL)
|
||||||
{
|
{
|
||||||
if (debug_Out_Filters)
|
if (debug_Out_Filters)
|
||||||
@@ -803,7 +807,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable anything with the string literal of a testing or depricated item
|
// Disable anything with the string literal of a testing or deprecated item
|
||||||
if (DisabledItemTextFilter == true &&
|
if (DisabledItemTextFilter == true &&
|
||||||
(itr->second.Name1.find("Test ") != std::string::npos ||
|
(itr->second.Name1.find("Test ") != std::string::npos ||
|
||||||
itr->second.Name1.find("TEST") != std::string::npos ||
|
itr->second.Name1.find("TEST") != std::string::npos ||
|
||||||
@@ -828,7 +832,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable all newItemsToListCount that have neither a sell or a buy price, with exception of item enhancements and trade goods
|
// Disable all items that have neither a sell or a buy price, with exception of item enhancements and trade goods
|
||||||
bool isEnchantingTradeGood = (itr->second.Class == ITEM_CLASS_TRADE_GOODS && itr->second.SubClass == ITEM_SUBCLASS_ENCHANTING);
|
bool isEnchantingTradeGood = (itr->second.Class == ITEM_CLASS_TRADE_GOODS && itr->second.SubClass == ITEM_SUBCLASS_ENCHANTING);
|
||||||
bool isItemEnhancement = (itr->second.Class == ITEM_CLASS_CONSUMABLE && itr->second.SubClass == ITEM_SUBCLASS_ITEM_ENHANCEMENT);
|
bool isItemEnhancement = (itr->second.Class == ITEM_CLASS_CONSUMABLE && itr->second.SubClass == ITEM_SUBCLASS_ITEM_ENHANCEMENT);
|
||||||
bool hasNoPrice = (itr->second.SellPrice == 0 && itr->second.BuyPrice == 0);
|
bool hasNoPrice = (itr->second.SellPrice == 0 && itr->second.BuyPrice == 0);
|
||||||
@@ -1101,7 +1105,7 @@ void AuctionHouseBot::AddNewAuctionBuyerBotBid(std::vector<Player*> AHBPlayers,
|
|||||||
// Do we have anything to bid? If not, stop here.
|
// Do we have anything to bid? If not, stop here.
|
||||||
if (possibleBids.empty())
|
if (possibleBids.empty())
|
||||||
{
|
{
|
||||||
//if (debug_Out) sLog->outError( "AHBuyer: I have no newItemsToListCount to bid on.");
|
//if (debug_Out) sLog->outError( "AHBuyer: I have no items to bid on.");
|
||||||
count = randBuyingBotBuyCandidatesPerBuyCycle;
|
count = randBuyingBotBuyCandidatesPerBuyCycle;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1266,13 +1270,30 @@ void AuctionHouseBot::Update()
|
|||||||
if (AHCharacters.empty() == true)
|
if (AHCharacters.empty() == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Only update if the update cycle has been hit
|
LastBuyCycleCount++;
|
||||||
LastCycleCount++;
|
LastSellCycleCount++;
|
||||||
if (LastCycleCount < CyclesBetweenBuyOrSell)
|
|
||||||
return;
|
|
||||||
LastCycleCount = 0;
|
|
||||||
CyclesBetweenBuyOrSell = urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax);
|
|
||||||
|
|
||||||
|
bool buyReady = false;
|
||||||
|
bool sellReady = false;
|
||||||
|
|
||||||
|
// Check if an update cycle has been hit. Set # of cycles until next update
|
||||||
|
if (LastBuyCycleCount >= CyclesBetweenBuyAction) // Should never be >, but we check anyway
|
||||||
|
{
|
||||||
|
LastBuyCycleCount = 0;
|
||||||
|
CyclesBetweenBuyAction = urand(CyclesBetweenBuyActionMin, CyclesBetweenBuyActionMax);
|
||||||
|
buyReady = true;
|
||||||
|
}
|
||||||
|
if (LastSellCycleCount >= CyclesBetweenSellAction) // Should never be >, but we check anyway
|
||||||
|
{
|
||||||
|
LastSellCycleCount = 0;
|
||||||
|
CyclesBetweenSellAction = urand(CyclesBetweenSellActionMin, CyclesBetweenSellActionMax);
|
||||||
|
sellReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only update if a Buy or Sell update cycle has been hit
|
||||||
|
if (!buyReady && !sellReady)
|
||||||
|
return;
|
||||||
|
|
||||||
// Load all AH Bot Players
|
// Load all AH Bot Players
|
||||||
std::vector<std::pair<std::unique_ptr<Player>, std::unique_ptr<WorldSession>>> AHBPlayers;
|
std::vector<std::pair<std::unique_ptr<Player>, std::unique_ptr<WorldSession>>> AHBPlayers;
|
||||||
AHBPlayers.reserve(AHCharacters.size());
|
AHBPlayers.reserve(AHCharacters.size());
|
||||||
@@ -1297,21 +1318,54 @@ void AuctionHouseBot::Update()
|
|||||||
playersPointerVector.reserve(AHBPlayers.size());
|
playersPointerVector.reserve(AHBPlayers.size());
|
||||||
for (const auto& pair : AHBPlayers)
|
for (const auto& pair : AHBPlayers)
|
||||||
playersPointerVector.emplace_back(pair.first.get());
|
playersPointerVector.emplace_back(pair.first.get());
|
||||||
|
|
||||||
|
|
||||||
// Add New Bids
|
// Helper: run factionHandler() for each enabled AH config.
|
||||||
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION) == false)
|
auto UpdateAuctionHouses = [&](auto factionHandler)
|
||||||
{
|
{
|
||||||
AddNewAuctions(playersPointerVector, &AllianceConfig);
|
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||||
if (BuyingBotBuyCandidatesPerBuyCycleMin > 0)
|
{
|
||||||
AddNewAuctionBuyerBotBid(playersPointerVector, &AllianceConfig);
|
factionHandler(&AllianceConfig);
|
||||||
|
factionHandler(&HordeConfig);
|
||||||
|
}
|
||||||
|
factionHandler(&NeutralConfig);
|
||||||
|
};
|
||||||
|
|
||||||
AddNewAuctions(playersPointerVector, &HordeConfig);
|
// Pass distinct factionHandler() definition to UpdateAuctionHouses based on Buy/Sell cycle
|
||||||
if (BuyingBotBuyCandidatesPerBuyCycleMin > 0)
|
// List New Auctions
|
||||||
AddNewAuctionBuyerBotBid(playersPointerVector, &HordeConfig);
|
if (sellReady)
|
||||||
}
|
UpdateAuctionHouses([&](FactionSpecificAuctionHouseConfig* cfg){
|
||||||
AddNewAuctions(playersPointerVector, &NeutralConfig);
|
AddNewAuctions(playersPointerVector, cfg);
|
||||||
if (BuyingBotBuyCandidatesPerBuyCycleMin > 0)
|
});
|
||||||
AddNewAuctionBuyerBotBid(playersPointerVector, &NeutralConfig);
|
|
||||||
|
// Place New Bids
|
||||||
|
if (buyReady && BuyingBotBuyCandidatesPerBuyCycleMin > 0)
|
||||||
|
UpdateAuctionHouses([&](FactionSpecificAuctionHouseConfig* cfg){
|
||||||
|
AddNewAuctionBuyerBotBid(playersPointerVector, cfg);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// // List New Auctions
|
||||||
|
// if (sellReady)
|
||||||
|
// {
|
||||||
|
// if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION) == false)
|
||||||
|
// {
|
||||||
|
// AddNewAuctions(playersPointerVector, &AllianceConfig);
|
||||||
|
// AddNewAuctions(playersPointerVector, &HordeConfig);
|
||||||
|
// }
|
||||||
|
// AddNewAuctions(playersPointerVector, &NeutralConfig);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Place New Bids
|
||||||
|
// if (buyReady && BuyingBotBuyCandidatesPerBuyCycleMin > 0)
|
||||||
|
// {
|
||||||
|
// if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION) == false)
|
||||||
|
// {
|
||||||
|
// AddNewAuctionBuyerBotBid(playersPointerVector, &AllianceConfig);
|
||||||
|
// AddNewAuctionBuyerBotBid(playersPointerVector, &HordeConfig);
|
||||||
|
// }
|
||||||
|
// AddNewAuctionBuyerBotBid(playersPointerVector, &NeutralConfig);
|
||||||
|
// }
|
||||||
|
|
||||||
// Remove AH Bot Players from world
|
// Remove AH Bot Players from world
|
||||||
for (auto& [player, session] : AHBPlayers)
|
for (auto& [player, session] : AHBPlayers)
|
||||||
@@ -1580,9 +1634,13 @@ uint32 AuctionHouseBot::GetRandomStackIncrementValue(std::string configKeyString
|
|||||||
|
|
||||||
void AuctionHouseBot::SetCyclesBetweenBuyOrSell()
|
void AuctionHouseBot::SetCyclesBetweenBuyOrSell()
|
||||||
{
|
{
|
||||||
std::string cyclesConfigString = sConfigMgr->GetOption<std::string>("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", "1");
|
std::string buyCyclesConfigString = sConfigMgr->GetOption<std::string>("AuctionHouseBot.MinutesBetweenBuyCycle", "1");
|
||||||
GetConfigMinAndMax(cyclesConfigString, CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax);
|
GetConfigMinAndMax(buyCyclesConfigString, CyclesBetweenBuyActionMin, CyclesBetweenBuyActionMax);
|
||||||
CyclesBetweenBuyOrSell = urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax);
|
CyclesBetweenBuyAction = urand(CyclesBetweenBuyActionMin, CyclesBetweenBuyActionMax);
|
||||||
|
|
||||||
|
std::string sellCyclesConfigString = sConfigMgr->GetOption<std::string>("AuctionHouseBot.MinutesBetweenSellCycle", "1");
|
||||||
|
GetConfigMinAndMax(sellCyclesConfigString, CyclesBetweenSellActionMin, CyclesBetweenSellActionMax);
|
||||||
|
CyclesBetweenSellAction = urand(CyclesBetweenSellActionMin, CyclesBetweenSellActionMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuctionHouseBot::SetBuyingBotBuyCandidatesPerBuyCycle()
|
void AuctionHouseBot::SetBuyingBotBuyCandidatesPerBuyCycle()
|
||||||
@@ -1713,7 +1771,7 @@ void AuctionHouseBot::AddValuesToSetByKeyMap(std::map<uint32, std::unordered_set
|
|||||||
std::string valueString = curBlock.substr(curBlock.find(":") + 1);
|
std::string valueString = curBlock.substr(curBlock.find(":") + 1);
|
||||||
if (valueString == "*")
|
if (valueString == "*")
|
||||||
{
|
{
|
||||||
for (int i = wildcardLowValue; i <= wildcardHighValue; i++)
|
for (uint32 i = wildcardLowValue; i <= wildcardHighValue; i++)
|
||||||
workingSetByKeyMap[keyValue].insert(i);
|
workingSetByKeyMap[keyValue].insert(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1820,7 +1878,7 @@ const char* AuctionHouseBot::GetCategoryName(ItemClass category)
|
|||||||
|
|
||||||
void AuctionHouseBot::PopulateVendorItemsPrices()
|
void AuctionHouseBot::PopulateVendorItemsPrices()
|
||||||
{
|
{
|
||||||
// Load vendor newItemsToListCount' prices into a vector for fast lookup
|
// Load vendor items' prices into a vector for fast lookup
|
||||||
QueryResult r = WorldDatabase.Query("SELECT MAX(entry) FROM item_template");
|
QueryResult r = WorldDatabase.Query("SELECT MAX(entry) FROM item_template");
|
||||||
Field* f = r->Fetch();
|
Field* f = r->Fetch();
|
||||||
uint32_t numItems = f[0].Get<uint32>();
|
uint32_t numItems = f[0].Get<uint32>();
|
||||||
|
|||||||
@@ -128,9 +128,12 @@ private:
|
|||||||
|
|
||||||
bool SellingBotEnabled;
|
bool SellingBotEnabled;
|
||||||
bool BuyingBotEnabled;
|
bool BuyingBotEnabled;
|
||||||
uint32 CyclesBetweenBuyOrSellMin;
|
uint32 CyclesBetweenBuyActionMin;
|
||||||
uint32 CyclesBetweenBuyOrSell;
|
uint32 CyclesBetweenBuyAction;
|
||||||
uint32 CyclesBetweenBuyOrSellMax;
|
uint32 CyclesBetweenBuyActionMax;
|
||||||
|
uint32 CyclesBetweenSellActionMin;
|
||||||
|
uint32 CyclesBetweenSellAction;
|
||||||
|
uint32 CyclesBetweenSellActionMax;
|
||||||
uint32 MaxBuyoutPriceInCopper;
|
uint32 MaxBuyoutPriceInCopper;
|
||||||
float BuyoutVariationReducePercent;
|
float BuyoutVariationReducePercent;
|
||||||
float BuyoutVariationAddPercent;
|
float BuyoutVariationAddPercent;
|
||||||
@@ -277,7 +280,8 @@ private:
|
|||||||
FactionSpecificAuctionHouseConfig HordeConfig;
|
FactionSpecificAuctionHouseConfig HordeConfig;
|
||||||
FactionSpecificAuctionHouseConfig NeutralConfig;
|
FactionSpecificAuctionHouseConfig NeutralConfig;
|
||||||
|
|
||||||
uint32 LastCycleCount;
|
uint32 LastBuyCycleCount;
|
||||||
|
uint32 LastSellCycleCount;
|
||||||
int ActiveListMultipleItemID;
|
int ActiveListMultipleItemID;
|
||||||
int RemainingListMultipleCount;
|
int RemainingListMultipleCount;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user