aboutsummaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/AuctionHouse.cpp6
-rw-r--r--src/game/AuctionHouseBot.cpp1198
-rw-r--r--src/game/AuctionHouseBot.h687
-rw-r--r--src/game/CMakeLists.txt2
-rw-r--r--src/game/Chat.cpp1
-rw-r--r--src/game/Chat.h1
-rw-r--r--src/game/Creature.h1
-rw-r--r--src/game/Level3.cpp375
-rw-r--r--src/game/Mail.cpp18
-rw-r--r--src/game/Spell.cpp13
-rw-r--r--src/game/Spell.h2
-rw-r--r--src/game/SpellEffects.cpp24
-rw-r--r--src/game/SpellMgr.h16
-rw-r--r--src/game/Unit.cpp95
-rw-r--r--src/game/Unit.h7
-rw-r--r--src/game/World.cpp7
16 files changed, 2394 insertions, 59 deletions
diff --git a/src/game/AuctionHouse.cpp b/src/game/AuctionHouse.cpp
index a12e8a8f238..39aaa864bd2 100644
--- a/src/game/AuctionHouse.cpp
+++ b/src/game/AuctionHouse.cpp
@@ -28,6 +28,7 @@
#include "UpdateMask.h"
#include "AuctionHouseObject.h"
#include "Util.h"
+#include "AuctionHouseBot.h"
//please DO NOT use iterator++, because it is slower than ++iterator!!!
//post-incrementation is always slower than pre-incrementation !
@@ -171,7 +172,10 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri
std::ostringstream msgAuctionOutbiddedSubject;
msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED;
- if (oldBidder)
+ if (oldBidder && !_player)
+ oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, AHBplayerGUID, newPrice, objmgr.GetAuctionOutBid(auction->bid), auction->item_template);
+
+ if (oldBidder && _player)
oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, _player->GetGUID(), newPrice, objmgr.GetAuctionOutBid(auction->bid), auction->item_template);
WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
diff --git a/src/game/AuctionHouseBot.cpp b/src/game/AuctionHouseBot.cpp
new file mode 100644
index 00000000000..f05d31abb41
--- /dev/null
+++ b/src/game/AuctionHouseBot.cpp
@@ -0,0 +1,1198 @@
+#include "AuctionHouseBot.h"
+#include "Bag.h"
+#include "Config/ConfigEnv.h"
+#include "Database/DatabaseEnv.h"
+#include "Item.h"
+#include "Log.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "World.h"
+#include "WorldSession.h"
+#include "time.h"
+#include <vector>
+#include <iostream>
+
+using namespace std;
+
+static bool debug_Out = sConfig.GetIntDefault("AuctionHouseBot.DEBUG", 0);
+
+static vector<uint32> npcItems;
+static vector<uint32> lootItems;
+static vector<uint32> whiteTradeGoods;
+static vector<uint32> greenTradeGoods;
+static vector<uint32> blueTradeGoods;
+static vector<uint32> purpleTradeGoods;
+static vector<uint32> whiteItems;
+static vector<uint32> greenItems;
+static vector<uint32> blueItems;
+static vector<uint32> purpleItems;
+
+static bool AHBSeller = 0;
+static bool AHBBuyer = 0;
+
+static bool Vendor_Items = 0;
+static bool Loot_Items = 0;
+static bool Other_Items = 0;
+
+static bool No_Bind = 0;
+static bool Bind_When_Picked_Up = 0;
+static bool Bind_When_Equipped = 0;
+static bool Bind_When_Use = 0;
+static bool Bind_Quest_Item = 0;
+
+static AHBConfig AllianceConfig = AHBConfig(2);
+static AHBConfig HordeConfig = AHBConfig(6);
+static AHBConfig NeutralConfig = AHBConfig(7);
+time_t _lastrun_a;
+time_t _lastrun_h;
+time_t _lastrun_n;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+///////////////////////////////////////////////////////////////////////////////
+static inline uint32 minValue(uint32 a, uint32 b)
+{
+ return a <= b ? a : b;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+///////////////////////////////////////////////////////////////////////////////
+static void addNewAuctions(Player *AHBplayer, AHBConfig *config)
+{
+ if (!AHBSeller)
+ return;
+ AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(config->GetAHID());
+ uint32 items = 0;
+ uint32 minItems = config->GetMinItems();
+ uint32 maxItems = config->GetMaxItems();
+ uint32 auctions = auctionHouse->Getcount();
+
+ if (auctions >= minItems)
+ return;
+ if (auctions <= maxItems)
+ {
+ if ((maxItems - auctions) > ItemsPerCycle)
+ items = ItemsPerCycle;
+ else
+ items = (maxItems - auctions);
+ }
+ uint32 wtgbin = config->GetPercents(AHB_WHITE_TG);
+ uint32 gtgbin = config->GetPercents(AHB_GREEN_TG);
+ uint32 btgbin = config->GetPercents(AHB_BLUE_TG);
+ uint32 ptgbin = config->GetPercents(AHB_PURPLE_TG);
+ uint32 wibin = config->GetPercents(AHB_WHITE_I);
+ uint32 gibin = config->GetPercents(AHB_GREEN_I);
+ uint32 bibin = config->GetPercents(AHB_BLUE_I);
+ uint32 pibin = config->GetPercents(AHB_PURPLE_I);
+ uint32 total = wtgbin + gtgbin + btgbin + ptgbin + wibin + gibin + bibin + pibin;
+
+ uint32 pItems = 0;
+ uint32 bItems = 0;
+ uint32 gItems = 0;
+ uint32 wItems = 0;
+ uint32 pTGoods = 0;
+ uint32 bTGoods = 0;
+ uint32 gTGoods = 0;
+ uint32 wTGoods = 0;
+ for (AuctionHouseObject::AuctionEntryMap::iterator itr = auctionHouse->GetAuctionsBegin();itr != auctionHouse->GetAuctionsEnd();++itr)
+ {
+ AuctionEntry *Aentry = itr->second;
+ Item *item = objmgr.GetAItem(Aentry->item_guidlow);
+ if( item )
+ {
+ ItemPrototype const *prototype = item->GetProto();
+ if( prototype )
+ {
+ switch (prototype->Quality)
+ {
+ case 0:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ wTGoods = wTGoods + 1;
+ else
+ wItems = wItems + 1;
+ break;
+
+ case 1:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ wTGoods = wTGoods + 1;
+ else
+ wItems = wItems + 1;
+ break;
+
+ case 2:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ gTGoods = gTGoods + 1;
+ else
+ gItems = gItems + 1;
+ break;
+
+ case 3:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ bTGoods = bTGoods + 1;
+ else
+ bItems = bItems + 1;
+ break;
+
+ case 4:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ pTGoods = pTGoods + 1;
+ else
+ pItems = pItems + 1;
+ break;
+ }
+ }
+ }
+ }
+ // only insert a few at a time, so as not to peg the processor
+ for (uint32 cnt = 1;cnt <= items;cnt++)
+ {
+ uint32 itemID = 0;
+ while (itemID == 0)
+ {
+ uint32 choice = urand(1, 8);
+ switch (choice)
+ {
+ case 1:
+ {
+ if ((purpleItems.size() > 0) && (pItems < pibin))
+ {
+ itemID = purpleItems[urand(0, purpleItems.size() - 1)];
+ pItems = pItems + 1;
+ break;
+ }
+ }
+ case 2:
+ {
+ if ((blueItems.size() > 0) && (bItems < bibin))
+ {
+ itemID = blueItems[urand(0, blueItems.size() - 1)];
+ bItems = bItems + 1;
+ break;
+ }
+ }
+ case 3:
+ {
+ if ((greenItems.size() > 0) && (gItems < gibin))
+ {
+ itemID = greenItems[urand(0, greenItems.size() - 1)];
+ gItems = gItems + 1;
+ break;
+ }
+ }
+ case 4:
+ {
+ if ((whiteItems.size() > 0) && (wItems < wibin))
+ {
+ itemID = whiteItems[urand(0, whiteItems.size() - 1)];
+ wItems = wItems + 1;
+ break;
+ }
+ }
+ case 5:
+ {
+ if ((purpleTradeGoods.size() > 0) && (pTGoods < ptgbin))
+ {
+ itemID = purpleTradeGoods[urand(0, purpleTradeGoods.size() - 1)];
+ pTGoods = pTGoods + 1;
+ break;
+ }
+ }
+ case 6:
+ {
+ if ((blueTradeGoods.size() > 0) && (bTGoods < btgbin))
+ {
+ itemID = blueTradeGoods[urand(0, blueTradeGoods.size() - 1)];
+ bTGoods = bTGoods + 1;
+ break;
+ }
+ }
+ case 7:
+ {
+ if ((greenTradeGoods.size() > 0) && (gTGoods < gtgbin))
+ {
+ itemID = greenTradeGoods[urand(0, greenTradeGoods.size() - 1)];
+ gTGoods = gTGoods + 1;
+ break;
+ }
+ }
+ case 8:
+ {
+ if ((whiteTradeGoods.size() > 0) && (wTGoods < wtgbin))
+ {
+ itemID = whiteTradeGoods[urand(0, whiteTradeGoods.size() - 1)];
+ wTGoods = wTGoods + 1;
+ break;
+ }
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ ItemPrototype const* prototype = objmgr.GetItemPrototype(itemID);
+ if (prototype == NULL)
+ {
+ sLog.outString("AuctionHouseBot: Huh?!?! prototype == NULL");
+ continue;
+ }
+
+ Item* item = Item::CreateItem(itemID, 1, AHBplayer);
+ item->AddToUpdateQueueOf(AHBplayer);
+ if (item == NULL)
+ {
+ sLog.outString("AuctionHouseBot: Item::CreateItem() returned NULL");
+ break;
+ }
+
+ uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID);
+ if (randomPropertyId != 0)
+ item->SetItemRandomProperties(randomPropertyId);
+
+ uint32 buyoutPrice;
+ uint32 bidPrice = 0;
+ uint32 stackCount = urand(1, item->GetMaxStackCount());
+
+ switch (SellMethod)
+ {
+ case 0:
+ buyoutPrice = prototype->SellPrice * item->GetCount();
+ break;
+ case 1:
+ buyoutPrice = prototype->BuyPrice * item->GetCount();
+ break;
+ default:
+ buyoutPrice = 0;
+ break;
+ }
+
+ switch (prototype->Quality)
+ {
+ case 1:
+ if (config->GetMaxStack(AHB_WHITE) != 0)
+ {
+ stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_WHITE)));
+ }
+ buyoutPrice *= urand(config->GetMinPrice(AHB_WHITE), config->GetMaxPrice(AHB_WHITE)) * stackCount;
+ buyoutPrice /= 100;
+ bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_WHITE), config->GetMaxBidPrice(AHB_WHITE));
+ bidPrice /= 100;
+ break;
+
+ case 2:
+ if (config->GetMaxStack(AHB_GREEN) != 0)
+ {
+ stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_GREEN)));
+ }
+ buyoutPrice *= urand(config->GetMinPrice(AHB_GREEN), config->GetMaxPrice(AHB_GREEN)) * stackCount;
+ buyoutPrice /= 100;
+ bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_GREEN), config->GetMaxBidPrice(AHB_GREEN));
+ bidPrice /= 100;
+ break;
+
+ case 3:
+ if (config->GetMaxStack(AHB_BLUE) != 0)
+ {
+ stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_BLUE)));
+ }
+ buyoutPrice *= urand(config->GetMinPrice(AHB_BLUE), config->GetMaxPrice(AHB_BLUE)) * stackCount;
+ buyoutPrice /= 100;
+ bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_BLUE), config->GetMaxBidPrice(AHB_BLUE));
+ bidPrice /= 100;
+ break;
+
+ case 4:
+ if (config->GetMaxStack(AHB_PURPLE) != 0)
+ {
+ stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(AHB_PURPLE)));
+ }
+ buyoutPrice *= urand(config->GetMinPrice(AHB_PURPLE), config->GetMaxPrice(AHB_PURPLE)) * stackCount;
+ buyoutPrice /= 100;
+ bidPrice = buyoutPrice * urand(config->GetMinBidPrice(AHB_PURPLE), config->GetMaxBidPrice(AHB_PURPLE));
+ bidPrice /= 100;
+ break;
+ }
+
+ item->SetCount(stackCount);
+
+ AuctionEntry* auctionEntry = new AuctionEntry;
+ auctionEntry->Id = objmgr.GenerateAuctionID();
+ auctionEntry->auctioneer = 0;
+ auctionEntry->item_guidlow = item->GetGUIDLow();
+ auctionEntry->item_template = item->GetEntry();
+ auctionEntry->owner = AHBplayer->GetGUIDLow();
+ auctionEntry->startbid = bidPrice;
+ auctionEntry->buyout = buyoutPrice;
+ auctionEntry->bidder = 0;
+ auctionEntry->bid = 0;
+ auctionEntry->deposit = 0;
+ auctionEntry->location = config->GetAHID();
+ auctionEntry->time = (time_t) (urand(config->GetMinTime(), config->GetMaxTime()) * 60 * 60 + time(NULL));
+ item->SaveToDB();
+ item->RemoveFromUpdateQueueOf(AHBplayer);
+ objmgr.AddAItem(item);
+ auctionHouse->AddAuction(auctionEntry);
+
+ CharacterDatabase.PExecute("INSERT INTO `auctionhouse` (`id`,"
+ "`auctioneerguid`,`itemguid`,`item_template`,"
+ "`itemowner`,`buyoutprice`,`time`,`buyguid`,"
+ "`lastbid`,`startbid`,`deposit`,`location`) "
+ "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', "
+ "'" I64FMTD "', '%u', '%u', '%u', '%u', '%u')",
+ auctionEntry->Id,
+ auctionEntry->auctioneer,
+ auctionEntry->item_guidlow,
+ auctionEntry->item_template,
+ auctionEntry->owner,
+ auctionEntry->buyout,
+ (uint64) auctionEntry->time,
+ auctionEntry->bidder,
+ auctionEntry->bid,
+ auctionEntry->startbid,
+ auctionEntry->deposit,
+ auctionEntry->location);
+ }
+}
+
+static void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, WorldSession *session)
+{
+ if (!AHBBuyer)
+ return;
+
+ // Fetches content of selected AH
+ AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(config->GetAHID());
+ AuctionHouseObject::AuctionEntryMap::iterator itr;
+
+ itr = auctionHouse->GetAuctionsBegin();
+ vector<uint32> possibleBids;
+
+ while (itr != auctionHouse->GetAuctionsEnd())
+ {
+ AuctionHouseObject::AuctionEntryMap::iterator tmp = itr;
+ ++itr;
+ // Check if the auction is ours
+ // if it is, we skip this iteration.
+ if(tmp->second->owner == AHBplayerGUID)
+ {
+ continue;
+ }
+ // Check that we haven't bidded in this auction already.
+ if(tmp->second->bidder != AHBplayerGUID)
+ {
+ uint32 tmpdata = tmp->second->Id;
+ possibleBids.push_back(tmpdata);
+ }
+ }
+
+ // Do we have anything to bid? If not, stop here.
+ if(possibleBids.empty())
+ {
+ return;
+ }
+
+ // Choose random auction from possible auctions
+ uint32 auctionID = possibleBids[urand(0, possibleBids.size() - 1)];
+
+ // from auctionhouse.cpp, creates auction pointer & player pointer
+ AuctionEntry* auction = auctionHouse->GetAuction(auctionID);
+
+ // get exact item information
+ Item *pItem = objmgr.GetAItem(auction->item_guidlow);
+ if (!pItem)
+ {
+ sLog.outError("Item doesn't exists, perhaps bought already?");
+ return;
+ }
+
+ // get item prototype
+ ItemPrototype const* prototype = objmgr.GetItemPrototype(auction->item_template);
+
+ // check which price we have to use, startbid or if it is bidded already
+ if(debug_Out)
+ {sLog.outError("Auction Number: %u", auction->Id);}
+ if(debug_Out)
+ {sLog.outError("Item Template: %u", auction->item_template);}
+ if(debug_Out)
+ {sLog.outError("Buy Price: %u", prototype->BuyPrice);}
+ if(debug_Out)
+ {sLog.outError("Sell Price: %u", prototype->SellPrice);}
+ if(debug_Out)
+ {sLog.outError("Quality: %u", prototype->Quality);}
+ uint32 currentprice;
+ if(auction->bid)
+ {
+ currentprice = auction->bid;
+ if(debug_Out)
+ {sLog.outError("Current Price: %u", auction->bid);}
+ }
+ else
+ {
+ currentprice = auction->startbid;
+ if(debug_Out)
+ {sLog.outError("Current Price: %u", auction->startbid);}
+ }
+ uint32 bidprice;
+
+ // Prepare portion from maximum bid
+ uint32 tmprate2 = urand(0, 100);
+ double tmprate = static_cast<double>(tmprate2);
+ if(debug_Out)
+ {sLog.outError("tmprate: %f", tmprate);}
+ double bidrate = tmprate / 100;
+ if(debug_Out)
+ {sLog.outError("bidrate: %f", bidrate);}
+ long double bidMax = 0;
+
+ // check that bid has acceptable value and take bid based on vendorprice, stacksize and quality
+ switch (BuyMethod)
+ {
+ case 0:
+ switch (prototype->Quality)
+ {
+ case 0:
+ if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY))
+ {
+ bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY);
+ }
+ break;
+ case 1:
+ if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE))
+ {
+ bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE);
+ }
+ break;
+ case 2:
+ if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN))
+ {
+ bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN);
+ }
+ break;
+ case 3:
+ if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE))
+ {
+ bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE);
+ }
+ break;
+ case 4:
+ if(currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE))
+ {
+ bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE);
+ }
+ break;
+ default:
+ // quality is something it shouldn't be, let's get out of here
+ if(debug_Out)
+ {sLog.outError("bidMax(fail): %f", bidMax);}
+ return;
+ break;
+ }
+ break;
+ case 1:
+ switch (prototype->Quality)
+ {
+ case 0:
+ if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY))
+ {
+ bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREY);
+ }
+ break;
+ case 1:
+ if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE))
+ {
+ bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_WHITE);
+ }
+ break;
+ case 2:
+ if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN))
+ {
+ bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_GREEN);
+ }
+ break;
+ case 3:
+ if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE))
+ {
+ bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_BLUE);
+ }
+ break;
+ case 4:
+ if(currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE))
+ {
+ bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(AHB_PURPLE);
+ }
+ break;
+ default:
+ // quality is something it shouldn't be, let's get out of here
+ if(debug_Out)
+ {sLog.outError("bidMax(fail): %f", bidMax);}
+ return;
+ break;
+ }
+ break;
+ default:
+ bidMax = 0;
+ break;
+ }
+ if(debug_Out)
+ {sLog.outError("bidMax(succeed): %f", bidMax);}
+
+ // check some special items, and do recalculating to their prices
+ switch (prototype->Class)
+ {
+ // ammo
+ case 6:
+ bidMax = 0;
+ break;
+ default:
+ break;
+ }
+
+ if(bidMax == 0)
+ {
+ // quality check failed to get bidmax, let's get out of here
+ return;
+ }
+
+ // Calculate our bid
+ long double bidvalue = currentprice + ( (bidMax - currentprice) * bidrate);
+ if(debug_Out)
+ {sLog.outError("bidvalue: %f", bidvalue);}
+ // Convert to uint32
+ bidprice = static_cast<uint32>(bidvalue);
+ if(debug_Out)
+ {sLog.outError("bidprice: %u", bidprice);}
+
+ // Check our bid is high enough to be valid. If not, correct it to minimum.
+ if((currentprice + objmgr.GetAuctionOutBid(currentprice)) > bidprice)
+ {
+ bidprice = currentprice + objmgr.GetAuctionOutBid(currentprice);
+ if(debug_Out)
+ {sLog.outError("bidprice(>): %u", bidprice);}
+ }
+
+ // Check wether we do normal bid, or buyout
+ if ((bidprice < auction->buyout) || (auction->buyout == 0))
+ {
+
+ if (auction->bidder > 0)
+ {
+ if ( auction->bidder == AHBplayer->GetGUIDLow() )
+ {
+ //pl->ModifyMoney( -int32(price - auction->bid));
+ }
+ else
+ {
+ // mail to last bidder and return money
+ session->SendAuctionOutbiddedMail( auction , bidprice );
+ //pl->ModifyMoney( -int32(price) );
+ }
+ }
+
+ auction->bidder = AHBplayer->GetGUIDLow();
+ auction->bid = bidprice;
+
+ // Saving auction into database
+ CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
+ }
+ else
+ {
+ //buyout
+ if (AHBplayer->GetGUIDLow() == auction->bidder )
+ {
+ //pl->ModifyMoney(-int32(auction->buyout - auction->bid));
+ }
+ else
+ {
+ //pl->ModifyMoney(-int32(auction->buyout));
+ if ( auction->bidder )
+ {
+ session->SendAuctionOutbiddedMail( auction, auction->buyout );
+ }
+ }
+ auction->bidder = AHBplayer->GetGUIDLow();
+ auction->bid = auction->buyout;
+
+ // Send mails to buyer & seller
+ objmgr.SendAuctionSuccessfulMail( auction );
+ objmgr.SendAuctionWonMail( auction );
+
+ // Remove item from auctionhouse
+ objmgr.RemoveAItem(auction->item_guidlow);
+ // Remove auction
+ auctionHouse->RemoveAuction(auction->Id);
+ // Remove from database
+ CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id);
+
+ delete auction;
+ }
+}
+///////////////////////////////////////////////////////////////////////////////
+//
+///////////////////////////////////////////////////////////////////////////////
+void AuctionHouseBot()
+{
+ time_t _newrun = time(NULL);
+ if ((!AHBSeller) && (!AHBBuyer))
+ return;
+
+ WorldSession _session(AHBplayerAccount, NULL, 0, true, 0, LOCALE_enUS);
+ Player _AHBplayer(&_session);
+ _AHBplayer.MinimalLoadFromDB(NULL, AHBplayerGUID);
+ ObjectAccessor::Instance().AddObject(&_AHBplayer);
+
+ if(sConfig.GetIntDefault("AllowTwoSide.Interaction.Auction",0) == 0)
+ {
+ addNewAuctions(&_AHBplayer, &AllianceConfig);
+ if (((_newrun - _lastrun_a) > (AllianceConfig.GetBiddingInterval() * 60)) && (AllianceConfig.GetBidsPerInterval() > 0))
+ {
+ uint32 bids = AllianceConfig.GetBidsPerInterval();
+ for (uint32 count = 1;count <= bids;count++)
+ {
+ addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session);
+ _lastrun_a = _newrun;
+ }
+ }
+ addNewAuctions(&_AHBplayer, &HordeConfig);
+ if (((_newrun - _lastrun_h) > (HordeConfig.GetBiddingInterval() *60)) && (HordeConfig.GetBidsPerInterval() > 0))
+ {
+ uint32 bids = HordeConfig.GetBidsPerInterval();
+ for (uint32 count = 1;count <= bids;count++)
+ {
+ addNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig, &_session);
+ _lastrun_h = _newrun;
+ }
+ }
+ }
+ addNewAuctions(&_AHBplayer, &NeutralConfig);
+ if (((_newrun - _lastrun_n) > (NeutralConfig.GetBiddingInterval() * 60)) && (NeutralConfig.GetBidsPerInterval() > 0))
+ {
+ uint32 bids = NeutralConfig.GetBidsPerInterval();
+ for (uint32 count = 1;count <= bids;count++)
+ {
+ addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig, &_session);
+ _lastrun_n = _newrun;
+ }
+ }
+ ObjectAccessor::Instance().RemoveObject(&_AHBplayer);
+}
+///////////////////////////////////////////////////////////////////////////////
+//
+///////////////////////////////////////////////////////////////////////////////
+void AuctionHouseBotInit()
+{
+ AHBSeller = sConfig.GetBoolDefault("AuctionHouseBot.EnableSeller", 0);
+ AHBBuyer = sConfig.GetBoolDefault("AuctionHouseBot.EnableBuyer", 0);
+ No_Bind = sConfig.GetBoolDefault("AuctionHouseBot.No_Bind", 1);
+ Bind_When_Picked_Up = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Picked_Up", 0);
+ Bind_When_Equipped = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Equipped", 1);
+ Bind_When_Use = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Use", 1);
+ Bind_Quest_Item = sConfig.GetBoolDefault("AuctionHouseBot.Bind_Quest_Item", 0);
+
+ if(sConfig.GetBoolDefault("AllowTwoSide.Interaction.Auction",0) == 0)
+ {
+ AuctionHouseBotLoadValues(&AllianceConfig);
+ AuctionHouseBotLoadValues(&HordeConfig);
+ }
+ AuctionHouseBotLoadValues(&NeutralConfig);
+
+ if (AHBSeller)
+ {
+ Vendor_Items = sConfig.GetBoolDefault("AuctionHouseBot.VendorItems", 0);
+ Loot_Items = sConfig.GetBoolDefault("AuctionHouseBot.LootItems", 1);
+ Other_Items = sConfig.GetBoolDefault("AuctionHouseBot.OtherItems", 0);
+
+ QueryResult* results = (QueryResult*) NULL;
+ char npcQuery[] = "SELECT distinct `item` FROM `npc_vendor`";
+ results = WorldDatabase.PQuery(npcQuery);
+ if (results != NULL)
+ {
+ do
+ {
+ Field* fields = results->Fetch();
+ npcItems.push_back(fields[0].GetUInt32());
+
+ } while (results->NextRow());
+
+ delete results;
+ }
+ else
+ {
+ sLog.outString("AuctionHouseBot: \"%s\" failed", npcQuery);
+ }
+
+ char lootQuery[] = "SELECT `item` FROM `creature_loot_template` UNION "
+ "SELECT `item` FROM `disenchant_loot_template` UNION "
+ "SELECT `item` FROM `fishing_loot_template` UNION "
+ "SELECT `item` FROM `gameobject_loot_template` UNION "
+ "SELECT `item` FROM `item_loot_template` UNION "
+ "SELECT `item` FROM `pickpocketing_loot_template` UNION "
+ "SELECT `item` FROM `prospecting_loot_template` UNION "
+ "SELECT `item` FROM `skinning_loot_template`";
+
+ results = WorldDatabase.PQuery(lootQuery);
+ if (results != NULL)
+ {
+ do
+ {
+ Field* fields = results->Fetch();
+ lootItems.push_back(fields[0].GetUInt32());
+
+ } while (results->NextRow());
+
+ delete results;
+ }
+ else
+ {
+ sLog.outString("AuctionHouseBot: \"%s\" failed", lootQuery);
+ }
+
+ for (uint32 itemID = 0; itemID < sItemStorage.MaxEntry; itemID++)
+ {
+ ItemPrototype const* prototype = objmgr.GetItemPrototype(itemID);
+
+ if (prototype == NULL)
+ continue;
+
+ switch (prototype->Bonding)
+ {
+ case 0:
+ if (!No_Bind)
+ continue;
+ break;
+ case 1:
+ if (!Bind_When_Picked_Up)
+ continue;
+ break;
+ case 2:
+ if (!Bind_When_Equipped)
+ continue;
+ break;
+ case 3:
+ if (!Bind_When_Use)
+ continue;
+ break;
+ case 4:
+ if (!Bind_Quest_Item)
+ continue;
+ break;
+ default:
+ continue;
+ break;
+ }
+
+ switch (SellMethod)
+ {
+ case 0:
+ if (prototype->SellPrice == 0)
+ continue;
+ break;
+ case 1:
+ if (prototype->BuyPrice == 0)
+ continue;
+ break;
+ default:
+ continue;
+ break;
+ }
+
+ if ((prototype->Quality < 1) || (prototype->Quality > 4))
+ continue;
+
+ if (Vendor_Items == 0)
+ {
+ bool isVendorItem = false;
+
+ for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++)
+ {
+ if (itemID == npcItems[i])
+ isVendorItem = true;
+ }
+
+ if (isVendorItem)
+ continue;
+ }
+
+ if (Loot_Items == 0)
+ {
+ bool isLootItem = false;
+
+ for (unsigned int i = 0; (i < lootItems.size()) && (!isLootItem); i++)
+ {
+ if (itemID == lootItems[i])
+ isLootItem = true;
+ }
+
+ if (isLootItem)
+ continue;
+ }
+
+ if (Other_Items == 0)
+ {
+ bool isVendorItem = false;
+ bool isLootItem = false;
+
+ for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++)
+ {
+ if (itemID == npcItems[i])
+ isVendorItem = true;
+ }
+ for (unsigned int i = 0; (i < lootItems.size()) && (!isLootItem); i++)
+ {
+ if (itemID == lootItems[i])
+ isLootItem = true;
+ }
+ if ((!isLootItem) && (!isVendorItem))
+ continue;
+ }
+
+ switch (prototype->Quality)
+ {
+ case 1:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ whiteTradeGoods.push_back(itemID);
+ else
+ whiteItems.push_back(itemID);
+ break;
+
+ case 2:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ greenTradeGoods.push_back(itemID);
+ else
+ greenItems.push_back(itemID);
+ break;
+
+ case 3:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ blueTradeGoods.push_back(itemID);
+ else
+ blueItems.push_back(itemID);
+ break;
+
+ case 4:
+ if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
+ purpleTradeGoods.push_back(itemID);
+ else
+ purpleItems.push_back(itemID);
+ break;
+ }
+ }
+
+ if ((whiteTradeGoods.size() == 0) &&
+ (greenTradeGoods.size() == 0) &&
+ (blueTradeGoods.size() == 0) &&
+ (purpleTradeGoods.size() == 0) &&
+ (whiteItems.size() == 0) &&
+ (greenItems.size() == 0) &&
+ (blueItems.size() == 0) &&
+ (purpleItems.size() == 0))
+ {
+ sLog.outString("AuctionHouseBot: No items");
+ AHBSeller = 0;
+ }
+
+ sLog.outString("AuctionHouseBot:");
+ sLog.outString("loaded %d white trade goods", whiteTradeGoods.size());
+ sLog.outString("loaded %d green trade goods", greenTradeGoods.size());
+ sLog.outString("loaded %d blue trade goods", blueTradeGoods.size());
+ sLog.outString("loaded %d purple trade goods", purpleTradeGoods.size());
+ sLog.outString("loaded %d white items", whiteItems.size());
+ sLog.outString("loaded %d green items", greenItems.size());
+ sLog.outString("loaded %d blue items", blueItems.size());
+ sLog.outString("loaded %d purple items", purpleItems.size());
+ }
+ sLog.outString("AuctionHouseBot by Paradox (original by ChrisK) has been loaded.");
+ sLog.outString("AuctionHouseBot now includes AHBuyer by Kerbe and Paradox");
+
+}
+void AuctionHouseBotCommands(uint32 command, uint32 ahMapID, uint32 col, char* args)
+{
+ AHBConfig *config;
+ switch (ahMapID)
+ {
+ case 2:
+ config = &AllianceConfig;
+ break;
+ case 6:
+ config = &HordeConfig;
+ break;
+ case 7:
+ config = &NeutralConfig;
+ break;
+ }
+ std::string color;
+ switch (col)
+ {
+ case AHB_GREY:
+ color = "grey";
+ break;
+ case AHB_WHITE:
+ color = "white";
+ break;
+ case AHB_GREEN:
+ color = "green";
+ break;
+ case AHB_BLUE:
+ color = "blue";
+ break;
+ case AHB_PURPLE:
+ color = "purple";
+ break;
+ default:
+ break;
+ }
+ switch (command)
+ {
+ case 0: //ahexpire
+ {
+ AuctionHouseObject* auctionHouse = objmgr.GetAuctionsMap(ahMapID);
+
+ AuctionHouseObject::AuctionEntryMap::iterator itr;
+ itr = auctionHouse->GetAuctionsBegin();
+
+ while (itr != auctionHouse->GetAuctionsEnd())
+ {
+ if (itr->second->owner == AHBplayerGUID)
+ itr->second->time = sWorld.GetGameTime();
+
+ ++itr;
+ }
+ }break;
+ case 1: //min items
+ {
+ char * param1 = strtok(args, " ");
+ uint32 minItems = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET minitems = '%u' WHERE auctionhouse = '%u'", minItems, ahMapID);
+ config->SetMinItems(minItems);
+ }break;
+ case 2: //max items
+ {
+ char * param1 = strtok(args, " ");
+ uint32 maxItems = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxitems = '%u' WHERE auctionhouse = '%u'", maxItems, ahMapID);
+ config->SetMaxItems(maxItems);
+ }break;
+ case 3: //min time
+ {
+ char * param1 = strtok(args, " ");
+ uint32 minTime = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET mintime = '%u' WHERE auctionhouse = '%u'", minTime, ahMapID);
+ config->SetMinTime(minTime);
+ }break;
+ case 4: //max time
+ {
+ char * param1 = strtok(args, " ");
+ uint32 maxTime = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxtime = '%u' WHERE auctionhouse = '%u'", maxTime, ahMapID);
+ config->SetMaxTime(maxTime);
+ }break;
+ case 5: //percentages
+ {
+ char * param1 = strtok(args, " ");
+ char * param2 = strtok(NULL, " ");
+ char * param3 = strtok(NULL, " ");
+ char * param4 = strtok(NULL, " ");
+ char * param5 = strtok(NULL, " ");
+ char * param6 = strtok(NULL, " ");
+ char * param7 = strtok(NULL, " ");
+ char * param8 = strtok(NULL, " ");
+ uint32 wtg = (uint32) strtoul(param1, NULL, 0);
+ uint32 gtg = (uint32) strtoul(param2, NULL, 0);
+ uint32 btg = (uint32) strtoul(param3, NULL, 0);
+ uint32 ptg = (uint32) strtoul(param4, NULL, 0);
+ uint32 wi = (uint32) strtoul(param5, NULL, 0);
+ uint32 gi = (uint32) strtoul(param6, NULL, 0);
+ uint32 bi = (uint32) strtoul(param7, NULL, 0);
+ uint32 pi = (uint32) strtoul(param8, NULL, 0);
+
+ CharacterDatabase.BeginTransaction();
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentwhitetradegoods = '%u' WHERE auctionhouse = '%u'", wtg, ahMapID);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentgreentradegoods = '%u' WHERE auctionhouse = '%u'", gtg, ahMapID);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentbluetradegoods = '%u' WHERE auctionhouse = '%u'", btg, ahMapID);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentpurpletradegoods = '%u' WHERE auctionhouse = '%u'", ptg, ahMapID);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentwhiteitems = '%u' WHERE auctionhouse = '%u'", wi, ahMapID);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentgreenitems = '%u' WHERE auctionhouse = '%u'", gi, ahMapID);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentblueitems = '%u' WHERE auctionhouse = '%u'", bi, ahMapID);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentpurpleitems = '%u' WHERE auctionhouse = '%u'", pi, ahMapID);
+ CharacterDatabase.CommitTransaction();
+ config->SetPercentages(wtg, gtg, btg, ptg, wi, gi, bi, pi);
+ }break;
+ case 6: //min prices
+ {
+ char * param1 = strtok(args, " ");
+ uint32 minPrice = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET minprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), minPrice, ahMapID);
+ config->SetMinPrice(col, minPrice);
+ }break;
+ case 7: //max prices
+ {
+ char * param1 = strtok(args, " ");
+ uint32 maxPrice = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), maxPrice, ahMapID);
+ config->SetMaxPrice(col, maxPrice);
+ }break;
+ case 8: //min bid price
+ {
+ char * param1 = strtok(args, " ");
+ uint32 minBidPrice = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET minbidprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), minBidPrice, ahMapID);
+ config->SetMinBidPrice(col, minBidPrice);
+ }break;
+ case 9: //max bid price
+ {
+ char * param1 = strtok(args, " ");
+ uint32 maxBidPrice = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxbidprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), maxBidPrice, ahMapID);
+ config->SetMaxBidPrice(col, maxBidPrice);
+ }break;
+ case 10: //max stacks
+ {
+ char * param1 = strtok(args, " ");
+ uint32 maxStack = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxstack%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), maxStack, ahMapID);
+ config->SetMaxStack(col, maxStack);
+ }break;
+ case 11: //buyer bid prices
+ {
+ char * param1 = strtok(args, " ");
+ uint32 buyerPrice = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET buyerprice%s = '%u' WHERE auctionhouse = '%u'",color.c_str(), buyerPrice, ahMapID);
+ config->SetBuyerPrice(col, buyerPrice);
+ }break;
+ case 12: //buyer bidding interval
+ {
+ char * param1 = strtok(args, " ");
+ uint32 bidInterval = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET buyerbiddinginterval = '%u' WHERE auctionhouse = '%u'", bidInterval, ahMapID);
+ config->SetBiddingInterval(bidInterval);
+ }break;
+ case 13: //buyer bids per interval
+ {
+ char * param1 = strtok(args, " ");
+ uint32 bidsPerInterval = (uint32) strtoul(param1, NULL, 0);
+ CharacterDatabase.PExecute("UPDATE auctionhousebot SET buyerbidsperinterval = '%u' WHERE auctionhouse = '%u'", bidsPerInterval, ahMapID);
+ config->SetBidsPerInterval(bidsPerInterval);
+ }break;
+ default:
+ break;
+ }
+}
+void AuctionHouseBotLoadValues(AHBConfig *config)
+{
+ if (AHBSeller)
+ {
+ //load min and max items
+ config->SetMinItems(CharacterDatabase.PQuery("SELECT minitems FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetMaxItems(CharacterDatabase.PQuery("SELECT maxitems FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minItems = %u", config->GetMinItems());
+ sLog.outError("maxItems = %u", config->GetMaxItems());}
+ //load min and max auction times
+ config->SetMinTime(CharacterDatabase.PQuery("SELECT mintime FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetMaxTime(CharacterDatabase.PQuery("SELECT maxtime FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minTime = %u", config->GetMinTime());
+ sLog.outError("maxTime = %u", config->GetMaxTime());}
+ //load percentages
+ uint32 wtg = CharacterDatabase.PQuery("SELECT percentwhitetradegoods FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ uint32 gtg = CharacterDatabase.PQuery("SELECT percentgreentradegoods FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ uint32 btg = CharacterDatabase.PQuery("SELECT percentbluetradegoods FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ uint32 ptg = CharacterDatabase.PQuery("SELECT percentpurpletradegoods FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ uint32 wi = CharacterDatabase.PQuery("SELECT percentwhiteitems FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ uint32 gi = CharacterDatabase.PQuery("SELECT percentgreenitems FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ uint32 bi = CharacterDatabase.PQuery("SELECT percentblueitems FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ uint32 pi = CharacterDatabase.PQuery("SELECT percentpurpleitems FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32();
+ config->SetPercentages(wtg, gtg, btg, ptg, wi, gi, bi, pi);
+ if(debug_Out)
+ {sLog.outError("percentWhiteTradeGoods = %u", config->GetPercentages(AHB_WHITE_TG));
+ sLog.outError("percentGreenTradeGoods = %u", config->GetPercentages(AHB_GREEN_TG));
+ sLog.outError("percentBlueTradeGoods = %u", config->GetPercentages(AHB_BLUE_TG));
+ sLog.outError("percentPurpleTradeGoods = %u", config->GetPercentages(AHB_PURPLE_TG));
+ sLog.outError("percentWhiteItems = %u", config->GetPercentages(AHB_WHITE_I));
+ sLog.outError("percentGreenItems = %u", config->GetPercentages(AHB_GREEN_I));
+ sLog.outError("percentBlueItems = %u", config->GetPercentages(AHB_BLUE_I));
+ sLog.outError("percentPurpleItems = %u", config->GetPercentages(AHB_PURPLE_I));}
+ //load min and max prices
+ config->SetMinPrice(AHB_WHITE, CharacterDatabase.PQuery("SELECT minpricewhite FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetMaxPrice(AHB_WHITE, CharacterDatabase.PQuery("SELECT maxpricewhite FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minPriceWhite = %u", config->GetMinPrice(AHB_WHITE));
+ sLog.outError("maxPriceWhite = %u", config->GetMaxPrice(AHB_WHITE));}
+ config->SetMinPrice(AHB_GREEN, CharacterDatabase.PQuery("SELECT minpricegreen FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetMaxPrice(AHB_GREEN, CharacterDatabase.PQuery("SELECT maxpricegreen FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minPriceGreen = %u", config->GetMinPrice(AHB_GREEN));
+ sLog.outError("maxPriceGreen = %u", config->GetMaxPrice(AHB_GREEN));}
+ config->SetMinPrice(AHB_BLUE, CharacterDatabase.PQuery("SELECT minpriceblue FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetMaxPrice(AHB_BLUE, CharacterDatabase.PQuery("SELECT maxpriceblue FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minPriceBlue = %u", config->GetMinPrice(AHB_BLUE));
+ sLog.outError("maxPriceBlue = %u", config->GetMaxPrice(AHB_BLUE));}
+ config->SetMinPrice(AHB_PURPLE, CharacterDatabase.PQuery("SELECT minpricepurple FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetMaxPrice(AHB_PURPLE, CharacterDatabase.PQuery("SELECT maxpricepurple FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minPricePurple = %u", config->GetMinPrice(AHB_PURPLE));
+ sLog.outError("maxPricePurple = %u", config->GetMaxPrice(AHB_PURPLE));}
+ //load min and max bid prices
+ config->SetMinBidPrice(AHB_WHITE, CharacterDatabase.PQuery("SELECT minbidpricewhite FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError(",minBidPriceWhite = %u", config->GetMinBidPrice(AHB_WHITE));}
+ config->SetMaxBidPrice(AHB_WHITE, CharacterDatabase.PQuery("SELECT maxbidpricewhite FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxBidPriceWhite = %u", config->GetMaxBidPrice(AHB_WHITE));}
+ config->SetMinBidPrice(AHB_GREEN, CharacterDatabase.PQuery("SELECT minbidpricegreen FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minBidPriceGreen = %u", config->GetMinBidPrice(AHB_GREEN));}
+ config->SetMaxBidPrice(AHB_GREEN, CharacterDatabase.PQuery("SELECT maxbidpricegreen FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxBidPriceGreen = %u", config->GetMaxBidPrice(AHB_GREEN));}
+ config->SetMinBidPrice(AHB_BLUE, CharacterDatabase.PQuery("SELECT minbidpriceblue FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minBidPriceBlue = %u", config->GetMinBidPrice(AHB_BLUE));}
+ config->SetMaxBidPrice(AHB_BLUE, CharacterDatabase.PQuery("SELECT maxbidpriceblue FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxBidPriceBlue = %u", config->GetMinBidPrice(AHB_BLUE));}
+ config->SetMinBidPrice(AHB_PURPLE, CharacterDatabase.PQuery("SELECT minbidpricepurple FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("minBidPricePurple = %u", config->GetMinBidPrice(AHB_PURPLE));}
+ config->SetMaxBidPrice(AHB_PURPLE, CharacterDatabase.PQuery("SELECT maxbidpricepurple FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxBidPricePurple = %u", config->GetMaxBidPrice(AHB_PURPLE));}
+ //load max stacks
+ config->SetMaxStack(AHB_WHITE, CharacterDatabase.PQuery("SELECT maxstackwhite FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxStackWhite = %u", config->GetMaxStack(AHB_WHITE));}
+ config->SetMaxStack(AHB_GREEN, CharacterDatabase.PQuery("SELECT maxstackgreen FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxStackGreen = %u", config->GetMaxStack(AHB_GREEN));}
+ config->SetMaxStack(AHB_BLUE, CharacterDatabase.PQuery("SELECT maxstackblue FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxStackBlue = %u", config->GetMaxStack(AHB_BLUE));}
+ config->SetMaxStack(AHB_PURPLE, CharacterDatabase.PQuery("SELECT maxstackpurple FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("maxStackPurple = %u", config->GetMaxStack(AHB_PURPLE));}
+ }
+ if (AHBBuyer)
+ {
+ //load buyer bid prices
+ config->SetBuyerPrice(AHB_GREY, CharacterDatabase.PQuery("SELECT buyerpricegrey FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetBuyerPrice(AHB_WHITE, CharacterDatabase.PQuery("SELECT buyerpricewhite FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetBuyerPrice(AHB_GREEN, CharacterDatabase.PQuery("SELECT buyerpricegreen FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetBuyerPrice(AHB_BLUE, CharacterDatabase.PQuery("SELECT buyerpriceblue FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ config->SetBuyerPrice(AHB_PURPLE, CharacterDatabase.PQuery("SELECT buyerpricepurple FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("buyerPriceGrey = %u", config->GetBuyerPrice(AHB_GREY));
+ sLog.outError("buyerPriceWhite = %u", config->GetBuyerPrice(AHB_WHITE));
+ sLog.outError("buyerPriceGreen = %u", config->GetBuyerPrice(AHB_GREEN));
+ sLog.outError("buyerPriceBlue = %u", config->GetBuyerPrice(AHB_BLUE));
+ sLog.outError("buyerPricePurple = %u", config->GetBuyerPrice(AHB_PURPLE));}
+ //load bidding interval
+ config->SetBiddingInterval(CharacterDatabase.PQuery("SELECT buyerbiddinginterval FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("buyerBiddingInterval = %u", config->GetBiddingInterval());}
+ //load bids per interval
+ config->SetBidsPerInterval(CharacterDatabase.PQuery("SELECT buyerbidsperinterval FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetUInt32());
+ if(debug_Out)
+ {sLog.outError("buyerBidsPerInterval = %u", config->GetBidsPerInterval());}
+ }
+}
diff --git a/src/game/AuctionHouseBot.h b/src/game/AuctionHouseBot.h
new file mode 100644
index 00000000000..71b14d17a4a
--- /dev/null
+++ b/src/game/AuctionHouseBot.h
@@ -0,0 +1,687 @@
+#ifndef AUCTION_HOUSE_BOT_H
+#define AUCTION_HOUSE_BOT_H
+#include "Common.h"
+#include "Log.h"
+#include "Config/ConfigEnv.h"
+#define AHB_GREY 0
+#define AHB_WHITE 1
+#define AHB_GREEN 2
+#define AHB_BLUE 3
+#define AHB_PURPLE 4
+#define AHB_GREY_TG 0
+#define AHB_WHITE_TG 1
+#define AHB_GREEN_TG 2
+#define AHB_BLUE_TG 3
+#define AHB_PURPLE_TG 4
+#define AHB_GREY_I 5
+#define AHB_WHITE_I 6
+#define AHB_GREEN_I 7
+#define AHB_BLUE_I 8
+#define AHB_PURPLE_I 9
+#define AHBplayerAccount sConfig.GetIntDefault("AuctionHouseBot.Account", 0)
+#define AHBplayerGUID sConfig.GetIntDefault("AuctionHouseBot.GUID", 0)
+#define ItemsPerCycle sConfig.GetIntDefault("AuctionHouseBot.ItemsPerCycle", 200)
+#define SellMethod sConfig.GetIntDefault("AuctionHouseBot.UseBuyPriceForSeller", 1)
+#define BuyMethod sConfig.GetIntDefault("AuctionHouseBot.UseBuyPriceForBuyer", 0)
+
+class AHBConfig
+{
+ private:
+ uint32 AHID;
+ uint32 minItems;
+ uint32 maxItems;
+ uint32 minTime;
+ uint32 maxTime;
+ uint32 percentWhiteTradeGoods;
+ uint32 percentGreenTradeGoods;
+ uint32 percentBlueTradeGoods;
+ uint32 percentPurpleTradeGoods;
+ uint32 percentWhiteItems;
+ uint32 percentGreenItems;
+ uint32 percentBlueItems;
+ uint32 percentPurpleItems;
+ uint32 minPriceWhite;
+ uint32 maxPriceWhite;
+ uint32 minBidPriceWhite;
+ uint32 maxBidPriceWhite;
+ uint32 maxStackWhite;
+ uint32 minPriceGreen;
+ uint32 maxPriceGreen;
+ uint32 minBidPriceGreen;
+ uint32 maxBidPriceGreen;
+ uint32 maxStackGreen;
+ uint32 minPriceBlue;
+ uint32 maxPriceBlue;
+ uint32 minBidPriceBlue;
+ uint32 maxBidPriceBlue;
+ uint32 maxStackBlue;
+ uint32 minPricePurple;
+ uint32 maxPricePurple;
+ uint32 minBidPricePurple;
+ uint32 maxBidPricePurple;
+ uint32 maxStackPurple;
+
+ uint32 buyerPriceGrey;
+ uint32 buyerPriceWhite;
+ uint32 buyerPriceGreen;
+ uint32 buyerPriceBlue;
+ uint32 buyerPricePurple;
+ uint32 buyerBiddingInterval;
+ uint32 buyerBidsPerInterval;
+
+ uint32 wtgp;
+ uint32 gtgp;
+ uint32 btgp;
+ uint32 ptgp;
+ uint32 wip;
+ uint32 gip;
+ uint32 bip;
+ uint32 pip;
+ public:
+ AHBConfig(uint32 ahid)
+ {
+ AHID = ahid;
+ }
+ AHBConfig()
+ {
+ }
+ uint32 GetAHID()
+ {
+ return AHID;
+ }
+ void SetMinItems(uint32 value)
+ {
+ minItems = value;
+ }
+ uint32 GetMinItems()
+ {
+ if ((minItems == 0) && (maxItems))
+ return maxItems;
+ else if ((maxItems) && (minItems > maxItems))
+ return maxItems;
+ else
+ return minItems;
+ }
+ void SetMaxItems(uint32 value)
+ {
+ maxItems = value;
+ CalculatePercents();
+ }
+ uint32 GetMaxItems()
+ {
+ return maxItems;
+ }
+ void SetMinTime(uint32 value)
+ {
+ minTime = value;
+ }
+ uint32 GetMinTime()
+ {
+ if (minTime < 1)
+ return 1;
+ else if ((maxTime) && (minTime > maxTime))
+ return maxTime;
+ else
+ return minTime;
+ }
+ void SetMaxTime(uint32 value)
+ {
+ maxTime = value;
+ }
+ uint32 GetMaxTime()
+ {
+ return maxTime;
+ }
+ void SetPercentages(uint32 wtg, uint32 gtg, uint32 btg, uint32 ptg, uint32 wi, uint32 gi, uint32 bi, uint32 pi)
+ {
+ uint32 totalPercent = wtg + gtg + btg + ptg + wi + gi + bi + pi;
+
+ if (totalPercent == 0)
+ {
+ maxItems = 0;
+ }
+ else if (totalPercent != 100)
+ {
+ double scale = (double) 100 / (double) totalPercent;
+
+ wtg = (uint32) (scale * (double) pi);
+ gtg = (uint32) (scale * (double) gtg);
+ btg = (uint32) (scale * (double) btg);
+ ptg = (uint32) (scale * (double) ptg);
+ wi = (uint32) (scale * (double) wi);
+ gi = (uint32) (scale * (double) gi);
+ bi = (uint32) (scale * (double) bi);
+ pi = 100 - wtg - gtg - btg - ptg - wi - gi - bi;
+
+ }
+ percentWhiteTradeGoods = wtg;
+ percentGreenTradeGoods = gtg;
+ percentBlueTradeGoods = btg;
+ percentPurpleTradeGoods = ptg;
+ percentWhiteItems = wi;
+ percentGreenItems = gi;
+ percentBlueItems = bi;
+ percentPurpleItems = pi;
+ CalculatePercents();
+ }
+ uint32 GetPercentages(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY_TG:
+ return 0;
+ break;
+ case AHB_WHITE_TG:
+ return percentWhiteTradeGoods;
+ break;
+ case AHB_GREEN_TG:
+ return percentGreenTradeGoods;
+ break;
+ case AHB_BLUE_TG:
+ return percentBlueTradeGoods;
+ break;
+ case AHB_PURPLE_TG:
+ return percentPurpleTradeGoods;
+ break;
+ case AHB_GREY_I:
+ return 0;
+ break;
+ case AHB_WHITE_I:
+ return percentWhiteItems;
+ break;
+ case AHB_GREEN_I:
+ return percentGreenItems;
+ break;
+ case AHB_BLUE_I:
+ return percentBlueItems;
+ break;
+ case AHB_PURPLE_I:
+ return percentPurpleItems;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ }
+ void SetMinPrice(uint32 color, uint32 value)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ break;
+ case AHB_WHITE:
+ minPriceWhite = value;
+ break;
+ case AHB_GREEN:
+ minPriceGreen = value;
+ break;
+ case AHB_BLUE:
+ minPriceBlue = value;
+ break;
+ case AHB_PURPLE:
+ minPricePurple = value;
+ break;
+ default:
+ break;
+ }
+ }
+ uint32 GetMinPrice(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ {
+ return 0;
+ break;
+ }
+ case AHB_WHITE:
+ {
+ if (minPriceWhite == 0)
+ return 150;
+ else if (minPriceWhite > maxPriceWhite)
+ return maxPriceWhite;
+ else
+ return minPriceWhite;
+ break;
+ }
+ case AHB_GREEN:
+ {
+ if (minPriceGreen == 0)
+ return 200;
+ else if (minPriceGreen > maxPriceGreen)
+ return maxPriceGreen;
+ else
+ return minPriceGreen;
+ break;
+ }
+ case AHB_BLUE:
+ {
+ if (minPriceBlue == 0)
+ return 250;
+ else if (minPriceBlue > maxPriceBlue)
+ return maxPriceBlue;
+ else
+ return minPriceBlue;
+ break;
+ }
+ case AHB_PURPLE:
+ {
+ if (minPricePurple == 0)
+ return 300;
+ else if (minPricePurple > maxPricePurple)
+ return maxPricePurple;
+ else
+ return minPricePurple;
+ break;
+ }
+ default:
+ {
+ return 0;
+ break;
+ }
+ }
+ }
+ void SetMaxPrice(uint32 color, uint32 value)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ break;
+ case AHB_WHITE:
+ maxPriceWhite = value;
+ break;
+ case AHB_GREEN:
+ maxPriceGreen = value;
+ break;
+ case AHB_BLUE:
+ maxPriceBlue = value;
+ break;
+ case AHB_PURPLE:
+ maxPricePurple = value;
+ break;
+ default:
+ break;
+ }
+ }
+ uint32 GetMaxPrice(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ {
+ return 0;
+ break;
+ }
+ case AHB_WHITE:
+ {
+ if (maxPriceWhite == 0)
+ return 250;
+ else
+ return maxPriceWhite;
+ break;
+ }
+ case AHB_GREEN:
+ {
+ if (maxPriceGreen == 0)
+ return 300;
+ else
+ return maxPriceGreen;
+ break;
+ }
+ case AHB_BLUE:
+ {
+ if (maxPriceBlue == 0)
+ return 350;
+ else
+ return maxPriceBlue;
+ break;
+ }
+ case AHB_PURPLE:
+ {
+ if (maxPricePurple == 0)
+ return 450;
+ else
+ return maxPricePurple;
+ break;
+ }
+ default:
+ {
+ return 0;
+ break;
+ }
+ }
+ }
+ void SetMinBidPrice(uint32 color, uint32 value)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ break;
+ case AHB_WHITE:
+ minBidPriceWhite = value;
+ break;
+ case AHB_GREEN:
+ minBidPriceGreen = value;
+ break;
+ case AHB_BLUE:
+ minBidPriceBlue = value;
+ break;
+ case AHB_PURPLE:
+ minBidPricePurple = value;
+ break;
+ default:
+ break;
+ }
+ }
+ uint32 GetMinBidPrice(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ {
+ return 0;
+ break;
+ }
+ case AHB_WHITE:
+ {
+ if (minBidPriceWhite > 100)
+ return 100;
+ else
+ return minBidPriceWhite;
+ break;
+ }
+ case AHB_GREEN:
+ {
+ if (minBidPriceGreen > 100)
+ return 100;
+ else
+ return minBidPriceGreen;
+ break;
+ }
+ case AHB_BLUE:
+ {
+ if (minBidPriceBlue > 100)
+ return 100;
+ else
+ return minBidPriceBlue;
+ break;
+ }
+ case AHB_PURPLE:
+ {
+ if (minBidPricePurple > 100)
+ return 100;
+ else
+ return minBidPricePurple;
+ break;
+ }
+ default:
+ {
+ return 0;
+ break;
+ }
+ }
+ }
+ void SetMaxBidPrice(uint32 color, uint32 value)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ break;
+ case AHB_WHITE:
+ maxBidPriceWhite = value;
+ break;
+ case AHB_GREEN:
+ maxBidPriceGreen = value;
+ break;
+ case AHB_BLUE:
+ maxBidPriceBlue = value;
+ break;
+ case AHB_PURPLE:
+ maxBidPricePurple = value;
+ break;
+ default:
+ break;
+ }
+ }
+ uint32 GetMaxBidPrice(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ {
+ return 0;
+ break;
+ }
+ case AHB_WHITE:
+ {
+ if (maxBidPriceWhite > 100)
+ return 100;
+ else
+ return maxBidPriceWhite;
+ break;
+ }
+ case AHB_GREEN:
+ {
+ if (maxBidPriceGreen > 100)
+ return 100;
+ else
+ return maxBidPriceGreen;
+ break;
+ }
+ case AHB_BLUE:
+ {
+ if (maxBidPriceBlue > 100)
+ return 100;
+ else
+ return maxBidPriceBlue;
+ break;
+ }
+ case AHB_PURPLE:
+ {
+ if (maxBidPricePurple > 100)
+ return 100;
+ else
+ return maxBidPricePurple;
+ break;
+ }
+ default:
+ {
+ return 0;
+ break;
+ }
+ }
+ }
+ void SetMaxStack(uint32 color, uint32 value)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ break;
+ case AHB_WHITE:
+ maxStackWhite = value;
+ break;
+ case AHB_GREEN:
+ maxStackGreen = value;
+ break;
+ case AHB_BLUE:
+ maxStackBlue = value;
+ break;
+ case AHB_PURPLE:
+ maxStackPurple = value;
+ break;
+ default:
+ break;
+ }
+ }
+ uint32 GetMaxStack(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ {
+ return 0;
+ break;
+ }
+ case AHB_WHITE:
+ {
+ return maxStackWhite;
+ break;
+ }
+ case AHB_GREEN:
+ {
+ return maxStackGreen;
+ break;
+ }
+ case AHB_BLUE:
+ {
+ return maxStackBlue;
+ break;
+ }
+ case AHB_PURPLE:
+ {
+ return maxStackPurple;
+ break;
+ }
+ default:
+ {
+ return 0;
+ break;
+ }
+ }
+ }
+ void SetBuyerPrice(uint32 color, uint32 value)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ buyerPriceGrey = value;
+ break;
+ case AHB_WHITE:
+ buyerPriceWhite = value;
+ break;
+ case AHB_GREEN:
+ buyerPriceGreen = value;
+ break;
+ case AHB_BLUE:
+ buyerPriceBlue = value;
+ break;
+ case AHB_PURPLE:
+ buyerPricePurple = value;
+ break;
+ default:
+ break;
+ }
+ }
+ uint32 GetBuyerPrice(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY:
+ return buyerPriceGrey;
+ break;
+ case AHB_WHITE:
+ return buyerPriceWhite;
+ break;
+ case AHB_GREEN:
+ return buyerPriceGreen;
+ break;
+ case AHB_BLUE:
+ return buyerPriceBlue;
+ break;
+ case AHB_PURPLE:
+ return buyerPricePurple;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ }
+ void SetBiddingInterval(uint32 value)
+ {
+ buyerBiddingInterval = value;
+ }
+ uint32 GetBiddingInterval()
+ {
+ return buyerBiddingInterval;
+ }
+ void CalculatePercents()
+ {
+ wtgp = (uint32) (((double)percentWhiteTradeGoods / 100.0) * maxItems);
+ gtgp = (uint32) (((double)percentGreenTradeGoods / 100.0) * maxItems);
+ btgp = (uint32) (((double)percentBlueTradeGoods / 100.0) * maxItems);
+ ptgp = (uint32) (((double)percentPurpleTradeGoods / 100.0) * maxItems);
+ wip = (uint32) (((double)percentWhiteItems / 100.0) * maxItems);
+ gip = (uint32) (((double)percentGreenItems / 100.0) * maxItems);
+ bip = (uint32) (((double)percentBlueItems / 100.0) * maxItems);
+ pip = (uint32) (((double)percentPurpleItems / 100.0) * maxItems);
+ uint32 total = wtgp + gtgp + btgp + ptgp + wip + gip + bip + pip;
+ if (total != maxItems)
+ {
+ wtgp = (uint32) (maxItems * (double) wtgp);
+ gtgp = (uint32) (maxItems * (double) gtgp);
+ btgp = (uint32) (maxItems * (double) btgp);
+ ptgp = (uint32) (maxItems * (double) ptgp);
+ wip = (uint32) (maxItems * (double) wip);
+ gip = (uint32) (maxItems * (double) gip);
+ bip = (uint32) (maxItems * (double) bip);
+ pip = (maxItems - (wtgp + gtgp + btgp + ptgp + wip + gip + bip));
+ total = wtgp + gtgp + btgp + ptgp + wip + gip + bip + pip;
+ }
+ //sLog.outString("%u %u %u %u %u %u %u %u", wtgp, gtgp, btgp, ptgp, wip, gip, bip, pip);
+ }
+ uint32 GetPercents(uint32 color)
+ {
+ switch(color)
+ {
+ case AHB_GREY_TG:
+ return 0;
+ break;
+ case AHB_WHITE_TG:
+ return wtgp;
+ break;
+ case AHB_GREEN_TG:
+ return gtgp;
+ break;
+ case AHB_BLUE_TG:
+ return btgp;
+ break;
+ case AHB_PURPLE_TG:
+ return ptgp;
+ break;
+ case AHB_GREY_I:
+ return 0;
+ break;
+ case AHB_WHITE_I:
+ return wip;
+ break;
+ case AHB_GREEN_I:
+ return gip;
+ break;
+ case AHB_BLUE_I:
+ return bip;
+ break;
+ case AHB_PURPLE_I:
+ return pip;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ }
+ void SetBidsPerInterval(uint32 value)
+ {
+ buyerBidsPerInterval = value;
+ }
+ uint32 GetBidsPerInterval()
+ {
+ return buyerBidsPerInterval;
+ }
+ ~AHBConfig()
+ {
+ }
+};
+void AuctionHouseBot();
+void AuctionHouseBotInit();
+void AuctionHouseBotLoadValues(AHBConfig*);
+void AuctionHouseBotCommands(uint32, uint32, uint32, char*);
+#endif
diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
index db1e31f2414..8cee1325205 100644
--- a/src/game/CMakeLists.txt
+++ b/src/game/CMakeLists.txt
@@ -13,6 +13,8 @@ SET(game_STAT_SRCS
ArenaTeam.h
ArenaTeamHandler.cpp
AuctionHouse.cpp
+ AuctionHouseBot.cpp
+ AuctionHouseBot.h
AuctionHouseObject.h
Bag.cpp
Bag.h
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 858c236a6fb..974a718b15e 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -622,6 +622,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "cometome", SEC_ADMINISTRATOR, false, &ChatHandler::HandleComeToMeCommand, "", NULL },
{ "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL },
{ "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
+ { "ahbotoptions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleAHBotOptionsCommand, "", NULL },
{ "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
{ "chardelete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
{ "sendmessage", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 36c196b1b14..73b561b164d 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -102,6 +102,7 @@ class ChatHandler
bool HandleAccountSetPasswordCommand(const char* args);
bool HandleHelpCommand(const char* args);
+ bool HandleAHBotOptionsCommand(const char * args);
bool HandleCommandsCommand(const char* args);
bool HandleStartCommand(const char* args);
bool HandleDismountCommand(const char* args);
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 8e4db98258e..6ba3c9178e3 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -635,6 +635,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool IsFormationLeader() {return (GetDBTableGUIDLow() && GetDBTableGUIDLow() == m_formationID);}
uint32 GetFormationID(){return m_formationID;}
+ Unit *SelectHostilTarget();
protected:
bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 12f251ec025..5016d0bcd56 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -52,6 +52,379 @@
#include "BattleGroundMgr.h"
#include "InstanceSaveMgr.h"
#include "InstanceData.h"
+#include "AuctionHouseBot.h"
+
+bool ChatHandler::HandleAHBotOptionsCommand(const char* args)
+{
+ uint32 ahMapID = 0;
+ char * opt = strtok((char*)args, " ");
+ char * ahMapIdStr = strtok(NULL, " ");
+ if (ahMapIdStr)
+ {
+ ahMapID = (uint32) strtoul(ahMapIdStr, NULL, 0);
+ }
+ if (!opt)
+ {
+ PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter");
+ PSendSysMessage("Try ahbotoptions help to see a list of options.");
+ return false;
+ }
+ int l = strlen(opt);
+
+ if (strncmp(opt,"help",l) == 0)
+ {
+ PSendSysMessage("AHBot commands:");
+ PSendSysMessage("ahexpire");
+ PSendSysMessage("minitems");
+ PSendSysMessage("maxitems");
+ PSendSysMessage("mintime");
+ PSendSysMessage("maxtime");
+ PSendSysMessage("percentages");
+ PSendSysMessage("minprice");
+ PSendSysMessage("maxprice");
+ PSendSysMessage("minbidprice");
+ PSendSysMessage("maxbidprice");
+ PSendSysMessage("maxstack");
+ PSendSysMessage("buyerprice");
+ PSendSysMessage("bidinterval");
+ PSendSysMessage("bidsperinterval");
+ return true;
+ }
+ else if (strncmp(opt,"ahexpire",l) == 0)
+ {
+ if (!ahMapIdStr)
+ {
+ PSendSysMessage("Syntax is: ahbotoptions ahexpire $ahMapID (2, 6 or 7)");
+ return false;
+ }
+ AuctionHouseBotCommands(0, ahMapID, NULL, NULL);
+ }
+ else if (strncmp(opt,"minitems",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minitems $ahMapID (2, 6 or 7) $minItems");
+ return false;
+ }
+ AuctionHouseBotCommands(1, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"maxitems",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxitems $ahMapID (2, 6 or 7) $maxItems");
+ return false;
+ }
+ AuctionHouseBotCommands(2, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"mintime",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions mintime $ahMapID (2, 6 or 7) $mintime");
+ return false;
+ }
+ AuctionHouseBotCommands(3, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"maxtime",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxtime $ahMapID (2, 6 or 7) $maxtime");
+ return false;
+ }
+ AuctionHouseBotCommands(4, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"percentages",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ char * param3 = strtok(NULL, " ");
+ char * param4 = strtok(NULL, " ");
+ char * param5 = strtok(NULL, " ");
+ char * param6 = strtok(NULL, " ");
+ char * param7 = strtok(NULL, " ");
+ char * param8 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2) || (!param3) || (!param4) || (!param5) || (!param6) || (!param7) || (!param8))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8");
+ PSendSysMessage("1 WhiteTradeGoods 2 GreenTradeGoods 3 BlueTradeGoods 4 PurpleTradeGoods");
+ PSendSysMessage("5 WhiteItems 6 GreenItems 7 BlueItems 8 PurpleItems");
+ PSendSysMessage("The total must add up to 100%");
+ return false;
+ }
+ uint32 wtg = (uint32) strtoul(param1, NULL, 0);
+ uint32 gtg = (uint32) strtoul(param2, NULL, 0);
+ uint32 btg = (uint32) strtoul(param3, NULL, 0);
+ uint32 ptg = (uint32) strtoul(param4, NULL, 0);
+ uint32 wi = (uint32) strtoul(param5, NULL, 0);
+ uint32 gi = (uint32) strtoul(param6, NULL, 0);
+ uint32 bi = (uint32) strtoul(param7, NULL, 0);
+ uint32 pi = (uint32) strtoul(param8, NULL, 0);
+ uint32 totalPercent = wtg + gtg + btg + ptg + wi + gi + bi + pi;
+ if ((totalPercent == 0) || (totalPercent != 100))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8");
+ PSendSysMessage("1 WhiteTradeGoods 2 GreenTradeGoods 3 BlueTradeGoods 4 PurpleTradeGoods");
+ PSendSysMessage("5 WhiteItems 6 GreenItems 7 BlueItems 8 PurpleItems");
+ PSendSysMessage("The total must add up to 100%");
+ return false;
+ }
+ char param[100];
+ param[0] = '\0';
+ strcat(param, param1);
+ strcat(param, " ");
+ strcat(param, param2);
+ strcat(param, " ");
+ strcat(param, param3);
+ strcat(param, " ");
+ strcat(param, param4);
+ strcat(param, " ");
+ strcat(param, param5);
+ strcat(param, " ");
+ strcat(param, param6);
+ strcat(param, " ");
+ strcat(param, param7);
+ strcat(param, " ");
+ strcat(param, param8);
+ AuctionHouseBotCommands(5, ahMapID, NULL, param);
+ }
+ else if (strncmp(opt,"minprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ if (strncmp(param1,"white",l) == 0)
+ {
+ AuctionHouseBotCommands(6, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ AuctionHouseBotCommands(6, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ AuctionHouseBotCommands(6, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ AuctionHouseBotCommands(6, ahMapID, AHB_PURPLE, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"maxprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ if (strncmp(param1,"white",l) == 0)
+ {
+ AuctionHouseBotCommands(7, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ AuctionHouseBotCommands(7, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ AuctionHouseBotCommands(7, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ AuctionHouseBotCommands(7, ahMapID, AHB_PURPLE, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"minbidprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ uint32 minBidPrice = (uint32) strtoul(param2, NULL, 0);
+ if ((minBidPrice < 1) || (minBidPrice > 100))
+ {
+ PSendSysMessage("The min bid price multiplier must be between 1 and 100");
+ return false;
+ }
+ if (strncmp(param1,"white",l) == 0)
+ {
+ AuctionHouseBotCommands(8, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ AuctionHouseBotCommands(8, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ AuctionHouseBotCommands(8, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ AuctionHouseBotCommands(8, ahMapID, AHB_PURPLE, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"maxbidprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxbidprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ uint32 maxBidPrice = (uint32) strtoul(param2, NULL, 0);
+ if ((maxBidPrice < 1) || (maxBidPrice > 100))
+ {
+ PSendSysMessage("The max bid price multiplier must be between 1 and 100");
+ return false;
+ }
+ if (strncmp(param1,"white",l) == 0)
+ {
+ AuctionHouseBotCommands(9, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ AuctionHouseBotCommands(9, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ AuctionHouseBotCommands(9, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ AuctionHouseBotCommands(9, ahMapID, AHB_PURPLE, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions max bidprice $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"maxstack",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $value");
+ return false;
+ }
+ uint32 maxStack = (uint32) strtoul(param2, NULL, 0);
+ if (maxStack < 0)
+ {
+ PSendSysMessage("maxstack can't be a negative number.");
+ return false;
+ }
+ if (strncmp(param1,"white",l) == 0)
+ {
+ AuctionHouseBotCommands(10, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ AuctionHouseBotCommands(10, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ AuctionHouseBotCommands(10, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ AuctionHouseBotCommands(10, ahMapID, AHB_PURPLE, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (white, green, blue or purple) $value");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"buyerprice",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ char * param2 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1) || (!param2))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price");
+ return false;
+ }
+ if (strncmp(param1,"white",l) == 0)
+ {
+ AuctionHouseBotCommands(11, ahMapID, AHB_WHITE, param2);
+ }
+ else if (strncmp(param1,"green",l) == 0)
+ {
+ AuctionHouseBotCommands(11, ahMapID, AHB_GREEN, param2);
+ }
+ else if (strncmp(param1,"blue",l) == 0)
+ {
+ AuctionHouseBotCommands(11, ahMapID, AHB_BLUE, param2);
+ }
+ else if (strncmp(param1,"purple",l) == 0)
+ {
+ AuctionHouseBotCommands(11, ahMapID, AHB_PURPLE, param2);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price");
+ return false;
+ }
+ }
+ else if (strncmp(opt,"bidinterval",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions bidinterval $ahMapID (2, 6 or 7) $interval(in minutes)");
+ return false;
+ }
+ AuctionHouseBotCommands(12, ahMapID, NULL, param1);
+ }
+ else if (strncmp(opt,"bidsperinterval",l) == 0)
+ {
+ char * param1 = strtok(NULL, " ");
+ if ((!ahMapIdStr) || (!param1))
+ {
+ PSendSysMessage("Syntax is: ahbotoptions bidsperinterval $ahMapID (2, 6 or 7) $bids");
+ return false;
+ }
+ AuctionHouseBotCommands(13, ahMapID, NULL, param1);
+ }
+ else
+ {
+ PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter");
+ PSendSysMessage("Try ahbotoptions help to see a list of options.");
+ return false;
+ }
+ return true;
+}
//reload commands
bool ChatHandler::HandleReloadAllCommand(const char*)
@@ -725,7 +1098,7 @@ bool ChatHandler::HandleLoadScriptsCommand(const char* args)
{
if(!LoadScriptingModule(args)) return true;
- sWorld.SendWorldText(LANG_SCRIPTS_RELOADED);
+ sWorld.SendGMText(LANG_SCRIPTS_RELOADED);
return true;
}
diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp
index 3d4126bd22a..398b6c42ada 100644
--- a/src/game/Mail.cpp
+++ b/src/game/Mail.cpp
@@ -30,6 +30,7 @@
#include "Unit.h"
#include "Language.h"
#include "Database/DBCStores.h"
+#include "AuctionHouseBot.h"
void MailItem::deleteItem( bool inDB )
{
@@ -348,7 +349,14 @@ void WorldSession::HandleReturnToSender(WorldPacket & recv_data )
}
}
- SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId);
+ if (m->sender == AHBplayerGUID)
+ {
+ SendReturnToSender(MAIL_CREATURE, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId);
+ }
+ else
+ {
+ SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId);
+ }
delete m; //we can deallocate old mail
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, 0);
@@ -767,6 +775,14 @@ void WorldSession::HandleMsgQueryNextMailtime(WorldPacket & /*recv_data*/ )
void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 stationery, uint32 sender_guidlow_or_entry, uint32 receiver_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay, uint16 mailTemplateId)
{
+ if (receiver_guidlow == AHBplayerGUID)
+ {
+ if(messageType == MAIL_AUCTION && mi) // auction mail with items
+ {
+ mi->deleteIncludedItems(true);
+ }
+ return;
+ }
uint32 mailId = objmgr.GenerateMailID();
time_t deliver_time = time(NULL) + deliver_delay;
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index f17cfa0c83a..6869485266a 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -2058,7 +2058,7 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
}
}
-void Spell::cancel()
+void Spell::cancel(bool report)
{
if(m_spellState == SPELL_STATE_FINISHED)
return;
@@ -2088,7 +2088,7 @@ void Spell::cancel()
m_caster->RemoveAurasDueToCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
SendChannelUpdate(0);
SendInterrupted(0);
- SendCastResult(SPELL_FAILED_INTERRUPTED);
+ SendCastResult(report ? SPELL_FAILED_INTERRUPTED : SPELL_FAILED_DONT_REPORT);
} break;
default:
@@ -3687,7 +3687,8 @@ uint8 Spell::CanCast(bool strict)
// check correctness positive/negative cast target (pet cast real check and cheating check)
if(IsPositiveSpell(m_spellInfo->Id))
{
- if(m_caster->IsHostileTo(target))
+ //dispel positivity is dependant on target, don't check it
+ if(m_caster->IsHostileTo(target) && !IsDispel(m_spellInfo))
return SPELL_FAILED_BAD_TARGETS;
}
else
@@ -3932,6 +3933,12 @@ uint8 Spell::CanCast(bool strict)
if(m_targets.getUnitTarget() && !m_caster->IsFriendlyTo(m_targets.getUnitTarget()) && !m_caster->HasInArc( M_PI, target ))
return SPELL_FAILED_UNIT_NOT_INFRONT;
}
+ else if (m_spellInfo->Id == 19938) // Awaken Peon
+ {
+ Unit *unit = m_targets.getUnitTarget();
+ if(!unit || !unit->HasAura(17743, 0))
+ return SPELL_FAILED_BAD_TARGETS;
+ }
break;
}
case SPELL_EFFECT_SCHOOL_DAMAGE:
diff --git a/src/game/Spell.h b/src/game/Spell.h
index d06862ad1fa..afef4262058 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -353,7 +353,7 @@ class Spell
~Spell();
void prepare(SpellCastTargets const* targets, Aura* triggeredByAura = NULL);
- void cancel();
+ void cancel(bool report = true);
void update(uint32 difftime);
void cast(bool skipCheck = false);
void finish(bool ok = true);
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index f4842154ed8..78df7d77bd6 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3707,20 +3707,20 @@ void Spell::EffectSummonGuardian(uint32 i)
// Search old Guardian only for players (if casted spell not have duration or cooldown)
// FIXME: some guardians have control spell applied and controlled by player and anyway player can't summon in this time
// so this code hack in fact
- if( m_caster->GetTypeId() == TYPEID_PLAYER && (duration <= 0 || GetSpellRecoveryTime(m_spellInfo)==0) )
- if(((Player*)m_caster)->HasGuardianWithEntry(pet_entry))
+ if( m_originalCaster->GetTypeId() == TYPEID_PLAYER && (duration <= 0 || GetSpellRecoveryTime(m_spellInfo)==0) )
+ if(((Player*)m_originalCaster)->HasGuardianWithEntry(pet_entry))
return; // find old guardian, ignore summon
// in another case summon new
- uint32 level = m_caster->getLevel();
+ uint32 level = m_originalCaster->getLevel();
// level of pet summoned using engineering item based at engineering skill level
- if(m_caster->GetTypeId()==TYPEID_PLAYER && m_CastItem)
+ if(m_originalCaster->GetTypeId()==TYPEID_PLAYER && m_CastItem)
{
ItemPrototype const *proto = m_CastItem->GetProto();
if(proto && proto->RequiredSkill == SKILL_ENGINERING)
{
- uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING);
+ uint16 skill202 = ((Player*)m_originalCaster)->GetSkillValue(SKILL_ENGINERING);
if(skill202)
{
level = skill202/5;
@@ -3783,14 +3783,14 @@ void Spell::EffectSummonGuardian(uint32 i)
if(duration > 0)
spawnCreature->SetDuration(duration);
- spawnCreature->SetOwnerGUID(m_caster->GetGUID());
+ spawnCreature->SetOwnerGUID(m_originalCaster->GetGUID());
spawnCreature->setPowerType(POWER_MANA);
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0);
- spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
+ spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_originalCaster->getFaction());
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0);
- spawnCreature->SetCreatorGUID(m_caster->GetGUID());
+ spawnCreature->SetCreatorGUID(m_originalCaster->GetGUID());
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
spawnCreature->InitStatsForLevel(level);
@@ -3798,8 +3798,8 @@ void Spell::EffectSummonGuardian(uint32 i)
spawnCreature->AIM_Initialize();
- if(m_caster->GetTypeId()==TYPEID_PLAYER)
- ((Player*)m_caster)->AddGuardian(spawnCreature);
+ if(m_originalCaster->GetTypeId()==TYPEID_PLAYER)
+ ((Player*)m_originalCaster)->AddGuardian(spawnCreature);
map->Add((Creature*)spawnCreature);
}
@@ -6162,6 +6162,10 @@ void Spell::EffectSendTaxi(uint32 i)
case 53335: //Stormwind Harbor Flight - Peaceful
mountid = 6852;
break;
+ case 41533: //Fly of the Netherwing
+ case 41540: //Fly of the Netherwing
+ mountid = 23468;
+ break;
}
((Player*)unitTarget)->ActivateTaxiPathTo(nodes,mountid);
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 5d9e2a3fed3..9903220677f 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -419,16 +419,22 @@ inline bool IsAreaAuraEffect(uint32 effect)
return true;
return false;
}
-
-inline bool IsDispelSpell(SpellEntry const *spellInfo)
+inline bool IsDispel(SpellEntry const *spellInfo)
{
//spellsteal is also dispel
if (spellInfo->Effect[0] == SPELL_EFFECT_DISPEL ||
- spellInfo->Effect[0] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
spellInfo->Effect[1] == SPELL_EFFECT_DISPEL ||
+ spellInfo->Effect[2] == SPELL_EFFECT_DISPEL)
+ return true;
+ return false;
+}
+inline bool IsDispelSpell(SpellEntry const *spellInfo)
+{
+ //spellsteal is also dispel
+ if (spellInfo->Effect[0] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
spellInfo->Effect[1] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
- spellInfo->Effect[2] == SPELL_EFFECT_DISPEL ||
- spellInfo->Effect[2] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF)
+ spellInfo->Effect[2] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
+ ||IsDispel(spellInfo))
return true;
return false;
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 79ec28dcb0c..471ff053550 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -185,8 +185,17 @@ Unit::~Unit()
if(m_uint32Values)
{
sLog.outDetail("Deconstruct Unit Entry = %u", GetEntry());
- if(m_scAuras.size())
+ /*for(int i = 0; i < TOTAL_AURAS; ++i)
+ {
+ if(m_modAuras[i].begin() != m_modAuras[i].end())
+ sLog.outError("Unit %u has mod auras during deconstruction", GetEntry());
+ }
+ if(m_scAuras.begin() != m_scAuras.end())
sLog.outError("Unit %u has sc auras during deconstruction", GetEntry());
+ if(m_interruptableAuras.begin() != m_interruptableAuras.end())
+ sLog.outError("Unit %u has interruptable auras during deconstruction", GetEntry());
+ if(m_ccAuras.begin() != m_ccAuras.end())
+ sLog.outError("Unit %u has cc auras during deconstruction", GetEntry());*/
}
}
@@ -4001,7 +4010,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
// Statue unsummoned at aura remove
Totem* statue = NULL;
- bool caster_channeled = false;
+ bool channeled = false;
if(IsChanneledSpell(AurSpellInfo))
{
if(!caster) // can be already located for IsSingleTargetSpell case
@@ -4011,8 +4020,25 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
{
if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE)
statue = ((Totem*)caster);
- else
- caster_channeled = caster==this;
+
+ // stop caster chanelling state
+ else if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]
+ //prevent recurential call
+ && caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED)
+ {
+ if (caster==this || !IsAreaOfEffectSpell(AurSpellInfo))
+ {
+ // remove auras only for non-aoe spells or when chanelled aura is removed
+ // because aoe spells don't require aura on target to continue
+ if (AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!=SPELL_AURA_PERIODIC_DUMMY
+ && AurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]!= SPELL_AURA_DUMMY)
+ //don't stop channeling of scripted spells (this is actually a hack)
+ {
+ caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel(false);
+ channeled = true;
+ }
+ }
+ }
}
}
@@ -4037,8 +4063,13 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
delete Aur;
- if(caster_channeled)
- RemoveAurasAtChanneledTarget (AurSpellInfo);
+ if(channeled)
+ {
+ //if target is not caster remove auras also on caster
+ if (caster!=this)
+ caster->RemoveAurasAtChanneledTarget (AurSpellInfo, caster);
+ RemoveAurasAtChanneledTarget (AurSpellInfo, caster);
+ }
if(statue)
statue->UnSummon();
@@ -9521,18 +9552,16 @@ void Unit::TauntFadeOut(Unit *taunter)
//======================================================================
-bool Unit::SelectHostilTarget()
+Unit* Creature::SelectHostilTarget()
{
//function provides main threat functionality
//next-victim-selection algorithm and evade mode are called
//threat list sorting etc.
- assert(GetTypeId()== TYPEID_UNIT);
//This function only useful once AI has been initialized
- if (!((Creature*)this)->AI())
- return false;
-
+ if (!AI())
+ return NULL;
Unit* target = NULL;
// First checking if we have some taunt on us
@@ -9543,7 +9572,7 @@ bool Unit::SelectHostilTarget()
// The last taunt aura caster is alive an we are happy to attack him
if ( (caster = tauntAuras.back()->GetCaster()) && caster->isAlive() )
- return true;
+ return getVictim();
else if (tauntAuras.size() > 1)
{
// We do not have last taunt aura caster but we have more taunt auras,
@@ -9574,36 +9603,36 @@ bool Unit::SelectHostilTarget()
{
if(!hasUnitState(UNIT_STAT_STUNNED))
SetInFront(target);
- ((Creature*)this)->AI()->AttackStart(target);
- return true;
+ AI()->AttackStart(target);
+ return getVictim();
}
// no target but something prevent go to evade mode
if( !isInCombat() /*|| HasAuraType(SPELL_AURA_MOD_TAUNT)*/ )
- return false;
+ return NULL;
// last case when creature don't must go to evade mode:
// it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list
// for example at owner command to pet attack some far away creature
// Note: creature not have targeted movement generator but have attacker in this case
- if( GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE )
+ /*if( GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE )
{
for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
{
if( (*itr)->IsInMap(this) && canAttack(*itr) && (*itr)->isInAccessiblePlaceFor((Creature*)this) )
return false;
}
- }
+ }*/
// search nearby enemy before enter evade mode
- if(((Creature*)this)->HasReactState(REACT_AGGRESSIVE))
+ if(HasReactState(REACT_AGGRESSIVE))
{
- if(Unit *target = ((Creature*)this)->SelectNearestTarget())
+ if(target = SelectNearestTarget())
{
- if(!((Creature*)this)->IsOutOfThreatArea(target))
+ if(!IsOutOfThreatArea(target))
{
- ((Creature*)this)->AI()->AttackStart(target);
- return true;
+ AI()->AttackStart(target);
+ return getVictim();
}
}
}
@@ -9614,16 +9643,16 @@ bool Unit::SelectHostilTarget()
for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
if((*itr)->IsPermanent())
{
- ((Creature*)this)->AI()->EnterEvadeMode();
+ AI()->EnterEvadeMode();
break;
}
- return false;
+ return NULL;
}
// enter in evade mode in other case
- ((Creature*)this)->AI()->EnterEvadeMode();
+ AI()->EnterEvadeMode();
- return false;
+ return NULL;
}
//======================================================================
@@ -11555,23 +11584,23 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
return true;
}
-void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
+void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo, Unit * caster)
{
- uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);
+/* uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT);
if(target_guid == GetGUID())
return;
if(!IS_UNIT_GUID(target_guid))
return;
- Unit* target = ObjectAccessor::GetUnit(*this, target_guid);
- if(!target)
+ Unit* target = ObjectAccessor::GetUnit(*this, target_guid);*/
+ if(!caster)
return;
- for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); )
+ for (AuraMap::iterator iter = GetAuras().begin(); iter != GetAuras().end(); )
{
- if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID())
- target->RemoveAura(iter);
+ if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID() == caster->GetGUID())
+ RemoveAura(iter);
else
++iter;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index b2ff5287309..669bc8a405f 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1148,7 +1148,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
void RemoveAurasDueToSpellByCancel(uint32 spellId);
- void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo);
+ void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo, Unit * caster);
void RemoveNotOwnSingleTargetAuras();
void RemoveSpellsCausingAura(AuraType auraType);
@@ -1275,7 +1275,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);
void DeleteThreatList();
- bool SelectHostilTarget();
+ //bool SelectHostilTarget();
void TauntApply(Unit* pVictim);
void TauntFadeOut(Unit *taunter);
ThreatManager& getThreatManager() { return m_ThreatManager; }
@@ -1506,6 +1506,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint32 m_reactiveTimer[MAX_REACTIVE];
uint32 m_regenTimer;
+ ThreatManager m_ThreatManager;
private:
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
//void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
@@ -1525,7 +1526,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Diminishing m_Diminishing;
// Manage all Units threatening us
- ThreatManager m_ThreatManager;
+// ThreatManager m_ThreatManager;
// Manage all Units that are threatened by us
HostilRefManager m_HostilRefManager;
diff --git a/src/game/World.cpp b/src/game/World.cpp
index fde4126db18..7dd1a54769f 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -51,6 +51,7 @@
#include "BattleGroundMgr.h"
#include "OutdoorPvPMgr.h"
#include "TemporarySummon.h"
+#include "AuctionHouseBot.h"
#include "WaypointMovementGenerator.h"
#include "VMapFactory.h"
#include "GlobalEvents.h"
@@ -1453,6 +1454,9 @@ void World::SetInitialWorldSettings()
uint32 nextGameEvent = gameeventmgr.Initialize();
m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); //depend on next event
+ sLog.outString("Initialize AuctionHouseBot...");
+ AuctionHouseBotInit();
+
sLog.outString( "WORLD: World initialized" );
}
@@ -1564,7 +1568,8 @@ void World::Update(uint32 diff)
/// <ul><li> Handle auctions when the timer has passed
if (m_timers[WUPDATE_AUCTIONS].Passed())
{
- m_timers[WUPDATE_AUCTIONS].Reset();
+ AuctionHouseBot();
+ m_timers[WUPDATE_AUCTIONS].Reset();
///- Update mails (return old mails with item, or delete them)
//(tested... works on win)