diff options
author | Wyrserth <wyrserth@protonmail.com> | 2019-06-27 20:27:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-27 20:27:04 +0200 |
commit | e77c2d55c40bc9d4a15de471de754376f4ec1c49 (patch) | |
tree | 767e3d0e4bdb741ecb02f7ea11757b331cbd099f | |
parent | 1c373f29ff178ae3562963f85734cc75b4b4b437 (diff) |
Core/GameObject: implement restock mechanic for non-consumable gameobjects (#23526)
-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 6c4e52d2e7a..e9f122eded8 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -510,6 +510,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; @@ -694,6 +701,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: { @@ -769,16 +783,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(); @@ -1308,6 +1327,10 @@ bool GameObject::ActivateToQuest(Player* 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)) { @@ -2307,6 +2330,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 e44002628a5..5059d58fe09 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -308,6 +308,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 |