diff options
author | Meji <alvaro.megias@outlook.com> | 2024-07-19 14:44:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-19 14:44:26 +0200 |
commit | 1426f58ff007eac2d9719b41f9189d82b733789e (patch) | |
tree | 62616bd2ae6e0c312cc1a403dd515ab4b78c1569 /src/server | |
parent | 53f0f2e5da3e7e6a9e6fa926e2f51ac8b506caa9 (diff) |
Core/AreaTriggers: Added ActionSet flags for serverside areatriggers (#30072)
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.cpp | 14 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 16 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 58 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h | 2 | ||||
-rw-r--r-- | src/server/game/Globals/AreaTriggerDataStore.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Grids/Notifiers/GridNotifiers.h | 12 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 8 |
9 files changed, 97 insertions, 23 deletions
diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index e7abc6bc837..2ddfd332b7c 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -679,6 +679,8 @@ void CriteriaHandler::UpdateCriteria(CriteriaType type, uint64 miscValue1 /*= 0* case CriteriaType::GotHaircut: case CriteriaType::EquipItemInSlot: case CriteriaType::EquipItem: + case CriteriaType::EnterAreaTriggerWithActionSet: + case CriteriaType::LeaveAreaTriggerWithActionSet: case CriteriaType::LearnedNewPet: case CriteriaType::EnterArea: case CriteriaType::LeaveArea: @@ -835,7 +837,6 @@ void CriteriaHandler::UpdateCriteria(CriteriaType type, uint64 miscValue1 /*= 0* case CriteriaType::KickTargetInLFGDungeon: case CriteriaType::AbandonedLFGDungeon: case CriteriaType::GroupedTankLeftEarlyInLFGDungeon: - case CriteriaType::EnterAreaTriggerWithActionSet: case CriteriaType::StartGarrisonMission: case CriteriaType::QualityUpgradedForGarrisonFollower: case CriteriaType::CompleteResearchGarrisonTalent: @@ -1235,12 +1236,14 @@ bool CriteriaHandler::IsCompletedCriteria(Criteria const* criteria, uint64 requi case CriteriaType::GotHaircut: case CriteriaType::EquipItemInSlot: case CriteriaType::EquipItem: + case CriteriaType::EnterAreaTriggerWithActionSet: + case CriteriaType::LeaveAreaTriggerWithActionSet: case CriteriaType::LearnedNewPet: - case CriteriaType::HonorLevelIncrease: - case CriteriaType::PrestigeLevelIncrease: case CriteriaType::EnterArea: case CriteriaType::LeaveArea: case CriteriaType::RecruitGarrisonFollower: + case CriteriaType::HonorLevelIncrease: + case CriteriaType::PrestigeLevelIncrease: case CriteriaType::ActivelyReachLevel: case CriteriaType::CollectTransmogSetFromGroup: case CriteriaType::EnterTopLevelArea: @@ -1667,6 +1670,11 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis if (miscValue1 != uint32(criteria->Entry->Asset.ScenarioID)) return false; break; + case CriteriaType::EnterAreaTriggerWithActionSet: + case CriteriaType::LeaveAreaTriggerWithActionSet: + if (!miscValue1 || miscValue1 != uint32(criteria->Entry->Asset.AreaTriggerActionSetID)) + return false; + break; default: break; } diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index ee36e011ff2..e1edf02d3c3 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -181,19 +181,19 @@ enum class AreaTriggerActionSetFlag : uint32 { None = 0x0000, OnlyTriggeredByCaster = 0x0001, - ResurrectIfConditionFails = 0x0002, + ResurrectIfConditionFails = 0x0002, /*NYI*/ Obsolete = 0x0004, AllowWhileGhost = 0x0008, AllowWhileDead = 0x0010, - UnifyAllInstances = 0x0020, + UnifyAllInstances = 0x0020, /*NYI*/ SuppressConditionError = 0x0040, // NYI NotTriggeredbyCaster = 0x0080, CreatorsPartyOnly = 0x0100, - DontRunOnLeaveWhenExpiring = 0x0200, + DontRunOnLeaveWhenExpiring = 0x0200, /*NYI*/ CanAffectUninteractible = 0x0400, - DontDespawnWithCreator = 0x0800, - CanAffectBeastmaster = 0x1000, - RequiresLineOfSight = 0x2000 + DontDespawnWithCreator = 0x0800, /*NYI*/ + CanAffectBeastmaster = 0x1000, // Can affect GMs + RequiresLineOfSight = 0x2000 /*NYI*/ }; DEFINE_ENUM_FLAG(AreaTriggerActionSetFlag); @@ -688,8 +688,8 @@ enum class CriteriaType : int16 GroupedTankLeftEarlyInLFRDungeon = 150, /*NYI*/ // Grouped tank left early in an LFR dungeon CompleteAnyScenario = 151, // Complete a Scenario CompleteScenario = 152, // Complete scenario "{Scenario}" - EnterAreaTriggerWithActionSet = 153, /*NYI*/ // Enter area trigger "{AreaTriggerActionSet}" - LeaveAreaTriggerWithActionSet = 154, /*NYI*/ // Leave area trigger "{AreaTriggerActionSet}" + EnterAreaTriggerWithActionSet = 153, // Enter area trigger "{AreaTriggerActionSet}" + LeaveAreaTriggerWithActionSet = 154, // Leave area trigger "{AreaTriggerActionSet}" LearnedNewPet = 155, // (Account Only) Learned a new pet UniquePetsOwned = 156, // (Account Only) Unique pets owned AccountObtainPetThroughBattle = 157, /*NYI*/ // (Account Only) Obtain a pet through battle diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 85fbcc8f27a..ced2a3d813c 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -626,13 +626,55 @@ void AreaTrigger::UpdateTargetList() if (GetTemplate()) { - if (ConditionContainer const* conditions = sConditionMgr->GetConditionsForAreaTrigger(GetTemplate()->Id.Id, GetTemplate()->Id.IsCustom)) + ConditionContainer const* conditions = sConditionMgr->GetConditionsForAreaTrigger(GetTemplate()->Id.Id, GetTemplate()->Id.IsCustom); + Trinity::Containers::EraseIf(targetList, [this, conditions](Unit const* target) { - Trinity::Containers::EraseIf(targetList, [conditions](Unit const* target) + if (GetCasterGuid() == target->GetGUID()) { + if (HasActionSetFlag(AreaTriggerActionSetFlag::NotTriggeredbyCaster)) + return true; + } + else + { + if (HasActionSetFlag(AreaTriggerActionSetFlag::OnlyTriggeredByCaster)) + return true; + + if (HasActionSetFlag(AreaTriggerActionSetFlag::CreatorsPartyOnly)) + { + Unit* caster = GetCaster(); + if (!caster) + return true; + + if (!caster->IsInRaidWith(target)) + return true; + } + } + + if (Player const* player = target->ToPlayer()) + { + switch (player->getDeathState()) + { + case DEAD: + if (!HasActionSetFlag(AreaTriggerActionSetFlag::AllowWhileGhost)) + return true; + break; + case CORPSE: + if (!HasActionSetFlag(AreaTriggerActionSetFlag::AllowWhileDead)) + return true; + break; + default: + break; + } + } + + if (!HasActionSetFlag(AreaTriggerActionSetFlag::CanAffectUninteractible) && target->IsUninteractible()) + return true; + + if (conditions) return !sConditionMgr->IsObjectMeetToConditions(target, *conditions); - }); - } + + return false; + }); } HandleUnitEnterExit(targetList); @@ -640,7 +682,7 @@ void AreaTrigger::UpdateTargetList() void AreaTrigger::SearchUnits(std::vector<Unit*>& targetList, float radius, bool check3D) { - Trinity::AnyUnitInObjectRangeCheck check(this, radius, check3D); + Trinity::AnyUnitInObjectRangeCheck check(this, radius, check3D, false); if (IsStaticSpawn()) { Trinity::PlayerListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check); @@ -803,6 +845,9 @@ void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList) ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTITY_ENTERED, GetEntry(), IsCustom(), IsStaticSpawn(), _spawnId); player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_AREA_TRIGGER_ENTER, GetEntry(), 1); + + if (GetTemplate()->ActionSetId) + player->UpdateCriteria(CriteriaType::EnterAreaTriggerWithActionSet, GetTemplate()->ActionSetId); } DoActions(unit); @@ -820,6 +865,9 @@ void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList) ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTITY_LEFT, GetEntry(), IsCustom(), IsStaticSpawn(), _spawnId); player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_AREA_TRIGGER_EXIT, GetEntry(), 1); + + if (GetTemplate()->ActionSetId) + player->UpdateCriteria(CriteriaType::LeaveAreaTriggerWithActionSet, GetTemplate()->ActionSetId); } UndoActions(leavingUnit); diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 7d454298108..8e58d86a7d0 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -76,6 +76,7 @@ class TC_GAME_API AreaTrigger final : public WorldObject, public GridObject<Area bool IsCustom() const { return _areaTriggerTemplate->Id.IsCustom; } bool IsServerSide() const { return _areaTriggerTemplate->Flags.HasFlag(AreaTriggerFlag::IsServerSide); } bool IsStaticSpawn() const { return _spawnId != 0; } + bool HasActionSetFlag(AreaTriggerActionSetFlag flag) const { return _areaTriggerTemplate->ActionSetFlags.HasFlag(flag); } bool IsNeverVisibleFor(WorldObject const* seer, bool allowServersideObjects = false) const override; diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp index 769a3a4033c..c4c9502c979 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp @@ -73,9 +73,10 @@ float AreaTriggerShapeInfo::GetMaxSearchRadius() const return 0.0f; } -AreaTriggerTemplate::AreaTriggerTemplate() : Flags(AreaTriggerFlag::None) +AreaTriggerTemplate::AreaTriggerTemplate() : Flags(AreaTriggerFlag::None), ActionSetFlags(AreaTriggerActionSetFlag::None) { Id = { 0, false }; + ActionSetId = 0; } AreaTriggerTemplate::~AreaTriggerTemplate() = default; diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h index 549baf41496..d72cfe3dda3 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h @@ -209,6 +209,8 @@ public: AreaTriggerId Id; EnumFlag<AreaTriggerFlag> Flags; + uint32 ActionSetId; + EnumFlag<AreaTriggerActionSetFlag> ActionSetFlags; std::vector<AreaTriggerAction> Actions; }; diff --git a/src/server/game/Globals/AreaTriggerDataStore.cpp b/src/server/game/Globals/AreaTriggerDataStore.cpp index 133b0b1724c..23da22989b3 100644 --- a/src/server/game/Globals/AreaTriggerDataStore.cpp +++ b/src/server/game/Globals/AreaTriggerDataStore.cpp @@ -147,8 +147,8 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger splines. DB table `areatrigger_create_properties_spline_point` is empty."); } - // 0 1 2 - if (QueryResult templates = WorldDatabase.Query("SELECT Id, IsCustom, Flags FROM `areatrigger_template`")) + // 0 1 2 3 4 + if (QueryResult templates = WorldDatabase.Query("SELECT Id, IsCustom, Flags, ActionSetId, ActionSetFlags FROM `areatrigger_template`")) { do { @@ -158,6 +158,8 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() areaTriggerTemplate.Id.Id = fields[0].GetUInt32(); areaTriggerTemplate.Id.IsCustom = fields[1].GetBool(); areaTriggerTemplate.Flags = AreaTriggerFlag(fields[2].GetUInt32()); + areaTriggerTemplate.ActionSetId = fields[3].GetUInt32(); + areaTriggerTemplate.ActionSetFlags = AreaTriggerActionSetFlag(fields[4].GetUInt32()); areaTriggerTemplate.Actions = std::move(actionsByAreaTrigger[areaTriggerTemplate.Id]); _areaTriggerTemplateStore[areaTriggerTemplate.Id] = areaTriggerTemplate; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 1e9f7801af6..ad3f9888c02 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1075,20 +1075,24 @@ namespace Trinity class AnyUnitInObjectRangeCheck { public: - AnyUnitInObjectRangeCheck(WorldObject const* obj, float range, bool check3D = true) : i_obj(obj), i_range(range), i_check3D(check3D) { } + AnyUnitInObjectRangeCheck(WorldObject const* obj, float range, bool check3D = true, bool reqAlive = true) : i_obj(obj), i_range(range), i_check3D(check3D), i_reqAlive(reqAlive) { } bool operator()(Unit* u) const { - if (u->IsAlive() && i_obj->IsWithinDist(u, i_range, i_check3D)) - return true; + if (i_reqAlive && !u->IsAlive()) + return false; - return false; + if (!i_obj->IsWithinDist(u, i_range, i_check3D)) + return false; + + return true; } private: WorldObject const* i_obj; float i_range; bool i_check3D; + bool i_reqAlive; }; // Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit) diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 7e6512fab8c..3cf1d49221a 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -509,6 +509,14 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge if (sScriptMgr->OnAreaTrigger(player, atEntry, packet.Entered)) return; + if (atEntry->AreaTriggerActionSetID) + { + if (packet.Entered) + player->UpdateCriteria(CriteriaType::EnterAreaTriggerWithActionSet, atEntry->AreaTriggerActionSetID); + else + player->UpdateCriteria(CriteriaType::LeaveAreaTriggerWithActionSet, atEntry->AreaTriggerActionSetID); + } + if (player->IsAlive() && packet.Entered) { // not using Player::UpdateQuestObjectiveProgress, ObjectID in quest_objectives can be set to -1, areatrigger_involvedrelation then holds correct id |