diff options
author | Wyrserth <wyrserth@protonmail.com> | 2019-06-27 20:27:04 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-12-13 00:42:17 +0100 |
commit | c637260a37271a9ed2b19d44a62210e833010bde (patch) | |
tree | e43636a27a02322cfbeed90debef76812d392bb5 | |
parent | a71823811e42718ba35260f0323bb0fb885a219a (diff) |
Core/GameObject: implement restock mechanic for non-consumable gameobjects (#23526)
(cherry picked from commit e77c2d55c40bc9d4a15de471de754376f4ec1c49)
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 39 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 1 |
2 files changed, 34 insertions, 6 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index cc0b3a1afba..d1c80e1a52a 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -634,6 +634,13 @@ void GameObject::Update(uint32 diff) } return; } + case GAMEOBJECT_TYPE_CHEST: + if (m_restockTime > GameTime::GetGameTime()) + return; + // If there is no restock timer, or if the restock timer passed, the chest becomes ready to loot + m_lootState = GO_READY; + AddToObjectUpdateIfNeeded(); + break; default: m_lootState = GO_READY; // for other GOis same switched without delay to GO_READY break; @@ -819,6 +826,13 @@ void GameObject::Update(uint32 diff) else m_groupLootTimer -= diff; } + + // Gameobject was partially looted and restock time passed, restock all loot now + if (GameTime::GetGameTime() >= m_restockTime) + { + m_lootState = GO_READY; + AddToObjectUpdateIfNeeded(); + } break; case GAMEOBJECT_TYPE_TRAP: { @@ -894,16 +908,21 @@ void GameObject::Update(uint32 diff) // Do not delete gameobjects that are not consumed on loot, while still allowing them to despawn when they expire if summoned bool isSummonedAndExpired = (GetOwner() || GetSpellId()) && m_respawnTime == 0; - bool isPermanentSpawn = m_respawnDelayTime == 0; - if (!GetGOInfo()->IsDespawnAtAction() && - ((GetGoType() == GAMEOBJECT_TYPE_GOOBER && (!isSummonedAndExpired || isPermanentSpawn)) || - (GetGoType() == GAMEOBJECT_TYPE_CHEST && !isSummonedAndExpired && GetGOInfo()->chest.chestRestockTime == 0))) // ToDo: chests with data2 (chestRestockTime) > 0 and data3 (consumable) = 0 should not despawn on loot + if (!GetGOInfo()->IsDespawnAtAction() && !isSummonedAndExpired) { - SetLootState(GO_READY); + if (GetGoType() == GAMEOBJECT_TYPE_CHEST && GetGOInfo()->chest.chestRestockTime > 0) + { + // Start restock timer when the chest is fully looted + m_restockTime = GameTime::GetGameTime() + GetGOInfo()->chest.chestRestockTime; + SetLootState(GO_NOT_READY); + AddToObjectUpdateIfNeeded(); + } + else + SetLootState(GO_READY); UpdateObjectVisibility(); return; } - else + else if (GetOwner() || GetSpellId()) { SetRespawnTime(0); Delete(); @@ -1461,6 +1480,10 @@ bool GameObject::ActivateToQuest(Player const* target) const } case GAMEOBJECT_TYPE_CHEST: { + // Chests become inactive while not ready to be looted + if (getLootState() == GO_NOT_READY) + return false; + // scan GO chest with loot including quest items if (LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->GetLootId(), target)) { @@ -2525,6 +2548,10 @@ void GameObject::SetLootState(LootState state, Unit* unit) AI()->OnLootStateChanged(state, unit); + // Start restock timer if the chest is partially looted or not looted at all + if (GetGoType() == GAMEOBJECT_TYPE_CHEST && state == GO_ACTIVATED && GetGOInfo()->chest.chestRestockTime > 0 && m_restockTime == 0) + m_restockTime = GameTime::GetGameTime() + GetGOInfo()->chest.chestRestockTime; + if (GetGoType() == GAMEOBJECT_TYPE_DOOR) // only set collision for doors on SetGoState return; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index f6ad0fc2eac..16af03dcfb7 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -333,6 +333,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> LootState m_lootState; ObjectGuid m_lootStateUnitGUID; // GUID of the unit passed with SetLootState(LootState, Unit*) bool m_spawnedByDefault; + time_t m_restockTime; time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). // For traps this: spell casting cooldown, for doors/buttons: reset time. GOState m_prevGoState; // What state to set whenever resetting |