aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Conditions/ConditionMgr.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-06-24 22:20:34 +0200
committerShauren <shauren.trinity@gmail.com>2022-06-24 22:20:34 +0200
commit5d27939667cf3ca985a33b93646fa4e34445c8d3 (patch)
tree38b082e57aadb156b888321f07f5457aa1d2c290 /src/server/game/Conditions/ConditionMgr.cpp
parente2cf6d68fc5d6b3316f69873ee3ab917b2c9d4c0 (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.cpp204
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;