diff options
author | Shauren <shauren.trinity@gmail.com> | 2022-06-24 22:20:34 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-06-24 22:20:34 +0200 |
commit | 5d27939667cf3ca985a33b93646fa4e34445c8d3 (patch) | |
tree | 38b082e57aadb156b888321f07f5457aa1d2c290 /src/server/game/Conditions/ConditionMgr.cpp | |
parent | e2cf6d68fc5d6b3316f69873ee3ab917b2c9d4c0 (diff) |
Core/Conditions: Implemented conditions for spawn groups
Diffstat (limited to 'src/server/game/Conditions/ConditionMgr.cpp')
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.cpp | 204 |
1 files changed, 140 insertions, 64 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 9377b4ff214..24d2a6b9260 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -28,6 +28,7 @@ #include "GameObject.h" #include "GameTime.h" #include "Group.h" +#include "InstanceScenario.h" #include "InstanceScript.h" #include "Item.h" #include "LanguageMgr.h" @@ -43,7 +44,6 @@ #include "RaceMask.h" #include "Realm.h" #include "ReputationMgr.h" -#include "Scenario.h" #include "ScriptMgr.h" #include "Spell.h" #include "SpellAuras.h" @@ -88,7 +88,8 @@ char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] "ConversationLine", "AreaTrigger Client Triggered", "Trainer Spell", - "Object Visibility (by ID)" + "Object Visibility (by ID)", + "Spawn Group" }; ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] = @@ -151,24 +152,109 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND { "Scene In Progress", true, false, false }, }; +ConditionSourceInfo::ConditionSourceInfo(WorldObject* target0, WorldObject* target1, WorldObject* target2) +{ + mConditionTargets[0] = target0; + mConditionTargets[1] = target1; + mConditionTargets[2] = target2; + mConditionMap = target0 ? target0->GetMap() : nullptr; + mLastFailedCondition = nullptr; +} + +ConditionSourceInfo::ConditionSourceInfo(Map const* map) +{ + std::fill(std::begin(mConditionTargets), std::end(mConditionTargets), nullptr); + mConditionMap = map; + mLastFailedCondition = nullptr; +} + // 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 { ASSERT(ConditionTarget < MAX_CONDITION_TARGETS); + + Map const* map = sourceInfo.mConditionMap; + bool condMeets = false; + bool needsObject = false; + switch (ConditionType) + { + case CONDITION_NONE: + condMeets = true; // empty condition, always met + break; + case CONDITION_ACTIVE_EVENT: + condMeets = sGameEventMgr->IsActiveEvent(ConditionValue1); + break; + case CONDITION_INSTANCE_INFO: + { + if (map->IsDungeon()) + { + if (InstanceScript const* instance = ((InstanceMap*)map)->GetInstanceScript()) + { + switch (ConditionValue3) + { + case INSTANCE_INFO_DATA: + condMeets = instance->GetData(ConditionValue1) == ConditionValue2; + break; + //case INSTANCE_INFO_GUID_DATA: + // condMeets = instance->GetGuidData(ConditionValue1) == ObjectGuid(uint64(ConditionValue2)); + // break; + case INSTANCE_INFO_BOSS_STATE: + condMeets = instance->GetBossState(ConditionValue1) == EncounterState(ConditionValue2); + break; + case INSTANCE_INFO_DATA64: + condMeets = instance->GetData64(ConditionValue1) == ConditionValue2; + break; + default: + condMeets = false; + break; + } + } + } + break; + } + case CONDITION_MAPID: + condMeets = map->GetId() == ConditionValue1; + break; + case CONDITION_WORLD_STATE: + { + condMeets = ConditionValue2 == sWorld->getWorldState(ConditionValue1); + break; + } + case CONDITION_REALM_ACHIEVEMENT: + { + AchievementEntry const* achievement = sAchievementStore.LookupEntry(ConditionValue1); + if (achievement && sAchievementMgr->IsRealmCompleted(achievement)) + condMeets = true; + break; + } + case CONDITION_DIFFICULTY_ID: + { + condMeets = map->GetDifficultyID() == ConditionValue1; + break; + } + case CONDITION_SCENARIO_STEP: + { + if (InstanceMap const* instanceMap = map->ToInstanceMap()) + if (Scenario const* scenario = instanceMap->GetInstanceScenario()) + if (ScenarioStepEntry const* step = scenario->GetStep()) + condMeets = step->ID == ConditionValue1; + break; + } + default: + needsObject = true; + break; + } + WorldObject* object = sourceInfo.mConditionTargets[ConditionTarget]; // object not present, return false - if (!object) + if (needsObject && !object) { TC_LOG_DEBUG("condition", "Condition object not found for %s", ToString().c_str()); return false; } - bool condMeets = false; switch (ConditionType) { - case CONDITION_NONE: - condMeets = true; // empty condition, always met - break; case CONDITION_AURA: { if (Unit* unit = object->ToUnit()) @@ -273,38 +359,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const } break; } - case CONDITION_ACTIVE_EVENT: - condMeets = sGameEventMgr->IsActiveEvent(ConditionValue1); - break; - case CONDITION_INSTANCE_INFO: - { - Map* map = object->GetMap(); - if (map->IsDungeon()) - { - if (InstanceScript const* instance = ((InstanceMap*)map)->GetInstanceScript()) - { - switch (ConditionValue3) - { - case INSTANCE_INFO_DATA: - condMeets = instance->GetData(ConditionValue1) == ConditionValue2; - break; - //case INSTANCE_INFO_GUID_DATA: - // condMeets = instance->GetGuidData(ConditionValue1) == ObjectGuid(uint64(ConditionValue2)); - // break; - case INSTANCE_INFO_BOSS_STATE: - condMeets = instance->GetBossState(ConditionValue1) == EncounterState(ConditionValue2); - break; - case INSTANCE_INFO_DATA64: - condMeets = instance->GetData64(ConditionValue1) == ConditionValue2; - break; - } - } - } - break; - } - case CONDITION_MAPID: - condMeets = object->GetMapId() == ConditionValue1; - break; case CONDITION_AREAID: condMeets = object->GetAreaId() == ConditionValue1; break; @@ -434,11 +488,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const condMeets = CompareValues(static_cast<ComparisionType>(ConditionValue2), unit->GetHealthPct(), static_cast<float>(ConditionValue1)); break; } - case CONDITION_WORLD_STATE: - { - condMeets = ConditionValue2 == sWorld->getWorldState(ConditionValue1); - break; - } case CONDITION_PHASEID: { condMeets = object->GetPhaseShift().HasPhase(ConditionValue1); @@ -462,13 +511,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const condMeets = creature->GetCreatureTemplate()->type == ConditionValue1; break; } - case CONDITION_REALM_ACHIEVEMENT: - { - AchievementEntry const* achievement = sAchievementStore.LookupEntry(ConditionValue1); - if (achievement && sAchievementMgr->IsRealmCompleted(achievement)) - condMeets = true; - break; - } case CONDITION_IN_WATER: { if (Unit* unit = object->ToUnit()) @@ -553,11 +595,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const } break; } - case CONDITION_DIFFICULTY_ID: - { - condMeets = object->GetMap()->GetDifficultyID() == ConditionValue1; - break; - } case CONDITION_GAMEMASTER: { if (Player* player = object->ToPlayer()) @@ -577,13 +614,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const static_cast<uint8>(ConditionValue2)); break; } - case CONDITION_SCENARIO_STEP: - { - if (Scenario const* scenario = object->GetScenario()) - if (ScenarioStepEntry const* step = scenario->GetStep()) - condMeets = step->ID == ConditionValue1; - break; - } case CONDITION_SCENE_IN_PROGRESS: { if (Player* player = object->ToPlayer()) @@ -591,7 +621,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const break; } default: - condMeets = false; break; } @@ -1002,6 +1031,32 @@ bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT); } +bool ConditionMgr::CanHaveConditionType(ConditionSourceType sourceType, ConditionTypes conditionType) +{ + switch (sourceType) + { + case CONDITION_SOURCE_TYPE_SPAWN_GROUP: + switch (conditionType) + { + case CONDITION_NONE: + case CONDITION_ACTIVE_EVENT: + case CONDITION_INSTANCE_INFO: + case CONDITION_MAPID: + case CONDITION_WORLD_STATE: + case CONDITION_REALM_ACHIEVEMENT: + case CONDITION_DIFFICULTY_ID: + case CONDITION_SCENARIO_STEP: + return true; + default: + return false; + } + break; + default: + break; + } + return true; +} + bool ConditionMgr::IsObjectMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, ConditionSourceInfo& sourceInfo) const { if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX) @@ -1023,6 +1078,12 @@ bool ConditionMgr::IsObjectMeetingNotGroupedConditions(ConditionSourceType sourc return IsObjectMeetingNotGroupedConditions(sourceType, entry, conditionSource); } +bool ConditionMgr::IsMapMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, Map const* map) const +{ + ConditionSourceInfo conditionSource(map); + return IsObjectMeetingNotGroupedConditions(sourceType, entry, conditionSource); +} + bool ConditionMgr::HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry) const { if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX) @@ -2097,6 +2158,21 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const } break; } + case CONDITION_SOURCE_TYPE_SPAWN_GROUP: + { + SpawnGroupTemplateData const* spawnGroup = sObjectMgr->GetSpawnGroupData(cond->SourceEntry); + if (!spawnGroup) + { + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spawn_group_template`, ignoring.", cond->ToString().c_str()); + return false; + } + if (spawnGroup->flags & (SPAWNGROUP_FLAG_SYSTEM | SPAWNGROUP_FLAG_MANUAL_SPAWN)) + { + TC_LOG_ERROR("sql.sql", "%s in `spawn_group_template` table cannot have SPAWNGROUP_FLAG_SYSTEM or SPAWNGROUP_FLAG_MANUAL_SPAWN flags, ignoring.", cond->ToString().c_str()); + return false; + } + break; + } default: TC_LOG_ERROR("sql.sql", "%s Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString().c_str()); return false; |