diff options
| author | Shauren <shauren.trinity@gmail.com> | 2024-04-12 00:18:20 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2024-04-12 00:18:20 +0200 |
| commit | 69da702b930d43738bcaf49ce57b333dfc19ecfd (patch) | |
| tree | 697d5a303ce10d25ea6e631cc4012c3ff3734c81 /src/server/game/Entities/Item | |
| parent | 8c274a8e8d496bf2ac1beafd31e0967e6659f967 (diff) | |
Core/Items: Implemented CreateTime item field and changed refund/soulbound trade timers to also count time offline
Diffstat (limited to 'src/server/game/Entities/Item')
| -rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 129 | ||||
| -rw-r--r-- | src/server/game/Entities/Item/Item.h | 7 |
2 files changed, 54 insertions, 82 deletions
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; |
