Core/Scripts: Integrate new ActionResultSetter with movement generators and spells

Port From (https://github.com/TrinityCore/TrinityCore/commit/b265c49977235dea5e7e69d7b6fb93f4943bf87a)
This commit is contained in:
Hondacrx
2024-08-05 14:12:00 -04:00
parent 22fbfd8360
commit 708df58712
13 changed files with 170 additions and 58 deletions
@@ -2497,6 +2497,8 @@ namespace Game.Entities
}
spell.m_customArg = args.CustomArg;
spell.m_scriptResult = args.ScriptResult;
spell.m_scriptWaitsForSpellHit = args.ScriptWaitsForSpellHit;
return spell.Prepare(targets.Targets, args.TriggeringAura);
}
+8 -7
View File
@@ -26,6 +26,7 @@ using Game.Spells;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Global;
namespace Game.Entities
@@ -6920,7 +6921,7 @@ namespace Game.Entities
public uint GetDeathTimer() { return m_deathTimer; }
public bool ActivateTaxiPathTo(List<uint> nodes, Creature npc = null, uint spellid = 0, uint preferredMountDisplay = 0, float? speed = null)
public bool ActivateTaxiPathTo(List<uint> nodes, Creature npc = null, uint spellid = 0, uint preferredMountDisplay = 0, float? speed = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
if (nodes.Count < 2)
{
@@ -7097,18 +7098,18 @@ namespace Game.Entities
ModifyMoney(-firstcost);
UpdateCriteria(CriteriaType.MoneySpentOnTaxis, firstcost);
GetSession().SendActivateTaxiReply();
StartTaxiMovement(mount_display_id, sourcepath, 0, speed);
StartTaxiMovement(mount_display_id, sourcepath, 0, speed, scriptResult);
}
return true;
}
public bool ActivateTaxiPathTo(uint taxi_path_id, uint spellid = 0, float? speed = null)
public bool ActivateTaxiPathTo(uint taxi_path_id, uint spellid = 0, float? speed = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
var entry = CliDB.TaxiPathStorage.LookupByKey(taxi_path_id);
if (entry == null)
return false;
return ActivateTaxiPathTo([entry.FromTaxiNode, entry.ToTaxiNode], null, spellid, 0, speed);
return ActivateTaxiPathTo([entry.FromTaxiNode, entry.ToTaxiNode], null, spellid, 0, speed, scriptResult);
}
public void FinishTaxiFlight()
@@ -7174,10 +7175,10 @@ namespace Game.Entities
}
}
StartTaxiMovement(mountDisplayId, path, startNode, null);
StartTaxiMovement(mountDisplayId, path, startNode, null, null);
}
void StartTaxiMovement(uint mountDisplayId, uint path, uint pathNode, float? speed)
void StartTaxiMovement(uint mountDisplayId, uint path, uint pathNode, float? speed, TaskCompletionSource<MovementStopReason> scriptResult)
{
// remove fake death
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Interacting);
@@ -7185,7 +7186,7 @@ namespace Game.Entities
if (mountDisplayId != 0)
Mount(mountDisplayId);
GetMotionMaster().MoveTaxiFlight(path, pathNode, speed);
GetMotionMaster().MoveTaxiFlight(path, pathNode, speed, scriptResult);
}
public bool GetsRecruitAFriendBonus(bool forXP)
@@ -5,6 +5,7 @@ using Framework.Constants;
using Game.AI;
using Game.Entities;
using System;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -13,15 +14,16 @@ namespace Game.Movement
public const float MIN_QUIET_DISTANCE = 28.0f;
public const float MAX_QUIET_DISTANCE = 43.0f;
public FleeingMovementGenerator(ObjectGuid fright)
public FleeingMovementGenerator(ObjectGuid fleeTargetGUID, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
_fleeTargetGUID = fright;
_fleeTargetGUID = fleeTargetGUID;
_timer = new TimeTracker();
Mode = MovementGeneratorMode.Default;
Priority = MovementGeneratorPriority.Highest;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.Fleeing;
ScriptResult = scriptResult;
}
public override void Initialize(Unit owner)
@@ -90,6 +92,9 @@ namespace Game.Movement
else if (owner.IsPlayer())
owner.StopMoving();
}
if (movementInform)
SetScriptResult(MovementStopReason.Finished);
}
void SetTargetLocation(Unit owner)
@@ -192,7 +197,7 @@ namespace Game.Movement
public class TimedFleeingMovementGenerator : FleeingMovementGenerator
{
public TimedFleeingMovementGenerator(ObjectGuid fright, TimeSpan time) : base(fright)
public TimedFleeingMovementGenerator(ObjectGuid fleeTargetGUID, TimeSpan time, TaskCompletionSource<MovementStopReason> scriptResult = null) : base(fleeTargetGUID, scriptResult)
{
_totalFleeTime = new TimeTracker(time);
}
@@ -228,6 +233,8 @@ namespace Game.Movement
if (movementInform)
{
SetScriptResult(MovementStopReason.Finished);
Creature ownerCreature = owner.ToCreature();
CreatureAI ai = ownerCreature != null ? ownerCreature.GetAI() : null;
if (ai != null)
@@ -9,6 +9,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -24,13 +25,14 @@ namespace Game.Movement
int _currentNode;
List<TaxiNodeChangeInfo> _pointsForPathSwitch = new(); //! node indexes and costs where TaxiPath changes
public FlightPathMovementGenerator(float? speed)
public FlightPathMovementGenerator(float? speed, TaskCompletionSource<MovementStopReason> scriptResult)
{
_speed = speed;
Mode = MovementGeneratorMode.Default;
Priority = MovementGeneratorPriority.Highest;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.InFlight;
ScriptResult = scriptResult;
}
public override void DoInitialize(Player owner)
@@ -157,6 +159,9 @@ namespace Game.Movement
}
owner.RemovePlayerFlag(PlayerFlags.TaxiBenchmark);
if (movementInform)
SetScriptResult(MovementStopReason.Finished);
}
uint GetPathAtMapEnd()
@@ -5,6 +5,7 @@ using Framework.Constants;
using Game.AI;
using Game.Entities;
using System;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -23,7 +24,7 @@ namespace Game.Movement
AbstractFollower _abstractFollower;
public FollowMovementGenerator(Unit target, float range, ChaseAngle angle, TimeSpan? duration)
public FollowMovementGenerator(Unit target, float range, ChaseAngle angle, TimeSpan? duration, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
_abstractFollower = new AbstractFollower(target);
_range = range;
@@ -33,6 +34,7 @@ namespace Game.Movement
Priority = MovementGeneratorPriority.Normal;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.Follow;
ScriptResult = scriptResult;
if (duration.HasValue)
_duration = new(duration.Value);
@@ -186,6 +188,8 @@ namespace Game.Movement
{
owner.ClearUnitState(UnitState.FollowMove);
UpdatePetSpeed(owner);
if (movementInform)
SetScriptResult(MovementStopReason.Finished);
}
}
@@ -4,6 +4,7 @@
using Framework.Constants;
using Game.Entities;
using System;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -38,6 +39,8 @@ namespace Game.Movement
_duration = new(args.Duration.Value);
_durationTracksSpline = false;
}
ScriptResult = args.ScriptResult;
}
public override void Initialize(Unit owner)
@@ -99,6 +102,8 @@ namespace Game.Movement
if (_arrivalSpellId != 0)
owner.CastSpell(Global.ObjAccessor.GetUnit(owner, _arrivalSpellTargetGuid), _arrivalSpellId, true);
SetScriptResult(MovementStopReason.Finished);
Creature creature = owner.ToCreature();
if (creature != null && creature.GetAI() != null)
creature.GetAI().MovementInform(_type, _pointId);
@@ -112,5 +117,6 @@ namespace Game.Movement
public uint? ArrivalSpellId;
public ObjectGuid? ArrivalSpellTarget;
public TimeSpan? Duration;
public TaskCompletionSource<MovementStopReason> ScriptResult;
}
}
@@ -4,6 +4,7 @@
using Framework.Constants;
using Game.Entities;
using System;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -56,7 +57,7 @@ namespace Game.Movement
float? _totalTurnAngle;
uint _diffSinceLastUpdate;
public RotateMovementGenerator(uint id, RotateDirection direction, TimeSpan? duration, float? turnSpeed, float? totalTurnAngle)
public RotateMovementGenerator(uint id, RotateDirection direction, TimeSpan? duration, float? turnSpeed, float? totalTurnAngle, TaskCompletionSource<MovementStopReason> scriptResult)
{
_id = id;
_direction = direction;
@@ -70,6 +71,7 @@ namespace Game.Movement
Priority = MovementGeneratorPriority.Normal;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.Rotating;
ScriptResult = scriptResult;
}
public override void Initialize(Unit owner)
@@ -142,8 +144,12 @@ namespace Game.Movement
{
AddFlag(MovementGeneratorFlags.Finalized);
if (movementInform && owner.IsCreature())
owner.ToCreature().GetAI().MovementInform(MovementGeneratorType.Rotate, _id);
if (movementInform)
{
SetScriptResult(MovementStopReason.Finished);
if (owner.IsCreature())
owner.ToCreature().GetAI().MovementInform(MovementGeneratorType.Rotate, _id);
}
}
public override MovementGeneratorType GetMovementGeneratorType() { return MovementGeneratorType.Rotate; }
@@ -5,6 +5,7 @@ using Framework.Constants;
using Game.AI;
using Game.Entities;
using System;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -14,6 +15,7 @@ namespace Game.Movement
public MovementGeneratorPriority Priority;
public MovementGeneratorFlags Flags;
public UnitState BaseUnitState;
public TaskCompletionSource<MovementStopReason> ScriptResult;
// on top first update
public virtual void Initialize(Unit owner) { }
@@ -68,8 +70,17 @@ namespace Game.Movement
{
return $"Mode: {Mode} Priority: {Priority} Flags: {Flags} BaseUniteState: {BaseUnitState}";
}
public void SetScriptResult(MovementStopReason reason)
{
if (ScriptResult != null)
{
ScriptResult.SetResult(reason);
ScriptResult = null;
}
}
}
public abstract class MovementGeneratorMedium<T> : MovementGenerator where T : Unit
{
public override void Initialize(Unit owner)
@@ -4,6 +4,7 @@
using Framework.Constants;
using Game.Entities;
using System;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -21,7 +22,7 @@ namespace Game.Movement
float? _closeEnoughDistance;
public PointMovementGenerator(uint id, float x, float y, float z, bool generatePath, float? speed = null, float? finalOrient = null, Unit faceTarget = null, SpellEffectExtraData spellEffectExtraData = null,
MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, float? closeEnoughDistance = null)
MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, float? closeEnoughDistance = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
_movementId = id;
_destination = new Position(x, y, z);
@@ -37,6 +38,7 @@ namespace Game.Movement
Priority = MovementGeneratorPriority.Normal;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.Roaming;
ScriptResult = scriptResult;
}
public override void Initialize(Unit owner)
@@ -192,6 +194,8 @@ namespace Game.Movement
public void MovementInform(Unit owner)
{
SetScriptResult(MovementStopReason.Finished);
// deliver EVENT_CHARGE to scripts, EVENT_CHARGE_PREPATH is just internal implementation detail of this movement generator
uint movementId = _movementId == EventId.ChargePrepath ? EventId.Charge : _movementId;
owner.ToCreature()?.GetAI()?.MovementInform(MovementGeneratorType.Point, movementId);
@@ -4,6 +4,7 @@
using Framework.Constants;
using Game.Entities;
using System;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -16,7 +17,7 @@ namespace Game.Movement
float _wanderDistance;
uint _wanderSteps;
public RandomMovementGenerator(float spawnDist = 0.0f, TimeSpan? duration = null)
public RandomMovementGenerator(float spawnDist = 0.0f, TimeSpan? duration = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
_timer = new TimeTracker();
_reference = new();
@@ -26,6 +27,8 @@ namespace Game.Movement
Priority = MovementGeneratorPriority.Normal;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.Roaming;
ScriptResult = scriptResult;
if (duration.HasValue)
_duration = new TimeTracker(duration.Value);
}
@@ -112,8 +115,11 @@ namespace Game.Movement
}
if (movementInform && HasFlag(MovementGeneratorFlags.InformEnabled))
{
SetScriptResult(MovementStopReason.Finished);
if (owner.IsAIEnabled())
owner.GetAI().MovementInform(MovementGeneratorType.Random, 0);
}
}
public override void Pause(uint timer)
@@ -7,6 +7,7 @@ using Game.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -30,8 +31,7 @@ namespace Game.Movement
bool _generatePath;
public WaypointMovementGenerator(uint pathId = 0, bool repeating = true, TimeSpan? duration = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default,
(TimeSpan min, TimeSpan max)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true)
(TimeSpan min, TimeSpan max)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
_nextMoveTime = new TimeTracker(0);
_pathId = pathId;
@@ -49,13 +49,14 @@ namespace Game.Movement
Priority = MovementGeneratorPriority.Normal;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.Roaming;
ScriptResult = scriptResult;
if (duration.HasValue)
_duration = new(duration.Value);
}
public WaypointMovementGenerator(WaypointPath path, bool repeating = true, TimeSpan? duration = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default,
(TimeSpan min, TimeSpan max)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true)
(TimeSpan min, TimeSpan max)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
_nextMoveTime = new TimeTracker(0);
_repeating = repeating;
@@ -72,6 +73,7 @@ namespace Game.Movement
Priority = MovementGeneratorPriority.Normal;
Flags = MovementGeneratorFlags.InitializationPending;
BaseUnitState = UnitState.Roaming;
ScriptResult = scriptResult;
if (duration.HasValue)
_duration = new(duration.Value);
@@ -176,6 +178,9 @@ namespace Game.Movement
{
RemoveFlag(MovementGeneratorFlags.Transitory);
AddFlag(MovementGeneratorFlags.InformEnabled);
AddFlag(MovementGeneratorFlags.Finalized);
owner.UpdateCurrentWaypointInfo(0, 0);
SetScriptResult(MovementStopReason.Finished);
return false;
}
}
@@ -268,6 +273,9 @@ namespace Game.Movement
// TODO: Research if this modification is needed, which most likely isnt
owner.SetWalk(false);
}
if (movementInform)
SetScriptResult(MovementStopReason.Finished);
}
public void MovementInform(Creature owner)
@@ -367,6 +375,8 @@ namespace Game.Movement
CreatureAI ai = owner.GetAI();
if (ai != null)
ai.WaypointPathEnded(currentWaypoint.Id, _path.Id);
SetScriptResult(MovementStopReason.Finished);
return;
}
}
@@ -406,7 +416,7 @@ namespace Game.Movement
init.SetAnimation(AnimTier.Ground);
break;
case WaypointMoveType.Takeoff:
init.SetAnimation(AnimTier.Hover);
init.SetAnimation(AnimTier.Fly);
break;
case WaypointMoveType.Run:
init.SetWalk(false);
+62 -36
View File
@@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
namespace Game.Movement
{
@@ -544,21 +545,30 @@ namespace Game.Movement
Add(new FollowMovementGenerator(target, SharedConst.PetFollowDist, new ChaseAngle(SharedConst.PetFollowAngle), null));
}
public void MoveRandom(float wanderDistance = 0.0f, TimeSpan? duration = null, MovementSlot slot = MovementSlot.Default)
public void MoveRandom(float wanderDistance = 0.0f, TimeSpan? duration = null, MovementSlot slot = MovementSlot.Default, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
if (_owner.IsTypeId(TypeId.Unit))
Add(new RandomMovementGenerator(wanderDistance, duration), slot);
Add(new RandomMovementGenerator(wanderDistance, duration, scriptResult), slot);
else if (scriptResult != null)
scriptResult.SetResult(MovementStopReason.Interrupted);
}
public void MoveFollow(Unit target, float dist, float angle = 0.0f, TimeSpan? duration = null, MovementSlot slot = MovementSlot.Active) { MoveFollow(target, dist, new ChaseAngle(angle), duration, slot); }
public void MoveFollow(Unit target, float dist, float angle = 0.0f, TimeSpan? duration = null, MovementSlot slot = MovementSlot.Active, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
MoveFollow(target, dist, new ChaseAngle(angle), duration, slot, scriptResult);
}
public void MoveFollow(Unit target, float dist, ChaseAngle angle, TimeSpan? duration = null, MovementSlot slot = MovementSlot.Active)
public void MoveFollow(Unit target, float dist, ChaseAngle angle, TimeSpan? duration = null, MovementSlot slot = MovementSlot.Active, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
// Ignore movement request if target not exist
if (target == null || target == _owner)
{
if (scriptResult != null)
scriptResult.SetResult(MovementStopReason.Interrupted);
return;
}
Add(new FollowMovementGenerator(target, dist, angle, duration), slot);
Add(new FollowMovementGenerator(target, dist, angle, duration, scriptResult), slot);
}
public void MoveChase(Unit target, float dist, float angle = 0.0f) { MoveChase(target, new ChaseRange(dist), new ChaseAngle(angle)); }
@@ -579,26 +589,30 @@ namespace Game.Movement
Add(new ConfusedMovementGenerator<Creature>());
}
public void MoveFleeing(Unit enemy, TimeSpan time = default)
public void MoveFleeing(Unit enemy, TimeSpan time = default, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
if (enemy == null)
{
if (scriptResult != null)
scriptResult.SetResult(MovementStopReason.Interrupted);
return;
}
if (_owner.IsCreature() && time > TimeSpan.Zero)
Add(new TimedFleeingMovementGenerator(enemy.GetGUID(), time));
Add(new TimedFleeingMovementGenerator(enemy.GetGUID(), time, scriptResult));
else
Add(new FleeingMovementGenerator(enemy.GetGUID()));
Add(new FleeingMovementGenerator(enemy.GetGUID(), scriptResult));
}
public void MovePoint(uint id, Position pos, bool generatePath = true, float? finalOrient = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, float? closeEnoughDistance = null)
public void MovePoint(uint id, Position pos, bool generatePath = true, float? finalOrient = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, float? closeEnoughDistance = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
MovePoint(id, pos.posX, pos.posY, pos.posZ, generatePath, finalOrient, speed, speedSelectionMode, closeEnoughDistance);
MovePoint(id, pos.posX, pos.posY, pos.posZ, generatePath, finalOrient, speed, speedSelectionMode, closeEnoughDistance, scriptResult);
}
public void MovePoint(uint id, float x, float y, float z, bool generatePath = true, float? finalOrient = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, float? closeEnoughDistance = null)
public void MovePoint(uint id, float x, float y, float z, bool generatePath = true, float? finalOrient = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, float? closeEnoughDistance = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
Log.outDebug(LogFilter.Movement, $"MotionMaster::MovePoint: '{_owner.GetGUID()}', targeted point Id: {id} (X: {x}, Y: {y}, Z: {z})");
Add(new PointMovementGenerator(id, x, y, z, generatePath, speed, finalOrient, null, null, speedSelectionMode, closeEnoughDistance));
Add(new PointMovementGenerator(id, x, y, z, generatePath, speed, finalOrient, null, null, speedSelectionMode, closeEnoughDistance, scriptResult));
}
public void MoveCloserAndStop(uint id, Unit target, float distance)
@@ -625,12 +639,12 @@ namespace Game.Movement
}
}
public void MoveLand(uint id, Position pos, uint? tierTransitionId = null, float? velocity = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default)
public void MoveLand(uint id, Position pos, uint? tierTransitionId = null, float? velocity = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
var initializer = (MoveSplineInit init) =>
{
init.MoveTo(pos, false);
init.SetAnimation(AnimTier.Ground, tierTransitionId.GetValueOrDefault(0));
init.SetAnimation(AnimTier.Ground, tierTransitionId.GetValueOrDefault(1));
switch (speedSelectionMode)
{
case MovementWalkRunSpeedSelectionMode.ForceRun:
@@ -647,15 +661,15 @@ namespace Game.Movement
init.SetVelocity(velocity.Value);
};
Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id));
Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id, new() { ScriptResult = scriptResult }));
}
public void MoveTakeoff(uint id, Position pos, uint? tierTransitionId = null, float? velocity = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default)
public void MoveTakeoff(uint id, Position pos, uint? tierTransitionId = null, float? velocity = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
var initializer = (MoveSplineInit init) =>
{
init.MoveTo(pos, false);
init.SetAnimation(AnimTier.Hover, tierTransitionId.GetValueOrDefault(0));
init.SetAnimation(AnimTier.Hover, tierTransitionId.GetValueOrDefault(15));
switch (speedSelectionMode)
{
case MovementWalkRunSpeedSelectionMode.ForceRun:
@@ -672,7 +686,7 @@ namespace Game.Movement
init.SetVelocity(velocity.Value);
};
Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id));
Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id, new() { ScriptResult = scriptResult }));
}
public void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint id = EventId.Charge, bool generatePath = false, Unit target = null, SpellEffectExtraData spellEffectExtraData = null)
@@ -755,16 +769,20 @@ namespace Game.Movement
MoveJump(x, y, z, 0.0f, speedXY, speedZ);
}
public void MoveJump(Position pos, float speedXY, float speedZ, uint id = EventId.Jump, bool hasOrientation = false, JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null)
public void MoveJump(Position pos, float speedXY, float speedZ, uint id = EventId.Jump, bool hasOrientation = false, JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), speedXY, speedZ, id, hasOrientation, arrivalCast, spellEffectExtraData);
MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), speedXY, speedZ, id, hasOrientation, arrivalCast, spellEffectExtraData, scriptResult);
}
public void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint id = EventId.Jump, bool hasOrientation = false, JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null)
public void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint id = EventId.Jump, bool hasOrientation = false, JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
Log.outDebug(LogFilter.Server, "Unit ({0}) jump to point (X: {1} Y: {2} Z: {3})", _owner.GetGUID().ToString(), x, y, z);
if (speedXY < 0.01f)
{
if (scriptResult != null)
scriptResult.SetResult(MovementStopReason.Interrupted);
return;
}
float moveTimeHalf = (float)(speedZ / gravity);
float max_height = -MoveSpline.ComputeFallElevation(moveTimeHalf, false, -speedZ);
@@ -788,17 +806,21 @@ namespace Game.Movement
arrivalSpellTargetGuid = arrivalCast.Target;
}
GenericMovementGenerator movement = new(initializer, MovementGeneratorType.Effect, id, new GenericMovementGeneratorArgs() { ArrivalSpellId = arrivalSpellId, ArrivalSpellTarget = arrivalSpellTargetGuid });
GenericMovementGenerator movement = new(initializer, MovementGeneratorType.Effect, id, new GenericMovementGeneratorArgs() { ArrivalSpellId = arrivalSpellId, ArrivalSpellTarget = arrivalSpellTargetGuid, ScriptResult = scriptResult });
movement.Priority = MovementGeneratorPriority.Highest;
movement.BaseUnitState = UnitState.Jumping;
Add(movement);
}
public void MoveJumpWithGravity(Position pos, float speedXY, float gravity, uint id = EventId.Jump, bool hasOrientation = false, JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null)
public void MoveJumpWithGravity(Position pos, float speedXY, float gravity, uint id = EventId.Jump, bool hasOrientation = false, JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
Log.outDebug(LogFilter.Movement, $"MotionMaster.MoveJumpWithGravity: '{_owner.GetGUID()}', jumps to point Id: {id} ({pos})");
if (speedXY < 0.01f)
{
if (scriptResult != null)
scriptResult.SetResult(MovementStopReason.Interrupted);
return;
}
var initializer = (MoveSplineInit init) =>
{
@@ -821,14 +843,14 @@ namespace Game.Movement
arrivalSpellTargetGuid = arrivalCast.Target;
}
GenericMovementGenerator movement = new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id, new GenericMovementGeneratorArgs() { ArrivalSpellId = arrivalSpellId, ArrivalSpellTarget = arrivalSpellTargetGuid });
GenericMovementGenerator movement = new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, id, new GenericMovementGeneratorArgs() { ArrivalSpellId = arrivalSpellId, ArrivalSpellTarget = arrivalSpellTargetGuid, ScriptResult = scriptResult });
movement.Priority = MovementGeneratorPriority.Highest;
movement.BaseUnitState = UnitState.Jumping;
movement.AddFlag(MovementGeneratorFlags.PersistOnDeath);
Add(movement);
}
public void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, byte stepCount, TimeSpan? duration = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default)
public void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, byte stepCount, TimeSpan? duration = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
var initializer = (MoveSplineInit init) =>
{
@@ -879,7 +901,7 @@ namespace Game.Movement
init.SetVelocity(speed.Value);
};
Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, 0, new GenericMovementGeneratorArgs() { Duration = duration }));
Add(new GenericMovementGenerator(initializer, MovementGeneratorType.Effect, 0, new GenericMovementGeneratorArgs() { Duration = duration, ScriptResult = scriptResult }));
}
public void MoveSmoothPath(uint pointId, Vector3[] pathPoints, int pathSize, bool walk = false, bool fly = false)
@@ -935,7 +957,7 @@ namespace Game.Movement
Add(new SplineChainMovementGenerator(info));
}
public void MoveFall(uint id = 0)
public void MoveFall(uint id = 0, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
// Use larger distance for vmap height search than in most other cases
float tz = _owner.GetMapHeight(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ(), true, MapConst.MaxFallDistance);
@@ -965,7 +987,7 @@ namespace Game.Movement
init.SetFall();
};
GenericMovementGenerator movement = new(initializer, MovementGeneratorType.Effect, id);
GenericMovementGenerator movement = new(initializer, MovementGeneratorType.Effect, id, new() { ScriptResult = scriptResult });
movement.Priority = MovementGeneratorPriority.Highest;
Add(movement);
}
@@ -994,7 +1016,7 @@ namespace Game.Movement
Log.outError(LogFilter.Server, $"MotionMaster::MoveSeekAssistanceDistract: {_owner.GetGUID()} attempted to call distract after assistance");
}
public void MoveTaxiFlight(uint path, uint pathnode, float? speed = null)
public void MoveTaxiFlight(uint path, uint pathnode, float? speed = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
if (_owner.IsTypeId(TypeId.Player))
{
@@ -1006,7 +1028,7 @@ namespace Game.Movement
bool hasExisting = HasMovementGenerator(gen => gen.GetMovementGeneratorType() == MovementGeneratorType.Flight);
Cypher.Assert(!hasExisting, "Duplicate flight path movement generator");
FlightPathMovementGenerator movement = new(speed);
FlightPathMovementGenerator movement = new(speed, scriptResult);
movement.LoadPath(_owner.ToPlayer());
Add(movement);
}
@@ -1029,20 +1051,24 @@ namespace Game.Movement
}
public void MovePath(uint pathId, bool repeatable, TimeSpan? duration = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default,
(TimeSpan min, TimeSpan max)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true)
(TimeSpan, TimeSpan)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
if (pathId == 0)
{
if (scriptResult != null)
scriptResult.SetResult(MovementStopReason.Interrupted);
return;
}
Log.outDebug(LogFilter.Movement, $"MotionMaster::MovePath: '{_owner.GetGUID()}', starts moving over path Id: {pathId} (repeatable: {repeatable})");
Add(new WaypointMovementGenerator(pathId, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd, wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath), MovementSlot.Default);
Add(new WaypointMovementGenerator(pathId, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd, wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath, scriptResult), MovementSlot.Default);
}
public void MovePath(WaypointPath path, bool repeatable, TimeSpan? duration = null, float? speed = null, MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode.Default,
(TimeSpan min, TimeSpan max)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true)
(TimeSpan, TimeSpan)? waitTimeRangeAtPathEnd = null, float? wanderDistanceAtPathEnds = null, bool? followPathBackwardsFromEndToStart = null, bool generatePath = true, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
Log.outDebug(LogFilter.Movement, $"MotionMaster::MovePath: '{_owner.GetGUID()}', starts moving over path Id: {path.Id} (repeatable: {repeatable})");
Add(new WaypointMovementGenerator(path, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd, wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath), MovementSlot.Default);
Add(new WaypointMovementGenerator(path, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd, wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath, scriptResult), MovementSlot.Default);
}
/// <summary>
@@ -1053,11 +1079,11 @@ namespace Game.Movement
/// <param name="time">How long should this movement last, infinite if not set</param>
/// <param name="turnSpeed">How fast should the unit rotate, in radians per second. Uses unit's turn speed if not set</param>
/// <param name="totalTurnAngle">Total angle of the entire movement, infinite if not set</param>
public void MoveRotate(uint id, RotateDirection direction, TimeSpan? time = null, float? turnSpeed = null, float? totalTurnAngle = null)
public void MoveRotate(uint id, RotateDirection direction, TimeSpan? time = null, float? turnSpeed = null, float? totalTurnAngle = null, TaskCompletionSource<MovementStopReason> scriptResult = null)
{
Log.outDebug(LogFilter.Movement, $"MotionMaster::MoveRotate: '{_owner.GetGUID()}', starts rotate (time: {time.GetValueOrDefault(TimeSpan.Zero)}ms, turnSpeed: {turnSpeed}, totalTurnAngle: {totalTurnAngle}, direction: {direction})");
Add(new RotateMovementGenerator(id, direction, time, turnSpeed, totalTurnAngle));
Add(new RotateMovementGenerator(id, direction, time, turnSpeed, totalTurnAngle, scriptResult));
}
public void MoveFormation(Unit leader, float range, float angle, uint point1, uint point2)
+24
View File
@@ -19,6 +19,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace Game.Spells
{
@@ -3000,6 +3001,9 @@ namespace Game.Spells
HandleImmediate();
}
if (m_scriptResult != null && !m_scriptWaitsForSpellHit)
m_scriptResult.SetResult(SpellCastResult.SpellCastOk);
CallScriptAfterCastHandlers();
var spell_triggered = Global.SpellMgr.GetSpellLinked(SpellLinkedType.Cast, m_spellInfo.Id);
@@ -3438,6 +3442,9 @@ namespace Game.Spells
m_spellState = SpellState.Finished;
if (m_scriptResult != null && (m_scriptWaitsForSpellHit || result != SpellCastResult.SpellCastOk))
m_scriptResult.SetResult(result);
if (m_caster == null)
return;
@@ -8225,6 +8232,9 @@ namespace Game.Spells
public List<Aura> m_appliedMods = new();
public TaskCompletionSource<SpellCastResult> m_scriptResult;
public bool m_scriptWaitsForSpellHit;
WorldObject m_caster;
public SpellValue m_spellValue;
ObjectGuid m_originalCasterGUID;
@@ -9516,6 +9526,9 @@ namespace Game.Spells
public Dictionary<SpellValueMod, int> SpellValueOverrides = new();
public object CustomArg;
public TaskCompletionSource<SpellCastResult> ScriptResult;
public bool ScriptWaitsForSpellHit;
public CastSpellExtraArgs() { }
public CastSpellExtraArgs(bool triggered)
@@ -9618,6 +9631,17 @@ namespace Game.Spells
return this;
}
public CastSpellExtraArgs SetScriptResult(TaskCompletionSource<SpellCastResult> scriptResult)
{
ScriptResult = scriptResult;
return this;
}
public CastSpellExtraArgs SetScriptWaitsForSpellHit(bool scriptWaitsForSpellHit)
{
ScriptWaitsForSpellHit = scriptWaitsForSpellHit;
return this;
}
public static implicit operator CastSpellExtraArgs(bool triggered) => new CastSpellExtraArgs(triggered);
public static implicit operator CastSpellExtraArgs(TriggerCastFlags trigger) => new CastSpellExtraArgs(trigger);