aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWyrserth <wyrserth@protonmail.com>2019-06-27 20:27:04 +0200
committerShauren <shauren.trinity@gmail.com>2021-12-13 00:42:17 +0100
commitc637260a37271a9ed2b19d44a62210e833010bde (patch)
treee43636a27a02322cfbeed90debef76812d392bb5
parenta71823811e42718ba35260f0323bb0fb885a219a (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.cpp39
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h1
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