diff options
| author | pete318 <pete318@hotmail.com> | 2015-10-02 03:20:42 +0100 |
|---|---|---|
| committer | pete318 <pete318@hotmail.com> | 2015-12-14 19:54:58 +0100 |
| commit | 0ac442f19fcfa8c39775c5ae06bba8f3bcbd0407 (patch) | |
| tree | ca323a2a4cab2a668e4ca3763138752d0d7877e4 /src/server/game/AuctionHouse/AuctionHouseMgr.cpp | |
| parent | 54424aff3051bdc2a05d44cbd56adf6f47b98229 (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)
Diffstat (limited to 'src/server/game/AuctionHouse/AuctionHouseMgr.cpp')
| -rw-r--r-- | src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 123 |
1 files changed, 122 insertions, 1 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(); |
