aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-04-12 00:18:20 +0200
committerShauren <shauren.trinity@gmail.com>2024-04-12 00:18:20 +0200
commit69da702b930d43738bcaf49ce57b333dfc19ecfd (patch)
tree697d5a303ce10d25ea6e631cc4012c3ff3734c81 /src
parent8c274a8e8d496bf2ac1beafd31e0967e6659f967 (diff)
Core/Items: Implemented CreateTime item field and changed refund/soulbound trade timers to also count time offline
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp6
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp4
-rw-r--r--src/server/game/Entities/Item/Item.cpp129
-rw-r--r--src/server/game/Entities/Item/Item.h7
-rw-r--r--src/server/game/Entities/Player/Player.cpp58
-rw-r--r--src/server/game/Guilds/Guild.cpp4
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp22
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp4
8 files changed, 105 insertions, 129 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index dece12412fe..a4f9520ff6b 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -24,7 +24,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
m_stmts.resize(MAX_CHARACTERDATABASE_STATEMENTS);
#define SelectItemInstanceContent "ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomBonusListId, " \
- "ii.durability, ii.playedTime, ii.text, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.context, ii.bonusListIDs, " \
+ "ii.durability, ii.playedTime, ii.createTime, ii.text, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.context, ii.bonusListIDs, " \
"iit.itemModifiedAppearanceAllSpecs, iit.itemModifiedAppearanceSpec1, iit.itemModifiedAppearanceSpec2, iit.itemModifiedAppearanceSpec3, iit.itemModifiedAppearanceSpec4, iit.itemModifiedAppearanceSpec5, " \
"iit.spellItemEnchantmentAllSpecs, iit.spellItemEnchantmentSpec1, iit.spellItemEnchantmentSpec2, iit.spellItemEnchantmentSpec3, iit.spellItemEnchantmentSpec4, iit.spellItemEnchantmentSpec5, " \
"iit.secondaryItemModifiedAppearanceAllSpecs, iit.secondaryItemModifiedAppearanceSpec1, iit.secondaryItemModifiedAppearanceSpec2, iit.secondaryItemModifiedAppearanceSpec3, iit.secondaryItemModifiedAppearanceSpec4, iit.secondaryItemModifiedAppearanceSpec5, " \
@@ -202,8 +202,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_ITEM_BOP_TRADE, "DELETE FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_ITEM_BOP_TRADE, "INSERT INTO item_soulbound_trade_data VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_INVENTORY_ITEM, "REPLACE INTO character_inventory (guid, bag, slot, item) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, text, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomBonusListId = ?, durability = ?, playedTime = ?, text = ?, battlePetSpeciesId = ?, battlePetBreedData = ?, battlePetLevel = ?, battlePetDisplayId = ?, context = ?, bonusListIDs = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomBonusListId = ?, durability = ?, playedTime = ?, createTime = ?, text = ?, battlePetSpeciesId = ?, battlePetBreedData = ?, battlePetLevel = ?, battlePetDisplayId = ?, context = ?, bonusListIDs = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE, "DELETE FROM item_instance WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER, "DELETE FROM item_instance WHERE owner_guid = ?", CONNECTION_ASYNC);
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index a89cca92af9..0634d60af82 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -529,12 +529,12 @@ void AuctionHouseMgr::LoadAuctions()
}
Item* item = NewItemOrBag(proto);
- if (!item->LoadFromDB(itemGuid, ObjectGuid::Create<HighGuid::Player>(fields[51].GetUInt64()), fields, itemEntry))
+ if (!item->LoadFromDB(itemGuid, ObjectGuid::Create<HighGuid::Player>(fields[52].GetUInt64()), fields, itemEntry))
{
delete item;
continue;
}
- uint32 auctionId = fields[52].GetUInt32();
+ uint32 auctionId = fields[53].GetUInt32();
itemsByAuction[auctionId].push_back(item);
++count;
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index c06f99716bb..00bf2adcd2f 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -452,7 +452,6 @@ Item::Item()
m_container = nullptr;
m_lootGenerated = false;
mb_in_trade = false;
- m_lastPlayedTimeUpdate = GameTime::GetGameTime();
m_paidMoney = 0;
m_paidExtendedCost = 0;
@@ -493,6 +492,7 @@ bool Item::Create(ObjectGuid::LowType guidlow, uint32 itemId, ItemContext contex
SetExpiration(itemProto->GetDuration());
SetCreatePlayedTime(0);
+ SetCreateTime(GameTime::GetGameTime());
SetContext(context);
if (itemProto->GetArtifactID())
@@ -604,6 +604,7 @@ void Item::SaveToDB(CharacterDatabaseTransaction trans)
stmt->setUInt32(++index, m_randomBonusListId);
stmt->setUInt16(++index, m_itemData->Durability);
stmt->setUInt32(++index, m_itemData->CreatePlayedTime);
+ stmt->setInt64(++index, m_itemData->CreateTime);
stmt->setString(++index, m_text);
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID));
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA));
@@ -826,21 +827,21 @@ void Item::SaveToDB(CharacterDatabaseTransaction trans)
bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fields, uint32 entry)
{
- // 0 1 2 3 4 5 6 7 8 9 10 11 12
- // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, text,
- // 13 14 15 16 17 18
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text,
+ // 14 15 16 17 18 19
// battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs,
- // 19 20 21 22 23 24
+ // 20 21 22 23 24 25
// itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, itemModifiedAppearanceSpec5,
- // 25 26 27 28 29 30
+ // 26 27 28 29 30 31
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, spellItemEnchantmentSpec5,
- // 31 32 33
+ // 32 33 34
// secondaryItemModifiedAppearanceAllSpecs, secondaryItemModifiedAppearanceSpec1, secondaryItemModifiedAppearanceSpec2,
- // 34 35 36
+ // 35 36 37
// secondaryItemModifiedAppearanceSpec3, secondaryItemModifiedAppearanceSpec4, secondaryItemModifiedAppearanceSpec5,
- // 37 38 39 40 41 42 43 44 45 46 47 48
+ // 38 39 40 41 42 43 44 45 46 47 48 49
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
- // 49 50
+ // 50 51
// fixedScalingLevel, artifactKnowledgeLevel FROM item_instance
// create item before any checks for store correct guid
@@ -901,16 +902,17 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
}
SetCreatePlayedTime(fields[11].GetUInt32());
- SetText(fields[12].GetString());
+ SetCreateTime(fields[12].GetInt64());
+ SetText(fields[13].GetString());
- SetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID, fields[13].GetUInt32());
- SetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA, fields[14].GetUInt32());
- SetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL, fields[15].GetUInt16());
- SetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID, fields[16].GetUInt32());
+ SetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID, fields[14].GetUInt32());
+ SetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA, fields[15].GetUInt32());
+ SetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL, fields[16].GetUInt16());
+ SetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID, fields[17].GetUInt32());
- SetContext(ItemContext(fields[17].GetUInt8()));
+ SetContext(ItemContext(fields[18].GetUInt8()));
- std::vector<std::string_view> bonusListString = Trinity::Tokenize(fields[18].GetStringView(), ' ', false);
+ std::vector<std::string_view> bonusListString = Trinity::Tokenize(fields[19].GetStringView(), ' ', false);
std::vector<int32> bonusListIDs;
bonusListIDs.reserve(bonusListString.size());
for (std::string_view token : bonusListString)
@@ -923,46 +925,46 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
for (uint8 i = 0; i < m_itemData->SpellCharges.size() && i < _bonusData.EffectCount && i < tokens.size(); ++i)
SetSpellCharges(i, Trinity::StringTo<int32>(tokens[i]).value_or(0));
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, fields[19].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, fields[20].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, fields[21].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, fields[22].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, fields[23].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_5, fields[24].GetUInt32());
-
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, fields[25].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, fields[26].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, fields[27].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, fields[28].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, fields[29].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_5, fields[30].GetUInt32());
-
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS, fields[31].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, fields[32].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, fields[33].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, fields[34].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, fields[35].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_5, fields[36].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, fields[20].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, fields[21].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, fields[22].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, fields[23].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, fields[24].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_5, fields[25].GetUInt32());
+
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, fields[26].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, fields[27].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, fields[28].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, fields[29].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, fields[30].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_5, fields[31].GetUInt32());
+
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS, fields[32].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, fields[33].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, fields[34].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, fields[35].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, fields[36].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_5, fields[37].GetUInt32());
uint32 const gemFields = 4;
ItemDynamicFieldGems gemData[MAX_GEM_SOCKETS];
memset(gemData, 0, sizeof(gemData));
for (uint32 i = 0; i < MAX_GEM_SOCKETS; ++i)
{
- gemData[i].ItemId = fields[37 + i * gemFields].GetUInt32();
- std::vector<std::string_view> gemBonusListIDs = Trinity::Tokenize(fields[38 + i * gemFields].GetStringView(), ' ', false);
+ gemData[i].ItemId = fields[38 + i * gemFields].GetUInt32();
+ std::vector<std::string_view> gemBonusListIDs = Trinity::Tokenize(fields[39 + i * gemFields].GetStringView(), ' ', false);
uint32 b = 0;
for (std::string_view token : gemBonusListIDs)
if (Optional<uint16> bonusListID = Trinity::StringTo<uint16>(token))
gemData[i].BonusListIDs[b++] = *bonusListID;
- gemData[i].Context = fields[39 + i * gemFields].GetUInt8();
+ gemData[i].Context = fields[40 + i * gemFields].GetUInt8();
if (gemData[i].ItemId)
- SetGem(i, &gemData[i], fields[40 + i * gemFields].GetUInt32());
+ SetGem(i, &gemData[i], fields[41 + i * gemFields].GetUInt32());
}
- SetModifier(ITEM_MODIFIER_TIMEWALKER_LEVEL, fields[49].GetUInt32());
- SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[50].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TIMEWALKER_LEVEL, fields[50].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[51].GetUInt32());
// Enchants must be loaded after all other bonus/scaling data
std::vector<std::string_view> enchantmentTokens = Trinity::Tokenize(fields[8].GetStringView(), ' ', false);
@@ -1659,6 +1661,7 @@ Item* Item::CloneItem(uint32 count, Player const* player /*= nullptr*/) const
newItem->ReplaceAllItemFlags(ItemFieldFlags(*m_itemData->DynamicFlags) & ~(ITEM_FIELD_FLAG_REFUNDABLE | ITEM_FIELD_FLAG_BOP_TRADEABLE));
newItem->SetExpiration(m_itemData->Expiration);
newItem->SetBonuses(m_itemData->ItemBonusKey->BonusListIDs);
+ newItem->SetFixedLevel(GetModifier(ITEM_MODIFIER_TIMEWALKER_LEVEL));
// player CAN be NULL in which case we must not update random properties because that accesses player's item update queue
if (player)
newItem->SetItemRandomBonusList(m_randomBonusListId);
@@ -1860,44 +1863,14 @@ void Item::SetNotRefundable(Player* owner, bool changestate /*= true*/, Characte
owner->GetSession()->GetCollectionMgr()->AddItemAppearance(this);
}
-void Item::UpdatePlayedTime(Player* owner)
-{
- /* Here we update our played time
- We simply add a number to the current played time,
- based on the time elapsed since the last update hereof.
- */
- // Get current played time
- uint32 current_playtime = m_itemData->CreatePlayedTime;
- // Calculate time elapsed since last played time update
- time_t curtime = GameTime::GetGameTime();
- uint32 elapsed = uint32(curtime - m_lastPlayedTimeUpdate);
- uint32 new_playtime = current_playtime + elapsed;
- // Check if the refund timer has expired yet
- if (new_playtime <= 2*HOUR)
- {
- // No? Proceed.
- // Update the data field
- SetCreatePlayedTime(new_playtime);
- // Flag as changed to get saved to DB
- SetState(ITEM_CHANGED, owner);
- // Speaks for itself
- m_lastPlayedTimeUpdate = curtime;
- return;
- }
- // Yes
- SetNotRefundable(owner);
-}
-
-uint32 Item::GetPlayedTime()
+uint32 Item::GetPlayedTime() const
{
- time_t curtime = GameTime::GetGameTime();
- uint32 elapsed = uint32(curtime - m_lastPlayedTimeUpdate);
- return *m_itemData->CreatePlayedTime + elapsed;
+ return *m_itemData->CreatePlayedTime;
}
-bool Item::IsRefundExpired()
+bool Item::IsRefundExpired() const
{
- return (GetPlayedTime() > 2*HOUR);
+ return *m_itemData->CreateTime + 2 * HOUR <= GameTime::GetGameTime();
}
void Item::SetSoulboundTradeable(GuidSet const& allowedLooters)
@@ -1923,7 +1896,7 @@ void Item::ClearSoulboundTradeable(Player* currentOwner)
bool Item::CheckSoulboundTradeExpire()
{
// called from owner's update - GetOwner() MUST be valid
- if (m_itemData->CreatePlayedTime + 2*HOUR < GetOwner()->GetTotalPlayedTime())
+ if (m_itemData->CreatePlayedTime + 4 * HOUR < GetOwner()->GetTotalPlayedTime())
{
ClearSoulboundTradeable(GetOwner());
return true; // remove from tradeable list
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index ff873c859e0..5ffb18941b9 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -309,6 +309,7 @@ class TC_GAME_API Item : public Object
void SendTimeUpdate(Player* owner);
void UpdateDuration(Player* owner, uint32 diff);
void SetCreatePlayedTime(uint32 createPlayedTime) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::CreatePlayedTime), createPlayedTime); }
+ void SetCreateTime(int64 createTime) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::CreateTime), createTime); }
// spell charges (signed but stored as unsigned)
int32 GetSpellCharges(uint8 index/*0..5*/ = 0) const { return m_itemData->SpellCharges[index]; }
@@ -363,9 +364,8 @@ class TC_GAME_API Item : public Object
uint64 GetPaidMoney() const { return m_paidMoney; }
uint32 GetPaidExtendedCost() const { return m_paidExtendedCost; }
- void UpdatePlayedTime(Player* owner);
- uint32 GetPlayedTime();
- bool IsRefundExpired();
+ uint32 GetPlayedTime() const;
+ bool IsRefundExpired() const;
// Soulbound trade system
void SetSoulboundTradeable(GuidSet const& allowedLooters);
@@ -458,7 +458,6 @@ class TC_GAME_API Item : public Object
ItemUpdateState uState;
int16 uQueuePos;
bool mb_in_trade; // true if item is currently in trade-window
- time_t m_lastPlayedTimeUpdate;
ObjectGuid m_refundRecipient;
uint64 m_paidMoney;
uint32 m_paidExtendedCost;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 50e5c2bcc71..77dea9acdf8 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3924,7 +3924,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
do
{
Field* fields = resultItems->Fetch();
- uint64 mailId = fields[44].GetUInt64();
+ uint64 mailId = fields[53].GetUInt64();
if (Item* mailItem = _LoadMailedItem(playerguid, nullptr, mailId, nullptr, fields, Trinity::Containers::MapGetValuePtr(additionalData, fields[0].GetUInt64())))
itemsByMail[mailId].push_back(mailItem);
@@ -11545,19 +11545,19 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
if (bonusListIDs)
item->SetBonuses(*bonusListIDs);
+ item->SetFixedLevel(GetLevel());
+ item->SetItemRandomBonusList(randomBonusListId);
+ item->SetCreatePlayedTime(GetTotalPlayedTime());
+
item = StoreItem(pos, item, update);
ItemAddedQuestCheck(itemId, count, false);
UpdateCriteria(CriteriaType::ObtainAnyItem, itemId, count);
UpdateCriteria(CriteriaType::AcquireItem, itemId, count);
- item->SetFixedLevel(GetLevel());
- item->SetItemRandomBonusList(randomBonusListId);
-
if (allowedLooters.size() > 1 && item->GetTemplate()->GetMaxStackSize() == 1 && item->IsSoulBound())
{
item->SetSoulboundTradeable(allowedLooters);
- item->SetCreatePlayedTime(GetTotalPlayedTime());
AddTradeableItem(item);
// save data
@@ -18804,19 +18804,23 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult,
PreparedQueryResult azeriteEmpoweredItemResult, uint32 timeDiff)
{
- // 0 1 2 3 4 5 6 7 8 9 10 11 12
- // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text,
- // 13 14 15 16 17 18
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text,
+ // 14 15 16 17 18 19
// battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs,
- // 19 20 21 22 23
- // itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4,
- // 24 25 26 27 28
- // spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4,
- // 29 30 31 32 33 34 35 36 37 38 39 40
+ // 20 21 22 23 24 25
+ // itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, itemModifiedAppearanceSpec5,
+ // 26 27 28 29 30 31
+ // spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, spellItemEnchantmentSpec5,
+ // 32 33 34
+ // secondaryItemModifiedAppearanceAllSpecs, secondaryItemModifiedAppearanceSpec1, secondaryItemModifiedAppearanceSpec2,
+ // 35 36 37
+ // secondaryItemModifiedAppearanceSpec3, secondaryItemModifiedAppearanceSpec4, secondaryItemModifiedAppearanceSpec5,
+ // 38 39 40 41 42 43 44 45 46 47 48 49
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
- // 41 42
+ // 50 51
// fixedScalingLevel, artifactKnowledgeLevel FROM item_instance
- // 43 44
+ // 52 53
// bag, slot
// FROM character_inventory ci
// JOIN item_instance ii ON ci.item = ii.guid
@@ -18867,8 +18871,8 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti
azeriteEmpoweredItem->LoadAzeriteEmpoweredItemData(this, *addionalDataPtr->AzeriteEmpoweredItem);
}
- ObjectGuid bagGuid = fields[51].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[51].GetUInt64()) : ObjectGuid::Empty;
- uint8 slot = fields[52].GetUInt8();
+ ObjectGuid bagGuid = fields[52].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[52].GetUInt64()) : ObjectGuid::Empty;
+ uint8 slot = fields[53].GetUInt8();
GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item);
GetSession()->GetCollectionMgr()->AddItemAppearance(item);
@@ -19082,10 +19086,10 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction trans, uint32 zoneId, uint3
}
else if (item->IsRefundable())
{
- if (item->GetPlayedTime() > (2 * HOUR))
+ if (item->IsRefundExpired())
{
TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player ({}, name: '{}') has item ({}) with expired refund time ({}). Deleting refund data and removing refundable flag.",
- GetGUID().ToString(), GetName(), item->GetGUID().ToString(), item->GetPlayedTime());
+ GetGUID().ToString(), GetName(), item->GetGUID().ToString(), GetTotalPlayedTime() - item->GetPlayedTime());
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE);
stmt->setUInt64(0, item->GetGUID().GetCounter());
@@ -19208,7 +19212,7 @@ Item* Player::_LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint
Item* item = NewItemOrBag(proto);
- ObjectGuid ownerGuid = fields[51].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[51].GetUInt64()) : ObjectGuid::Empty;
+ ObjectGuid ownerGuid = fields[52].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[52].GetUInt64()) : ObjectGuid::Empty;
if (!item->LoadFromDB(itemGuid, ownerGuid, fields, itemEntry))
{
TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems: Item (GUID: {}) in mail ({}) doesn't exist, deleted from mail.", itemGuid, mailId);
@@ -19297,7 +19301,7 @@ void Player::_LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mail
do
{
Field* fields = mailItemsResult->Fetch();
- uint64 mailId = fields[52].GetUInt64();
+ uint64 mailId = fields[53].GetUInt64();
_LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], fields, Trinity::Containers::MapGetValuePtr(additionalData, fields[0].GetUInt64()));
} while (mailItemsResult->NextRow());
}
@@ -20599,10 +20603,10 @@ void Player::_SaveInventory(CharacterDatabaseTransaction trans)
i_next = itr;
++i_next;
- Item* iPtr = GetItemByGuid(*itr);
- if (iPtr)
+ if (Item* iPtr = GetItemByGuid(*itr))
{
- iPtr->UpdatePlayedTime(this);
+ if (iPtr->IsRefundable() && iPtr->IsRefundExpired())
+ iPtr->SetNotRefundable(this);
continue;
}
else
@@ -28609,8 +28613,8 @@ void Player::DeleteRefundReference(ObjectGuid it)
void Player::SendRefundInfo(Item* item)
{
- // This function call unsets ITEM_FIELD_FLAG_REFUNDABLE if played time is over 2 hours.
- item->UpdatePlayedTime(this);
+ if (item->IsRefundable() && item->IsRefundExpired())
+ item->SetNotRefundable(this);
if (!item->IsRefundable())
{
@@ -28634,7 +28638,7 @@ void Player::SendRefundInfo(Item* item)
WorldPackets::Item::SetItemPurchaseData setItemPurchaseData;
setItemPurchaseData.ItemGUID = item->GetGUID();
- setItemPurchaseData.PurchaseTime = GetTotalPlayedTime() - item->GetPlayedTime();
+ setItemPurchaseData.PurchaseTime = item->m_itemData->CreatePlayedTime;
setItemPurchaseData.Contents.Money = item->GetPaidMoney();
for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 714d9fd4729..ab8475a32b6 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -377,7 +377,7 @@ void Guild::BankTab::LoadFromDB(Field* fields)
bool Guild::BankTab::LoadItemFromDB(Field* fields)
{
- uint8 slotId = fields[53].GetUInt8();
+ uint8 slotId = fields[54].GetUInt8();
ObjectGuid::LowType itemGuid = fields[0].GetUInt64();
uint32 itemEntry = fields[1].GetUInt32();
if (slotId >= GUILD_BANK_MAX_SLOTS)
@@ -2642,7 +2642,7 @@ void Guild::LoadBankTabFromDB(Field* fields)
bool Guild::LoadBankItemFromDB(Field* fields)
{
- uint8 tabId = fields[52].GetUInt8();
+ uint8 tabId = fields[53].GetUInt8();
if (tabId >= _GetPurchasedTabsSize())
{
TC_LOG_ERROR("guild", "Invalid tab for item (GUID: {}, id: #{}) in guild bank, skipped.",
diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp
index b7d32576147..52fe71f578b 100644
--- a/src/server/game/Guilds/GuildMgr.cpp
+++ b/src/server/game/Guilds/GuildMgr.cpp
@@ -401,23 +401,23 @@ void GuildMgr::LoadGuilds()
// Delete orphan guild bank items
CharacterDatabase.DirectExecute("DELETE gbi FROM guild_bank_item gbi LEFT JOIN guild g ON gbi.guildId = g.guildId WHERE g.guildId IS NULL");
- // 0 1 2 3 4 5 6 7 8 9 10 11 12
- // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, text,
- // 13 14 15 16 17 18
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text,
+ // 14 15 16 17 18 19
// battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs,
- // 19 20 21 22 23 24
+ // 20 21 22 23 24 25
// itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, itemModifiedAppearanceSpec5,
- // 25 26 27 28 29 30
+ // 26 27 28 29 30 31
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, spellItemEnchantmentSpec5,
- // 31 32 33
+ // 32 33 34
// secondaryItemModifiedAppearanceAllSpecs, secondaryItemModifiedAppearanceSpec1, secondaryItemModifiedAppearanceSpec2,
- // 34 35 36
+ // 35 36 37
// secondaryItemModifiedAppearanceSpec3, secondaryItemModifiedAppearanceSpec4, secondaryItemModifiedAppearanceSpec5,
- // 37 38 39 40 41 42 43 44 45 46 47 48
+ // 38 39 40 41 42 43 44 45 46 47 48 49
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
- // 49 50
+ // 50 51
// fixedScalingLevel, artifactKnowledgeLevel
- // 51 52 53
+ // 52 53 54
// guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid
PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEMS));
@@ -431,7 +431,7 @@ void GuildMgr::LoadGuilds()
do
{
Field* fields = result->Fetch();
- uint64 guildId = fields[51].GetUInt64();
+ uint64 guildId = fields[52].GetUInt64();
if (Guild* guild = GetGuildById(guildId))
guild->LoadBankItemFromDB(fields);
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index 62a2c74a2ba..4012ccff590 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -134,7 +134,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
}
// adjust time (depends on /played)
- if (myItems[i]->IsBOPTradeable())
+ if (*myItems[i]->m_itemData->CreatePlayedTime)
myItems[i]->SetCreatePlayedTime(trader->GetTotalPlayedTime() - (_player->GetTotalPlayedTime() - myItems[i]->m_itemData->CreatePlayedTime));
// store
trader->MoveItemToInventory(traderDst, myItems[i], true, true);
@@ -152,7 +152,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
}
// adjust time (depends on /played)
- if (hisItems[i]->IsBOPTradeable())
+ if (*hisItems[i]->m_itemData->CreatePlayedTime)
hisItems[i]->SetCreatePlayedTime(_player->GetTotalPlayedTime() - (trader->GetTotalPlayedTime() - hisItems[i]->m_itemData->CreatePlayedTime));
// store
_player->MoveItemToInventory(playerDst, hisItems[i], true, true);