aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Conditions/ConditionMgr.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-01-11 20:56:24 +0100
committerShauren <shauren.trinity@gmail.com>2024-01-11 20:56:24 +0100
commit0b5406dd882c6d96bc1be6fd0a78375c3b316415 (patch)
tree095fe9c5ebd20ae4163784b925f1dcd83b45f407 /src/server/game/Conditions/ConditionMgr.cpp
parent913d769b80bb2a5187c6df562ec013db540bf8ea (diff)
Core/Conditions: Refactor ConditionMgr internals to get rid of separate containers for some condition source types
Diffstat (limited to 'src/server/game/Conditions/ConditionMgr.cpp')
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp676
1 files changed, 250 insertions, 426 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index f18af4a220b..9d11270d594 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -57,7 +57,7 @@
#include <random>
#include <sstream>
-char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] =
+char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX_DB_ALLOWED] =
{
"None",
"Creature Loot",
@@ -179,6 +179,15 @@ ConditionSourceInfo::ConditionSourceInfo(Map const* map)
mLastFailedCondition = nullptr;
}
+std::size_t ConditionId::GetHash() const
+{
+ std::size_t hashVal = 0;
+ Trinity::hash_combine(hashVal, SourceGroup);
+ Trinity::hash_combine(hashVal, SourceEntry);
+ Trinity::hash_combine(hashVal, SourceId);
+ return hashVal;
+}
+
// Checks if object meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: SmartAI)
bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
@@ -904,8 +913,10 @@ std::string Condition::ToString(bool ext /*= false*/) const
std::ostringstream ss;
ss << "[Condition ";
ss << "SourceType: " << SourceType;
- if (SourceType < CONDITION_SOURCE_TYPE_MAX)
+ if (SourceType < CONDITION_SOURCE_TYPE_MAX_DB_ALLOWED)
ss << " (" << ConditionMgr::StaticSourceTypeData[SourceType] << ")";
+ else if (SourceType == CONDITION_SOURCE_TYPE_REFERENCE_CONDITION)
+ ss << " (Reference)";
else
ss << " (Unknown)";
if (ConditionMgr::CanHaveSourceGroupSet(SourceType))
@@ -943,26 +954,26 @@ uint32 ConditionMgr::GetSearcherTypeMaskForConditionList(ConditionContainer cons
for (ConditionContainer::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
{
// no point of having not loaded conditions in list
- ASSERT((*i)->isLoaded() && "ConditionMgr::GetSearcherTypeMaskForConditionList - not yet loaded condition found in list");
- std::map<uint32, uint32>::const_iterator itr = elseGroupSearcherTypeMasks.find((*i)->ElseGroup);
+ ASSERT(i->isLoaded() && "ConditionMgr::GetSearcherTypeMaskForConditionList - not yet loaded condition found in list");
+ std::map<uint32, uint32>::const_iterator itr = elseGroupSearcherTypeMasks.find(i->ElseGroup);
// group not filled yet, fill with widest mask possible
if (itr == elseGroupSearcherTypeMasks.end())
- elseGroupSearcherTypeMasks[(*i)->ElseGroup] = GRID_MAP_TYPE_MASK_ALL;
+ elseGroupSearcherTypeMasks[i->ElseGroup] = GRID_MAP_TYPE_MASK_ALL;
// no point of checking anymore, empty mask
else if (!itr->second)
continue;
- if ((*i)->ReferenceId) // handle reference
+ if (i->ReferenceId) // handle reference
{
- ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->ReferenceId);
- ASSERT(ref != ConditionReferenceStore.end() && "ConditionMgr::GetSearcherTypeMaskForConditionList - incorrect reference");
- elseGroupSearcherTypeMasks[(*i)->ElseGroup] &= GetSearcherTypeMaskForConditionList((*ref).second);
+ auto ref = ConditionStore[CONDITION_SOURCE_TYPE_REFERENCE_CONDITION].find({ i->ReferenceId, 0, 0 });
+ ASSERT(ref != ConditionStore[CONDITION_SOURCE_TYPE_REFERENCE_CONDITION].end() && "ConditionMgr::GetSearcherTypeMaskForConditionList - incorrect reference");
+ elseGroupSearcherTypeMasks[i->ElseGroup] &= GetSearcherTypeMaskForConditionList(*(ref->second));
}
else // handle normal condition
{
// object will match conditions in one ElseGroupStore only when it matches all of them
// so, let's find a smallest possible mask which satisfies all conditions
- elseGroupSearcherTypeMasks[(*i)->ElseGroup] &= (*i)->GetSearcherTypeMaskForCondition();
+ elseGroupSearcherTypeMasks[i->ElseGroup] &= i->GetSearcherTypeMaskForCondition();
}
}
// object will match condition when one of the checks in ElseGroupStore is matching
@@ -978,38 +989,35 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo,
{
// groupId, groupCheckPassed
std::map<uint32, bool> elseGroupStore;
- for (Condition const* condition : conditions)
+ for (Condition const& condition : conditions)
{
- TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList {} val1: {}", condition->ToString(), condition->ConditionValue1);
- if (condition->isLoaded())
+ TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList {} val1: {}", condition.ToString(), condition.ConditionValue1);
+ if (condition.isLoaded())
{
//! Find ElseGroup in ElseGroupStore
- std::map<uint32, bool>::const_iterator itr = elseGroupStore.find(condition->ElseGroup);
- //! If not found, add an entry in the store and set to true (placeholder)
- if (itr == elseGroupStore.end())
- elseGroupStore[condition->ElseGroup] = true;
- else if (!(*itr).second) //! If another condition in this group was unmatched before this, don't bother checking (the group is false anyway)
+ std::map<uint32, bool>::iterator itr = elseGroupStore.try_emplace(condition.ElseGroup, true).first;
+ if (!itr->second) //! If another condition in this group was unmatched before this, don't bother checking (the group is false anyway)
continue;
- if (condition->ReferenceId)//handle reference
+ if (condition.ReferenceId)//handle reference
{
- ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find(condition->ReferenceId);
- if (ref != ConditionReferenceStore.end())
+ auto ref = ConditionStore[CONDITION_SOURCE_TYPE_REFERENCE_CONDITION].find({ condition.ReferenceId, 0, 0 });
+ if (ref != ConditionStore[CONDITION_SOURCE_TYPE_REFERENCE_CONDITION].end())
{
- if (!IsObjectMeetToConditionList(sourceInfo, ref->second))
- elseGroupStore[condition->ElseGroup] = false;
+ if (!IsObjectMeetToConditionList(sourceInfo, *ref->second))
+ itr->second = false;
}
else
{
TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList {} Reference template -{} not found",
- condition->ToString(), condition->ReferenceId); // checked at loading, should never happen
+ condition.ToString(), condition.ReferenceId); // checked at loading, should never happen
}
}
else //handle normal condition
{
- if (!condition->Meets(sourceInfo))
- elseGroupStore[condition->ElseGroup] = false;
+ if (!condition.Meets(sourceInfo))
+ itr->second = false;
}
}
}
@@ -1066,7 +1074,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType)
sourceType == CONDITION_SOURCE_TYPE_GRAVEYARD ||
sourceType == CONDITION_SOURCE_TYPE_AREATRIGGER ||
sourceType == CONDITION_SOURCE_TYPE_TRAINER_SPELL ||
- sourceType == CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY);
+ sourceType == CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY ||
+ sourceType == CONDITION_SOURCE_TYPE_REFERENCE_CONDITION);
}
bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType)
@@ -1104,11 +1113,11 @@ bool ConditionMgr::IsObjectMeetingNotGroupedConditions(ConditionSourceType sourc
{
if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
{
- ConditionsByEntryMap::const_iterator i = ConditionStore[sourceType].find(entry);
+ auto i = ConditionStore[sourceType].find({ 0, int32(entry), 0 });
if (i != ConditionStore[sourceType].end())
{
TC_LOG_DEBUG("condition", "GetConditionsForNotGroupedEntry: found conditions for type {} and entry {}", uint32(sourceType), entry);
- return IsObjectMeetToConditions(sourceInfo, i->second);
+ return IsObjectMeetToConditions(sourceInfo, *i->second);
}
}
@@ -1130,87 +1139,66 @@ bool ConditionMgr::IsMapMeetingNotGroupedConditions(ConditionSourceType sourceTy
bool ConditionMgr::HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry) const
{
if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
- if (ConditionStore[sourceType].find(entry) != ConditionStore[sourceType].end())
- return true;
+ return ConditionStore[sourceType].contains({ 0, int32(entry), 0 });
return false;
}
bool ConditionMgr::IsObjectMeetingSpellClickConditions(uint32 creatureId, uint32 spellId, WorldObject const* clicker, WorldObject const* target) const
{
- ConditionEntriesByCreatureIdMap::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
- if (itr != SpellClickEventConditionStore.end())
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT].find({ creatureId, int32(spellId), 0 });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT].end())
{
- ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
- if (i != itr->second.end())
- {
- TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {} spell {}", creatureId, spellId);
- ConditionSourceInfo sourceInfo(clicker, target);
- return IsObjectMeetToConditions(sourceInfo, i->second);
- }
+ TC_LOG_DEBUG("condition", "IsObjectMeetingSpellClickConditions: found conditions for SpellClickEvent entry {} spell {}", creatureId, spellId);
+ ConditionSourceInfo sourceInfo(clicker, target);
+ return IsObjectMeetToConditions(sourceInfo, *itr->second);
}
return true;
}
-ConditionContainer const* ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) const
+bool ConditionMgr::HasConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) const
{
- ConditionEntriesByCreatureIdMap::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
- if (itr != SpellClickEventConditionStore.end())
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT].find({ creatureId, int32(spellId), 0 });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT].end())
{
- ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
- if (i != itr->second.end())
- {
- TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {} spell {}", creatureId, spellId);
- return &i->second;
- }
+ TC_LOG_DEBUG("condition", "HasConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {} spell {}", creatureId, spellId);
+ return true;
}
- return nullptr;
+ return false;
}
bool ConditionMgr::IsObjectMeetingVehicleSpellConditions(uint32 creatureId, uint32 spellId, Player const* player, Unit const* vehicle) const
{
- ConditionEntriesByCreatureIdMap::const_iterator itr = VehicleSpellConditionStore.find(creatureId);
- if (itr != VehicleSpellConditionStore.end())
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_VEHICLE_SPELL].find({ creatureId, int32(spellId), 0 });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_VEHICLE_SPELL].end())
{
- ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
- if (i != itr->second.end())
- {
- TC_LOG_DEBUG("condition", "GetConditionsForVehicleSpell: found conditions for Vehicle entry {} spell {}", creatureId, spellId);
- ConditionSourceInfo sourceInfo(player, vehicle);
- return IsObjectMeetToConditions(sourceInfo, i->second);
- }
+ TC_LOG_DEBUG("condition", "GetConditionsForVehicleSpell: found conditions for Vehicle entry {} spell {}", creatureId, spellId);
+ ConditionSourceInfo sourceInfo(player, vehicle);
+ return IsObjectMeetToConditions(sourceInfo, *itr->second);
}
return true;
}
bool ConditionMgr::IsObjectMeetingSmartEventConditions(int64 entryOrGuid, uint32 eventId, uint32 sourceType, Unit const* unit, WorldObject const* baseObject) const
{
- SmartEventConditionContainer::const_iterator itr = SmartEventConditionStore.find(std::make_pair(entryOrGuid, sourceType));
- if (itr != SmartEventConditionStore.end())
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_SMART_EVENT].find({ eventId + 1, int32(entryOrGuid), sourceType });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_SMART_EVENT].end())
{
- ConditionsByEntryMap::const_iterator i = itr->second.find(eventId + 1);
- if (i != itr->second.end())
- {
- TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid {} eventId {}", entryOrGuid, eventId);
- ConditionSourceInfo sourceInfo(unit, baseObject);
- return IsObjectMeetToConditions(sourceInfo, i->second);
- }
+ TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid {} eventId {}", entryOrGuid, eventId);
+ ConditionSourceInfo sourceInfo(unit, baseObject);
+ return IsObjectMeetToConditions(sourceInfo, *itr->second);
}
return true;
}
bool ConditionMgr::IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player const* player, Creature const* vendor) const
{
- ConditionEntriesByCreatureIdMap::const_iterator itr = NpcVendorConditionContainerStore.find(creatureId);
- if (itr != NpcVendorConditionContainerStore.end())
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_NPC_VENDOR].find({ creatureId, int32(itemId), 0 });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_NPC_VENDOR].end())
{
- ConditionsByEntryMap::const_iterator i = (*itr).second.find(itemId);
- if (i != (*itr).second.end())
- {
- TC_LOG_DEBUG("condition", "GetConditionsForNpcVendor: found conditions for creature entry {} item {}", creatureId, itemId);
- ConditionSourceInfo sourceInfo(player, vendor);
- return IsObjectMeetToConditions(sourceInfo, i->second);
- }
+ TC_LOG_DEBUG("condition", "GetConditionsForNpcVendor: found conditions for creature entry {} item {}", creatureId, itemId);
+ ConditionSourceInfo sourceInfo(player, vendor);
+ return IsObjectMeetToConditions(sourceInfo, *itr->second);
}
return true;
}
@@ -1222,30 +1210,30 @@ bool ConditionMgr::IsSpellUsedInSpellClickConditions(uint32 spellId) const
ConditionContainer const* ConditionMgr::GetConditionsForAreaTrigger(uint32 areaTriggerId, bool isServerSide) const
{
- return Trinity::Containers::MapGetValuePtr(AreaTriggerConditionContainerStore, { areaTriggerId, isServerSide });
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_AREATRIGGER].find({ areaTriggerId, isServerSide ? 1 : 0, 0 });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_AREATRIGGER].end())
+ return itr->second.get();
+ return nullptr;
}
bool ConditionMgr::IsObjectMeetingTrainerSpellConditions(uint32 trainerId, uint32 spellId, Player* player) const
{
- ConditionEntriesByCreatureIdMap::const_iterator itr = TrainerSpellConditionContainerStore.find(trainerId);
- if (itr != TrainerSpellConditionContainerStore.end())
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_NPC_VENDOR].find({ trainerId, int32(spellId), 0 });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_NPC_VENDOR].end())
{
- ConditionsByEntryMap::const_iterator i = (*itr).second.find(spellId);
- if (i != (*itr).second.end())
- {
- TC_LOG_DEBUG("condition", "GetConditionsForTrainerSpell: found conditions for trainer id {} spell {}", trainerId, spellId);
- return IsObjectMeetToConditions(player, i->second);
- }
+ TC_LOG_DEBUG("condition", "IsObjectMeetingTrainerSpellConditions: found conditions for trainer id {} spell {}", trainerId, spellId);
+ return IsObjectMeetToConditions(player, *itr->second);
}
return true;
}
bool ConditionMgr::IsObjectMeetingVisibilityByObjectIdConditions(uint32 objectType, uint32 entry, WorldObject const* seer) const
{
- if (ConditionContainer const* conditions = Trinity::Containers::MapGetValuePtr(ObjectVisibilityConditionStore, { objectType, entry }))
+ auto itr = ConditionStore[CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY].find({ objectType, int32(entry), 0 });
+ if (itr != ConditionStore[CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY].end())
{
TC_LOG_DEBUG("condition", "IsObjectMeetingVisibilityByObjectIdConditions: found conditions for objectType {} entry {}", objectType, entry);
- return IsObjectMeetToConditions(seer, *conditions);
+ return IsObjectMeetToConditions(seer, *itr->second);
}
return true;
}
@@ -1265,26 +1253,6 @@ void ConditionMgr::LoadConditions(bool isReload)
//must clear all custom handled cases (groupped types) before reload
if (isReload)
{
- TC_LOG_INFO("misc", "Reseting Loot Conditions...");
- LootTemplates_Creature.ResetConditions();
- LootTemplates_Fishing.ResetConditions();
- LootTemplates_Gameobject.ResetConditions();
- LootTemplates_Item.ResetConditions();
- LootTemplates_Mail.ResetConditions();
- LootTemplates_Milling.ResetConditions();
- LootTemplates_Pickpocketing.ResetConditions();
- LootTemplates_Reference.ResetConditions();
- LootTemplates_Skinning.ResetConditions();
- LootTemplates_Disenchant.ResetConditions();
- LootTemplates_Prospecting.ResetConditions();
- LootTemplates_Spell.ResetConditions();
-
- TC_LOG_INFO("misc", "Re-Loading `gossip_menu` Table for Conditions!");
- sObjectMgr->LoadGossipMenu();
-
- TC_LOG_INFO("misc", "Re-Loading `gossip_menu_option` Table for Conditions!");
- sObjectMgr->LoadGossipMenuItems();
-
sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists();
sObjectMgr->UnloadPhaseConditions();
@@ -1301,330 +1269,256 @@ void ConditionMgr::LoadConditions(bool isReload)
uint32 count = 0;
+ auto getOrInitConditions = [this](ConditionSourceType sourceType, ConditionId const& id)
+ {
+ auto [itr, inserted] = ConditionStore[sourceType].try_emplace(id, nullptr);
+ if (inserted)
+ itr->second = std::make_shared<std::vector<Condition>>();
+ return itr->second;
+ };
+
do
{
Field* fields = result->Fetch();
- Condition* cond = new Condition();
+ Condition cond;
int32 iSourceTypeOrReferenceId = fields[0].GetInt32();
- cond->SourceGroup = fields[1].GetUInt32();
- cond->SourceEntry = fields[2].GetInt32();
- cond->SourceId = fields[3].GetInt32();
- cond->ElseGroup = fields[4].GetUInt32();
+ cond.SourceGroup = fields[1].GetUInt32();
+ cond.SourceEntry = fields[2].GetInt32();
+ cond.SourceId = fields[3].GetInt32();
+ cond.ElseGroup = fields[4].GetUInt32();
int32 iConditionTypeOrReference = fields[5].GetInt32();
- cond->ConditionTarget = fields[6].GetUInt8();
- cond->ConditionValue1 = fields[7].GetUInt32();
- cond->ConditionValue2 = fields[8].GetUInt32();
- cond->ConditionValue3 = fields[9].GetUInt32();
- cond->NegativeCondition = fields[10].GetBool();
- cond->ErrorType = fields[11].GetUInt32();
- cond->ErrorTextId = fields[12].GetUInt32();
- cond->ScriptId = sObjectMgr->GetScriptId(fields[13].GetString());
+ cond.ConditionTarget = fields[6].GetUInt8();
+ cond.ConditionValue1 = fields[7].GetUInt32();
+ cond.ConditionValue2 = fields[8].GetUInt32();
+ cond.ConditionValue3 = fields[9].GetUInt32();
+ cond.NegativeCondition = fields[10].GetBool();
+ cond.ErrorType = fields[11].GetUInt32();
+ cond.ErrorTextId = fields[12].GetUInt32();
+ cond.ScriptId = sObjectMgr->GetScriptId(fields[13].GetString());
if (iConditionTypeOrReference >= 0)
- cond->ConditionType = ConditionTypes(iConditionTypeOrReference);
+ cond.ConditionType = ConditionTypes(iConditionTypeOrReference);
if (iSourceTypeOrReferenceId >= 0)
- cond->SourceType = ConditionSourceType(iSourceTypeOrReferenceId);
+ cond.SourceType = ConditionSourceType(iSourceTypeOrReferenceId);
if (iConditionTypeOrReference < 0)//it has a reference
{
if (iConditionTypeOrReference == iSourceTypeOrReferenceId)//self referencing, skip
{
TC_LOG_ERROR("sql.sql", "Condition reference {} is referencing self, skipped", iSourceTypeOrReferenceId);
- delete cond;
continue;
}
- cond->ReferenceId = uint32(abs(iConditionTypeOrReference));
+
+ cond.ReferenceId = uint32(-iConditionTypeOrReference);
char const* rowType = "reference template";
if (iSourceTypeOrReferenceId >= 0)
rowType = "reference";
//check for useless data
- if (cond->ConditionTarget)
- TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in ConditionTarget ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionTarget);
- if (cond->ConditionValue1)
- TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value1 ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue1);
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value2 ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value3 ({})!", rowType, iSourceTypeOrReferenceId, cond->ConditionValue3);
- if (cond->NegativeCondition)
- TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in NegativeCondition ({})!", rowType, iSourceTypeOrReferenceId, cond->NegativeCondition);
- if (cond->SourceGroup && iSourceTypeOrReferenceId < 0)
- TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in SourceGroup ({})!", rowType, iSourceTypeOrReferenceId, cond->SourceGroup);
- if (cond->SourceEntry && iSourceTypeOrReferenceId < 0)
- TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in SourceEntry ({})!", rowType, iSourceTypeOrReferenceId, cond->SourceEntry);
- }
- else if (!isConditionTypeValid(cond))//doesn't have reference, validate ConditionType
- {
- delete cond;
+ if (cond.ConditionTarget)
+ TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in ConditionTarget ({})!", rowType, iSourceTypeOrReferenceId, cond.ConditionTarget);
+ if (cond.ConditionValue1)
+ TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value1 ({})!", rowType, iSourceTypeOrReferenceId, cond.ConditionValue1);
+ if (cond.ConditionValue2)
+ TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value2 ({})!", rowType, iSourceTypeOrReferenceId, cond.ConditionValue2);
+ if (cond.ConditionValue3)
+ TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in value3 ({})!", rowType, iSourceTypeOrReferenceId, cond.ConditionValue3);
+ if (cond.NegativeCondition)
+ TC_LOG_ERROR("sql.sql", "Condition {} {} has useless data in NegativeCondition ({})!", rowType, iSourceTypeOrReferenceId, cond.NegativeCondition);
+ }
+ else if (!isConditionTypeValid(&cond))//doesn't have reference, validate ConditionType
continue;
- }
if (iSourceTypeOrReferenceId < 0)//it is a reference template
{
- ConditionReferenceStore[std::abs(iSourceTypeOrReferenceId)].push_back(cond);//add to reference storage
- ++count;
- continue;
- }//end of reference templates
+ if (cond.SourceGroup)
+ TC_LOG_ERROR("sql.sql", "Condition reference template {} has useless data in SourceGroup ({})!", iSourceTypeOrReferenceId, cond.SourceGroup);
+ if (cond.SourceEntry)
+ TC_LOG_ERROR("sql.sql", "Condition reference template {} has useless data in SourceEntry ({})!", iSourceTypeOrReferenceId, cond.SourceEntry);
+ if (cond.SourceId)
+ TC_LOG_ERROR("sql.sql", "Condition reference template {} has useless data in SourceId ({})!", iSourceTypeOrReferenceId, cond.SourceId);
- //if not a reference and SourceType is invalid, skip
- if (iConditionTypeOrReference >= 0 && !isSourceTypeValid(cond))
- {
- delete cond;
- continue;
+ cond.SourceType = CONDITION_SOURCE_TYPE_REFERENCE_CONDITION;
+ cond.SourceGroup = -iSourceTypeOrReferenceId;
}
+ else if (!isSourceTypeValid(&cond)) //if not a reference and SourceType is invalid, skip
+ continue;
//Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
- if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType))
+ if (cond.SourceGroup && !CanHaveSourceGroupSet(cond.SourceType))
{
- TC_LOG_ERROR("sql.sql", "{} has not allowed value of SourceGroup = {}!", cond->ToString(), cond->SourceGroup);
- delete cond;
+ TC_LOG_ERROR("sql.sql", "{} has not allowed value of SourceGroup = {}!", cond.ToString(), cond.SourceGroup);
continue;
}
- if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType))
+ if (cond.SourceId && !CanHaveSourceIdSet(cond.SourceType))
{
- TC_LOG_ERROR("sql.sql", "{} has not allowed value of SourceId = {}!", cond->ToString(), cond->SourceId);
- delete cond;
+ TC_LOG_ERROR("sql.sql", "{} has not allowed value of SourceId = {}!", cond.ToString(), cond.SourceId);
continue;
}
- if (cond->ErrorType && cond->SourceType != CONDITION_SOURCE_TYPE_SPELL)
- {
- TC_LOG_ERROR("sql.sql", "{} can't have ErrorType ({}), set to 0!", cond->ToString(), cond->ErrorType);
- cond->ErrorType = 0;
- }
-
- if (cond->ErrorTextId && !cond->ErrorType)
+ if (cond.ErrorType && cond.SourceType != CONDITION_SOURCE_TYPE_SPELL)
{
- TC_LOG_ERROR("sql.sql", "{} has any ErrorType, ErrorTextId ({}) is set, set to 0!", cond->ToString(), cond->ErrorTextId);
- cond->ErrorTextId = 0;
+ TC_LOG_ERROR("sql.sql", "{} can't have ErrorType ({}), set to 0!", cond.ToString(), cond.ErrorType);
+ cond.ErrorType = 0;
}
- if (cond->SourceGroup)
+ if (cond.ErrorTextId && !cond.ErrorType)
{
- bool valid = false;
- // handle grouped conditions
- switch (cond->SourceType)
- {
- case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Creature.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Disenchant.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Fishing.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Gameobject.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Item.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Mail.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Milling.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Pickpocketing.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Prospecting.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Reference.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Skinning.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE:
- valid = addToLootTemplate(cond, LootTemplates_Spell.GetLootForConditionFill(cond->SourceGroup));
- break;
- case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
- valid = addToGossipMenus(cond);
- break;
- case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
- valid = addToGossipMenuItems(cond);
- break;
- case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
- {
- SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
- if (cond->ConditionType == CONDITION_AURA)
- SpellsUsedInSpellClickConditions.insert(cond->ConditionValue1);
- valid = true;
- ++count;
- continue; // do not add to m_AllocatedMemory to avoid double deleting
- }
- case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET:
- valid = addToSpellImplicitTargetConditions(cond);
- break;
- case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
- {
- VehicleSpellConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
- valid = true;
- ++count;
- continue; // do not add to m_AllocatedMemory to avoid double deleting
- }
- case CONDITION_SOURCE_TYPE_SMART_EVENT:
- {
- //! TODO: PAIR_32 ?
- std::pair<int32, uint32> key = std::make_pair(cond->SourceEntry, cond->SourceId);
- SmartEventConditionStore[key][cond->SourceGroup].push_back(cond);
- valid = true;
- ++count;
- continue;
- }
- case CONDITION_SOURCE_TYPE_NPC_VENDOR:
- {
- NpcVendorConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
- valid = true;
- ++count;
- continue;
- }
- case CONDITION_SOURCE_TYPE_PHASE:
- valid = addToPhases(cond);
- break;
- case CONDITION_SOURCE_TYPE_GRAVEYARD:
- valid = addToGraveyardData(cond);
- break;
- case CONDITION_SOURCE_TYPE_AREATRIGGER:
- {
- AreaTriggerConditionContainerStore[{ cond->SourceGroup, cond->SourceEntry }].push_back(cond);
- valid = true;
- ++count;
- continue;
- }
- case CONDITION_SOURCE_TYPE_TRAINER_SPELL:
- {
- TrainerSpellConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
- valid = true;
- ++count;
- continue;
- }
- case CONDITION_SOURCE_TYPE_OBJECT_ID_VISIBILITY:
- {
- ObjectVisibilityConditionStore[{ cond->SourceGroup, uint32(cond->SourceEntry) }].push_back(cond);
- valid = true;
- ++count;
- continue;
- }
- default:
- break;
- }
-
- if (!valid)
- {
- TC_LOG_ERROR("sql.sql", "{} Not handled grouped condition.", cond->ToString());
- delete cond;
- }
- else
- {
- AllocatedMemoryStore.push_back(cond);
- ++count;
- }
- continue;
+ TC_LOG_ERROR("sql.sql", "{} has any ErrorType, ErrorTextId ({}) is set, set to 0!", cond.ToString(), cond.ErrorTextId);
+ cond.ErrorTextId = 0;
}
- //handle not grouped conditions
- //add new Condition to storage based on Type/Entry
- if (cond->SourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT && cond->ConditionType == CONDITION_AURA)
- SpellsUsedInSpellClickConditions.insert(cond->ConditionValue1);
- ConditionStore[cond->SourceType][cond->SourceEntry].push_back(cond);
+ getOrInitConditions(cond.SourceType, { cond.SourceGroup, cond.SourceEntry, cond.SourceId })->emplace_back(std::move(cond));
++count;
}
while (result->NextRow());
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Creature.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Disenchant.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Fishing.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Gameobject.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Item.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Mail.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Milling.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Pickpocketing.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Prospecting.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Reference.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Skinning.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE])
+ addToLootTemplate(id, conditions, LootTemplates_Spell.GetLootForConditionFill(id.SourceGroup));
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_GOSSIP_MENU])
+ addToGossipMenus(id, conditions);
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION])
+ addToGossipMenuItems(id, conditions);
+
+ SpellsUsedInSpellClickConditions.clear();
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT])
+ for (Condition const& condition : *conditions)
+ if (condition.ConditionType == CONDITION_AURA)
+ SpellsUsedInSpellClickConditions.insert(condition.ConditionValue1);
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET])
+ for (Condition const& condition : *conditions)
+ addToSpellImplicitTargetConditions(condition);
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_PHASE])
+ addToPhases(id, conditions);
+
+ for (auto&& [id, conditions] : ConditionStore[CONDITION_SOURCE_TYPE_GRAVEYARD])
+ addToGraveyardData(id, conditions);
+
TC_LOG_INFO("server.loading", ">> Loaded {} conditions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot) const
+void ConditionMgr::addToLootTemplate(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions, LootTemplate* loot) const
{
if (!loot)
{
- TC_LOG_ERROR("sql.sql", "{} LootTemplate {} not found.", cond->ToString(), cond->SourceGroup);
- return false;
+ for (Condition const& condition : *conditions)
+ TC_LOG_ERROR("sql.sql", "{} LootTemplate {} not found.", condition.ToString(), id.SourceGroup);
+ return;
}
- if (loot->addConditionItem(cond))
- return true;
+ if (loot->LinkConditions(id, ConditionsReference{ conditions }))
+ return;
- TC_LOG_ERROR("sql.sql", "{} Item {} not found in LootTemplate {}.", cond->ToString(), cond->SourceEntry, cond->SourceGroup);
- return false;
+ for (Condition const& condition : *conditions)
+ TC_LOG_ERROR("sql.sql", "{} Item {} not found in LootTemplate {}.", condition.ToString(), id.SourceEntry, id.SourceGroup);
}
-bool ConditionMgr::addToGossipMenus(Condition* cond) const
+void ConditionMgr::addToGossipMenus(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const
{
- GossipMenusMapBoundsNonConst pMenuBounds = sObjectMgr->GetGossipMenusMapBoundsNonConst(cond->SourceGroup);
+ GossipMenusMapBoundsNonConst pMenuBounds = sObjectMgr->GetGossipMenusMapBoundsNonConst(id.SourceGroup);
if (pMenuBounds.first != pMenuBounds.second)
{
for (GossipMenusContainer::iterator itr = pMenuBounds.first; itr != pMenuBounds.second; ++itr)
- {
- if (itr->second.MenuID == cond->SourceGroup && (itr->second.TextID == uint32(cond->SourceEntry) || cond->SourceEntry == 0))
- itr->second.Conditions.push_back(cond);
- }
- return true;
+ if (itr->second.MenuID == id.SourceGroup && (itr->second.TextID == uint32(id.SourceEntry) || id.SourceEntry == 0))
+ itr->second.Conditions = { conditions };
+
+ return;
}
- TC_LOG_ERROR("sql.sql", "{} GossipMenu {} not found.", cond->ToString(), cond->SourceGroup);
- return false;
+ for (Condition const& condition : *conditions)
+ TC_LOG_ERROR("sql.sql", "{} GossipMenu {} not found.", condition.ToString(), id.SourceGroup);
}
-bool ConditionMgr::addToGossipMenuItems(Condition* cond) const
+void ConditionMgr::addToGossipMenuItems(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const
{
- Trinity::IteratorPair pMenuItemBounds = sObjectMgr->GetGossipMenuItemsMapBoundsNonConst(cond->SourceGroup);
+ Trinity::IteratorPair pMenuItemBounds = sObjectMgr->GetGossipMenuItemsMapBoundsNonConst(id.SourceGroup);
for (auto& [_, gossipMenuItem] : pMenuItemBounds)
{
- if (gossipMenuItem.MenuID == cond->SourceGroup && gossipMenuItem.OrderIndex == uint32(cond->SourceEntry))
+ if (gossipMenuItem.MenuID == id.SourceGroup && gossipMenuItem.OrderIndex == uint32(id.SourceEntry))
{
- gossipMenuItem.Conditions.push_back(cond);
- return true;
+ gossipMenuItem.Conditions = { conditions };
+ return;
}
}
- TC_LOG_ERROR("sql.sql", "{} GossipMenuId {} Item {} not found.", cond->ToString(), cond->SourceGroup, cond->SourceEntry);
- return false;
+ for (Condition const& condition : *conditions)
+ TC_LOG_ERROR("sql.sql", "{} GossipMenuId {} Item {} not found.", condition.ToString(), id.SourceGroup, id.SourceEntry);
}
-bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
+void ConditionMgr::addToSpellImplicitTargetConditions(Condition const& cond) const
{
- bool valid = false;
- sSpellMgr->ForEachSpellInfoDifficulty(cond->SourceEntry, [&](SpellInfo const* spellInfo)
+ sSpellMgr->ForEachSpellInfoDifficulty(cond.SourceEntry, [&](SpellInfo const* spellInfo)
{
- uint32 conditionEffMask = cond->SourceGroup;
+ uint32 conditionEffMask = cond.SourceGroup;
std::list<uint32> sharedMasks;
for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
{
// additional checks by condition type
if (conditionEffMask & (1 << spellEffectInfo.EffectIndex))
{
- switch (cond->ConditionType)
+ switch (cond.ConditionType)
{
case CONDITION_OBJECT_ENTRY_GUID:
{
uint32 implicitTargetMask = GetTargetFlagMask(spellEffectInfo.TargetA.GetObjectType()) | GetTargetFlagMask(spellEffectInfo.TargetB.GetObjectType());
- if ((implicitTargetMask & TARGET_FLAG_UNIT_MASK) && cond->ConditionValue1 != TYPEID_UNIT && cond->ConditionValue1 != TYPEID_PLAYER)
+ if ((implicitTargetMask & TARGET_FLAG_UNIT_MASK) && cond.ConditionValue1 != TYPEID_UNIT && cond.ConditionValue1 != TYPEID_PLAYER)
{
TC_LOG_ERROR("sql.sql", "{} in `condition` table - spell {} EFFECT_{} - "
- "target requires ConditionValue1 to be either TYPEID_UNIT ({}) or TYPEID_PLAYER ({})", cond->ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_UNIT), uint32(TYPEID_PLAYER));
+ "target requires ConditionValue1 to be either TYPEID_UNIT ({}) or TYPEID_PLAYER ({})", cond.ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_UNIT), uint32(TYPEID_PLAYER));
return;
}
- if ((implicitTargetMask & TARGET_FLAG_GAMEOBJECT_MASK) && cond->ConditionValue1 != TYPEID_GAMEOBJECT)
+ if ((implicitTargetMask & TARGET_FLAG_GAMEOBJECT_MASK) && cond.ConditionValue1 != TYPEID_GAMEOBJECT)
{
TC_LOG_ERROR("sql.sql", "{} in `condition` table - spell {} EFFECT_{} - "
- "target requires ConditionValue1 to be TYPEID_GAMEOBJECT ({})", cond->ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_GAMEOBJECT));
+ "target requires ConditionValue1 to be TYPEID_GAMEOBJECT ({})", cond.ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_GAMEOBJECT));
return;
}
- if ((implicitTargetMask & TARGET_FLAG_CORPSE_MASK) && cond->ConditionValue1 != TYPEID_CORPSE)
+ if ((implicitTargetMask & TARGET_FLAG_CORPSE_MASK) && cond.ConditionValue1 != TYPEID_CORPSE)
{
TC_LOG_ERROR("sql.sql", "{} in `condition` table - spell {} EFFECT_{} - "
- "target requires ConditionValue1 to be TYPEID_CORPSE ({})", cond->ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_CORPSE));
+ "target requires ConditionValue1 to be TYPEID_CORPSE ({})", cond.ToString(), spellInfo->Id, uint32(spellEffectInfo.EffectIndex), uint32(TYPEID_CORPSE));
return;
}
break;
@@ -1641,9 +1535,8 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
// build new shared mask with found effect
uint32 sharedMask = 1 << spellEffectInfo.EffectIndex;
- ConditionContainer* cmp = spellEffectInfo.ImplicitTargetConditions;
for (size_t effIndex = spellEffectInfo.EffectIndex + 1; effIndex < spellInfo->GetEffects().size(); ++effIndex)
- if (spellInfo->GetEffect(SpellEffIndex(effIndex)).ImplicitTargetConditions == cmp)
+ if (spellInfo->GetEffect(SpellEffIndex(effIndex)).ImplicitTargetConditions == spellEffectInfo.ImplicitTargetConditions)
sharedMask |= 1 << effIndex;
sharedMasks.push_back(sharedMask);
@@ -1663,7 +1556,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
return;
// get shared data
- ConditionContainer* sharedList = spellInfo->GetEffect(SpellEffIndex(firstEffIndex)).ImplicitTargetConditions;
+ std::shared_ptr<ConditionContainer> sharedList = spellInfo->GetEffect(SpellEffIndex(firstEffIndex)).ImplicitTargetConditions;
// there's already data entry for that sharedMask
if (sharedList)
@@ -1673,7 +1566,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
{
TC_LOG_ERROR("sql.sql", "{} in `condition` table, has incorrect SourceGroup {} (spell effectMask) set - "
"effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring (Difficulty {}).",
- cond->ToString(), cond->SourceGroup, uint32(spellInfo->Difficulty));
+ cond.ToString(), cond.SourceGroup, uint32(spellInfo->Difficulty));
return;
}
}
@@ -1681,7 +1574,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
else
{
// add new list, create new shared mask
- sharedList = new ConditionContainer();
+ sharedList = std::make_shared<ConditionContainer>();
bool assigned = false;
for (size_t i = firstEffIndex; i < spellInfo->GetEffects().size(); ++i)
{
@@ -1693,25 +1586,20 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
}
if (!assigned)
- {
- delete sharedList;
break;
- }
}
sharedList->push_back(cond);
break;
}
}
- valid = true;
});
- return true;
}
-bool ConditionMgr::addToPhases(Condition* cond) const
+void ConditionMgr::addToPhases(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const
{
- if (!cond->SourceEntry)
+ if (!id.SourceEntry)
{
- if (PhaseInfoStruct const* phaseInfo = sObjectMgr->GetPhaseInfo(cond->SourceGroup))
+ if (PhaseInfoStruct const* phaseInfo = sObjectMgr->GetPhaseInfo(id.SourceGroup))
{
bool found = false;
for (uint32 areaId : phaseInfo->Areas)
@@ -1720,9 +1608,9 @@ bool ConditionMgr::addToPhases(Condition* cond) const
{
for (PhaseAreaInfo& phase : *phases)
{
- if (phase.PhaseInfo->Id == cond->SourceGroup)
+ if (phase.PhaseInfo->Id == id.SourceGroup)
{
- phase.Conditions.push_back(cond);
+ phase.Conditions.insert(phase.Conditions.end(), conditions->begin(), conditions->end());
found = true;
}
}
@@ -1730,35 +1618,35 @@ bool ConditionMgr::addToPhases(Condition* cond) const
}
if (found)
- return true;
+ return;
}
}
- else if (std::vector<PhaseAreaInfo>* phases = const_cast<std::vector<PhaseAreaInfo>*>(sObjectMgr->GetPhasesForArea(cond->SourceEntry)))
+ else if (std::vector<PhaseAreaInfo>* phases = const_cast<std::vector<PhaseAreaInfo>*>(sObjectMgr->GetPhasesForArea(id.SourceEntry)))
{
for (PhaseAreaInfo& phase : *phases)
{
- if (phase.PhaseInfo->Id == cond->SourceGroup)
+ if (phase.PhaseInfo->Id == id.SourceGroup)
{
- phase.Conditions.push_back(cond);
- return true;
+ phase.Conditions.insert(phase.Conditions.end(), conditions->begin(), conditions->end());
+ return;
}
}
}
- TC_LOG_ERROR("sql.sql", "{} Area {} does not have phase {}.", cond->ToString(), cond->SourceEntry, cond->SourceGroup);
- return false;
+ for (Condition const& condition : *conditions)
+ TC_LOG_ERROR("sql.sql", "{} Area {} does not have phase {}.", condition.ToString(), id.SourceEntry, id.SourceGroup);
}
-bool ConditionMgr::addToGraveyardData(Condition* cond) const
+void ConditionMgr::addToGraveyardData(ConditionId const& id, std::shared_ptr<std::vector<Condition>> conditions) const
{
- if (GraveyardData* graveyard = const_cast<GraveyardData*>(sObjectMgr->FindGraveyardData(cond->SourceEntry, cond->SourceGroup)))
+ if (GraveyardData* graveyard = const_cast<GraveyardData*>(sObjectMgr->FindGraveyardData(id.SourceEntry, id.SourceGroup)))
{
- graveyard->Conditions.push_back(cond);
- return true;
+ graveyard->Conditions = { conditions };
+ return;
}
- TC_LOG_ERROR("sql.sql", "{}, Graveyard {} does not have ghostzone {}.", cond->ToString(), cond->SourceEntry, cond->SourceGroup);
- return false;
+ for (Condition const& condition : *conditions)
+ TC_LOG_ERROR("sql.sql", "{}, Graveyard {} does not have ghostzone {}.", condition.ToString(), id.SourceEntry, id.SourceGroup);
}
bool ConditionMgr::isSourceTypeValid(Condition* cond) const
@@ -2146,7 +2034,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const
TC_LOG_ERROR("sql.sql", "{} in `condition` table, unexpected SourceEntry value (expected 0 or 1), ignoring.", cond->ToString());
return false;
}
- if (!sAreaTriggerDataStore->GetAreaTriggerTemplate({ uint32(cond->SourceGroup), bool(cond->SourceEntry) }))
+ if (!sAreaTriggerDataStore->GetAreaTriggerTemplate({ uint32(cond->SourceGroup), cond->SourceEntry == 1 }))
{
TC_LOG_ERROR("sql.sql", "{} in `condition` table, does not exist in `areatrigger_template`, ignoring.", cond->ToString());
return false;
@@ -2815,74 +2703,10 @@ void ConditionMgr::LogUselessConditionValue(Condition* cond, uint8 index, uint32
void ConditionMgr::Clean()
{
- for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)
- for (ConditionContainer::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- delete *it;
-
- ConditionReferenceStore.clear();
-
- for (uint32 i = 0; i < CONDITION_SOURCE_TYPE_MAX; ++i)
- {
- for (ConditionsByEntryMap::iterator it = ConditionStore[i].begin(); it != ConditionStore[i].end(); ++it)
- for (ConditionContainer::const_iterator itr = it->second.begin(); itr != it->second.end(); ++itr)
- delete *itr;
+ for (std::unordered_map<ConditionId, std::shared_ptr<std::vector<Condition>>>& conditionsMap : ConditionStore)
+ conditionsMap.clear();
- ConditionStore[i].clear();
- }
-
- for (ConditionEntriesByCreatureIdMap::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
- for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
- delete *i;
-
- VehicleSpellConditionStore.clear();
-
- for (SmartEventConditionContainer::iterator itr = SmartEventConditionStore.begin(); itr != SmartEventConditionStore.end(); ++itr)
- for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
- delete *i;
-
- SmartEventConditionStore.clear();
-
- for (ConditionEntriesByCreatureIdMap::iterator itr = SpellClickEventConditionStore.begin(); itr != SpellClickEventConditionStore.end(); ++itr)
- for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
- delete *i;
-
- SpellClickEventConditionStore.clear();
SpellsUsedInSpellClickConditions.clear();
-
- for (ConditionEntriesByCreatureIdMap::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
- for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
- delete *i;
-
- NpcVendorConditionContainerStore.clear();
-
- for (ConditionEntriesByAreaTriggerIdMap::iterator itr = AreaTriggerConditionContainerStore.begin(); itr != AreaTriggerConditionContainerStore.end(); ++itr)
- for (ConditionContainer::const_iterator i = itr->second.begin(); i != itr->second.end(); ++i)
- delete *i;
-
- AreaTriggerConditionContainerStore.clear();
-
- for (ConditionEntriesByCreatureIdMap::iterator itr = TrainerSpellConditionContainerStore.begin(); itr != TrainerSpellConditionContainerStore.end(); ++itr)
- for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
- delete *i;
-
- TrainerSpellConditionContainerStore.clear();
-
- for (auto&& [_, conditions] : ObjectVisibilityConditionStore)
- for (Condition* condition : conditions)
- delete condition;
-
- ObjectVisibilityConditionStore.clear();
-
- // this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
- for (std::vector<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
- delete *itr;
-
- AllocatedMemoryStore.clear();
}
inline bool PlayerConditionCompare(int32 comparisonType, int32 value1, int32 value2)