aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpete318 <pete318@hotmail.com>2015-10-02 03:20:42 +0100
committerpete318 <pete318@hotmail.com>2015-12-14 19:54:58 +0100
commit0ac442f19fcfa8c39775c5ae06bba8f3bcbd0407 (patch)
treeca323a2a4cab2a668e4ca3763138752d0d7877e4
parent54424aff3051bdc2a05d44cbd56adf6f47b98229 (diff)
Improved Auction house deposit handling.
Including the weird quirks. Changes: * Deposit caculated according to same rule as client. (detailed below). Should always match client deposit now * Deposit for multiple auctions now only collected once. Deferred calculation of deposit until all auctions listed. Deposit calculation is as follows: Base deposit calculation = MSV x 15/75% (depending on AH). However this is not rounded. Case to int is used (so always round down) The remainder is held in a float. The base is then multiplied by number of items, and the time multiplier (x2 for 24 hour, x4 for 48 hour) The nearest (no of items or lower) no of items when multiplied by the remainder that creates a whole number is then multiplied by the time multiplier (x1/x2/x4) and then added to deposit. Example: Item sell price 1s25. Deposit 18.75c (15% of 1s25). So base deposit = 18, remainder 0.75. Time 24h (x2) Item count 1 = 36c. Remainder = 0.75 (n) Min = 1s. Deposit 1s Item sell price 1s25. Deposit 18.75c (15% of 1s25). So base deposit = 18, remainder 0.75. Time 24h (x2) Item count 2 = 72c. Remainder = 1.50 (n) Min = 1s. Deposit 1s Item sell price 1s25. Deposit 18.75c (15% of 1s25). So base deposit = 18, remainder 0.75. Time 24h (x2) Item count 3 = 108c. Remainder = 2.25 (n) Min = 1s. Deposit 1s08c Item sell price 1s25. Deposit 18.75c (15% of 1s25). So base deposit = 18, remainder 0.75. Time 24h (x2) Item count 4 = 144c. Remainder = 3.00 (n) Min = 1s. Deposit 1s50c (144c + (3c * 2)) Horrible kludge, to re-create a very weird deposit method. Closes #15674 (PR) Closes #15643 (Issue)
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp123
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h11
-rw-r--r--src/server/game/Entities/Player/Player.cpp1
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp7
-rw-r--r--src/server/game/World/World.cpp8
-rw-r--r--src/server/game/World/World.h1
6 files changed, 147 insertions, 4 deletions
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 768def2ff4d..20d30704c13 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -83,12 +83,23 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32
float multiplier = CalculatePct(float(entry->depositPercent), 3);
uint32 timeHr = (((time / 60) / 60) / 12);
- uint32 deposit = uint32(((multiplier * MSV * count / 3) * timeHr * 3) * sWorld->getRate(RATE_AUCTION_DEPOSIT));
+ uint32 deposit = uint32(MSV * multiplier * sWorld->getRate(RATE_AUCTION_DEPOSIT));
+ float remainderbase = float(MSV * multiplier * sWorld->getRate(RATE_AUCTION_DEPOSIT)) - deposit;
+
+ deposit *= timeHr * count;
+
+ int i = count;
+ while (i > 0 && (remainderbase * i) != uint32(remainderbase * i))
+ i--;
+
+ if (i)
+ deposit += remainderbase * i * timeHr;
TC_LOG_DEBUG("auctionHouse", "MSV: %u", MSV);
TC_LOG_DEBUG("auctionHouse", "Items: %u", count);
TC_LOG_DEBUG("auctionHouse", "Multiplier: %f", multiplier);
TC_LOG_DEBUG("auctionHouse", "Deposit: %u", deposit);
+ TC_LOG_DEBUG("auctionHouse", "Deposit rm: %f", remainderbase * count);
if (deposit < AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT))
return AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT);
@@ -389,6 +400,116 @@ bool AuctionHouseMgr::RemoveAItem(ObjectGuid::LowType id, bool deleteItem)
return true;
}
+void AuctionHouseMgr::PendingAuctionAdd(Player* player, AuctionEntry* aEntry)
+{
+ PlayerAuctions* thisAH;
+ auto itr = pendingAuctionMap.find(player->GetGUID());
+ if (itr != pendingAuctionMap.end())
+ thisAH = itr->second.first;
+ else
+ {
+ thisAH = new PlayerAuctions;
+ pendingAuctionMap[player->GetGUID()] = AuctionPair(thisAH, 0);
+ }
+ thisAH->push_back(aEntry);
+}
+
+uint32 AuctionHouseMgr::PendingAuctionCount(const Player* player) const
+{
+ auto const itr = pendingAuctionMap.find(player->GetGUID());
+ if (itr != pendingAuctionMap.end())
+ return itr->second.first->size();
+
+ return 0;
+}
+
+void AuctionHouseMgr::PendingAuctionProcess(Player* player)
+{
+ auto iterMap = pendingAuctionMap.find(player->GetGUID());
+ if (iterMap == pendingAuctionMap.end())
+ return;
+
+ PlayerAuctions* thisAH = iterMap->second.first;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ uint32 totalItems = 0;
+ for (auto itrAH = thisAH->begin(); itrAH != thisAH->end(); ++itrAH)
+ {
+ AuctionEntry* AH = (*itrAH);
+ totalItems += AH->itemCount;
+ }
+
+ uint32 totaldeposit = 0;
+ auto itr = (*thisAH->begin());
+
+ if (Item* item = GetAItem(itr->itemGUIDLow))
+ totaldeposit = GetAuctionDeposit(itr->auctionHouseEntry, itr->etime, item, totalItems);
+
+ uint32 depositremain = totaldeposit;
+ for (auto itr = thisAH->begin(); itr != thisAH->end(); ++itr)
+ {
+ AuctionEntry* AH = (*itr);
+
+ if (next(itr) == thisAH->end())
+ AH->deposit = depositremain;
+ else
+ {
+ AH->deposit = totaldeposit / thisAH->size();
+ depositremain -= AH->deposit;
+ }
+
+ AH->DeleteFromDB(trans);
+ AH->SaveToDB(trans);
+ }
+
+ CharacterDatabase.CommitTransaction(trans);
+ pendingAuctionMap.erase(player->GetGUID());
+ delete thisAH;
+ player->ModifyMoney(-int32(totaldeposit));
+}
+
+void AuctionHouseMgr::UpdatePendingAuctions()
+{
+ for (auto itr = pendingAuctionMap.begin(); itr != pendingAuctionMap.end();)
+ {
+ ObjectGuid playerGUID = itr->first;
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID))
+ {
+ // Check if there were auctions since last update process if not
+ if (PendingAuctionCount(player) == itr->second.second)
+ {
+ ++itr;
+ PendingAuctionProcess(player);
+ }
+ else
+ {
+ ++itr;
+ pendingAuctionMap[playerGUID].second = PendingAuctionCount(player);
+ }
+ }
+ else
+ {
+ // Expire any auctions that we couldn't get a deposit for
+ TC_LOG_WARN("auctionHouse", "Player %s was offline, unable to retrieve deposit!", playerGUID.ToString().c_str());
+ PlayerAuctions* thisAH = itr->second.first;
+ ++itr;
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ for (auto AHitr = thisAH->begin(); AHitr != thisAH->end();)
+ {
+ AuctionEntry* AH = (*AHitr);
+ ++AHitr;
+ AH->expire_time = time(NULL);
+ AH->DeleteFromDB(trans);
+ AH->SaveToDB(trans);
+ }
+ CharacterDatabase.CommitTransaction(trans);
+ pendingAuctionMap.erase(playerGUID);
+ delete thisAH;
+ }
+ }
+}
+
void AuctionHouseMgr::Update()
{
mHordeAuctions.Update();
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index 45cdba361f3..1f885837a44 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -22,6 +22,7 @@
#include "Common.h"
#include "DatabaseEnv.h"
#include "DBCStructure.h"
+#include <set>
class Item;
class Player;
@@ -82,6 +83,7 @@ struct AuctionEntry
time_t expire_time;
ObjectGuid::LowType bidder;
uint32 deposit; //deposit can be calculated only when creating auction
+ uint32 etime;
AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc
// helpers
@@ -151,6 +153,8 @@ class AuctionHouseMgr
}
typedef std::unordered_map<ObjectGuid::LowType, Item*> ItemMap;
+ typedef std::vector<AuctionEntry*> PlayerAuctions;
+ typedef std::pair<PlayerAuctions*, uint32> AuctionPair;
AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
AuctionHouseObject* GetAuctionsMapByHouseId(uint8 auctionHouseId);
@@ -184,7 +188,10 @@ class AuctionHouseMgr
void AddAItem(Item* it);
bool RemoveAItem(ObjectGuid::LowType id, bool deleteItem = false);
-
+ void PendingAuctionAdd(Player* player, AuctionEntry* aEntry);
+ uint32 PendingAuctionCount(const Player* player) const;
+ void PendingAuctionProcess(Player* player);
+ void UpdatePendingAuctions();
void Update();
private:
@@ -193,6 +200,8 @@ class AuctionHouseMgr
AuctionHouseObject mAllianceAuctions;
AuctionHouseObject mNeutralAuctions;
+ std::map<ObjectGuid, AuctionPair> pendingAuctionMap;
+
ItemMap mAitems;
};
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a8f015a8749..4804aece416 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1535,6 +1535,7 @@ void Player::Update(uint32 p_time)
//because we don't want player's ghost teleported from graveyard
if (IsHasDelayedTeleport() && IsAlive())
TeleportTo(m_teleport_dest, m_teleport_options);
+
}
void Player::setDeathState(DeathState s)
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 8ecf86680ca..a9680ff69bb 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -303,18 +303,21 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
AH->buyout = buyout;
AH->expire_time = time(NULL) + auctionTime;
AH->deposit = deposit;
+ AH->etime = etime;
AH->auctionHouseEntry = auctionHouseEntry;
TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u",
_player->GetName().c_str(), _player->GetGUID().GetCounter(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUID().GetCounter(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
sAuctionMgr->AddAItem(item);
auctionHouse->AddAuction(AH);
+ sAuctionMgr->PendingAuctionAdd(_player, AH);
_player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
item->DeleteFromInventoryDB(trans);
item->SaveToDB(trans);
+
AH->SaveToDB(trans);
_player->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
@@ -351,12 +354,14 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
AH->buyout = buyout;
AH->expire_time = time(NULL) + auctionTime;
AH->deposit = deposit;
+ AH->etime = etime;
AH->auctionHouseEntry = auctionHouseEntry;
TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u",
_player->GetName().c_str(), _player->GetGUID().GetCounter(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUID().GetCounter(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
sAuctionMgr->AddAItem(newItem);
auctionHouse->AddAuction(AH);
+ sAuctionMgr->PendingAuctionAdd(_player, AH);
for (uint32 j = 0; j < itemsCount; ++j)
{
@@ -396,8 +401,6 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
}
-
- _player->ModifyMoney(-int32(deposit));
}
//this function is called when client bids or buys out auction
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index c41caa8f955..bcfd105f3c6 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1782,6 +1782,7 @@ void World::SetInitialWorldSettings()
m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS);
m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS);
+ m_timers[WUPDATE_AUCTIONS_PENDING].SetInterval(250);
m_timers[WUPDATE_UPTIME].SetInterval(m_int_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS);
//Update "uptime" table based on configuration entry in minutes.
m_timers[WUPDATE_CORPSES].SetInterval(20 * MINUTE * IN_MILLISECONDS);
@@ -2052,6 +2053,13 @@ void World::Update(uint32 diff)
sAuctionMgr->Update();
}
+ if (m_timers[WUPDATE_AUCTIONS_PENDING].Passed())
+ {
+ m_timers[WUPDATE_AUCTIONS_PENDING].Reset();
+
+ sAuctionMgr->UpdatePendingAuctions();
+ }
+
/// <li> Handle AHBot operations
if (m_timers[WUPDATE_AHBOT].Passed())
{
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 133ac3f2386..c76b11276cc 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -69,6 +69,7 @@ enum ShutdownExitCode
enum WorldTimers
{
WUPDATE_AUCTIONS,
+ WUPDATE_AUCTIONS_PENDING,
WUPDATE_WEATHERS,
WUPDATE_UPTIME,
WUPDATE_CORPSES,