aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-04-06 20:50:59 +0200
committerOvahlord <dreadkiller@gmx.de>2024-05-28 16:34:58 +0200
commit093546f22c2908017bbcf36e0b589ca5d7660eff (patch)
treecefa11a47127a1f63d4b87d8fb128182eb4d2f5b /src
parent3438404575d1e4ed7c7b2063d0e6f36b1d976800 (diff)
Core/Scripts: Integrate new ActionResultSetter with movement generators and spells
(cherry picked from commit b265c49977235dea5e7e69d7b6fb93f4943bf87a)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Object/Object.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp16
-rw-r--r--src/server/game/Entities/Player/Player.h10
-rw-r--r--src/server/game/Movement/MotionMaster.cpp128
-rw-r--r--src/server/game/Movement/MotionMaster.h52
-rw-r--r--src/server/game/Movement/MovementGenerator.cpp14
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.h6
-rw-r--r--src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp11
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h7
-rw-r--r--src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.cpp9
-rw-r--r--src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.h3
-rw-r--r--src/server/game/Movement/MovementGenerators/FollowMovementGenerator.cpp8
-rw-r--r--src/server/game/Movement/MovementGenerators/FollowMovementGenerator.h4
-rw-r--r--src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp3
-rw-r--r--src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h1
-rw-r--r--src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp13
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/IdleMovementGenerator.h3
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp5
-rw-r--r--src/server/game/Movement/MovementGenerators/PointMovementGenerator.h4
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp13
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h3
-rw-r--r--src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp20
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h6
-rw-r--r--src/server/game/Spells/Spell.cpp6
-rw-r--r--src/server/game/Spells/Spell.h3
-rw-r--r--src/server/game/Spells/SpellDefines.h7
26 files changed, 262 insertions, 95 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 6794ad6a21e..edd9206ff30 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2965,6 +2965,8 @@ SpellCastResult WorldObject::CastSpell(CastSpellTargetArg const& targets, uint32
}
spell->m_customArg = args.CustomArg;
+ spell->m_scriptResult = args.ScriptResult;
+ spell->m_scriptWaitsForSpellHit = args.ScriptWaitsForSpellHit;
return spell->prepare(*targets.Targets, args.TriggeringAura);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 90baf8de819..7c1e2d036bb 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -22072,7 +22072,7 @@ UF::PVPInfo const* Player::GetPvpInfoForBracket(int8 bracket) const
}
bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc /*= nullptr*/, uint32 spellid /*= 0*/, uint32 preferredMountDisplay /*= 0*/,
- Optional<float> speed /*= {}*/)
+ Optional<float> speed /*= {}*/, Optional<Scripting::v2::ActionResultSetter<MovementStopReason>> const& scriptResult /*= {}*/)
{
if (nodes.size() < 2)
{
@@ -22252,18 +22252,19 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
ModifyMoney(-int64(firstcost));
UpdateCriteria(CriteriaType::MoneySpentOnTaxis, firstcost);
GetSession()->SendActivateTaxiReply(ERR_TAXIOK);
- StartTaxiMovement(mount_display_id, sourcepath, 0, speed);
+ StartTaxiMovement(mount_display_id, sourcepath, 0, speed, Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>(scriptResult));
}
return true;
}
-bool Player::ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid /*= 0*/, Optional<float> speed /*= {}*/)
+bool Player::ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid /*= 0*/, Optional<float> speed /*= {}*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>> const& scriptResult /*= {}*/)
{
TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(taxi_path_id);
if (!entry)
return false;
- return ActivateTaxiPathTo({ { entry->FromTaxiNode, entry->ToTaxiNode } }, nullptr, spellid, 0, speed);
+ return ActivateTaxiPathTo({ { entry->FromTaxiNode, entry->ToTaxiNode } }, nullptr, spellid, 0, speed, scriptResult);
}
void Player::FinishTaxiFlight()
@@ -22329,10 +22330,11 @@ void Player::ContinueTaxiFlight()
}
}
- StartTaxiMovement(mountDisplayId, path, startNode, {});
+ StartTaxiMovement(mountDisplayId, path, startNode, {}, {});
}
-void Player::StartTaxiMovement(uint32 mountDisplayId, uint32 path, uint32 pathNode, Optional<float> speed)
+void Player::StartTaxiMovement(uint32 mountDisplayId, uint32 path, uint32 pathNode, Optional<float> speed,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult)
{
// remove fake death
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Interacting);
@@ -22340,7 +22342,7 @@ void Player::StartTaxiMovement(uint32 mountDisplayId, uint32 path, uint32 pathNo
if (mountDisplayId)
Mount(mountDisplayId);
- GetMotionMaster()->MoveTaxiFlight(path, pathNode, speed);
+ GetMotionMaster()->MoveTaxiFlight(path, pathNode, speed, std::move(scriptResult));
}
void Player::InitDataForForm(bool reapplyMods)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 1e8eab39d21..95e09d1ac73 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -102,6 +102,7 @@ enum InventoryType : uint8;
enum ItemClass : uint8;
enum LootError : uint8;
enum LootType : uint8;
+enum class MovementStopReason : uint8;
enum PlayerRestState : uint8;
enum class PlayerCreateMode : int8;
enum RestTypes : uint8;
@@ -1150,12 +1151,15 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
PlayerTaxi m_taxi;
void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(GetRace(), GetClass(), GetLevel()); }
- bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0, uint32 preferredMountDisplay = 0, Optional<float> speed = {});
- bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0, Optional<float> speed = {});
+ bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = nullptr, uint32 spellid = 0, uint32 preferredMountDisplay = 0, Optional<float> speed = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>> const& scriptResult = {});
+ bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0, Optional<float> speed = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>> const& scriptResult = {});
void FinishTaxiFlight();
void CleanupAfterTaxiFlight();
void ContinueTaxiFlight();
- void StartTaxiMovement(uint32 mountDisplayId, uint32 path, uint32 pathNode, Optional<float> speed);
+ void StartTaxiMovement(uint32 mountDisplayId, uint32 path, uint32 pathNode, Optional<float> speed,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult);
bool IsDeveloper() const { return HasPlayerFlag(PLAYER_FLAGS_DEVELOPER); }
void SetDeveloper(bool on) { if (on) SetPlayerFlag(PLAYER_FLAGS_DEVELOPER); else RemovePlayerFlag(PLAYER_FLAGS_DEVELOPER); }
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 5fadcff5f58..7b43eea41ae 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -46,6 +46,7 @@
#include "GenericMovementGenerator.h"
#include "HomeMovementGenerator.h"
#include "IdleMovementGenerator.h"
+#include "Memory.h"
#include "PointMovementGenerator.h"
#include "RandomMovementGenerator.h"
#include "SplineChainMovementGenerator.h"
@@ -596,23 +597,31 @@ void MotionMaster::MoveTargetedHome()
}
}
-void MotionMaster::MoveRandom(float wanderDistance, Optional<Milliseconds> duration, MovementSlot slot /*= MOTION_SLOT_DEFAULT*/)
+void MotionMaster::MoveRandom(float wanderDistance /*= 0.0f*/, Optional<Milliseconds> duration /*= {}*/, MovementSlot slot /*= MOTION_SLOT_DEFAULT*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
if (_owner->GetTypeId() == TYPEID_UNIT)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveRandom: '{}', started random movement (spawnDist: {})", _owner->GetGUID(), wanderDistance);
- Add(new RandomMovementGenerator<Creature>(wanderDistance, duration), slot);
+ Add(new RandomMovementGenerator<Creature>(wanderDistance, duration, std::move(scriptResult)), slot);
}
+ else if (scriptResult)
+ scriptResult->SetResult(MovementStopReason::Interrupted);
}
-void MotionMaster::MoveFollow(Unit* target, float dist, ChaseAngle angle, Optional<Milliseconds> duration /*= {}*/, MovementSlot slot/* = MOTION_SLOT_ACTIVE*/)
+void MotionMaster::MoveFollow(Unit* target, float dist, ChaseAngle angle, Optional<Milliseconds> duration /*= {}*/, MovementSlot slot/* = MOTION_SLOT_ACTIVE*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
// Ignore movement request if target not exist
if (!target || target == _owner)
+ {
+ if (scriptResult)
+ scriptResult->SetResult(MovementStopReason::Interrupted);
return;
+ }
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveFollow: '{}', starts following '{}'", _owner->GetGUID(), target->GetGUID());
- Add(new FollowMovementGenerator(target, dist, angle, duration), slot);
+ Add(new FollowMovementGenerator(target, dist, angle, duration, std::move(scriptResult)), slot);
}
void MotionMaster::MoveChase(Unit* target, Optional<ChaseRange> dist, Optional<ChaseAngle> angle)
@@ -639,29 +648,36 @@ void MotionMaster::MoveConfused()
}
}
-void MotionMaster::MoveFleeing(Unit* enemy, Milliseconds time /*= 0ms*/)
+void MotionMaster::MoveFleeing(Unit* enemy, Milliseconds time /*= 0ms*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
if (!enemy)
+ {
+ if (scriptResult)
+ scriptResult->SetResult(MovementStopReason::Interrupted);
return;
+ }
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveFleeing: '{}', flees from '{}' (time: {}ms)", _owner->GetGUID(), enemy->GetGUID(), time.count());
if (_owner->GetTypeId() == TYPEID_UNIT && time > 0ms)
- Add(new TimedFleeingMovementGenerator(enemy->GetGUID(), time));
+ Add(new TimedFleeingMovementGenerator(enemy->GetGUID(), time, std::move(scriptResult)));
else
- Add(new FleeingMovementGenerator(enemy->GetGUID()));
+ Add(new FleeingMovementGenerator(enemy->GetGUID(), std::move(scriptResult)));
}
void MotionMaster::MovePoint(uint32 id, Position const& pos, bool generatePath/* = true*/, Optional<float> finalOrient/* = {}*/, Optional<float> speed /*= {}*/,
- MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/, Optional<float> closeEnoughDistance /*= {}*/)
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/, Optional<float> closeEnoughDistance /*= {}*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
- MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath, finalOrient, speed, speedSelectionMode, closeEnoughDistance);
+ MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath, finalOrient, speed, speedSelectionMode, closeEnoughDistance, std::move(scriptResult));
}
void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generatePath /*= true*/, Optional<float> finalOrient /*= {}*/, Optional<float> speed /*= {}*/,
- MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/, Optional<float> closeEnoughDistance /*= {}*/)
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/, Optional<float> closeEnoughDistance /*= {}*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MovePoint: '{}', targeted point Id: {} (X: {}, Y: {}, Z: {})", _owner->GetGUID(), id, x, y, z);
- Add(new PointMovementGenerator(id, x, y, z, generatePath, speed, finalOrient, nullptr, nullptr, speedSelectionMode, closeEnoughDistance));
+ Add(new PointMovementGenerator(id, x, y, z, generatePath, speed, finalOrient, nullptr, nullptr, speedSelectionMode, closeEnoughDistance, std::move(scriptResult)));
}
void MotionMaster::MoveCloserAndStop(uint32 id, Unit* target, float distance)
@@ -688,14 +704,15 @@ void MotionMaster::MoveCloserAndStop(uint32 id, Unit* target, float distance)
}
void MotionMaster::MoveLand(uint32 id, Position const& pos, Optional<int32> tierTransitionId /*= {}*/, Optional<float> velocity /*= {}*/,
- MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/)
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveLand: '{}', landing point Id: {} (X: {}, Y: {}, Z: {})", _owner->GetGUID(), id, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
{
init.MoveTo(PositionToVector3(pos), false);
- init.SetAnimation(AnimTier::Ground, tierTransitionId.value_or(0));
+ init.SetAnimation(AnimTier::Ground, tierTransitionId.value_or(1));
switch (speedSelectionMode)
{
case MovementWalkRunSpeedSelectionMode::ForceRun:
@@ -711,18 +728,19 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, Optional<int32> tier
if (velocity)
init.SetVelocity(*velocity);
};
- Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id));
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, { .ScriptResult = std::move(scriptResult) }));
}
void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, Optional<int32> tierTransitionId /*= {}*/, Optional<float> velocity /*= {}*/,
- MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/)
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveTakeoff: '{}', landing point Id: {} (X: {}, Y: {}, Z: {})", _owner->GetGUID(), id, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
{
init.MoveTo(PositionToVector3(pos), false);
- init.SetAnimation(AnimTier::Hover, tierTransitionId.value_or(0));
+ init.SetAnimation(AnimTier::Hover, tierTransitionId.value_or(15));
switch (speedSelectionMode)
{
case MovementWalkRunSpeedSelectionMode::ForceRun:
@@ -738,7 +756,7 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, Optional<int32> t
if (velocity)
init.SetVelocity(*velocity);
};
- Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id));
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, { .ScriptResult = std::move(scriptResult) }));
}
void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_CHARGE*/, uint32 id /*= EVENT_CHARGE*/, bool generatePath /*= false*/,
@@ -826,17 +844,24 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
}
void MotionMaster::MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id/* = EVENT_JUMP*/, bool hasOrientation/* = false*/,
- JumpArrivalCastArgs const* arrivalCast /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/)
+ JumpArrivalCastArgs const* arrivalCast /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
- 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, std::move(scriptResult));
}
void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id /*= EVENT_JUMP*/, bool hasOrientation /* = false*/,
- JumpArrivalCastArgs const* arrivalCast /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/)
+ JumpArrivalCastArgs const* arrivalCast /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveJump: '{}', jumps to point Id: {} (X: {}, Y: {}, Z: {})", _owner->GetGUID(), id, x, y, z);
if (speedXY < 0.01f)
+ {
+ if (scriptResult)
+ scriptResult->SetResult(MovementStopReason::Interrupted);
return;
+ }
float moveTimeHalf = speedZ / Movement::gravity;
float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ);
@@ -861,18 +886,23 @@ void MotionMaster::MoveJump(float x, float y, float z, float o, float speedXY, f
}
GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id,
- { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid });
+ { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid, .ScriptResult = std::move(scriptResult) });
movement->Priority = MOTION_PRIORITY_HIGHEST;
movement->BaseUnitState = UNIT_STATE_JUMPING;
Add(movement);
}
void MotionMaster::MoveJumpWithGravity(Position const& pos, float speedXY, float gravity, uint32 id/* = EVENT_JUMP*/, bool hasOrientation/* = false*/,
- JumpArrivalCastArgs const* arrivalCast /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/)
+ JumpArrivalCastArgs const* arrivalCast /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveJumpWithGravity: '{}', jumps to point Id: {} ({})", _owner->GetGUID(), id, pos.ToString());
if (speedXY < 0.01f)
+ {
+ if (scriptResult)
+ scriptResult->SetResult(MovementStopReason::Interrupted);
return;
+ }
std::function<void(Movement::MoveSplineInit&)> initializer = [=, effect = (spellEffectExtraData ? Optional<Movement::SpellEffectExtraData>(*spellEffectExtraData) : Optional<Movement::SpellEffectExtraData>())](Movement::MoveSplineInit& init)
{
@@ -896,7 +926,7 @@ void MotionMaster::MoveJumpWithGravity(Position const& pos, float speedXY, float
}
GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id,
- { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid });
+ { .ArrivalSpellId = arrivalSpellId, .ArrivalSpellTarget = arrivalSpellTargetGuid, .ScriptResult = std::move(scriptResult) });
movement->Priority = MOTION_PRIORITY_HIGHEST;
movement->BaseUnitState = UNIT_STATE_JUMPING;
movement->AddFlag(MOVEMENTGENERATOR_FLAG_PERSIST_ON_DEATH);
@@ -905,7 +935,8 @@ void MotionMaster::MoveJumpWithGravity(Position const& pos, float speedXY, float
void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount,
Optional<Milliseconds> duration /*= {}*/, Optional<float> speed /*= {}*/,
- MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/)
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
std::function<void(Movement::MoveSplineInit&)> initializer = [=, this](Movement::MoveSplineInit& init)
{
@@ -953,7 +984,7 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool
init.SetVelocity(*speed);
};
- Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, 0, { .Duration = duration }));
+ Add(new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, 0, { .Duration = duration, .ScriptResult = std::move(scriptResult) }));
}
void MotionMaster::MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk, bool fly)
@@ -1014,8 +1045,15 @@ void MotionMaster::ResumeSplineChain(SplineChainResumeInfo const& info)
Add(new SplineChainMovementGenerator(info));
}
-void MotionMaster::MoveFall(uint32 id/* = 0*/)
+void MotionMaster::MoveFall(uint32 id /*= 0*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
+ auto setterScopeExit = Trinity::make_unique_ptr_with_deleter(&scriptResult, [](Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>* opt)
+ {
+ if (opt->has_value())
+ (*opt)->SetResult(MovementStopReason::Interrupted);
+ });
+
// Use larger distance for vmap height search than in most other cases
float tz = _owner->GetMapHeight(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
if (tz <= INVALID_HEIGHT)
@@ -1042,13 +1080,13 @@ void MotionMaster::MoveFall(uint32 id/* = 0*/)
return;
}
- std::function<void(Movement::MoveSplineInit&)> initializer = [=, this](Movement::MoveSplineInit& init)
+ std::function<void(Movement::MoveSplineInit&)> initializer = [this, tz](Movement::MoveSplineInit& init)
{
init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz + _owner->GetHoverOffset(), false);
init.SetFall();
};
- GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id);
+ GenericMovementGenerator* movement = new GenericMovementGenerator(std::move(initializer), EFFECT_MOTION_TYPE, id, { .ScriptResult = std::move(*setterScopeExit.release()) });
movement->Priority = MOTION_PRIORITY_HIGHEST;
Add(movement);
}
@@ -1079,7 +1117,8 @@ void MotionMaster::MoveSeekAssistanceDistract(uint32 time)
TC_LOG_ERROR("movement.motionmaster", "MotionMaster::MoveSeekAssistanceDistract: '{}', attempted to call distract assistance.", _owner->GetGUID());
}
-void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode, Optional<float> speed /*= {}*/)
+void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode, Optional<float> speed /*= {}*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
if (_owner->GetTypeId() == TYPEID_PLAYER)
{
@@ -1091,7 +1130,7 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode, Optional<float>
bool hasExisting = HasMovementGenerator([](MovementGenerator const* gen) { return gen->GetMovementGeneratorType() == FLIGHT_MOTION_TYPE; });
ASSERT(!hasExisting, "Duplicate flight path movement generator");
- FlightPathMovementGenerator* movement = new FlightPathMovementGenerator(speed);
+ FlightPathMovementGenerator* movement = new FlightPathMovementGenerator(speed, std::move(scriptResult));
movement->LoadPath(_owner->ToPlayer(), pathnode);
Add(movement);
}
@@ -1112,36 +1151,45 @@ void MotionMaster::MoveDistract(uint32 timer, float orientation)
Add(new DistractMovementGenerator(timer, orientation));
}
-void MotionMaster::MovePath(uint32 pathId, bool repeatable, Optional<Milliseconds> duration, Optional<float> speed,
- MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
- Optional<float> wanderDistanceAtPathEnds, Optional<bool> followPathBackwardsFromEndToStart, bool generatePath)
+void MotionMaster::MovePath(uint32 pathId, bool repeatable, Optional<Milliseconds> duration /*= {}*/, Optional<float> speed /*= {}*/,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/,
+ Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd /*= {}*/,
+ Optional<float> wanderDistanceAtPathEnds /*= {}*/, Optional<bool> followPathBackwardsFromEndToStart /*= {}*/, bool generatePath /*= true*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
if (!pathId)
+ {
+ if (scriptResult)
+ scriptResult->SetResult(MovementStopReason::Interrupted);
return;
+ }
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
_owner->GetGUID(), pathId, repeatable ? "YES" : "NO");
Add(new WaypointMovementGenerator<Creature>(pathId, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd,
- wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath), MOTION_SLOT_DEFAULT);
+ wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath, std::move(scriptResult)), MOTION_SLOT_DEFAULT);
}
-void MotionMaster::MovePath(WaypointPath const& path, bool repeatable, Optional<Milliseconds> duration, Optional<float> speed,
- MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
- Optional<float> wanderDistanceAtPathEnds, Optional<bool> followPathBackwardsFromEndToStart, bool generatePath)
+void MotionMaster::MovePath(WaypointPath const& path, bool repeatable, Optional<Milliseconds> duration /*= {}*/, Optional<float> speed /*= {}*/,
+ MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/,
+ Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd /*= {}*/,
+ Optional<float> wanderDistanceAtPathEnds /*= {}*/, Optional<bool> followPathBackwardsFromEndToStart /*= {}*/, bool generatePath /*= true*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MovePath: '{}', starts moving over path Id: {} (repeatable: {})",
_owner->GetGUID(), path.Id, repeatable ? "YES" : "NO");
Add(new WaypointMovementGenerator<Creature>(path, repeatable, duration, speed, speedSelectionMode, waitTimeRangeAtPathEnd,
- wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath), MOTION_SLOT_DEFAULT);
+ wanderDistanceAtPathEnds, followPathBackwardsFromEndToStart, generatePath, std::move(scriptResult)), MOTION_SLOT_DEFAULT);
}
void MotionMaster::MoveRotate(uint32 id, RotateDirection direction, Optional<Milliseconds> time /*= {}*/,
- Optional<float> turnSpeed /*= {}*/, Optional<float> totalTurnAngle /*= {}*/)
+ Optional<float> turnSpeed /*= {}*/, Optional<float> totalTurnAngle /*= {}*/,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
{
TC_LOG_DEBUG("movement.motionmaster", "MotionMaster::MoveRotate: '{}', starts rotate (time: {}ms, turnSpeed: {}, totalTurnAngle: {}, direction: {})",
_owner->GetGUID(), time.value_or(0ms).count(), turnSpeed, totalTurnAngle, direction);
- Add(new RotateMovementGenerator(id, direction, time, turnSpeed, totalTurnAngle));
+ Add(new RotateMovementGenerator(id, direction, time, turnSpeed, totalTurnAngle, std::move(scriptResult)));
}
void MotionMaster::MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2)
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 87cee0adf85..2f2d4d9d6da 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -156,16 +156,21 @@ class TC_GAME_API MotionMaster
void MoveIdle();
void MoveTargetedHome();
- void MoveRandom(float wanderDistance = 0.0f, Optional<Milliseconds> duration = {}, MovementSlot slot = MOTION_SLOT_DEFAULT);
- void MoveFollow(Unit* target, float dist, ChaseAngle angle, Optional<Milliseconds> duration = {}, MovementSlot slot = MOTION_SLOT_ACTIVE);
+ void MoveRandom(float wanderDistance = 0.0f, Optional<Milliseconds> duration = {}, MovementSlot slot = MOTION_SLOT_DEFAULT,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
+ void MoveFollow(Unit* target, float dist, ChaseAngle angle, Optional<Milliseconds> duration = {}, MovementSlot slot = MOTION_SLOT_ACTIVE,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveChase(Unit* target, Optional<ChaseRange> dist = {}, Optional<ChaseAngle> angle = {});
void MoveChase(Unit* target, float dist, float angle) { MoveChase(target, ChaseRange(dist), ChaseAngle(angle)); }
void MoveConfused();
- void MoveFleeing(Unit* enemy, Milliseconds time = 0ms);
+ void MoveFleeing(Unit* enemy, Milliseconds time = 0ms,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MovePoint(uint32 id, Position const& pos, bool generatePath = true, Optional<float> finalOrient = {}, Optional<float> speed = {},
- MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default, Optional<float> closeEnoughDistance = {});
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default, Optional<float> closeEnoughDistance = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true, Optional<float> finalOrient = {}, Optional<float> speed = {},
- MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default, Optional<float> closeEnoughDistance = {});
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default, Optional<float> closeEnoughDistance = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
/*
* Makes the unit move toward the target until it is at a certain distance from it. The unit then stops.
* Only works in 2D.
@@ -174,37 +179,50 @@ class TC_GAME_API MotionMaster
void MoveCloserAndStop(uint32 id, Unit* target, float distance);
// These two movement types should only be used with creatures having landing/takeoff animations
void MoveLand(uint32 id, Position const& pos, Optional<int32> tierTransitionId = {}, Optional<float> velocity = {},
- MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default);
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveTakeoff(uint32 id, Position const& pos, Optional<int32> tierTransitionId = {}, Optional<float> velocity = {},
- MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default);
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, bool generatePath = false, Unit const* target = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
void MoveCharge(PathGenerator const& path, float speed = SPEED_CHARGE, Unit const* target = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
void MoveKnockbackFrom(Position const& origin, float speedXY, float speedZ, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
void MoveJumpTo(float angle, float speedXY, float speedZ);
- void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
- void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
- void MoveJumpWithGravity(Position const& pos, float speedXY, float gravity, uint32 id = EVENT_JUMP, bool hasOrientation = false, JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr);
+ void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false,
+ JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
+ void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false,
+ JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
+ void MoveJumpWithGravity(Position const& pos, float speedXY, float gravity, uint32 id = EVENT_JUMP, bool hasOrientation = false,
+ JumpArrivalCastArgs const* arrivalCast = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount,
Optional<Milliseconds> duration = {}, Optional<float> speed = {},
- MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default);
+ MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk = false, bool fly = false);
// Walk along spline chain stored in DB (script_spline_chain_meta and script_spline_chain_waypoints)
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk);
void MoveAlongSplineChain(uint32 pointId, std::vector<SplineChainLink> const& chain, bool walk);
void ResumeSplineChain(SplineChainResumeInfo const& info);
- void MoveFall(uint32 id = 0);
+ void MoveFall(uint32 id = 0,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveSeekAssistance(float x, float y, float z);
void MoveSeekAssistanceDistract(uint32 timer);
- void MoveTaxiFlight(uint32 path, uint32 pathnode, Optional<float> speed = {});
+ void MoveTaxiFlight(uint32 path, uint32 pathnode, Optional<float> speed = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveDistract(uint32 time, float orientation);
void MovePath(uint32 pathId, bool repeatable, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd = {}, Optional<float> wanderDistanceAtPathEnds = {},
- Optional<bool> followPathBackwardsFromEndToStart = {}, bool generatePath = true);
+ Optional<bool> followPathBackwardsFromEndToStart = {}, bool generatePath = true,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MovePath(WaypointPath const& path, bool repeatable, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd = {}, Optional<float> wanderDistanceAtPathEnds = {},
- Optional<bool> followPathBackwardsFromEndToStart = {}, bool generatePath = true);
+ Optional<bool> followPathBackwardsFromEndToStart = {}, bool generatePath = true,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
/**
* \brief Makes the Unit turn in place
@@ -213,9 +231,11 @@ class TC_GAME_API MotionMaster
* \param time How long should this movement last, infinite if not set
* \param turnSpeed How fast should the unit rotate, in radians per second. Uses unit's turn speed if not set
* \param totalTurnAngle Total angle of the entire movement, infinite if not set
+ * \param scriptResult Awaitable script result (for internal use)
*/
void MoveRotate(uint32 id, RotateDirection direction, Optional<Milliseconds> time = {},
- Optional<float> turnSpeed = {}, Optional<float> totalTurnAngle = {});
+ Optional<float> turnSpeed = {}, Optional<float> totalTurnAngle = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
void MoveFormation(Unit* leader, float range, float angle, uint32 point1, uint32 point2);
void LaunchMoveSpline(std::function<void(Movement::MoveSplineInit& init)>&& initializer, uint32 id = 0, MovementGeneratorPriority priority = MOTION_PRIORITY_NORMAL, MovementGeneratorType type = EFFECT_MOTION_TYPE);
diff --git a/src/server/game/Movement/MovementGenerator.cpp b/src/server/game/Movement/MovementGenerator.cpp
index 455f91795a5..38844c0d821 100644
--- a/src/server/game/Movement/MovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerator.cpp
@@ -25,7 +25,10 @@
#include "WaypointMovementGenerator.h"
#include <sstream>
-MovementGenerator::~MovementGenerator() { }
+MovementGenerator::~MovementGenerator()
+{
+ SetScriptResult(MovementStopReason::Interrupted);
+}
std::string MovementGenerator::GetDebugInfo() const
{
@@ -38,6 +41,15 @@ std::string MovementGenerator::GetDebugInfo() const
return sstr.str();
}
+void MovementGenerator::SetScriptResult(MovementStopReason reason)
+{
+ if (ScriptResult)
+ {
+ ScriptResult->SetResult(reason);
+ ScriptResult.reset();
+ }
+}
+
IdleMovementFactory::IdleMovementFactory() : MovementGeneratorCreator(IDLE_MOTION_TYPE) { }
MovementGenerator* IdleMovementFactory::Create(Unit* /*object*/) const
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index a2c43528e49..79d3a5b9191 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -22,6 +22,8 @@
#include "FactoryHolder.h"
#include "MovementDefines.h"
#include "ObjectRegistry.h"
+#include "Optional.h"
+#include "ScriptActionResult.h"
class Creature;
class Unit;
@@ -85,6 +87,10 @@ class TC_GAME_API MovementGenerator
uint8 Priority;
uint16 Flags;
uint32 BaseUnitState;
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>> ScriptResult;
+
+ protected:
+ void SetScriptResult(MovementStopReason reason);
};
template<class T, class D>
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
index bedeccbe350..3e03b58d28c 100644
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -26,12 +26,14 @@
#define MIN_QUIET_DISTANCE 28.0f
#define MAX_QUIET_DISTANCE 43.0f
-FleeingMovementGenerator::FleeingMovementGenerator(ObjectGuid fleeTargetGUID) : _fleeTargetGUID(fleeTargetGUID), _timer(0)
+FleeingMovementGenerator::FleeingMovementGenerator(ObjectGuid fleeTargetGUID,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/) : _fleeTargetGUID(fleeTargetGUID), _timer(0)
{
Mode = MOTION_MODE_DEFAULT;
Priority = MOTION_PRIORITY_HIGHEST;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_FLEEING;
+ ScriptResult = std::move(scriptResult);
}
MovementGeneratorType FleeingMovementGenerator::GetMovementGeneratorType() const
@@ -89,7 +91,7 @@ void FleeingMovementGenerator::Deactivate(Unit* owner)
owner->ClearUnitState(UNIT_STATE_FLEEING_MOVE);
}
-void FleeingMovementGenerator::Finalize(Unit* owner, bool active, bool /*movementInform*/)
+void FleeingMovementGenerator::Finalize(Unit* owner, bool active, bool movementInform)
{
AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
@@ -105,6 +107,9 @@ void FleeingMovementGenerator::Finalize(Unit* owner, bool active, bool /*movemen
else if (owner->IsPlayer())
owner->StopMoving();
}
+
+ if (movementInform)
+ SetScriptResult(MovementStopReason::Finished);
}
void FleeingMovementGenerator::SetTargetLocation(Unit* owner)
@@ -223,6 +228,8 @@ void TimedFleeingMovementGenerator::Finalize(Unit* owner, bool active, bool move
if (movementInform)
{
+ SetScriptResult(MovementStopReason::Finished);
+
Creature* ownerCreature = owner->ToCreature();
if (CreatureAI* AI = ownerCreature ? ownerCreature->AI() : nullptr)
AI->MovementInform(TIMED_FLEEING_MOTION_TYPE, 0);
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
index 3e039265963..d8a28e9e54b 100755
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
@@ -28,7 +28,8 @@ struct Position;
class FleeingMovementGenerator : public MovementGenerator
{
public:
- explicit FleeingMovementGenerator(ObjectGuid fleeTargetGUID);
+ explicit FleeingMovementGenerator(ObjectGuid fleeTargetGUID,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
MovementGeneratorType GetMovementGeneratorType() const override;
@@ -52,7 +53,9 @@ class FleeingMovementGenerator : public MovementGenerator
class TimedFleeingMovementGenerator : public FleeingMovementGenerator
{
public:
- explicit TimedFleeingMovementGenerator(ObjectGuid fleeTargetGUID, Milliseconds time) : FleeingMovementGenerator(fleeTargetGUID), _totalFleeTime(time) { }
+ explicit TimedFleeingMovementGenerator(ObjectGuid fleeTargetGUID, Milliseconds time,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {})
+ : FleeingMovementGenerator(fleeTargetGUID, std::move(scriptResult)), _totalFleeTime(time) { }
bool Update(Unit*, uint32) override;
void Finalize(Unit*, bool, bool) override;
diff --git a/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.cpp
index 02184136e2c..0a95fad135e 100644
--- a/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.cpp
@@ -32,7 +32,8 @@
#define SKIP_SPLINE_POINT_DISTANCE_SQ (40.f * 40.f)
#define PLAYER_FLIGHT_SPEED 32.0f
-FlightPathMovementGenerator::FlightPathMovementGenerator(Optional<float> speed)
+FlightPathMovementGenerator::FlightPathMovementGenerator(Optional<float> speed,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult)
{
_speed = speed;
_endGridX = 0.0f;
@@ -44,6 +45,7 @@ FlightPathMovementGenerator::FlightPathMovementGenerator(Optional<float> speed)
Priority = MOTION_PRIORITY_HIGHEST;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_IN_FLIGHT;
+ ScriptResult = std::move(scriptResult);
}
MovementGeneratorType FlightPathMovementGenerator::GetMovementGeneratorType() const
@@ -152,7 +154,7 @@ void FlightPathMovementGenerator::DoDeactivate(Player* /*owner*/)
AddFlag(MOVEMENTGENERATOR_FLAG_DEACTIVATED);
}
-void FlightPathMovementGenerator::DoFinalize(Player* owner, bool active, bool/* movementInform*/)
+void FlightPathMovementGenerator::DoFinalize(Player* owner, bool active, bool movementInform)
{
AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
if (!active)
@@ -179,6 +181,9 @@ void FlightPathMovementGenerator::DoFinalize(Player* owner, bool active, bool/*
}
owner->RemovePlayerFlag(PLAYER_FLAGS_TAXI_BENCHMARK);
+
+ if (movementInform)
+ SetScriptResult(MovementStopReason::Finished);
}
uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
diff --git a/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.h
index 2abc4c275f4..ada9c742781 100644
--- a/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/FlightPathMovementGenerator.h
@@ -33,7 +33,8 @@ struct TaxiPathNodeEntry;
class FlightPathMovementGenerator : public MovementGeneratorMedium<Player, FlightPathMovementGenerator>, public PathMovementBase<Player, std::vector<TaxiPathNodeEntry const*>>
{
public:
- explicit FlightPathMovementGenerator(Optional<float> speed);
+ explicit FlightPathMovementGenerator(Optional<float> speed,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult);
MovementGeneratorType GetMovementGeneratorType() const override;
bool GetResetPosition(Unit* owner, float& x, float& y, float& z) override;
diff --git a/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.cpp
index a1ad2219d88..475a30481e5 100644
--- a/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.cpp
@@ -35,13 +35,15 @@ static void DoMovementInform(Unit* owner, Unit* target)
AI->MovementInform(FOLLOW_MOTION_TYPE, target->GetGUID().GetCounter());
}
-FollowMovementGenerator::FollowMovementGenerator(Unit* target, float range, ChaseAngle angle, Optional<Milliseconds> duration)
+FollowMovementGenerator::FollowMovementGenerator(Unit* target, float range, ChaseAngle angle, Optional<Milliseconds> duration,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
: AbstractFollower(ASSERT_NOTNULL(target)), _range(range), _angle(angle), _checkTimer(CHECK_INTERVAL)
{
Mode = MOTION_MODE_DEFAULT;
Priority = MOTION_PRIORITY_NORMAL;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_FOLLOW;
+ ScriptResult = std::move(scriptResult);
if (duration)
_duration.emplace(*duration);
}
@@ -196,13 +198,15 @@ void FollowMovementGenerator::Deactivate(Unit* owner)
owner->ClearUnitState(UNIT_STATE_FOLLOW_MOVE);
}
-void FollowMovementGenerator::Finalize(Unit* owner, bool active, bool/* movementInform*/)
+void FollowMovementGenerator::Finalize(Unit* owner, bool active, bool movementInform)
{
AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
if (active)
{
owner->ClearUnitState(UNIT_STATE_FOLLOW_MOVE);
UpdatePetSpeed(owner);
+ if (movementInform)
+ SetScriptResult(MovementStopReason::Finished);
}
}
diff --git a/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.h
index 27c3bd3bcf5..300ab9ce555 100644
--- a/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/FollowMovementGenerator.h
@@ -21,7 +21,6 @@
#include "AbstractFollower.h"
#include "MovementDefines.h"
#include "MovementGenerator.h"
-#include "Optional.h"
#include "Position.h"
#include "Timer.h"
@@ -33,7 +32,8 @@ class Unit;
class FollowMovementGenerator : public MovementGenerator, public AbstractFollower
{
public:
- explicit FollowMovementGenerator(Unit* target, float range, ChaseAngle angle, Optional<Milliseconds> duration);
+ explicit FollowMovementGenerator(Unit* target, float range, ChaseAngle angle, Optional<Milliseconds> duration,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
~FollowMovementGenerator();
void Initialize(Unit*) override;
diff --git a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp
index 7bd9d084bc4..090f129cd8a 100644
--- a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.cpp
@@ -40,6 +40,7 @@ GenericMovementGenerator::GenericMovementGenerator(std::function<void(Movement::
_duration.emplace(*args.Duration);
_durationTracksSpline = false;
}
+ ScriptResult = std::move(args.ScriptResult);
}
void GenericMovementGenerator::Initialize(Unit* owner)
@@ -101,6 +102,8 @@ void GenericMovementGenerator::MovementInform(Unit* owner)
if (_arrivalSpellId)
owner->CastSpell(ObjectAccessor::GetUnit(*owner, _arrivalSpellTargetGuid), _arrivalSpellId, true);
+ SetScriptResult(MovementStopReason::Finished);
+
if (Creature* creature = owner->ToCreature())
{
if (creature->AI())
diff --git a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h
index f9c46515e6b..f88b53c3fb0 100644
--- a/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/GenericMovementGenerator.h
@@ -32,6 +32,7 @@ struct GenericMovementGeneratorArgs
Optional<uint32> ArrivalSpellId;
Optional<ObjectGuid> ArrivalSpellTarget;
Optional<Milliseconds> Duration;
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>> ScriptResult;
};
class GenericMovementGenerator : public MovementGenerator
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
index 7aa6a59178c..1b524873841 100644
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
@@ -63,13 +63,16 @@ MovementGeneratorType IdleMovementGenerator::GetMovementGeneratorType() const
//----------------------------------------------------//
RotateMovementGenerator::RotateMovementGenerator(uint32 id, RotateDirection direction, Optional<Milliseconds> duration,
- Optional<float> turnSpeed, Optional<float> totalTurnAngle) : _id(id), _duration(duration), _turnSpeed(turnSpeed), _totalTurnAngle(totalTurnAngle),
+ Optional<float> turnSpeed, Optional<float> totalTurnAngle,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult) : _id(id), _duration(duration),
+ _turnSpeed(turnSpeed), _totalTurnAngle(totalTurnAngle),
_direction(direction), _diffSinceLastUpdate(0)
{
Mode = MOTION_MODE_DEFAULT;
Priority = MOTION_PRIORITY_NORMAL;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_ROTATING;
+ ScriptResult = std::move(scriptResult);
}
void RotateMovementGenerator::Initialize(Unit* owner)
@@ -142,8 +145,12 @@ void RotateMovementGenerator::Finalize(Unit* owner, bool/* active*/, bool moveme
{
AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
- if (movementInform && owner->GetTypeId() == TYPEID_UNIT)
- owner->ToCreature()->AI()->MovementInform(ROTATE_MOTION_TYPE, _id);
+ if (movementInform)
+ {
+ SetScriptResult(MovementStopReason::Finished);
+ if (owner->IsCreature())
+ owner->ToCreature()->AI()->MovementInform(ROTATE_MOTION_TYPE, _id);
+ }
}
MovementGeneratorType RotateMovementGenerator::GetMovementGeneratorType() const
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
index d525b9200f8..6e9fe57ba9f 100755
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
@@ -43,7 +43,8 @@ class RotateMovementGenerator : public MovementGenerator
static constexpr float MIN_ANGLE_DELTA_FOR_FACING_UPDATE = 0.05f;
explicit RotateMovementGenerator(uint32 id, RotateDirection direction, Optional<Milliseconds> duration,
- Optional<float> turnSpeed, Optional<float> totalTurnAngle);
+ Optional<float> turnSpeed, Optional<float> totalTurnAngle,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult);
void Initialize(Unit*) override;
void Reset(Unit*) override;
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index a626e6ece49..60c4b73a8e8 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -31,7 +31,7 @@
PointMovementGenerator::PointMovementGenerator(uint32 id, float x, float y, float z, bool generatePath, Optional<float> speed /*= {}*/, Optional<float> finalOrient /*= {}*/,
Unit const* faceTarget /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/,
MovementWalkRunSpeedSelectionMode speedSelectionMode /*= MovementWalkRunSpeedSelectionMode::Default*/,
- Optional<float> closeEnoughDistance /*= {}*/)
+ Optional<float> closeEnoughDistance /*= {}*/, Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
: _movementId(id), _destination(x, y, z), _speed(speed), _generatePath(generatePath), _finalOrient(finalOrient),
i_faceTarget(faceTarget), _speedSelectionMode(speedSelectionMode), _closeEnoughDistance(closeEnoughDistance)
{
@@ -39,6 +39,7 @@ PointMovementGenerator::PointMovementGenerator(uint32 id, float x, float y, floa
this->Priority = MOTION_PRIORITY_NORMAL;
this->Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
this->BaseUnitState = UNIT_STATE_ROAMING;
+ this->ScriptResult = std::move(scriptResult);
if (spellEffectExtraData)
this->i_spellEffectExtra = std::make_unique<Movement::SpellEffectExtraData>(*spellEffectExtraData);
@@ -195,6 +196,8 @@ void PointMovementGenerator::Finalize(Unit* owner, bool active, bool movementInf
void PointMovementGenerator::MovementInform(Unit* owner)
{
+ SetScriptResult(MovementStopReason::Finished);
+
// deliver EVENT_CHARGE to scripts, EVENT_CHARGE_PREPATH is just internal implementation detail of this movement generator
uint32 movementId = _movementId == EVENT_CHARGE_PREPATH ? uint32(EVENT_CHARGE) : _movementId;
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
index 8666a2ccc57..ea5ffc8ada3 100644
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
@@ -19,7 +19,6 @@
#define TRINITY_POINTMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
-#include "Optional.h"
#include "Position.h"
class Creature;
@@ -34,7 +33,8 @@ class PointMovementGenerator : public MovementGenerator
explicit PointMovementGenerator(uint32 id, float x, float y, float z, bool generatePath, Optional<float> speed = {}, Optional<float> finalOrient = {},
Unit const* faceTarget = nullptr, Movement::SpellEffectExtraData const* spellEffectExtraData = nullptr,
MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
- Optional<float> closeEnoughDistance = {});
+ Optional<float> closeEnoughDistance = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
MovementGeneratorType GetMovementGeneratorType() const override;
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 1e2298ed088..e1ab9c3ad38 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -18,24 +18,28 @@
#include "RandomMovementGenerator.h"
#include "Creature.h"
#include "CreatureAI.h"
-#include "MovementDefines.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
+#include "MovementDefines.h"
#include "PathGenerator.h"
#include "Random.h"
template<class T>
-RandomMovementGenerator<T>::RandomMovementGenerator(float distance, Optional<Milliseconds> duration) : _timer(0), _reference(), _wanderDistance(distance), _wanderSteps(0)
+RandomMovementGenerator<T>::RandomMovementGenerator(float distance, Optional<Milliseconds> duration,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/) : _timer(0), _reference(), _wanderDistance(distance), _wanderSteps(0)
{
this->Mode = MOTION_MODE_DEFAULT;
this->Priority = MOTION_PRIORITY_NORMAL;
this->Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
this->BaseUnitState = UNIT_STATE_ROAMING;
+ this->ScriptResult = std::move(scriptResult);
if (duration)
_duration.emplace(*duration);
}
-template RandomMovementGenerator<Creature>::RandomMovementGenerator(float distance, Optional<Milliseconds> duration);
+template
+RandomMovementGenerator<Creature>::RandomMovementGenerator(float distance, Optional<Milliseconds> duration,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult);
template<class T>
MovementGeneratorType RandomMovementGenerator<T>::GetMovementGeneratorType() const
@@ -265,6 +269,9 @@ void RandomMovementGenerator<Creature>::DoFinalize(Creature* owner, bool active,
}
if (movementInform && HasFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED))
+ {
+ SetScriptResult(MovementStopReason::Finished);
if (owner->IsAIEnabled())
owner->AI()->MovementInform(RANDOM_MOTION_TYPE, 0);
+ }
}
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
index 5d6ff652f2b..f67b4096e70 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
@@ -29,7 +29,8 @@ template<class T>
class RandomMovementGenerator : public MovementGeneratorMedium<T, RandomMovementGenerator<T>>
{
public:
- explicit RandomMovementGenerator(float distance = 0.0f, Optional<Milliseconds> duration = {});
+ explicit RandomMovementGenerator(float distance = 0.0f, Optional<Milliseconds> duration = {},
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
MovementGeneratorType GetMovementGeneratorType() const override;
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index afbaae40562..55f462d3f41 100644
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -30,7 +30,8 @@
WaypointMovementGenerator<Creature>::WaypointMovementGenerator(uint32 pathId, bool repeating, Optional<Milliseconds> duration, Optional<float> speed,
MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
- Optional<float> wanderDistanceAtPathEnds, Optional<bool> followPathBackwardsFromEndToStart, bool generatePath)
+ Optional<float> wanderDistanceAtPathEnds, Optional<bool> followPathBackwardsFromEndToStart, bool generatePath,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
: _nextMoveTime(0), _pathId(pathId), _repeating(repeating), _loadedFromDB(true),
_speed(speed), _speedSelectionMode(speedSelectionMode), _waitTimeRangeAtPathEnd(std::move(waitTimeRangeAtPathEnd)),
_wanderDistanceAtPathEnds(wanderDistanceAtPathEnds), _followPathBackwardsFromEndToStart(followPathBackwardsFromEndToStart), _isReturningToStart(false),
@@ -40,13 +41,15 @@ WaypointMovementGenerator<Creature>::WaypointMovementGenerator(uint32 pathId, bo
Priority = MOTION_PRIORITY_NORMAL;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_ROAMING;
+ ScriptResult = std::move(scriptResult);
if (duration)
_duration.emplace(*duration);
}
WaypointMovementGenerator<Creature>::WaypointMovementGenerator(WaypointPath const& path, bool repeating, Optional<Milliseconds> duration, Optional<float> speed,
MovementWalkRunSpeedSelectionMode speedSelectionMode, Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd,
- Optional<float> wanderDistanceAtPathEnds, Optional<bool> followPathBackwardsFromEndToStart, bool generatePath)
+ Optional<float> wanderDistanceAtPathEnds, Optional<bool> followPathBackwardsFromEndToStart, bool generatePath,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult /*= {}*/)
: _nextMoveTime(0), _pathId(0), _repeating(repeating), _loadedFromDB(false),
_speed(speed), _speedSelectionMode(speedSelectionMode), _waitTimeRangeAtPathEnd(std::move(waitTimeRangeAtPathEnd)),
_wanderDistanceAtPathEnds(wanderDistanceAtPathEnds), _followPathBackwardsFromEndToStart(followPathBackwardsFromEndToStart), _isReturningToStart(false),
@@ -58,6 +61,7 @@ WaypointMovementGenerator<Creature>::WaypointMovementGenerator(WaypointPath cons
Priority = MOTION_PRIORITY_NORMAL;
Flags = MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING;
BaseUnitState = UNIT_STATE_ROAMING;
+ ScriptResult = std::move(scriptResult);
if (duration)
_duration.emplace(*duration);
}
@@ -166,6 +170,9 @@ bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* owner, uint32 diff)
{
RemoveFlag(MOVEMENTGENERATOR_FLAG_TRANSITORY);
AddFlag(MOVEMENTGENERATOR_FLAG_INFORM_ENABLED);
+ AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
+ owner->UpdateCurrentWaypointInfo(0, 0);
+ SetScriptResult(MovementStopReason::Finished);
return false;
}
}
@@ -248,7 +255,7 @@ void WaypointMovementGenerator<Creature>::DoDeactivate(Creature* owner)
owner->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
}
-void WaypointMovementGenerator<Creature>::DoFinalize(Creature* owner, bool active, bool/* movementInform*/)
+void WaypointMovementGenerator<Creature>::DoFinalize(Creature* owner, bool active, bool movementInform)
{
AddFlag(MOVEMENTGENERATOR_FLAG_FINALIZED);
if (active)
@@ -258,6 +265,9 @@ void WaypointMovementGenerator<Creature>::DoFinalize(Creature* owner, bool activ
// TODO: Research if this modification is needed, which most likely isnt
owner->SetWalk(false);
}
+
+ if (movementInform)
+ SetScriptResult(MovementStopReason::Finished);
}
void WaypointMovementGenerator<Creature>::MovementInform(Creature* owner)
@@ -353,6 +363,8 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun
// inform AI
if (CreatureAI* AI = owner->AI())
AI->WaypointPathEnded(waypoint.Id, GetPath()->Id);
+
+ SetScriptResult(MovementStopReason::Finished);
return;
}
}
@@ -391,7 +403,7 @@ void WaypointMovementGenerator<Creature>::StartMove(Creature* owner, bool relaun
init.SetAnimation(AnimTier::Ground);
break;
case WaypointMoveType::TakeOff:
- init.SetAnimation(AnimTier::Hover);
+ init.SetAnimation(AnimTier::Fly);
break;
case WaypointMoveType::Run:
init.SetWalk(false);
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
index 8de8f5de52b..23d5cc1c7c6 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
@@ -38,11 +38,13 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium<Creat
explicit WaypointMovementGenerator(uint32 pathId, bool repeating, Optional<Milliseconds> duration = {}, Optional<float> speed = {},
MovementWalkRunSpeedSelectionMode speedSelectionMode = MovementWalkRunSpeedSelectionMode::Default,
Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd = {}, Optional<float> wanderDistanceAtPathEnds = {},
- Optional<bool> followPathBackwardsFromEndToStart = {}, bool generatePath = true);
+ Optional<bool> followPathBackwardsFromEndToStart = {}, bool generatePath = true,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
explicit WaypointMovementGenerator(WaypointPath const& path, bool repeating, Optional<Milliseconds> duration, Optional<float> speed,
MovementWalkRunSpeedSelectionMode speedSelectionMode,
Optional<std::pair<Milliseconds, Milliseconds>> waitTimeRangeAtPathEnd, Optional<float> wanderDistanceAtPathEnds,
- Optional<bool> followPathBackwardsFromEndToStart, bool generatePath);
+ Optional<bool> followPathBackwardsFromEndToStart, bool generatePath,
+ Optional<Scripting::v2::ActionResultSetter<MovementStopReason>>&& scriptResult = {});
~WaypointMovementGenerator();
MovementGeneratorType GetMovementGeneratorType() const override;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index bb43a8be767..9927b4f7ec2 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -3882,6 +3882,9 @@ void Spell::_cast(bool skipCheck)
handle_immediate();
}
+ if (m_scriptResult && !m_scriptWaitsForSpellHit)
+ m_scriptResult->SetResult(SPELL_CAST_OK);
+
CallScriptAfterCastHandlers();
if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(SPELL_LINK_CAST, m_spellInfo->Id))
@@ -4313,6 +4316,9 @@ void Spell::finish(SpellCastResult result)
return;
m_spellState = SPELL_STATE_FINISHED;
+ if (m_scriptResult && (m_scriptWaitsForSpellHit || result != SPELL_CAST_OK))
+ m_scriptResult->SetResult(result);
+
if (!m_caster)
return;
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 0c484b5ba56..e9ec910e322 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -603,6 +603,9 @@ class TC_GAME_API Spell
UsedSpellMods m_appliedMods;
+ Optional<Scripting::v2::ActionResultSetter<SpellCastResult>> m_scriptResult;
+ bool m_scriptWaitsForSpellHit = false;
+
int32 GetCastTime() const { return m_casttime; }
int32 GetRemainingCastTime() const { return m_timer; }
bool IsAutoRepeat() const { return m_autoRepeat; }
diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h
index 8e9b6d3ada5..7458c8925f5 100644
--- a/src/server/game/Spells/SpellDefines.h
+++ b/src/server/game/Spells/SpellDefines.h
@@ -24,6 +24,7 @@
#include "ObjectGuid.h"
#include "Optional.h"
#include "Position.h"
+#include "ScriptActionResult.h"
#include <any>
#include <vector>
@@ -38,6 +39,7 @@ class WorldObject;
enum Difficulty : uint8;
enum ProcFlags : uint32;
enum ProcFlags2 : int32;
+enum SpellCastResult : int32;
namespace UF
{
@@ -474,6 +476,8 @@ struct TC_GAME_API CastSpellExtraArgs
CastSpellExtraArgs& AddSpellMod(SpellValueMod mod, int32 val) { SpellValueOverrides.AddMod(mod, val); return *this; }
CastSpellExtraArgs& AddSpellBP0(int32 val) { return AddSpellMod(SPELLVALUE_BASE_POINT0, val); } // because i don't want to type SPELLVALUE_BASE_POINT0 300 times
CastSpellExtraArgs& SetCustomArg(std::any customArg) { CustomArg = std::move(customArg); return *this; }
+ CastSpellExtraArgs& SetScriptResult(Scripting::v2::ActionResultSetter<SpellCastResult> scriptResult) { ScriptResult.emplace(std::move(scriptResult)); return *this; }
+ CastSpellExtraArgs& SetScriptWaitsForSpellHit(bool scriptWaitsForSpellHit) { ScriptWaitsForSpellHit = scriptWaitsForSpellHit; return *this; }
TriggerCastFlags TriggerFlags = TRIGGERED_NONE;
Item* CastItem = nullptr;
@@ -497,6 +501,9 @@ struct TC_GAME_API CastSpellExtraArgs
std::vector<std::pair<SpellValueMod, int32>> data;
} SpellValueOverrides;
std::any CustomArg;
+
+ Optional<Scripting::v2::ActionResultSetter<SpellCastResult>> ScriptResult;
+ bool ScriptWaitsForSpellHit = false;
};
struct SpellCastVisual