Fix item vendor refund for stackable items.

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-04-28 19:38:37 +02:00
parent 95e5ba5bdb
commit a82d3d88c9
5 changed files with 71 additions and 35 deletions
+3 -2
View File
@@ -1055,11 +1055,12 @@ void Item::BuildUpdate(UpdateDataMapType& data_map)
ClearUpdateMask(false); ClearUpdateMask(false);
} }
void Item::SaveRefundDataToDB() void Item::SaveRefundDataToDB(uint32 count)
{ {
std::ostringstream ss; std::ostringstream ss;
ss << "INSERT INTO item_refund_instance VALUES("; ss << "REPLACE INTO item_refund_instance VALUES(";
ss << GetGUIDLow() << ","; ss << GetGUIDLow() << ",";
ss << count << ", ";
ss << GetRefundRecipient() << ","; ss << GetRefundRecipient() << ",";
ss << GetPaidMoney() << ","; ss << GetPaidMoney() << ",";
ss << GetPaidExtendedCost(); ss << GetPaidExtendedCost();
+1 -1
View File
@@ -243,7 +243,7 @@ class Item : public Object
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result); virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result);
virtual void DeleteFromDB(); virtual void DeleteFromDB();
void DeleteFromInventoryDB(); void DeleteFromInventoryDB();
void SaveRefundDataToDB(); void SaveRefundDataToDB(uint32 count);
void DeleteRefundDataFromDB(); void DeleteRefundDataFromDB();
bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; } bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
+15 -12
View File
@@ -1395,15 +1395,17 @@ void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data)
return; return;
} }
uint32 itemCount = item->GetCount();
WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4);
data << uint64(guid); // item guid data << uint64(guid); // item guid
data << uint32(item->GetPaidMoney()); // money cost data << uint32(item->GetPaidMoney() * itemCount); // money cost
data << uint32(iece->reqhonorpoints); // honor point cost data << uint32(iece->reqhonorpoints * itemCount); // honor point cost
data << uint32(iece->reqarenapoints); // arena point cost data << uint32(iece->reqarenapoints * itemCount); // arena point cost
for (uint8 i = 0; i < 5; ++i) // item cost data for (uint8 i = 0; i < 5; ++i) // item cost data
{ {
data << iece->reqitem[i]; data << iece->reqitem[i];
data << iece->reqitemcount[i]; data << (iece->reqitemcount[i] * itemCount);
} }
data << uint32(0); data << uint32(0);
data << uint32(GetPlayer()->GetTotalPlayedTime() - item->GetPlayedTime()); data << uint32(GetPlayer()->GetTotalPlayedTime() - item->GetPlayedTime());
@@ -1453,12 +1455,13 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data)
return; return;
} }
uint32 moneyRefund = item->GetPaidMoney(); uint32 itemCount = item->GetCount(); // stacked refundable items.
uint32 moneyRefund = item->GetPaidMoney()*itemCount;
bool store_error = false; bool store_error = false;
for (uint8 i = 0; i < 5; ++i) for (uint8 i = 0; i < 5; ++i)
{ {
uint32 count = iece->reqitemcount[i]; uint32 count = iece->reqitemcount[i] * itemCount;
uint32 itemid = iece->reqitem[i]; uint32 itemid = iece->reqitem[i];
if (count && itemid) if (count && itemid)
@@ -1486,12 +1489,12 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data)
data << uint64(guid); // item guid data << uint64(guid); // item guid
data << uint32(0); // 0, or error code data << uint32(0); // 0, or error code
data << uint32(moneyRefund); // money cost data << uint32(moneyRefund); // money cost
data << uint32(iece->reqhonorpoints); // honor point cost data << uint32(iece->reqhonorpoints * itemCount); // honor point cost
data << uint32(iece->reqarenapoints); // arena point cost data << uint32(iece->reqarenapoints * itemCount); // arena point cost
for (uint8 i = 0; i < 5; ++i) // item cost data for (uint8 i = 0; i < 5; ++i) // item cost data
{ {
data << iece->reqitem[i]; data << iece->reqitem[i];
data << iece->reqitemcount[i]; data << (iece->reqitemcount[i] * itemCount);
} }
SendPacket(&data); SendPacket(&data);
@@ -1504,7 +1507,7 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data)
// Grant back extendedcost items // Grant back extendedcost items
for (uint8 i = 0; i < 5; ++i) for (uint8 i = 0; i < 5; ++i)
{ {
uint32 count = iece->reqitemcount[i]; uint32 count = iece->reqitemcount[i] * itemCount;
uint32 itemid = iece->reqitem[i]; uint32 itemid = iece->reqitem[i];
if (count && itemid) if (count && itemid)
{ {
@@ -1521,12 +1524,12 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data)
_player->ModifyMoney(moneyRefund); _player->ModifyMoney(moneyRefund);
// Grant back Honor points // Grant back Honor points
uint32 honorRefund = iece->reqhonorpoints; uint32 honorRefund = iece->reqhonorpoints * itemCount;
if (honorRefund) if (honorRefund)
_player->ModifyHonorPoints(honorRefund); _player->ModifyHonorPoints(honorRefund);
// Grant back Arena points // Grant back Arena points
uint32 arenaRefund = iece->reqarenapoints; uint32 arenaRefund = iece->reqarenapoints * itemCount;
if (arenaRefund) if (arenaRefund)
_player->ModifyArenaPoints(arenaRefund); _player->ModifyArenaPoints(arenaRefund);
} }
+47 -16
View File
@@ -12042,6 +12042,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
if (IsInventoryPos(dst)) if (IsInventoryPos(dst))
{ {
// change item amount before check (for unique max count check) // change item amount before check (for unique max count check)
AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() - count);
pSrcItem->SetCount(pSrcItem->GetCount() - count); pSrcItem->SetCount(pSrcItem->GetCount() - count);
ItemPosCountVec dest; ItemPosCountVec dest;
@@ -12050,6 +12051,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
{ {
delete pNewItem; delete pNewItem;
pSrcItem->SetCount(pSrcItem->GetCount() + count); pSrcItem->SetCount(pSrcItem->GetCount() + count);
AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() + count);
SendEquipError(msg, pSrcItem, NULL); SendEquipError(msg, pSrcItem, NULL);
return; return;
} }
@@ -12058,10 +12060,18 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
pSrcItem->SendUpdateToPlayer(this); pSrcItem->SendUpdateToPlayer(this);
pSrcItem->SetState(ITEM_CHANGED, this); pSrcItem->SetState(ITEM_CHANGED, this);
StoreItem(dest, pNewItem, true); StoreItem(dest, pNewItem, true);
AddRefundReference(pNewItem->GetGUID(), count);
pNewItem->SetPaidExtendedCost(pSrcItem->GetPaidExtendedCost());
pNewItem->SetPaidMoney(pSrcItem->GetPaidMoney());
pNewItem->SetRefundRecipient(GetGUIDLow());
pNewItem->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, pSrcItem->GetPlayedTime());
pNewItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE);
pNewItem->SaveRefundDataToDB(count);
} }
else if (IsBankPos (dst)) else if (IsBankPos (dst))
{ {
// change item amount before check (for unique max count check) // change item amount before check (for unique max count check)
AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() - count);
pSrcItem->SetCount(pSrcItem->GetCount() - count); pSrcItem->SetCount(pSrcItem->GetCount() - count);
ItemPosCountVec dest; ItemPosCountVec dest;
@@ -12069,6 +12079,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
if (msg != EQUIP_ERR_OK) if (msg != EQUIP_ERR_OK)
{ {
delete pNewItem; delete pNewItem;
AlterRefundReferenceCount(pSrcItem->GetGUID(), pSrcItem->GetCount() + count);
pSrcItem->SetCount(pSrcItem->GetCount() + count); pSrcItem->SetCount(pSrcItem->GetCount() + count);
SendEquipError(msg, pSrcItem, NULL); SendEquipError(msg, pSrcItem, NULL);
return; return;
@@ -12078,6 +12089,13 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
pSrcItem->SendUpdateToPlayer(this); pSrcItem->SendUpdateToPlayer(this);
pSrcItem->SetState(ITEM_CHANGED, this); pSrcItem->SetState(ITEM_CHANGED, this);
BankItem(dest, pNewItem, true); BankItem(dest, pNewItem, true);
AddRefundReference(pNewItem->GetGUID(), count);
pNewItem->SetPaidExtendedCost(pSrcItem->GetPaidExtendedCost());
pNewItem->SetPaidMoney(pSrcItem->GetPaidMoney());
pNewItem->SetRefundRecipient(GetGUIDLow());
pNewItem->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, pSrcItem->GetPlayedTime());
pNewItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE);
pNewItem->SaveRefundDataToDB(count);
} }
else if (IsEquipmentPos (dst)) else if (IsEquipmentPos (dst))
{ {
@@ -16500,7 +16518,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
else else
{ {
QueryResult_AutoPtr result2 = CharacterDatabase.PQuery( QueryResult_AutoPtr result2 = CharacterDatabase.PQuery(
"SELECT player_guid,paidMoney,paidExtendedCost FROM `item_refund_instance` WHERE item_guid = '%u' AND player_guid = '%u' LIMIT 1", "SELECT count,player_guid,paidMoney,paidExtendedCost FROM `item_refund_instance` WHERE item_guid = '%u' AND player_guid = '%u' LIMIT 1",
item->GetGUIDLow(), GetGUIDLow()); item->GetGUIDLow(), GetGUIDLow());
if (!result2) if (!result2)
{ {
@@ -16512,10 +16530,10 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
else else
{ {
fields = result2->Fetch(); fields = result2->Fetch();
item->SetRefundRecipient(fields[0].GetUInt32()); item->SetRefundRecipient(fields[1].GetUInt32());
item->SetPaidMoney(fields[1].GetUInt32()); item->SetPaidMoney(fields[2].GetUInt32());
item->SetPaidExtendedCost(fields[2].GetUInt32()); item->SetPaidExtendedCost(fields[3].GetUInt32());
AddRefundReference(item->GetGUID()); AddRefundReference(item->GetGUID(), fields[0].GetUInt32());
} }
} }
} }
@@ -17653,14 +17671,14 @@ void Player::_SaveInventory()
// the client auto counts down in real time after having received the initial played time on the first // the client auto counts down in real time after having received the initial played time on the first
// SMSG_ITEM_REFUND_INFO_RESPONSE packet. // SMSG_ITEM_REFUND_INFO_RESPONSE packet.
// Item::UpdatePlayedTime is only called when needed, which is in DB saves, and item refund info requests. // Item::UpdatePlayedTime is only called when needed, which is in DB saves, and item refund info requests.
std::set<uint64>::iterator i_next; std::map<uint64, uint32>::iterator i_next;
for (std::set<uint64>::iterator itr = m_refundableItems.begin(); itr!= m_refundableItems.end(); itr = i_next) for (std::map<uint64, uint32>::iterator itr = m_refundableItems.begin(); itr!= m_refundableItems.end(); itr = i_next)
{ {
// use copy iterator because itr may be invalid after operations in this loop // use copy iterator because itr may be invalid after operations in this loop
i_next = itr; i_next = itr;
++i_next; ++i_next;
Item* iPtr = GetItemByGuid(*itr); Item* iPtr = GetItemByGuid(itr->first);
if (iPtr) if (iPtr)
{ {
iPtr->UpdatePlayedTime(this); iPtr->UpdatePlayedTime(this);
@@ -17668,7 +17686,7 @@ void Player::_SaveInventory()
} }
else else
{ {
sLog.outError("Can't find item guid " UI64FMTD " but is in refundable storage for player %u ! Removing.", (*itr), GetGUIDLow()); sLog.outError("Can't find item guid " UI64FMTD " but is in refundable storage for player %u ! Removing.", itr->first, GetGUIDLow());
m_refundableItems.erase(itr); m_refundableItems.erase(itr);
} }
} }
@@ -19525,8 +19543,8 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
it->SetRefundRecipient(GetGUIDLow()); it->SetRefundRecipient(GetGUIDLow());
it->SetPaidMoney(price); it->SetPaidMoney(price);
it->SetPaidExtendedCost(crItem->ExtendedCost); it->SetPaidExtendedCost(crItem->ExtendedCost);
it->SaveRefundDataToDB(); it->SaveRefundDataToDB(it->GetCount());
AddRefundReference(it->GetGUID()); AddRefundReference(it->GetGUID(), it->GetCount());
} }
} }
} }
@@ -19583,8 +19601,8 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
it->SetRefundRecipient(GetGUIDLow()); it->SetRefundRecipient(GetGUIDLow());
it->SetPaidMoney(price); it->SetPaidMoney(price);
it->SetPaidExtendedCost(crItem->ExtendedCost); it->SetPaidExtendedCost(crItem->ExtendedCost);
it->SaveRefundDataToDB(); it->SaveRefundDataToDB(it->GetCount());
AddRefundReference(it->GetGUID()); AddRefundReference(it->GetGUID(), it->GetCount());
} }
} }
} }
@@ -23603,12 +23621,25 @@ void Player::SendDuelCountdown(uint32 counter)
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }
void Player::AddRefundReference(uint64 it) void Player::AddRefundReference(uint64 it, uint32 stackCount)
{ {
m_refundableItems.insert(it); m_refundableItems[it] = stackCount;
} }
void Player::DeleteRefundReference(uint64 it) void Player::DeleteRefundReference(uint64 it)
{ {
m_refundableItems.erase(it); std::map<uint64,uint32>::iterator itr = m_refundableItems.find(it);
if (itr != m_refundableItems.end())
{
m_refundableItems.erase(itr);
}
}
void Player::AlterRefundReferenceCount(uint64 it, uint32 newCount)
{
std::map<uint64,uint32>::iterator itr = m_refundableItems.find(it);
if (itr != m_refundableItems.end())
{
itr->second = newCount;
}
} }
+3 -2
View File
@@ -1200,7 +1200,8 @@ class Player : public Unit, public GridObject<Player>
uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const;
uint8 _CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL) const; uint8 _CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL) const;
void AddRefundReference(uint64 it); void AddRefundReference(uint64 it, uint32 stackCount);
void AlterRefundReferenceCount(uint64 it, uint32 newCount);
void DeleteRefundReference(uint64 it); void DeleteRefundReference(uint64 it);
void ApplyEquipCooldown(Item * pItem); void ApplyEquipCooldown(Item * pItem);
@@ -2588,7 +2589,7 @@ class Player : public Unit, public GridObject<Player>
uint8 _CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 slot_end, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot) const; uint8 _CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 slot_end, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot) const;
Item* _StoreItem(uint16 pos, Item *pItem, uint32 count, bool clone, bool update); Item* _StoreItem(uint16 pos, Item *pItem, uint32 count, bool clone, bool update);
std::set<uint64> m_refundableItems; std::map<uint64, uint32> m_refundableItems;
void UpdateKnownCurrencies(uint32 itemId, bool apply); void UpdateKnownCurrencies(uint32 itemId, bool apply);
int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest); int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest);