aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/GameObject
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-10-17 23:11:46 +0200
committerShauren <shauren.trinity@gmail.com>2022-10-17 23:11:46 +0200
commit133334a902b705dae6f7e92bb1009b84cf1c51d2 (patch)
tree5a48c30a00441d36c285b78da396b5549eabbb87 /src/server/game/Entities/GameObject
parentaf76b41ace2917ece0aa3f97e4f46e095a7c815f (diff)
Core/Loot: Implemented personal loot and tag sharing for non-boss loot
Diffstat (limited to 'src/server/game/Entities/GameObject')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp95
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h11
2 files changed, 26 insertions, 80 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index ed2dc526fba..4dffcf2652e 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -34,7 +34,6 @@
#include "GossipDef.h"
#include "GridNotifiersImpl.h"
#include "Group.h"
-#include "GroupMgr.h"
#include "Item.h"
#include "Log.h"
#include "Loot.h"
@@ -1419,45 +1418,45 @@ void GameObject::SendGameObjectDespawn()
Loot* GameObject::GetFishLoot(Player* lootOwner)
{
- uint32 zone, subzone;
uint32 defaultzone = 1;
- GetZoneAndAreaId(zone, subzone);
Loot* fishLoot = new Loot(GetMap(), GetGUID(), LOOT_FISHING, nullptr);
- // if subzone loot exist use it
- fishLoot->FillLoot(subzone, LootTemplates_Fishing, lootOwner, true, true);
- if (fishLoot->empty()) //use this becase if zone or subzone has set LOOT_MODE_JUNK_FISH,Even if no normal drop, fishloot->FillLoot return true. it wrong.
+ uint32 areaId = GetAreaId();
+ while (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId))
{
- //subzone no result,use zone loot
- fishLoot->FillLoot(zone, LootTemplates_Fishing, lootOwner, true, true);
- //use zone 1 as default, somewhere fishing got nothing,becase subzone and zone not set, like Off the coast of Storm Peaks.
- if (fishLoot->empty())
- fishLoot->FillLoot(defaultzone, LootTemplates_Fishing, lootOwner, true, true);
+ fishLoot->FillLoot(areaId, LootTemplates_Fishing, lootOwner, true, true);
+ if (!fishLoot->isLooted())
+ break;
+
+ areaId = areaEntry->ParentAreaID;
}
+ if (fishLoot->isLooted())
+ fishLoot->FillLoot(defaultzone, LootTemplates_Fishing, lootOwner, true, true);
+
return fishLoot;
}
Loot* GameObject::GetFishLootJunk(Player* lootOwner)
{
- uint32 zone, subzone;
uint32 defaultzone = 1;
- GetZoneAndAreaId(zone, subzone);
Loot* fishLoot = new Loot(GetMap(), GetGUID(), LOOT_FISHING_JUNK, nullptr);
- // if subzone loot exist use it
- fishLoot->FillLoot(subzone, LootTemplates_Fishing, lootOwner, true, true, LOOT_MODE_JUNK_FISH);
- if (fishLoot->empty()) //use this becase if zone or subzone has normal mask drop, then fishloot->FillLoot return true.
+ uint32 areaId = GetAreaId();
+ while (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId))
{
- //use zone loot
- fishLoot->FillLoot(zone, LootTemplates_Fishing, lootOwner, true, true, LOOT_MODE_JUNK_FISH);
- if (fishLoot->empty())
- //use zone 1 as default
- fishLoot->FillLoot(defaultzone, LootTemplates_Fishing, lootOwner, true, true, LOOT_MODE_JUNK_FISH);
+ fishLoot->FillLoot(areaId, LootTemplates_Fishing, lootOwner, true, true, LOOT_MODE_JUNK_FISH);
+ if (!fishLoot->isLooted())
+ break;
+
+ areaId = areaEntry->ParentAreaID;
}
+ if (fishLoot->isLooted())
+ fishLoot->FillLoot(defaultzone, LootTemplates_Fishing, lootOwner, true, true, LOOT_MODE_JUNK_FISH);
+
return fishLoot;
}
@@ -3279,49 +3278,6 @@ void GameObject::UpdateModel()
GetMap()->InsertGameObjectModel(*m_model);
}
-Player* GameObject::GetLootRecipient() const
-{
- if (!m_lootRecipient)
- return nullptr;
- return ObjectAccessor::FindConnectedPlayer(m_lootRecipient);
-}
-
-Group* GameObject::GetLootRecipientGroup() const
-{
- if (!m_lootRecipientGroup)
- return nullptr;
- return sGroupMgr->GetGroupByGUID(m_lootRecipientGroup);
-}
-
-void GameObject::SetLootRecipient(Unit* unit, Group* group)
-{
- // set the player whose group should receive the right
- // to loot the creature after it dies
- // should be set to nullptr after the loot disappears
-
- if (!unit)
- {
- m_lootRecipient.Clear();
- m_lootRecipientGroup = group ? group->GetGUID() : ObjectGuid::Empty;
- return;
- }
-
- if (unit->GetTypeId() != TYPEID_PLAYER && !unit->IsVehicle())
- return;
-
- Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself();
- if (!player) // normal creature, no player involved
- return;
-
- m_lootRecipient = player->GetGUID();
-
- // either get the group from the passed parameter or from unit's one
- if (group)
- m_lootRecipientGroup = group->GetGUID();
- else if (Group* unitGroup = player->GetGroup())
- m_lootRecipientGroup = unitGroup->GetGUID();
-}
-
bool GameObject::IsLootAllowedFor(Player const* player) const
{
if (Loot const* loot = GetLootForPlayer(player)) // check only if loot was already generated
@@ -3332,15 +3288,8 @@ bool GameObject::IsLootAllowedFor(Player const* player) const
return false;
}
- if (!m_lootRecipient && !m_lootRecipientGroup)
- return true;
-
- if (player->GetGUID() == m_lootRecipient)
- return true;
-
- Group const* playerGroup = player->GetGroup();
- if (!playerGroup || playerGroup != GetLootRecipientGroup()) // if we dont have a group we arent the recipient
- return false; // if go doesnt have group bound it means it was solo killed by someone else
+ if (HasLootRecipient())
+ return m_tapList.find(player->GetGUID()) != m_tapList.end();
return true;
}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 55d86f1e5f8..7d7d0563532 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -27,7 +27,6 @@
class GameObject;
class GameObjectAI;
class GameObjectModel;
-class Group;
class OPvPCapturePoint;
class Transport;
class TransportBase;
@@ -281,11 +280,10 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
std::unique_ptr<Loot> m_loot;
std::unordered_map<ObjectGuid, std::unique_ptr<Loot>> m_personalLoot;
- Player* GetLootRecipient() const;
- Group* GetLootRecipientGroup() const;
- void SetLootRecipient(Unit* unit, Group* group = nullptr);
+ GuidUnorderedSet const& GetTapList() const { return m_tapList; }
+ void SetTapList(GuidUnorderedSet tapList) { m_tapList = std::move(tapList); }
bool IsLootAllowedFor(Player const* player) const;
- bool HasLootRecipient() const { return !m_lootRecipient.IsEmpty() || !m_lootRecipientGroup.IsEmpty(); }
+ bool HasLootRecipient() const { return !m_tapList.empty(); }
Loot* GetLootForPlayer(Player const* /*player*/) const override;
GameObject* GetLinkedTrap();
@@ -427,8 +425,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
QuaternionData m_localRotation;
Position m_stationaryPosition;
- ObjectGuid m_lootRecipient;
- ObjectGuid m_lootRecipientGroup;
+ GuidUnorderedSet m_tapList;
uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable
ObjectGuid m_linkedTrap;