aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2023-07-03 00:17:17 +0200
committerShauren <shauren.trinity@gmail.com>2023-07-03 00:17:17 +0200
commita3ef01f87bd56e553972277a38cf9a98a3397495 (patch)
tree6660b5d730181e073a80f28b63d150984f823f3f /src/server/game
parent36ecc2d8cb8d913a6ac0936031de47b18c69a90d (diff)
Core/GameObjects: Only start loot restock timer if loot contents were modified and ignore it for personal loot
Closes #29023
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp22
-rw-r--r--src/server/game/Handlers/LootHandler.cpp4
-rw-r--r--src/server/game/Loot/Loot.cpp12
-rw-r--r--src/server/game/Loot/Loot.h3
4 files changed, 27 insertions, 14 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index e7726b1f595..72bb7094edc 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1210,19 +1210,21 @@ void GameObject::Update(uint32 diff)
break;
case GAMEOBJECT_TYPE_CHEST:
if (m_loot)
+ {
m_loot->Update();
+ // Non-consumable chest was partially looted and restock time passed, restock all loot now
+ if (GetGOInfo()->chest.consumable == 0 && GetGOInfo()->chest.chestRestockTime && GameTime::GetGameTime() >= m_restockTime)
+ {
+ m_restockTime = 0;
+ m_lootState = GO_READY;
+ ClearLoot();
+ UpdateDynamicFlagsForNearbyPlayers();
+ }
+ }
+
for (auto&& [playerOwner, loot] : m_personalLoot)
loot->Update();
-
- // Non-consumable chest was partially looted and restock time passed, restock all loot now
- if (GetGOInfo()->chest.consumable == 0 && GetGOInfo()->chest.chestRestockTime && GameTime::GetGameTime() >= m_restockTime)
- {
- m_restockTime = 0;
- m_lootState = GO_READY;
- ClearLoot();
- UpdateDynamicFlagsForNearbyPlayers();
- }
break;
case GAMEOBJECT_TYPE_TRAP:
{
@@ -3310,7 +3312,7 @@ 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)
+ if (GetGoType() == GAMEOBJECT_TYPE_CHEST && state == GO_ACTIVATED && GetGOInfo()->chest.chestRestockTime > 0 && m_restockTime == 0 && m_loot && m_loot->IsChanged())
m_restockTime = GameTime::GetGameTime() + GetGOInfo()->chest.chestRestockTime;
if (GetGoType() == GAMEOBJECT_TYPE_DOOR) // only set collision for doors on SetGoState
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index 998f5d09ce4..223ee9a84a3 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -26,7 +26,6 @@
#include "GridNotifiersImpl.h"
#include "Group.h"
#include "Guild.h"
-#include "GuildMgr.h"
#include "Item.h"
#include "Log.h"
#include "Loot.h"
@@ -79,7 +78,6 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPackets::Loot::LootItem& p
AELootResult aeResult;
AELootResult* aeResultPtr = player->GetAELootView().size() > 1 ? &aeResult : nullptr;
- /// @todo Implement looting by LootObject guid
for (WorldPackets::Loot::LootRequest const& req : packet.Loot)
{
Loot* loot = Trinity::Containers::MapGetValuePtr(player->GetAELootView(), req.Object);
@@ -198,7 +196,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPackets::Loot::LootMoney& /*packet
SendPacket(packet.Write());
}
- loot->gold = 0;
+ loot->LootMoney();
// Delete the money loot record from the DB
if (loot->loot_type == LOOT_ITEM)
diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp
index ac75747d60a..c005aba2ccb 100644
--- a/src/server/game/Loot/Loot.cpp
+++ b/src/server/game/Loot/Loot.cpp
@@ -623,7 +623,7 @@ void LootRoll::Finish(RollVoteMap::const_iterator winnerItr)
Loot::Loot(Map* map, ObjectGuid owner, LootType type, Group const* group) : gold(0), unlootedCount(0), loot_type(type),
_guid(map ? ObjectGuid::Create<HighGuid::LootObject>(map->GetId(), 0, map->GenerateLowGuid<HighGuid::LootObject>()) : ObjectGuid::Empty),
_owner(owner), _itemContext(ItemContext::NONE), _lootMethod(group ? group->GetLootMethod() : FREE_FOR_ALL),
- _lootMaster(group ? group->GetMasterLooterGuid() : ObjectGuid::Empty), _wasOpened(false), _dungeonEncounterId(0)
+ _lootMaster(group ? group->GetMasterLooterGuid() : ObjectGuid::Empty), _wasOpened(false), _changed(false), _dungeonEncounterId(0)
{
}
@@ -717,6 +717,9 @@ void Loot::OnLootOpened(Map* map, ObjectGuid looter)
if (!itr->second.TryToStart(map, *this, lootListId, maxEnchantingSkill))
_rolls.erase(itr);
}
+
+ if (!_rolls.empty())
+ _changed = true;
}
else if (_lootMethod == MASTER_LOOT)
{
@@ -893,6 +896,12 @@ bool Loot::AutoStore(Player* player, uint8 bag, uint8 slot, bool broadcast, bool
return allLooted;
}
+void Loot::LootMoney()
+{
+ gold = 0;
+ _changed = true;
+}
+
LootItem const* Loot::GetItemInSlot(uint32 lootListId) const
{
if (lootListId < items.size())
@@ -931,6 +940,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootListId, Player const* player, NotNorma
if (is_looted)
return nullptr;
+ _changed = true;
return item;
}
diff --git a/src/server/game/Loot/Loot.h b/src/server/game/Loot/Loot.h
index d80bcb78ffa..0a57e11b575 100644
--- a/src/server/game/Loot/Loot.h
+++ b/src/server/game/Loot/Loot.h
@@ -305,6 +305,7 @@ struct TC_GAME_API Loot
void SetDungeonEncounterId(uint32 dungeonEncounterId) { _dungeonEncounterId = dungeonEncounterId; }
bool isLooted() const { return gold == 0 && unlootedCount == 0; }
+ bool IsChanged() const { return _changed; }
void NotifyLootList(Map const* map) const;
void NotifyItemRemoved(uint8 lootListId, Map const* map);
@@ -324,6 +325,7 @@ struct TC_GAME_API Loot
bool AutoStore(Player* player, uint8 bag, uint8 slot, bool broadcast = false, bool createdByPlayer = false);
+ void LootMoney();
LootItem const* GetItemInSlot(uint32 lootListId) const;
LootItem* LootItemInSlot(uint32 lootListId, Player const* player, NotNormalLootItem** ffaItem = nullptr);
bool hasItemForAll() const;
@@ -348,6 +350,7 @@ private:
ObjectGuid _lootMaster;
GuidUnorderedSet _allowedLooters;
bool _wasOpened; // true if at least one player received the loot content
+ bool _changed;
uint32 _dungeonEncounterId;
};