diff options
author | ModoX <moardox@gmail.com> | 2021-10-06 10:22:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-06 10:22:41 +0200 |
commit | 3548467c93a3859f7df72c456d600300539dc6b2 (patch) | |
tree | 32f098a4a6af3a767ac3c02265e111a5d0920b14 /src | |
parent | f602a83bb46d485b1c6adeac53384348b7a1102f (diff) |
Core/Conditions: Implemented conditions for areatriggers (#27021)
* also added example fix for Death's Power Grows quest
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Conditions/ConditionMgr.h | 6 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 11 |
3 files changed, 47 insertions, 3 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 6a6e936bba4..88f0336ce4e 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -17,6 +17,8 @@ #include "ConditionMgr.h" #include "AchievementMgr.h" +#include "AreaTrigger.h" +#include "AreaTriggerDataStore.h" #include "Containers.h" #include "DatabaseEnv.h" #include "DB2Stores.h" @@ -74,7 +76,9 @@ char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] "Npc Vendor", "Spell Proc", "Terrain Swap", - "Phase" + "Phase", + "Graveyard", + "AreaTrigger", }; ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] = @@ -931,7 +935,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT || sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT || sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR || - sourceType == CONDITION_SOURCE_TYPE_PHASE); + sourceType == CONDITION_SOURCE_TYPE_PHASE || + sourceType == CONDITION_SOURCE_TYPE_AREATRIGGER); } bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) @@ -1048,6 +1053,11 @@ bool ConditionMgr::IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 return true; } +ConditionContainer const* ConditionMgr::GetConditionsForAreaTrigger(uint32 areaTriggerId, bool isServerSide) const +{ + return Trinity::Containers::MapGetValuePtr(AreaTriggerConditionContainerStore, { areaTriggerId, isServerSide }); +} + ConditionMgr* ConditionMgr::instance() { static ConditionMgr instance; @@ -1284,6 +1294,13 @@ void ConditionMgr::LoadConditions(bool isReload) case CONDITION_SOURCE_TYPE_PHASE: valid = addToPhases(cond); break; + case CONDITION_SOURCE_TYPE_AREATRIGGER: + { + AreaTriggerConditionContainerStore[{ cond->SourceGroup, cond->SourceEntry }].push_back(cond); + valid = true; + ++count; + continue; + } default: break; } @@ -1886,6 +1903,18 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const return false; } break; + case CONDITION_SOURCE_TYPE_AREATRIGGER: + if (cond->SourceEntry != 0 && cond->SourceEntry != 1) + { + TC_LOG_ERROR("sql.sql", "%s in `condition` table, unexpected SourceEntry value (expected 0 or 1), ignoring.", cond->ToString().c_str()); + return false; + } + if (!sAreaTriggerDataStore->GetAreaTriggerTemplate({ uint32(cond->SourceGroup), bool(cond->SourceEntry) })) + { + TC_LOG_ERROR("sql.sql", "%s in `condition` table, does not exist in `areatrigger_template`, 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; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 207c311731e..5cfb0cfb3e9 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -168,7 +168,8 @@ enum ConditionSourceType CONDITION_SOURCE_TYPE_TERRAIN_SWAP = 25, CONDITION_SOURCE_TYPE_PHASE = 26, CONDITION_SOURCE_TYPE_GRAVEYARD = 27, - CONDITION_SOURCE_TYPE_MAX = 28 // MAX + CONDITION_SOURCE_TYPE_AREATRIGGER = 28, + CONDITION_SOURCE_TYPE_MAX = 29 // MAX }; enum RelationType @@ -259,6 +260,7 @@ typedef std::array<ConditionsByEntryMap, CONDITION_SOURCE_TYPE_MAX> ConditionEnt 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 { @@ -286,6 +288,7 @@ class TC_GAME_API ConditionMgr bool IsObjectMeetingVehicleSpellConditions(uint32 creatureId, uint32 spellId, Player* player, Unit* vehicle) const; bool IsObjectMeetingSmartEventConditions(int64 entryOrGuid, uint32 eventId, uint32 sourceType, Unit* unit, WorldObject* baseObject) const; bool IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player* player, Creature* vendor) const; + ConditionContainer const* GetConditionsForAreaTrigger(uint32 areaTriggerId, bool isServerSide) const; static uint32 GetPlayerConditionLfgValue(Player const* player, PlayerConditionLfgStatus status); static bool IsPlayerMeetingCondition(Player const* player, PlayerConditionEntry const* condition); @@ -321,6 +324,7 @@ class TC_GAME_API ConditionMgr ConditionEntriesByCreatureIdMap SpellClickEventConditionStore; ConditionEntriesByCreatureIdMap NpcVendorConditionContainerStore; SmartEventConditionContainer SmartEventConditionStore; + ConditionEntriesByAreaTriggerIdMap AreaTriggerConditionContainerStore; }; #define sConditionMgr ConditionMgr::instance() diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 55f6cb7f04c..ae69a5ed902 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -359,6 +359,17 @@ void AreaTrigger::UpdateTargetList() break; } + if (GetTemplate()) + { + if (ConditionContainer const* conditions = sConditionMgr->GetConditionsForAreaTrigger(GetTemplate()->Id.Id, GetTemplate()->Id.IsServerSide)) + { + targetList.erase(std::remove_if(targetList.begin(), targetList.end(), [conditions](Unit* target) + { + return !sConditionMgr->IsObjectMeetToConditions(target, *conditions); + }), targetList.end()); + } + } + HandleUnitEnterExit(targetList); } |