aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMachiavelli <none@none>2010-03-18 17:27:40 +0100
committerMachiavelli <none@none>2010-03-18 17:27:40 +0100
commit302af79bc250257c61f78e489986eaa1f20292c7 (patch)
tree08fc629bab8c01e088d097b0f7e93a83c1269515 /src
parent72833e158440dc8f411a75a386861f936bfe108b (diff)
Implement vendor item refund system.
For info about this system, see: hxxp://us.blizzard.com/support/article.xml?locale=en_US&articleId=27351 Thanks to: - Opterman, Malcrom, Xanadu + anonymous colleagues for aiding research on packet structure - Aokromes and Svannon for testing --HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/game/Item.cpp70
-rw-r--r--src/game/Item.h51
-rw-r--r--src/game/ItemHandler.cpp158
-rw-r--r--src/game/Player.cpp146
-rw-r--r--src/game/Player.h5
5 files changed, 344 insertions, 86 deletions
diff --git a/src/game/Item.cpp b/src/game/Item.cpp
index e5fb2ce4a40..eaf4ed776e7 100644
--- a/src/game/Item.cpp
+++ b/src/game/Item.cpp
@@ -247,6 +247,8 @@ Item::Item( )
m_container = NULL;
m_lootGenerated = false;
mb_in_trade = false;
+ m_lastPlayedTimeUpdate = time(NULL);
+ m_RefundData = NULL;
}
bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner)
@@ -328,6 +330,8 @@ void Item::SaveToDB()
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", guid);
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow());
+ if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ DeleteRefundDataFromDB();
delete this;
return;
}
@@ -411,7 +415,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result
SetOwnerGUID(owner_guid);
need_save = true;
}
-
+
if (need_save) // normal item changed state set not work at loading
{
std::ostringstream ss;
@@ -1043,3 +1047,67 @@ void Item::BuildUpdate(UpdateDataMapType& data_map)
BuildFieldsUpdate(owner, data_map);
ClearUpdateMask(false);
}
+
+void Item::SaveRefundDataToDB()
+{
+ ItemRefund* RefundData = GetRefundData();
+ if (!RefundData)
+ return;
+
+ std::ostringstream ss;
+ ss << "INSERT INTO item_refund_instance VALUES(";
+ ss << GetGUIDLow() << ",";
+ ss << RefundData->eligibleFor << ",";
+ ss << RefundData->paidMoney << ",";
+ ss << RefundData->paidHonorPoints << ",";
+ ss << RefundData->paidArenaPoints << ",";
+
+ for (uint8 i=0; i<5; ++i)
+ {
+ ss << RefundData->paidItemId[i] << ",";
+ ss << RefundData->paidItemCount[i];
+ if (i < 4)
+ ss << ",";
+ }
+ ss << ")";
+
+ CharacterDatabase.Execute(ss.str().c_str());
+}
+
+void Item::DeleteRefundDataFromDB()
+{
+ CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
+}
+
+void Item::SetNotRefundable(Player *owner)
+{
+ if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ return;
+
+ if (m_RefundData)
+ delete m_RefundData;
+
+ RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE);
+ SetState(ITEM_CHANGED, owner);
+ DeleteRefundDataFromDB();
+ owner->DeleteRefundReference(this);
+}
+
+void Item::UpdatePlayedTime(Player *owner)
+{
+ time_t curtime = time(NULL);
+ uint32 elapsed = curtime - m_lastPlayedTimeUpdate;
+ SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, GetPlayedTime(true) + elapsed);
+ SetState(ITEM_CHANGED, owner);
+ m_lastPlayedTimeUpdate = curtime;
+}
+
+uint32 Item::GetPlayedTime(bool raw)
+{
+ if (raw)
+ return GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME);
+
+ time_t curtime = time(NULL);
+ uint32 elapsed = curtime - m_lastPlayedTimeUpdate;
+ return uint32(GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) + elapsed);
+} \ No newline at end of file
diff --git a/src/game/Item.h b/src/game/Item.h
index 9a520782f58..60d04559e79 100644
--- a/src/game/Item.h
+++ b/src/game/Item.h
@@ -218,6 +218,27 @@ struct ItemRequiredTarget
bool ItemCanGoIntoBag(ItemPrototype const *proto, ItemPrototype const *pBagProto);
+struct ItemRefund
+{
+ ItemRefund()
+ {
+ paidMoney = 0;
+ paidHonorPoints = 0;
+ paidArenaPoints = 0;
+ for (uint8 i=0;i<5;++i)
+ {
+ paidItemId[i] = 0;
+ paidItemCount[i] = 0;
+ }
+ }
+ uint32 eligibleFor;
+ uint32 paidMoney;
+ uint32 paidHonorPoints;
+ uint32 paidArenaPoints;
+ uint32 paidItemId[5];
+ uint32 paidItemCount[5];
+};
+
class Item : public Object
{
public:
@@ -243,6 +264,8 @@ class Item : public Object
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result = QueryResult_AutoPtr(NULL));
virtual void DeleteFromDB();
void DeleteFromInventoryDB();
+ void SaveRefundDataToDB();
+ void DeleteRefundDataFromDB();
bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
@@ -321,20 +344,12 @@ class Item : public Object
bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
// Item Refund system
- uint32 GetPaidHonorPoints() { return m_paidHonorPoints; }
- uint32 GetPaidArenaPoints() { return m_paidArenaPoints; }
- uint32 GetPaidExtendedCostId(uint32 pos) { return m_paidExtendedCostId[pos]; }
- uint32 GetPaidExtendedCostCount(uint32 pos) { return m_paidExtendedCostCount[pos]; }
- uint32 GetRefundExpiryTime() { return GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME); }
- void SetRefundExpiryTime(uint32 timeval) { SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, timeval); }
- void SetPaidHonorPoints(uint32 value) { m_paidHonorPoints = value; }
- void SetPaidArenaPoints(uint32 value) { m_paidArenaPoints = value; }
- void SetPaidExtendedCost(uint32 pos, uint32 entry, uint32 count)
- {
- m_paidExtendedCostId[pos] = entry;
- m_paidExtendedCostCount[pos] = count;
- }
-
+ ItemRefund *GetRefundData() { return m_RefundData; }
+ void SetRefundData(ItemRefund *RefundData) { m_RefundData = RefundData; }
+ void SetNotRefundable(Player *owner);
+ void UpdatePlayedTime(Player *owner);
+ uint32 GetPlayedTime(bool raw = false);
+
void BuildUpdate(UpdateDataMapType& );
private:
@@ -343,11 +358,7 @@ class Item : public Object
ItemUpdateState uState;
int16 uQueuePos;
bool mb_in_trade; // true if item is currently in trade-window
-
- // refund system
- uint32 m_paidHonorPoints;
- uint32 m_paidArenaPoints;
- uint32 m_paidExtendedCostId[5];
- uint32 m_paidExtendedCostCount[5];
+ time_t m_lastPlayedTimeUpdate;
+ ItemRefund *m_RefundData;
};
#endif
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 4cc3758f269..1afe43f43a9 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -1350,36 +1350,53 @@ void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data)
sLog.outDebug("WORLD: CMSG_ITEM_REFUND_INFO");
uint64 guid;
-
recv_data >> guid; // item guid
Item *item = _player->GetItemByGuid(guid);
-
- if(!item)
+ if (!item)
{
sLog.outDebug("Item refund: item not found!");
return;
}
- if(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
{
sLog.outDebug("Item refund: item not refundable!");
return;
}
- // item refund system not implemented yet
- WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); // guess size
- data << uint64(guid); // item guid
- data << uint32(1); // unknown
- data << uint32(item->GetPaidHonorPoints()); // honor point cost
- data << uint32(item->GetPaidArenaPoints()); // arena point cost
- for(uint32 i = 0; i < 5; ++i) // extended cost data
+ if (item->GetPlayedTime() > (2*HOUR)) // item refund has expired
+ item->SetNotRefundable(GetPlayer());
+
+ ItemRefund* RefundData = item->GetRefundData();
+ if (!RefundData)
{
- data << uint32(item->GetPaidExtendedCostId(i));
- data << uint32(item->GetPaidExtendedCostCount(i));
+ sLog.outDebug("Item refund: cannot find refundable data.");
+ item->SetNotRefundable(GetPlayer());
+ return;
+ }
+
+ if (GetPlayer()->GetGUIDLow() != RefundData->eligibleFor) // Formerly refundable item got traded
+ {
+ sLog.outDebug("Item refund: item was traded!");
+ item->SetNotRefundable(GetPlayer());
+ return;
+ }
+
+ item->UpdatePlayedTime(GetPlayer());
+
+ WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4);
+ data << uint64(guid); // item guid
+ data << uint32(RefundData->paidMoney); // money cost
+ data << uint32(RefundData->paidHonorPoints); // honor point cost
+ data << uint32(RefundData->paidArenaPoints); // arena point cost
+ for (uint8 i = 0; i < 5; ++i) // item cost data
+ {
+ data << RefundData->paidItemId[i];
+ data << RefundData->paidItemCount[i];
}
data << uint32(0);
- data << uint32(0);
+ data << uint32(GetPlayer()->GetTotalPlayedTime() - item->GetPlayedTime());
SendPacket(&data);
}
@@ -1390,67 +1407,118 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data)
recv_data >> guid; // item guid
Item *item = _player->GetItemByGuid(guid);
- if(!item)
+ if (!item)
{
sLog.outDebug("Item refund: item not found!");
return;
}
- if(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
{
sLog.outDebug("Item refund: item not refundable!");
return;
}
- if(item->GetRefundExpiryTime() <= time(NULL)) // item refund has expired
+ if (item->GetPlayedTime() > (2*HOUR)) // item refund has expired
{
- WorldPacket data(SMSG_ITEM_REFUND_RESULT);
- data << uint64(guid); // guid
- data << uint32(1); // error, abort refund
+ item->SetNotRefundable(GetPlayer());
+ WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4);
+ data << uint64(guid); // Guid
+ data << uint32(10); // Error!
+ SendPacket(&data);
return;
}
- WorldPacket data(SMSG_ITEM_REFUND_RESULT);
- data << uint64(guid); // guid?
- data << uint32(0); // must be 0 or client side error in refund
- data << uint32(0); // unk - message sent to client?
- data << uint32(item->GetPaidHonorPoints()); // honor points refund
- data << uint32(item->GetPaidArenaPoints()); // arena points refund
- for(uint32 i = 0; i < 5; ++i) // extended cost?
+ ItemRefund* RefundData = item->GetRefundData();
+ if (!RefundData)
{
- data << uint32(item->GetPaidExtendedCostId(i));
- data << uint32(item->GetPaidExtendedCostCount(i));
+ sLog.outDebug("Item refund: cannot find refundable data.");
+ item->SetNotRefundable(GetPlayer());
+ return;
}
- SendPacket(&data);
-
- // Grant back extendedcost items
- uint32 count = 0;
- uint32 itemid = 0;
- for(uint32 i = 0; i < 5; ++i)
+
+ if (GetPlayer()->GetGUIDLow() != RefundData->eligibleFor) // Formerly refundable item got traded
+ {
+ sLog.outDebug("Item refund: item was traded!");
+ item->SetNotRefundable(GetPlayer());
+ return;
+ }
+
+ bool store_error = false;
+ for (uint8 i = 0; i < 5; ++i)
{
- count = item->GetPaidExtendedCostCount(i);
- itemid = item->GetPaidExtendedCostId(i);
+ uint32 count = RefundData->paidItemCount[i];
+ uint32 itemid = RefundData->paidItemId[i];
+
if (count && itemid)
{
ItemPosCountVec dest;
uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count);
- if (msg == EQUIP_ERR_OK)
+ if (msg != EQUIP_ERR_OK)
{
- Item* it = _player->StoreNewItem(dest, itemid, true);
- _player->SendNewItem(it, count, true, false, true);
+ store_error = true;
+ break;
}
+ }
+ }
+
+ if (store_error)
+ {
+ WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4);
+ data << uint64(guid); // Guid
+ data << uint32(10); // Error!
+ SendPacket(&data);
+ return;
+ }
+
+ WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4+4+4+4+4*4+4*4);
+ data << uint64(guid); // item guid
+ data << uint32(0); // 0, or error code
+ data << uint32(RefundData->paidMoney); // money cost
+ data << uint32(RefundData->paidHonorPoints); // honor point cost
+ data << uint32(RefundData->paidArenaPoints); // arena point cost
+ for (uint8 i = 0; i < 5; ++i) // item cost data
+ {
+ data << RefundData->paidItemId[i];
+ data << RefundData->paidItemCount[i];
+ }
+ SendPacket(&data);
- // What to do if there's no space?
+ // Delete any references to the refund data
+ item->DeleteRefundDataFromDB();
+ GetPlayer()->DeleteRefundReference(item);
+ // Destroy item
+ _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
+
+ // Grant back extendedcost items
+ for (uint8 i = 0; i < 5; ++i)
+ {
+ uint32 count = RefundData->paidItemCount[i];
+ uint32 itemid = RefundData->paidItemId[i];
+ if (count && itemid)
+ {
+ ItemPosCountVec dest;
+ uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count);
+ ASSERT(msg == EQUIP_ERR_OK) /// Already checked before
+ Item* it = _player->StoreNewItem(dest, itemid, true);
+ _player->SendNewItem(it, count, true, false, true);
}
}
+
+ // Grant back money
+ uint32 moneyRefund = RefundData->paidMoney;
+ if (moneyRefund)
+ _player->ModifyMoney(moneyRefund);
+
// Grant back Honor points
- if (uint32 honorRefund = item->GetPaidHonorPoints() > 0)
+ uint32 honorRefund = RefundData->paidHonorPoints;
+ if (honorRefund)
_player->ModifyHonorPoints(honorRefund);
// Grant back Arena points
- if (uint32 arenaRefund = item->GetPaidArenaPoints() > 0)
+ uint32 arenaRefund = RefundData->paidArenaPoints;
+ if (arenaRefund)
_player->ModifyArenaPoints(arenaRefund);
- // Destroy item
- _player->DestroyItemCount(item->GetEntry(), 1, true, true);
+ delete RefundData;
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index fa4759dacd1..d53d61581c1 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -11560,6 +11560,9 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
RemoveEnchantmentDurations(pItem);
RemoveItemDurations(pItem);
+
+ if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ DeleteRefundReference(pItem);
ItemRemovedQuestCheck( pItem->GetEntry(), pItem->GetCount() );
@@ -16366,6 +16369,47 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
continue;
}
+ if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ {
+ if (item->GetPlayedTime() > (2*HOUR))
+ {
+ sLog.outDebug("Item::LoadFromDB, Item GUID: %u: refund time expired, deleting refund data and removing refundable flag.", item->GetGUIDLow());
+ CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", item->GetGUIDLow());
+ item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE);
+ }
+ else
+ {
+ QueryResult_AutoPtr result2 = CharacterDatabase.PQuery(
+ "SELECT player_guid,paidMoney,paidHonor,paidArena,"
+ "paidItem_1,paidItemCount_1,paidItem_2,paidItemCount_2,paidItem_3,paidItemCount_3,paidItem_4,paidItemCount_4,"
+ "paidItem_5,paidItemCount_5 FROM item_refund_instance WHERE item_guid = '%u' LIMIT 1",
+ item->GetGUIDLow());
+ if (!result2)
+ {
+ sLog.outDebug("Item::LoadFromDB, "
+ "Item GUID: %u has field flags & ITEM_FLAGS_REFUNDABLE but has no data in item_refund_instance, removing flag.",
+ item->GetGUIDLow());
+ RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE);
+ }
+ else
+ {
+ fields = result2->Fetch();
+ ItemRefund* RefundData = new ItemRefund();
+ RefundData->eligibleFor = fields[0].GetUInt32();
+ RefundData->paidMoney = fields[1].GetUInt32();
+ RefundData->paidHonorPoints = fields[2].GetUInt32();
+ RefundData->paidArenaPoints = fields[3].GetUInt32();
+ for (uint8 i=0, j=4; i<5; ++i, j+=2)
+ {
+ RefundData->paidItemId[i] = fields[j].GetUInt32();
+ RefundData->paidItemCount[i] = fields[j+1].GetUInt32();
+ }
+ item->SetRefundData(RefundData);
+ AddRefundReference(item);
+ }
+ }
+ }
+
bool success = true;
if (!bag_guid)
@@ -17444,6 +17488,23 @@ void Player::_SaveInventory()
m_items[i]->FSetState(ITEM_NEW);
}
+ // Updated played time for refundable items
+ for (std::set<Item*>::iterator itr = m_refundableItems.begin(); itr!= m_refundableItems.end();)
+ {
+ // Item could be deleted, or traded.
+ // In the first case, DeleteRefundDataFromDB() was already called in Item::SaveToDB()
+ Item* iPtr = (*itr);
+ if (!iPtr || iPtr->GetOwner() != this)
+ m_refundableItems.erase(itr++);
+ else
+ {
+ iPtr->UpdatePlayedTime(this);
+ if (iPtr->GetPlayedTime() > (2*HOUR))
+ iPtr->SetNotRefundable(this);
+ ++itr;
+ }
+ }
+
// update enchantment durations
for (EnchantDurationList::iterator itr = m_enchantDuration.begin(); itr != m_enchantDuration.end(); ++itr)
itr->item->SetEnchantmentDuration(itr->slot,itr->leftduration, this);
@@ -19252,6 +19313,11 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false;
}
+ uint32 honorPoints = 0;
+ uint32 arenaPoints = 0;
+ uint32 itemCostId[5] = {0,0,0,0,0};
+ uint32 itemCostCount[5] = {0,0,0,0,0};
+
if ((bag == NULL_BAG && slot == NULL_SLOT) || IsInventoryPos(bag, slot))
{
ItemPosCountVec dest;
@@ -19263,22 +19329,18 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
}
ModifyMoney( -(int32)price );
- uint32 arenaPoints = 0;
- uint32 honorPoints = 0;
- uint32 extendedCost[5] = {0,0,0,0,0};
- uint32 extendedCostCount[5] = {0,0,0,0,0};
-
+
if (crItem->ExtendedCost) // case for new honor system
{
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
if (iece->reqhonorpoints)
{
- honorPoints = iece->reqhonorpoints * count;
+ honorPoints = iece->reqhonorpoints;
ModifyHonorPoints( - int32(honorPoints) );
}
if (iece->reqarenapoints)
{
- arenaPoints = iece->reqarenapoints * count;
+ arenaPoints = iece->reqarenapoints;
ModifyArenaPoints( - int32(arenaPoints) );
}
for (uint8 i = 0; i < 5; ++i)
@@ -19286,8 +19348,8 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
if (iece->reqitem[i])
{
DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true);
- extendedCost[i] = iece->reqitem[i];
- extendedCostCount[i] = iece->reqitemcount[i];
+ itemCostId[i] = iece->reqitem[i];
+ itemCostCount[i] = iece->reqitemcount[i];
}
}
}
@@ -19303,15 +19365,22 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
data << uint32(count);
GetSession()->SendPacket(&data);
SendNewItem(it, pProto->BuyCount*count, true, false, false);
-
- // Item Refund system, only works for non stackable items with extendedcost
- if(count == 1 && crItem->ExtendedCost )
- {
- it->SetPaidArenaPoints(arenaPoints);
- it->SetPaidHonorPoints(honorPoints);
- it->SetRefundExpiryTime( time(NULL)+(HOUR*2) );
- for (uint8 i = 0; i < 5; ++i)
- it->SetPaidExtendedCost(i, extendedCost[i], extendedCostCount[i]);
+
+ if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ {
+ ItemRefund* RefundData = new ItemRefund();
+ RefundData->eligibleFor = GetGUIDLow();
+ RefundData->paidMoney = price;
+ RefundData->paidHonorPoints = honorPoints;
+ RefundData->paidArenaPoints = arenaPoints;
+ for (uint8 i=0; i<5; ++i)
+ {
+ RefundData->paidItemId[i] = itemCostId[i];
+ RefundData->paidItemCount[i] = itemCostCount[i] ;
+ }
+ it->SetRefundData(RefundData);
+ it->SaveRefundDataToDB();
+ AddRefundReference(it);
}
}
}
@@ -19336,13 +19405,23 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
{
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
if (iece->reqhonorpoints)
- ModifyHonorPoints( - int32(iece->reqhonorpoints));
+ {
+ honorPoints = iece->reqhonorpoints;
+ ModifyHonorPoints( - int32(honorPoints) );
+ }
if (iece->reqarenapoints)
- ModifyArenaPoints( - int32(iece->reqarenapoints));
+ {
+ arenaPoints = iece->reqarenapoints;
+ ModifyArenaPoints( - int32(arenaPoints));
+ }
for (uint8 i = 0; i < 5; ++i)
{
if(iece->reqitem[i])
+ {
DestroyItemCount(iece->reqitem[i], iece->reqitemcount[i], true);
+ itemCostId[i] = iece->reqitem[i];
+ itemCostCount[i] = iece->reqitemcount[i];
+ }
}
}
@@ -19360,6 +19439,23 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
SendNewItem(it, pProto->BuyCount*count, true, false, false);
AutoUnequipOffhandIfNeed();
+
+ if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
+ {
+ ItemRefund* RefundData = new ItemRefund();
+ RefundData->eligibleFor = GetGUIDLow();
+ RefundData->paidMoney = price;
+ RefundData->paidHonorPoints = honorPoints;
+ RefundData->paidArenaPoints = arenaPoints;
+ for (uint8 i=0; i<5; ++i)
+ {
+ RefundData->paidItemId[i] = itemCostId[i];
+ RefundData->paidItemCount[i] = itemCostCount[i] ;
+ }
+ it->SetRefundData(RefundData);
+ it->SaveRefundDataToDB();
+ AddRefundReference(it);
+ }
}
}
else
@@ -23284,3 +23380,13 @@ void Player::SendDuelCountdown(uint32 counter)
data << uint32(counter); // seconds
GetSession()->SendPacket(&data);
}
+
+void Player::AddRefundReference(Item* it)
+{
+ m_refundableItems.insert(it);
+}
+
+void Player::DeleteRefundReference(Item* it)
+{
+ m_refundableItems.erase(it);
+} \ No newline at end of file
diff --git a/src/game/Player.h b/src/game/Player.h
index 10e566c6664..d39f381f016 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1189,6 +1189,9 @@ class Player : public Unit, public GridObject<Player>
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;
+
+ void AddRefundReference(Item* it);
+ void DeleteRefundReference(Item* it);
void ApplyEquipCooldown( Item * pItem );
void SetAmmo( uint32 item );
@@ -2554,6 +2557,8 @@ 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;
Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update );
+ std::set<Item*> m_refundableItems;
+
void UpdateKnownCurrencies(uint32 itemId, bool apply);
int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest);
void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData );