mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Conditions: Refactor ConditionMgr internals to get rid of separate containers for some condition source types
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@
|
||||
#include "Define.h"
|
||||
#include "Hash.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@@ -183,7 +184,10 @@ enum ConditionSourceType
|
||||
CONDITION_SOURCE_TYPE_TRAINER_SPELL = 31,
|
||||
CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY = 32,
|
||||
CONDITION_SOURCE_TYPE_SPAWN_GROUP = 33,
|
||||
CONDITION_SOURCE_TYPE_MAX = 34 // MAX
|
||||
|
||||
CONDITION_SOURCE_TYPE_MAX_DB_ALLOWED,
|
||||
CONDITION_SOURCE_TYPE_REFERENCE_CONDITION = CONDITION_SOURCE_TYPE_MAX_DB_ALLOWED, // internal, not set in db
|
||||
CONDITION_SOURCE_TYPE_MAX // MAX
|
||||
};
|
||||
|
||||
enum RelationType
|
||||
@@ -219,6 +223,23 @@ struct TC_GAME_API ConditionSourceInfo
|
||||
ConditionSourceInfo(Map const* map);
|
||||
};
|
||||
|
||||
struct TC_GAME_API ConditionId
|
||||
{
|
||||
uint32 SourceGroup = 0;
|
||||
int32 SourceEntry = 0;
|
||||
uint32 SourceId = 0;
|
||||
|
||||
std::size_t GetHash() const;
|
||||
bool operator==(ConditionId const& right) const = default;
|
||||
std::strong_ordering operator<=>(ConditionId const& right) const = default;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct std::hash<ConditionId>
|
||||
{
|
||||
std::size_t operator()(ConditionId const& id) const noexcept { return id.GetHash(); }
|
||||
};
|
||||
|
||||
struct TC_GAME_API Condition
|
||||
{
|
||||
ConditionSourceType SourceType; //SourceTypeOrReferenceId
|
||||
@@ -264,13 +285,9 @@ struct TC_GAME_API Condition
|
||||
std::string ToString(bool ext = false) const; /// For logging purpose
|
||||
};
|
||||
|
||||
typedef std::vector<Condition*> ConditionContainer;
|
||||
typedef std::unordered_map<uint32 /*SourceEntry*/, ConditionContainer> ConditionsByEntryMap;
|
||||
typedef std::vector<Condition> ConditionContainer;
|
||||
typedef std::unordered_map<ConditionId, std::shared_ptr<ConditionContainer>> ConditionsByEntryMap; // stored as shared_ptr to give out weak_ptrs to hold by other code (ownership not shared)
|
||||
typedef std::array<ConditionsByEntryMap, CONDITION_SOURCE_TYPE_MAX> ConditionEntriesByTypeArray;
|
||||
typedef std::unordered_map<uint32, ConditionsByEntryMap> ConditionEntriesByCreatureIdMap;
|
||||
typedef std::unordered_map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionsByEntryMap> SmartEventConditionContainer;
|
||||
typedef std::unordered_map<uint32, ConditionContainer> ConditionReferenceContainer;//only used for references
|
||||
typedef std::unordered_map<std::pair<int32, bool>, ConditionContainer> ConditionEntriesByAreaTriggerIdMap;
|
||||
|
||||
class TC_GAME_API ConditionMgr
|
||||
{
|
||||
@@ -296,7 +313,7 @@ class TC_GAME_API ConditionMgr
|
||||
bool IsMapMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, Map const* map) const;
|
||||
bool HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry) const;
|
||||
bool IsObjectMeetingSpellClickConditions(uint32 creatureId, uint32 spellId, WorldObject const* clicker, WorldObject const* target) const;
|
||||
ConditionContainer const* GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) const;
|
||||
bool HasConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) const;
|
||||
bool IsObjectMeetingVehicleSpellConditions(uint32 creatureId, uint32 spellId, Player const* player, Unit const* vehicle) const;
|
||||
bool IsObjectMeetingSmartEventConditions(int64 entryOrGuid, uint32 eventId, uint32 sourceType, Unit const* unit, WorldObject const* baseObject) const;
|
||||
bool IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player const* player, Creature const* vendor) const;
|
||||
@@ -319,37 +336,61 @@ class TC_GAME_API ConditionMgr
|
||||
bool HasConditionValue2;
|
||||
bool HasConditionValue3;
|
||||
};
|
||||
static char const* const StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX];
|
||||
static char const* const StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX_DB_ALLOWED];
|
||||
static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX];
|
||||
|
||||
private:
|
||||
bool isSourceTypeValid(Condition* cond) const;
|
||||
bool addToLootTemplate(Condition* cond, LootTemplate* loot) const;
|
||||
bool addToGossipMenus(Condition* cond) const;
|
||||
bool addToGossipMenuItems(Condition* cond) const;
|
||||
bool addToSpellImplicitTargetConditions(Condition* cond) const;
|
||||
bool addToPhases(Condition* cond) const;
|
||||
bool addToGraveyardData(Condition* cond) const;
|
||||
void addToLootTemplate(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions, LootTemplate* loot) const;
|
||||
void addToGossipMenus(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const;
|
||||
void addToGossipMenuItems(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const;
|
||||
void addToSpellImplicitTargetConditions(Condition const& cond) const;
|
||||
void addToPhases(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const;
|
||||
void addToGraveyardData(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const;
|
||||
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionContainer const& conditions) const;
|
||||
|
||||
static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value);
|
||||
|
||||
void Clean(); // free up resources
|
||||
std::vector<Condition*> AllocatedMemoryStore; // some garbage collection :)
|
||||
|
||||
ConditionEntriesByTypeArray ConditionStore;
|
||||
ConditionReferenceContainer ConditionReferenceStore;
|
||||
ConditionEntriesByCreatureIdMap VehicleSpellConditionStore;
|
||||
ConditionEntriesByCreatureIdMap SpellClickEventConditionStore;
|
||||
ConditionEntriesByCreatureIdMap NpcVendorConditionContainerStore;
|
||||
SmartEventConditionContainer SmartEventConditionStore;
|
||||
|
||||
std::unordered_set<uint32> SpellsUsedInSpellClickConditions;
|
||||
ConditionEntriesByAreaTriggerIdMap AreaTriggerConditionContainerStore;
|
||||
ConditionEntriesByCreatureIdMap TrainerSpellConditionContainerStore;
|
||||
std::unordered_map<std::pair<uint32 /*object type*/, uint32 /*object id*/>, ConditionContainer> ObjectVisibilityConditionStore;
|
||||
};
|
||||
|
||||
#define sConditionMgr ConditionMgr::instance()
|
||||
|
||||
struct ConditionsReference
|
||||
{
|
||||
bool Meets(WorldObject const* object) const
|
||||
{
|
||||
if (std::shared_ptr<std::vector<Condition>> conditions = Conditions.lock())
|
||||
return sConditionMgr->IsObjectMeetToConditions(object, *conditions);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Meets(WorldObject const* object1, WorldObject const* object2) const
|
||||
{
|
||||
if (std::shared_ptr<std::vector<Condition>> conditions = Conditions.lock())
|
||||
return sConditionMgr->IsObjectMeetToConditions(object1, object2, *conditions);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Meets(ConditionSourceInfo& sourceInfo) const
|
||||
{
|
||||
if (std::shared_ptr<std::vector<Condition>> conditions = Conditions.lock())
|
||||
return sConditionMgr->IsObjectMeetToConditions(sourceInfo, *conditions);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
if (std::shared_ptr<std::vector<Condition>> conditions = Conditions.lock())
|
||||
return conditions->empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::weak_ptr<ConditionContainer> Conditions;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14000,7 +14000,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId, bool showQues
|
||||
|
||||
for (auto const& [_, gossipMenuItem] : menuItemBounds)
|
||||
{
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, source, gossipMenuItem.Conditions))
|
||||
if (!gossipMenuItem.Conditions.Meets(this, source))
|
||||
continue;
|
||||
|
||||
bool canTalk = true;
|
||||
@@ -14326,7 +14326,7 @@ uint32 Player::GetGossipTextId(uint32 menuId, WorldObject* source)
|
||||
if (!itr->second.TextID)
|
||||
continue;
|
||||
|
||||
if (sConditionMgr->IsObjectMeetToConditions(this, source, itr->second.Conditions))
|
||||
if (itr->second.Conditions.Meets(this, source))
|
||||
textId = itr->second.TextID;
|
||||
}
|
||||
|
||||
@@ -14352,7 +14352,7 @@ uint32 Player::GetGossipMenuForSource(WorldObject* source)
|
||||
|
||||
for (GossipMenusContainer::const_iterator itr = menuBounds.first; itr != menuBounds.second; ++itr)
|
||||
{
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, source, itr->second.Conditions))
|
||||
if (!itr->second.Conditions.Meets(this, source))
|
||||
continue;
|
||||
|
||||
menuIdToShow = menuId;
|
||||
@@ -25130,7 +25130,7 @@ void Player::UpdateVisibleGameobjectsOrSpellClicks()
|
||||
auto clickBounds = sObjectMgr->GetSpellClickInfoMapBounds(obj->GetEntry());
|
||||
for (auto const& clickPair : clickBounds)
|
||||
{
|
||||
if (sConditionMgr->GetConditionsForSpellClickEvent(obj->GetEntry(), clickPair.second.spellId))
|
||||
if (sConditionMgr->HasConditionsForSpellClickEvent(obj->GetEntry(), clickPair.second.spellId))
|
||||
{
|
||||
UF::ObjectData::Base objMask;
|
||||
UF::UnitData::Base unitMask;
|
||||
|
||||
@@ -6900,7 +6900,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveyardInZone(WorldLocation con
|
||||
|
||||
if (conditionObject)
|
||||
{
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(conditionSource, data.Conditions))
|
||||
if (!data.Conditions.Meets(conditionSource))
|
||||
continue;
|
||||
|
||||
if (int16(entry->Loc.GetMapId()) == mapEntry->ParentMapID && !conditionObject->GetPhaseShift().HasVisibleMapId(entry->Loc.GetMapId()))
|
||||
@@ -6909,15 +6909,18 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveyardInZone(WorldLocation con
|
||||
else if (team != 0)
|
||||
{
|
||||
bool teamConditionMet = true;
|
||||
for (Condition const* cond : data.Conditions)
|
||||
if (std::shared_ptr<std::vector<Condition>> conditions = data.Conditions.Conditions.lock())
|
||||
{
|
||||
if (cond->ConditionType != CONDITION_TEAM)
|
||||
continue;
|
||||
for (Condition const& cond : *conditions)
|
||||
{
|
||||
if (cond.ConditionType != CONDITION_TEAM)
|
||||
continue;
|
||||
|
||||
if (cond->ConditionValue1 == team)
|
||||
continue;
|
||||
if (cond.ConditionValue1 == team)
|
||||
continue;
|
||||
|
||||
teamConditionMet = false;
|
||||
teamConditionMet = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!teamConditionMet)
|
||||
|
||||
@@ -755,14 +755,14 @@ struct GossipMenuItems
|
||||
uint32 BoxBroadcastTextID;
|
||||
Optional<int32> SpellID;
|
||||
Optional<int32> OverrideIconID;
|
||||
ConditionContainer Conditions;
|
||||
ConditionsReference Conditions;
|
||||
};
|
||||
|
||||
struct GossipMenus
|
||||
{
|
||||
uint32 MenuID;
|
||||
uint32 TextID;
|
||||
ConditionContainer Conditions;
|
||||
ConditionsReference Conditions;
|
||||
};
|
||||
|
||||
struct GossipMenuAddon
|
||||
@@ -836,7 +836,7 @@ struct WorldSafeLocsEntry
|
||||
struct GraveyardData
|
||||
{
|
||||
uint32 safeLocId;
|
||||
ConditionContainer Conditions;
|
||||
ConditionsReference Conditions;
|
||||
};
|
||||
|
||||
typedef std::multimap<uint32, GraveyardData> GraveyardContainer;
|
||||
|
||||
@@ -369,7 +369,7 @@ void WorldSession::HandleRequestCemeteryList(WorldPackets::Misc::RequestCemetery
|
||||
for (auto it = range.first; it != range.second && graveyardIds.size() < 16; ++it) // client max
|
||||
{
|
||||
ConditionSourceInfo conditionSource(_player);
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(conditionSource, it->second.Conditions))
|
||||
if (!it->second.Conditions.Meets(conditionSource))
|
||||
continue;
|
||||
|
||||
graveyardIds.push_back(it->first);
|
||||
|
||||
@@ -75,10 +75,10 @@ bool LootItem::AllowedForPlayer(Player const* player, Loot const* loot) const
|
||||
}
|
||||
|
||||
bool LootItem::AllowedForPlayer(Player const* player, Loot const* loot, uint32 itemid, bool needs_quest, bool follow_loot_rules, bool strictUsabilityCheck,
|
||||
ConditionContainer const& conditions)
|
||||
ConditionsReference const& conditions)
|
||||
{
|
||||
// DB conditions check
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(player, conditions))
|
||||
if (!conditions.Meets(player))
|
||||
return false;
|
||||
|
||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
|
||||
@@ -956,7 +956,7 @@ bool Loot::hasItemForAll() const
|
||||
return true;
|
||||
|
||||
for (LootItem const& item : items)
|
||||
if (!item.is_looted && item.follow_loot_rules && !item.freeforall && item.conditions.empty())
|
||||
if (!item.is_looted && item.follow_loot_rules && !item.freeforall && item.conditions.IsEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ struct TC_GAME_API LootItem
|
||||
ItemRandomBonusListId randomBonusListId;
|
||||
std::vector<int32> BonusListIDs;
|
||||
ItemContext context;
|
||||
ConditionContainer conditions; // additional loot condition
|
||||
ConditionsReference conditions; // additional loot condition
|
||||
GuidSet allowedGUIDs;
|
||||
ObjectGuid rollWinnerGUID; // Stores the guid of person who won loot, if his bags are full only he can see the item in loot list!
|
||||
uint8 count : 8;
|
||||
@@ -208,7 +208,7 @@ struct TC_GAME_API LootItem
|
||||
// Basic checks for player/item compatibility - if false no chance to see the item in the loot - used only for loot generation
|
||||
bool AllowedForPlayer(Player const* player, Loot const* loot) const;
|
||||
static bool AllowedForPlayer(Player const* player, Loot const* loot, uint32 itemid, bool needs_quest, bool follow_loot_rules, bool strictUsabilityCheck,
|
||||
ConditionContainer const& conditions);
|
||||
ConditionsReference const& conditions);
|
||||
void AddAllowedLooter(Player const* player);
|
||||
GuidSet const& GetAllowedLooters() const { return allowedGUIDs; }
|
||||
bool HasAllowedLooter(ObjectGuid const& looter) const;
|
||||
|
||||
@@ -101,7 +101,6 @@ class LootTemplate::LootGroup // A set of loot def
|
||||
void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const;
|
||||
LootStoreItemList* GetExplicitlyChancedItemList() { return &ExplicitlyChanced; }
|
||||
LootStoreItemList* GetEqualChancedItemList() { return &EqualChanced; }
|
||||
void CopyConditions(ConditionContainer conditions);
|
||||
private:
|
||||
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
|
||||
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
|
||||
@@ -217,15 +216,6 @@ bool LootStore::HaveQuestLootForPlayer(uint32 loot_id, Player const* player) con
|
||||
return false;
|
||||
}
|
||||
|
||||
void LootStore::ResetConditions()
|
||||
{
|
||||
for (LootTemplateMap::iterator itr = m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr)
|
||||
{
|
||||
ConditionContainer empty;
|
||||
itr->second->CopyConditions(empty);
|
||||
}
|
||||
}
|
||||
|
||||
LootTemplate const* LootStore::GetLootFor(uint32 loot_id) const
|
||||
{
|
||||
LootTemplateMap::const_iterator tab = m_LootTemplates.find(loot_id);
|
||||
@@ -453,15 +443,6 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const* player) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void LootTemplate::LootGroup::CopyConditions(ConditionContainer /*conditions*/)
|
||||
{
|
||||
for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
|
||||
(*i)->conditions.clear();
|
||||
|
||||
for (LootStoreItemList::iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i)
|
||||
(*i)->conditions.clear();
|
||||
}
|
||||
|
||||
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
|
||||
void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode, Player const* personalLooter /*= nullptr*/) const
|
||||
{
|
||||
@@ -558,16 +539,6 @@ void LootTemplate::AddEntry(LootStoreItem* item)
|
||||
Entries.push_back(item);
|
||||
}
|
||||
|
||||
void LootTemplate::CopyConditions(ConditionContainer const& conditions)
|
||||
{
|
||||
for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
|
||||
(*i)->conditions.clear();
|
||||
|
||||
for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i)
|
||||
if (LootGroup* group = *i)
|
||||
group->CopyConditions(conditions);
|
||||
}
|
||||
|
||||
void LootTemplate::CopyConditions(LootItem* li) const
|
||||
{
|
||||
// Copies the conditions list from a template item to a LootItemData
|
||||
@@ -880,21 +851,15 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se
|
||||
group->CheckLootRefs(store, ref_set);
|
||||
}
|
||||
|
||||
bool LootTemplate::addConditionItem(Condition* cond)
|
||||
bool LootTemplate::LinkConditions(ConditionId const& id, ConditionsReference reference)
|
||||
{
|
||||
if (!cond || !cond->isLoaded())//should never happen, checked at loading
|
||||
{
|
||||
TC_LOG_ERROR("loot", "LootTemplate::addConditionItem: condition is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Entries.empty())
|
||||
{
|
||||
for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
|
||||
for (LootStoreItem* item : Entries)
|
||||
{
|
||||
if ((*i)->itemid == uint32(cond->SourceEntry))
|
||||
if (item->itemid == uint32(id.SourceEntry))
|
||||
{
|
||||
(*i)->conditions.push_back(cond);
|
||||
item->conditions = std::move(reference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -902,20 +867,19 @@ bool LootTemplate::addConditionItem(Condition* cond)
|
||||
|
||||
if (!Groups.empty())
|
||||
{
|
||||
for (LootGroups::iterator groupItr = Groups.begin(); groupItr != Groups.end(); ++groupItr)
|
||||
for (LootGroup* group : Groups)
|
||||
{
|
||||
LootGroup* group = *groupItr;
|
||||
if (!group)
|
||||
continue;
|
||||
|
||||
LootStoreItemList* itemList = group->GetExplicitlyChancedItemList();
|
||||
if (!itemList->empty())
|
||||
{
|
||||
for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
|
||||
for (LootStoreItem* item : *itemList)
|
||||
{
|
||||
if ((*i)->itemid == uint32(cond->SourceEntry))
|
||||
if (item->itemid == uint32(id.SourceEntry))
|
||||
{
|
||||
(*i)->conditions.push_back(cond);
|
||||
item->conditions = std::move(reference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -924,11 +888,11 @@ bool LootTemplate::addConditionItem(Condition* cond)
|
||||
itemList = group->GetEqualChancedItemList();
|
||||
if (!itemList->empty())
|
||||
{
|
||||
for (LootStoreItemList::iterator i = itemList->begin(); i != itemList->end(); ++i)
|
||||
for (LootStoreItem* item : *itemList)
|
||||
{
|
||||
if ((*i)->itemid == uint32(cond->SourceEntry))
|
||||
if (item->itemid == uint32(id.SourceEntry))
|
||||
{
|
||||
(*i)->conditions.push_back(cond);
|
||||
item->conditions = std::move(reference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ struct TC_GAME_API LootStoreItem
|
||||
uint8 groupid;
|
||||
uint8 mincount; // mincount for drop items
|
||||
uint8 maxcount; // max drop count for the item mincount or Ref multiplicator
|
||||
ConditionContainer conditions; // additional loot condition
|
||||
ConditionsReference conditions; // additional loot condition
|
||||
|
||||
// Constructor
|
||||
// displayid is filled in IsValid() which must be called after
|
||||
@@ -85,7 +85,6 @@ class TC_GAME_API LootStore
|
||||
bool HaveQuestLootForPlayer(uint32 loot_id, Player const* player) const;
|
||||
|
||||
LootTemplate const* GetLootFor(uint32 loot_id) const;
|
||||
void ResetConditions();
|
||||
LootTemplate* GetLootForConditionFill(uint32 loot_id);
|
||||
|
||||
char const* GetName() const { return m_name; }
|
||||
@@ -115,7 +114,6 @@ class TC_GAME_API LootTemplate
|
||||
// Rolls for every item in the template and adds the rolled items the the loot
|
||||
void Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId, Player const* personalLooter = nullptr) const;
|
||||
void ProcessPersonalLoot(std::unordered_map<Player*, std::unique_ptr<Loot>>& personalLoot, bool rate, uint16 lootMode) const;
|
||||
void CopyConditions(ConditionContainer const& conditions);
|
||||
void CopyConditions(LootItem* li) const;
|
||||
|
||||
// True if template includes at least 1 drop for the player
|
||||
@@ -128,7 +126,7 @@ class TC_GAME_API LootTemplate
|
||||
// Checks integrity of the template
|
||||
void Verify(LootStore const& store, uint32 Id) const;
|
||||
void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const;
|
||||
bool addConditionItem(Condition* cond);
|
||||
bool LinkConditions(ConditionId const& id, ConditionsReference reference);
|
||||
bool isReference(uint32 id);
|
||||
|
||||
private:
|
||||
|
||||
@@ -25,7 +25,7 @@ PhaseShift& PhaseShift::operator=(PhaseShift const& right) = default;
|
||||
PhaseShift& PhaseShift::operator=(PhaseShift&& right) noexcept = default;
|
||||
PhaseShift::~PhaseShift() = default;
|
||||
|
||||
bool PhaseShift::AddPhase(uint32 phaseId, PhaseFlags flags, std::vector<Condition*> const* areaConditions, int32 references /*= 1*/)
|
||||
bool PhaseShift::AddPhase(uint32 phaseId, PhaseFlags flags, std::vector<Condition> const* areaConditions, int32 references /*= 1*/)
|
||||
{
|
||||
auto insertResult = Phases.emplace(phaseId, flags, nullptr);
|
||||
ModifyPhasesReferences(insertResult.first, references);
|
||||
|
||||
@@ -56,13 +56,13 @@ class TC_GAME_API PhaseShift
|
||||
public:
|
||||
struct PhaseRef
|
||||
{
|
||||
PhaseRef(uint32 id, PhaseFlags flags, std::vector<Condition*> const* conditions)
|
||||
PhaseRef(uint32 id, PhaseFlags flags, std::vector<Condition> const* conditions)
|
||||
: Id(id), Flags(flags), References(0), AreaConditions(conditions) { }
|
||||
|
||||
uint16 Id;
|
||||
EnumFlag<PhaseFlags> Flags;
|
||||
int32 References;
|
||||
std::vector<Condition*> const* AreaConditions;
|
||||
std::vector<Condition> const* AreaConditions;
|
||||
std::strong_ordering operator<=>(PhaseRef const& right) const { return Id <=> right.Id; }
|
||||
bool operator==(PhaseRef const& right) const { return Id == right.Id; }
|
||||
bool IsPersonal() const { return Flags.HasFlag(PhaseFlags::Personal); }
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
|
||||
ObjectGuid GetPersonalGuid() const { return PersonalGuid; }
|
||||
|
||||
bool AddPhase(uint32 phaseId, PhaseFlags flags, std::vector<Condition*> const* areaConditions, int32 references = 1);
|
||||
bool AddPhase(uint32 phaseId, PhaseFlags flags, std::vector<Condition> const* areaConditions, int32 references = 1);
|
||||
EraseResult<PhaseContainer> RemovePhase(uint32 phaseId);
|
||||
bool HasPhase(uint32 phaseId) const { return Phases.find(PhaseRef(phaseId, PhaseFlags::None, nullptr)) != Phases.end(); }
|
||||
PhaseContainer const& GetPhases() const { return Phases; }
|
||||
|
||||
@@ -2525,7 +2525,7 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
|
||||
continue;
|
||||
|
||||
std::vector<WorldObject*> units;
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions.get();
|
||||
|
||||
float radius = spellEffectInfo.CalcRadius(ref);
|
||||
float extraSearchRadius = 0.0f;
|
||||
@@ -2647,7 +2647,7 @@ void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit*
|
||||
selectionType = spellEffectInfo.TargetB.GetCheckType();
|
||||
|
||||
std::vector<Unit*> units;
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions.get();
|
||||
|
||||
Trinity::WorldObjectSpellAreaTargetCheck check(radius, GetDynobjOwner(), dynObjOwnerCaster, dynObjOwnerCaster, m_spellInfo, selectionType, condList, TARGET_OBJECT_TYPE_UNIT);
|
||||
Trinity::UnitListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(GetDynobjOwner(), units, check);
|
||||
|
||||
@@ -1129,7 +1129,7 @@ void Spell::SelectImplicitNearbyTargets(SpellEffectInfo const& spellEffectInfo,
|
||||
break;
|
||||
}
|
||||
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions.get();
|
||||
|
||||
// handle emergency case - try to use other provided targets if no conditions provided
|
||||
if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
|
||||
@@ -1313,7 +1313,7 @@ void Spell::SelectImplicitConeTargets(SpellEffectInfo const& spellEffectInfo, Sp
|
||||
std::list<WorldObject*> targets;
|
||||
SpellTargetObjectTypes objectType = targetType.GetObjectType();
|
||||
SpellTargetCheckTypes selectionType = targetType.GetCheckType();
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions.get();
|
||||
float radius = spellEffectInfo.CalcRadius(m_caster, targetIndex) * m_spellValue->RadiusMod;
|
||||
|
||||
if (uint32 containerTypeMask = GetSearcherTypeMask(m_spellInfo, spellEffectInfo, objectType, condList))
|
||||
@@ -1417,15 +1417,15 @@ void Spell::SelectImplicitAreaTargets(SpellEffectInfo const& spellEffectInfo, Sp
|
||||
if (!m_caster->IsUnit() || !m_caster->ToUnit()->IsInRaidWith(targetedUnit))
|
||||
targets.push_back(m_targets.GetUnitTarget());
|
||||
else
|
||||
SearchAreaTargets(targets, spellEffectInfo, radius, targetedUnit, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions);
|
||||
SearchAreaTargets(targets, spellEffectInfo, radius, targetedUnit, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions.get());
|
||||
}
|
||||
break;
|
||||
case TARGET_UNIT_CASTER_AND_SUMMONS:
|
||||
targets.push_back(m_caster);
|
||||
SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions);
|
||||
SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions.get());
|
||||
break;
|
||||
default:
|
||||
SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions);
|
||||
SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions.get());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1872,7 +1872,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffectInfo const& spellEffectInfo, Sp
|
||||
float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
|
||||
|
||||
std::list<WorldObject*> targets;
|
||||
Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions, TARGET_OBJECT_TYPE_NONE);
|
||||
Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions.get(), TARGET_OBJECT_TYPE_NONE);
|
||||
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> searcher(m_caster, targets, check, GRID_MAP_TYPE_MASK_ALL);
|
||||
SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
|
||||
if (targets.empty())
|
||||
@@ -1969,7 +1969,7 @@ void Spell::SelectImplicitLineTargets(SpellEffectInfo const& spellEffectInfo, Sp
|
||||
return;
|
||||
}
|
||||
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
|
||||
ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions.get();
|
||||
float radius = spellEffectInfo.CalcRadius(m_caster, targetIndex) * m_spellValue->RadiusMod;
|
||||
|
||||
if (uint32 containerTypeMask = GetSearcherTypeMask(m_spellInfo, spellEffectInfo, objectType, condList))
|
||||
@@ -2240,7 +2240,7 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
|
||||
|
||||
WorldObject* chainSource = m_spellInfo->HasAttribute(SPELL_ATTR2_CHAIN_FROM_CASTER) ? m_caster : target;
|
||||
std::list<WorldObject*> tempTargets;
|
||||
SearchAreaTargets(tempTargets, spellEffectInfo, searchRadius, chainSource, m_caster, objectType, selectType, spellEffectInfo.ImplicitTargetConditions);
|
||||
SearchAreaTargets(tempTargets, spellEffectInfo, searchRadius, chainSource, m_caster, objectType, selectType, spellEffectInfo.ImplicitTargetConditions.get());
|
||||
tempTargets.remove(target);
|
||||
|
||||
// remove targets which are always invalid for chain spells
|
||||
|
||||
@@ -5059,18 +5059,8 @@ void SpellInfo::_InitializeSpellPositivity()
|
||||
void SpellInfo::_UnloadImplicitTargetConditionLists()
|
||||
{
|
||||
// find the same instances of ConditionList and delete them.
|
||||
for (SpellEffectInfo const& effect : _effects)
|
||||
{
|
||||
ConditionContainer* cur = effect.ImplicitTargetConditions;
|
||||
if (!cur)
|
||||
continue;
|
||||
|
||||
for (size_t j = effect.EffectIndex; j < _effects.size(); ++j)
|
||||
if (_effects[j].ImplicitTargetConditions == cur)
|
||||
_effects[j].ImplicitTargetConditions = nullptr;
|
||||
|
||||
delete cur;
|
||||
}
|
||||
for (SpellEffectInfo& effect : _effects)
|
||||
effect.ImplicitTargetConditions = nullptr;
|
||||
}
|
||||
|
||||
bool SpellInfo::MeetsFutureSpellPlayerCondition(Player const* player) const
|
||||
|
||||
@@ -237,7 +237,7 @@ public:
|
||||
uint32 TriggerSpell;
|
||||
flag128 SpellClassMask;
|
||||
float BonusCoefficientFromAP;
|
||||
std::vector<Condition*>* ImplicitTargetConditions;
|
||||
std::shared_ptr<std::vector<Condition>> ImplicitTargetConditions;
|
||||
EnumFlag<SpellEffectAttributes> EffectAttributes;
|
||||
// SpellScalingEntry
|
||||
struct ScalingInfo
|
||||
|
||||
@@ -1225,7 +1225,7 @@ public:
|
||||
{
|
||||
handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_LABEL, "Standard items", loot->items.size());
|
||||
for (LootItem const& item : loot->items)
|
||||
if (!item.is_looted && !item.freeforall && item.conditions.empty())
|
||||
if (!item.is_looted && !item.freeforall && item.conditions.IsEmpty())
|
||||
_ShowLootEntry(handler, item.itemid, item.count);
|
||||
|
||||
if (!loot->GetPlayerFFAItems().empty())
|
||||
|
||||
Reference in New Issue
Block a user