Core/AreaTriggers: Added ActionSet flags for serverside areatriggers
Port From (https://github.com/TrinityCore/TrinityCore/commit/1426f58ff007eac2d9719b41f9189d82b733789e)
This commit is contained in:
@@ -661,8 +661,8 @@ namespace Framework.Constants
|
|||||||
GroupedTankLeftEarlyInLFRDungeon = 150, /*NYI*/ // Grouped tank left early in an LFR dungeon
|
GroupedTankLeftEarlyInLFRDungeon = 150, /*NYI*/ // Grouped tank left early in an LFR dungeon
|
||||||
CompleteAnyScenario = 151, // Complete a Scenario
|
CompleteAnyScenario = 151, // Complete a Scenario
|
||||||
CompleteScenario = 152, // Complete scenario "{Scenario}"
|
CompleteScenario = 152, // Complete scenario "{Scenario}"
|
||||||
EnterAreaTriggerWithActionSet = 153, /*NYI*/ // Enter area trigger "{AreaTriggerActionSet}"
|
EnterAreaTriggerWithActionSet = 153, // Enter area trigger "{AreaTriggerActionSet}"
|
||||||
LeaveAreaTriggerWithActionSet = 154, /*NYI*/ // Leave area trigger "{AreaTriggerActionSet}"
|
LeaveAreaTriggerWithActionSet = 154, // Leave area trigger "{AreaTriggerActionSet}"
|
||||||
LearnedNewPet = 155, // (Account Only) Learned a new pet
|
LearnedNewPet = 155, // (Account Only) Learned a new pet
|
||||||
UniquePetsOwned = 156, // (Account Only) Unique pets owned
|
UniquePetsOwned = 156, // (Account Only) Unique pets owned
|
||||||
AccountObtainPetThroughBattle = 157, /*NYI*/ // (Account Only) Obtain a pet through battle
|
AccountObtainPetThroughBattle = 157, /*NYI*/ // (Account Only) Obtain a pet through battle
|
||||||
|
|||||||
@@ -957,19 +957,19 @@ namespace Framework.Constants
|
|||||||
{
|
{
|
||||||
None = 0x00,
|
None = 0x00,
|
||||||
OnlyTriggeredByCaster = 0x01,
|
OnlyTriggeredByCaster = 0x01,
|
||||||
ResurrectIfConditionFails = 0x02,
|
ResurrectIfConditionFails = 0x02, // NYI
|
||||||
Obsolete = 0x04,
|
Obsolete = 0x04,
|
||||||
AllowWhileGhost = 0x08,
|
AllowWhileGhost = 0x08,
|
||||||
AllowWhileDead = 0x10,
|
AllowWhileDead = 0x10,
|
||||||
UnifyAllInstances = 0x20,
|
UnifyAllInstances = 0x20, // NYI
|
||||||
SuppressConditionError = 0x40, // NYI
|
SuppressConditionError = 0x40, // NYI
|
||||||
NotTriggeredbyCaster = 0x80,
|
NotTriggeredbyCaster = 0x80,
|
||||||
CreatorsPartyOnly = 0x100,
|
CreatorsPartyOnly = 0x100,
|
||||||
DontRunOnLeaveWhenExpiring = 0x200,
|
DontRunOnLeaveWhenExpiring = 0x200, // NYI
|
||||||
CanAffectUninteractible = 0x400,
|
CanAffectUninteractible = 0x400,
|
||||||
DontDespawnWithCreator = 0x800,
|
DontDespawnWithCreator = 0x800, // NYI
|
||||||
CanAffectBeastmaster = 0x1000,
|
CanAffectBeastmaster = 0x1000, // Can affect GMs
|
||||||
RequiresLineOfSight = 0x2000
|
RequiresLineOfSight = 0x2000 // NYI
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AreaTriggerShapeType
|
public enum AreaTriggerShapeType
|
||||||
|
|||||||
@@ -262,6 +262,8 @@ namespace Game.Achievements
|
|||||||
case CriteriaType.GotHaircut:
|
case CriteriaType.GotHaircut:
|
||||||
case CriteriaType.EquipItemInSlot:
|
case CriteriaType.EquipItemInSlot:
|
||||||
case CriteriaType.EquipItem:
|
case CriteriaType.EquipItem:
|
||||||
|
case CriteriaType.EnterAreaTriggerWithActionSet:
|
||||||
|
case CriteriaType.LeaveAreaTriggerWithActionSet:
|
||||||
case CriteriaType.LearnedNewPet:
|
case CriteriaType.LearnedNewPet:
|
||||||
case CriteriaType.EnterArea:
|
case CriteriaType.EnterArea:
|
||||||
case CriteriaType.LeaveArea:
|
case CriteriaType.LeaveArea:
|
||||||
@@ -420,7 +422,6 @@ namespace Game.Achievements
|
|||||||
case CriteriaType.KickTargetInLFGDungeon:
|
case CriteriaType.KickTargetInLFGDungeon:
|
||||||
case CriteriaType.AbandonedLFGDungeon:
|
case CriteriaType.AbandonedLFGDungeon:
|
||||||
case CriteriaType.GroupedTankLeftEarlyInLFGDungeon:
|
case CriteriaType.GroupedTankLeftEarlyInLFGDungeon:
|
||||||
case CriteriaType.EnterAreaTriggerWithActionSet:
|
|
||||||
case CriteriaType.StartGarrisonMission:
|
case CriteriaType.StartGarrisonMission:
|
||||||
case CriteriaType.QualityUpgradedForGarrisonFollower:
|
case CriteriaType.QualityUpgradedForGarrisonFollower:
|
||||||
case CriteriaType.CompleteResearchGarrisonTalent:
|
case CriteriaType.CompleteResearchGarrisonTalent:
|
||||||
@@ -820,12 +821,14 @@ namespace Game.Achievements
|
|||||||
case CriteriaType.GotHaircut:
|
case CriteriaType.GotHaircut:
|
||||||
case CriteriaType.EquipItemInSlot:
|
case CriteriaType.EquipItemInSlot:
|
||||||
case CriteriaType.EquipItem:
|
case CriteriaType.EquipItem:
|
||||||
|
case CriteriaType.EnterAreaTriggerWithActionSet:
|
||||||
|
case CriteriaType.LeaveAreaTriggerWithActionSet:
|
||||||
case CriteriaType.LearnedNewPet:
|
case CriteriaType.LearnedNewPet:
|
||||||
case CriteriaType.HonorLevelIncrease:
|
|
||||||
case CriteriaType.PrestigeLevelIncrease:
|
|
||||||
case CriteriaType.EnterArea:
|
case CriteriaType.EnterArea:
|
||||||
case CriteriaType.LeaveArea:
|
case CriteriaType.LeaveArea:
|
||||||
case CriteriaType.RecruitGarrisonFollower:
|
case CriteriaType.RecruitGarrisonFollower:
|
||||||
|
case CriteriaType.HonorLevelIncrease:
|
||||||
|
case CriteriaType.PrestigeLevelIncrease:
|
||||||
case CriteriaType.ActivelyReachLevel:
|
case CriteriaType.ActivelyReachLevel:
|
||||||
case CriteriaType.CollectTransmogSetFromGroup:
|
case CriteriaType.CollectTransmogSetFromGroup:
|
||||||
case CriteriaType.EnterTopLevelArea:
|
case CriteriaType.EnterTopLevelArea:
|
||||||
@@ -1219,6 +1222,11 @@ namespace Game.Achievements
|
|||||||
if (miscValue1 != criteria.Entry.Asset)
|
if (miscValue1 != criteria.Entry.Asset)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case CriteriaType.EnterAreaTriggerWithActionSet:
|
||||||
|
case CriteriaType.LeaveAreaTriggerWithActionSet:
|
||||||
|
if (miscValue1 == 0 || miscValue1 != criteria.Entry.Asset)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ namespace Game.DataStorage
|
|||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 AreaTrigger splines. DB table `areatrigger_create_properties_spline_point` is empty.");
|
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 AreaTrigger splines. DB table `areatrigger_create_properties_spline_point` is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 1 2
|
// 0 1 2 3 4
|
||||||
SQLResult templates = DB.World.Query("SELECT Id, IsCustom, Flags FROM `areatrigger_template`");
|
SQLResult templates = DB.World.Query("SELECT Id, IsCustom, Flags, ActionSetId, ActionSetFlags FROM `areatrigger_template`");
|
||||||
if (!templates.IsEmpty())
|
if (!templates.IsEmpty())
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
@@ -113,6 +113,8 @@ namespace Game.DataStorage
|
|||||||
AreaTriggerTemplate areaTriggerTemplate = new();
|
AreaTriggerTemplate areaTriggerTemplate = new();
|
||||||
areaTriggerTemplate.Id = new(templates.Read<uint>(0), templates.Read<bool>(1));
|
areaTriggerTemplate.Id = new(templates.Read<uint>(0), templates.Read<bool>(1));
|
||||||
areaTriggerTemplate.Flags = (AreaTriggerFlag)templates.Read<uint>(2);
|
areaTriggerTemplate.Flags = (AreaTriggerFlag)templates.Read<uint>(2);
|
||||||
|
areaTriggerTemplate.ActionSetId = templates.Read<uint>(3);
|
||||||
|
areaTriggerTemplate.ActionSetFlags = (AreaTriggerActionSetFlag)templates.Read<uint>(4);
|
||||||
areaTriggerTemplate.Actions = actionsByAreaTrigger[areaTriggerTemplate.Id];
|
areaTriggerTemplate.Actions = actionsByAreaTrigger[areaTriggerTemplate.Id];
|
||||||
|
|
||||||
_areaTriggerTemplateStore[areaTriggerTemplate.Id] = areaTriggerTemplate;
|
_areaTriggerTemplateStore[areaTriggerTemplate.Id] = areaTriggerTemplate;
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ namespace Game.DataStorage
|
|||||||
public float BoxYaw;
|
public float BoxYaw;
|
||||||
public sbyte ShapeType;
|
public sbyte ShapeType;
|
||||||
public short ShapeID;
|
public short ShapeID;
|
||||||
public int AreaTriggerActionSetID;
|
public uint AreaTriggerActionSetID;
|
||||||
public sbyte Flags;
|
public sbyte Flags;
|
||||||
|
|
||||||
public AreaTriggerShapeType GetShapeType() { return (AreaTriggerShapeType)ShapeType; }
|
public AreaTriggerShapeType GetShapeType() { return (AreaTriggerShapeType)ShapeType; }
|
||||||
|
|||||||
@@ -606,8 +606,55 @@ namespace Game.Entities
|
|||||||
if (GetTemplate() != null)
|
if (GetTemplate() != null)
|
||||||
{
|
{
|
||||||
var conditions = Global.ConditionMgr.GetConditionsForAreaTrigger(GetTemplate().Id.Id, GetTemplate().Id.IsCustom);
|
var conditions = Global.ConditionMgr.GetConditionsForAreaTrigger(GetTemplate().Id.Id, GetTemplate().Id.IsCustom);
|
||||||
if (conditions != null && !conditions.Empty())
|
targetList.RemoveAll(target =>
|
||||||
targetList.RemoveAll(target => !Global.ConditionMgr.IsObjectMeetToConditions(target, conditions));
|
{
|
||||||
|
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 == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!caster.IsInRaidWith(target))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = target.ToPlayer();
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
switch (player.GetDeathState())
|
||||||
|
{
|
||||||
|
case DeathState.Dead:
|
||||||
|
if (!HasActionSetFlag(AreaTriggerActionSetFlag.AllowWhileGhost))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case DeathState.Corpse:
|
||||||
|
if (!HasActionSetFlag(AreaTriggerActionSetFlag.AllowWhileDead))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HasActionSetFlag(AreaTriggerActionSetFlag.CanAffectUninteractible) && target.IsUninteractible())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (conditions != null)
|
||||||
|
return !Global.ConditionMgr.IsObjectMeetToConditions(target, conditions);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleUnitEnterExit(targetList);
|
HandleUnitEnterExit(targetList);
|
||||||
@@ -615,7 +662,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
void SearchUnits(List<Unit> targetList, float radius, bool check3D)
|
void SearchUnits(List<Unit> targetList, float radius, bool check3D)
|
||||||
{
|
{
|
||||||
var check = new AnyUnitInObjectRangeCheck(this, radius, check3D);
|
var check = new AnyUnitInObjectRangeCheck(this, radius, check3D, false);
|
||||||
if (IsStaticSpawn())
|
if (IsStaticSpawn())
|
||||||
{
|
{
|
||||||
List<Player> temp = new List<Player>();
|
List<Player> temp = new List<Player>();
|
||||||
@@ -770,6 +817,9 @@ namespace Game.Entities
|
|||||||
player.SendSysMessage(CypherStrings.DebugAreatriggerEntityEntered, GetEntry(), IsCustom(), IsStaticSpawn(), _spawnId);
|
player.SendSysMessage(CypherStrings.DebugAreatriggerEntityEntered, GetEntry(), IsCustom(), IsStaticSpawn(), _spawnId);
|
||||||
|
|
||||||
player.UpdateQuestObjectiveProgress(QuestObjectiveType.AreaTriggerEnter, (int)GetEntry(), 1);
|
player.UpdateQuestObjectiveProgress(QuestObjectiveType.AreaTriggerEnter, (int)GetEntry(), 1);
|
||||||
|
|
||||||
|
if (GetTemplate().ActionSetId != 0)
|
||||||
|
player.UpdateCriteria(CriteriaType.EnterAreaTriggerWithActionSet, GetTemplate().ActionSetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
DoActions(unit);
|
DoActions(unit);
|
||||||
@@ -789,6 +839,9 @@ namespace Game.Entities
|
|||||||
player.SendSysMessage(CypherStrings.DebugAreatriggerEntityLeft, GetEntry(), IsCustom(), IsStaticSpawn(), _spawnId);
|
player.SendSysMessage(CypherStrings.DebugAreatriggerEntityLeft, GetEntry(), IsCustom(), IsStaticSpawn(), _spawnId);
|
||||||
|
|
||||||
player.UpdateQuestObjectiveProgress(QuestObjectiveType.AreaTriggerExit, (int)GetEntry(), 1);
|
player.UpdateQuestObjectiveProgress(QuestObjectiveType.AreaTriggerExit, (int)GetEntry(), 1);
|
||||||
|
|
||||||
|
if (GetTemplate().ActionSetId != 0)
|
||||||
|
player.UpdateCriteria(CriteriaType.LeaveAreaTriggerWithActionSet, GetTemplate().ActionSetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
UndoActions(leavingUnit);
|
UndoActions(leavingUnit);
|
||||||
@@ -1344,6 +1397,7 @@ namespace Game.Entities
|
|||||||
public bool IsCustom() { return _areaTriggerTemplate.Id.IsCustom; }
|
public bool IsCustom() { return _areaTriggerTemplate.Id.IsCustom; }
|
||||||
public bool IsServerSide() { return _areaTriggerTemplate.Flags.HasFlag(AreaTriggerFlag.IsServerSide); }
|
public bool IsServerSide() { return _areaTriggerTemplate.Flags.HasFlag(AreaTriggerFlag.IsServerSide); }
|
||||||
public bool IsStaticSpawn() { return _spawnId != 0; }
|
public bool IsStaticSpawn() { return _spawnId != 0; }
|
||||||
|
public bool HasActionSetFlag(AreaTriggerActionSetFlag flag) { return _areaTriggerTemplate.ActionSetFlags.HasFlag(flag); }
|
||||||
|
|
||||||
[System.Diagnostics.Conditional("DEBUG")]
|
[System.Diagnostics.Conditional("DEBUG")]
|
||||||
void DebugVisualizePosition()
|
void DebugVisualizePosition()
|
||||||
|
|||||||
@@ -243,6 +243,8 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
public AreaTriggerId Id;
|
public AreaTriggerId Id;
|
||||||
public AreaTriggerFlag Flags;
|
public AreaTriggerFlag Flags;
|
||||||
|
public uint ActionSetId;
|
||||||
|
public AreaTriggerActionSetFlag ActionSetFlags;
|
||||||
public List<AreaTriggerAction> Actions = new();
|
public List<AreaTriggerAction> Actions = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -187,6 +187,14 @@ namespace Game
|
|||||||
if (Global.ScriptMgr.OnAreaTrigger(player, atEntry, packet.Entered))
|
if (Global.ScriptMgr.OnAreaTrigger(player, atEntry, packet.Entered))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (atEntry.AreaTriggerActionSetID != 0)
|
||||||
|
{
|
||||||
|
if (packet.Entered)
|
||||||
|
player.UpdateCriteria(CriteriaType.EnterAreaTriggerWithActionSet, atEntry.AreaTriggerActionSetID);
|
||||||
|
else
|
||||||
|
player.UpdateCriteria(CriteriaType.LeaveAreaTriggerWithActionSet, atEntry.AreaTriggerActionSetID);
|
||||||
|
}
|
||||||
|
|
||||||
if (player.IsAlive() && packet.Entered)
|
if (player.IsAlive() && packet.Entered)
|
||||||
{
|
{
|
||||||
// not using Player.UpdateQuestObjectiveProgress, ObjectID in quest_objectives can be set to -1, areatrigger_involvedrelation then holds correct id
|
// not using Player.UpdateQuestObjectiveProgress, ObjectID in quest_objectives can be set to -1, areatrigger_involvedrelation then holds correct id
|
||||||
|
|||||||
@@ -2130,17 +2130,21 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public class AnyUnitInObjectRangeCheck : ICheck<Unit>
|
public class AnyUnitInObjectRangeCheck : ICheck<Unit>
|
||||||
{
|
{
|
||||||
public AnyUnitInObjectRangeCheck(WorldObject obj, float range, bool check3D = true)
|
public AnyUnitInObjectRangeCheck(WorldObject obj, float range, bool check3D = true, bool reqAlive = true)
|
||||||
{
|
{
|
||||||
i_obj = obj;
|
i_obj = obj;
|
||||||
i_range = range;
|
i_range = range;
|
||||||
i_check3D = check3D;
|
i_check3D = check3D;
|
||||||
|
i_reqAlive = reqAlive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Invoke(Unit u)
|
public bool Invoke(Unit u)
|
||||||
{
|
{
|
||||||
if (u.IsAlive() && i_obj.IsWithinDist(u, i_range, i_check3D))
|
if (i_reqAlive && !u.IsAlive())
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
|
if (!i_obj.IsWithinDist(u, i_range, i_check3D))
|
||||||
|
return false;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2148,6 +2152,7 @@ namespace Game.Maps
|
|||||||
WorldObject i_obj;
|
WorldObject i_obj;
|
||||||
float i_range;
|
float i_range;
|
||||||
bool i_check3D;
|
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)
|
// Success at unit in range, range update for next check (this can be use with UnitLastSearcher to find nearest unit)
|
||||||
@@ -2543,7 +2548,7 @@ namespace Game.Maps
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AnyPlayerInObjectRangeCheck : ICheck<Player>
|
public class AnyPlayerInObjectRangeCheck : ICheck<Player>
|
||||||
{
|
{
|
||||||
public AnyPlayerInObjectRangeCheck(WorldObject obj, float range, bool reqAlive = true)
|
public AnyPlayerInObjectRangeCheck(WorldObject obj, float range, bool reqAlive = true)
|
||||||
@@ -3035,7 +3040,7 @@ namespace Game.Maps
|
|||||||
i_range = i_obj.GetDistance(obj);
|
i_range = i_obj.GetDistance(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AnyDeadUnitObjectInRangeCheck<T> : ICheck<T> where T : WorldObject
|
public class AnyDeadUnitObjectInRangeCheck<T> : ICheck<T> where T : WorldObject
|
||||||
{
|
{
|
||||||
public AnyDeadUnitObjectInRangeCheck(WorldObject searchObj, float range)
|
public AnyDeadUnitObjectInRangeCheck(WorldObject searchObj, float range)
|
||||||
|
|||||||
Reference in New Issue
Block a user