aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2024_07_19_00_world.sql9
-rw-r--r--src/server/game/Achievements/CriteriaHandler.cpp14
-rw-r--r--src/server/game/DataStores/DBCEnums.h16
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp58
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.h1
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp3
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h2
-rw-r--r--src/server/game/Globals/AreaTriggerDataStore.cpp6
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h12
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp8
10 files changed, 106 insertions, 23 deletions
diff --git a/sql/updates/world/master/2024_07_19_00_world.sql b/sql/updates/world/master/2024_07_19_00_world.sql
new file mode 100644
index 00000000000..5c637411122
--- /dev/null
+++ b/sql/updates/world/master/2024_07_19_00_world.sql
@@ -0,0 +1,9 @@
+ALTER TABLE `areatrigger_template`
+ ADD `ActionSetId` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `Flags`,
+ ADD `ActionSetFlags` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `ActionSetId`;
+
+UPDATE `areatrigger_template` SET `ActionSetFlags`=8 WHERE `Id`=48 AND `IsCustom`=1;
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=28 AND `SourceGroup`=48 AND `SourceEntry`=1;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(28,48,1,0,0,36,0,0,0,0,'',1,0,0,'','Only trigger areatrigger when player is dead');
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