From 889ffd07656ec000c8bfce9992d095720145639c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=82ngelo=20Tadeucci?= Date: Mon, 28 Apr 2025 09:45:39 -0300 Subject: [PATCH 1/4] Feat: Patrols with AirWaypoint --- Maple2.File.Ingest/Mapper/MapEntityMapper.cs | 2 +- Maple2.Model/Metadata/MapEntity/PatrolData.cs | 3 +- .../Manager/Field/AgentNavigation.cs | 23 ++++++++- .../ActorStateComponent/MovementState.cs | 13 +++++ .../MovementStateStates/MovementState.Walk.cs | 47 ++++++++++++++++- .../MovementState.WalkTask.cs | 50 +++++++++++++++++++ .../Model/Field/Actor/FieldNpc.cs | 30 ++++++++--- 7 files changed, 156 insertions(+), 12 deletions(-) diff --git a/Maple2.File.Ingest/Mapper/MapEntityMapper.cs b/Maple2.File.Ingest/Mapper/MapEntityMapper.cs index 1f9f481a4..11bcaddee 100644 --- a/Maple2.File.Ingest/Mapper/MapEntityMapper.cs +++ b/Maple2.File.Ingest/Mapper/MapEntityMapper.cs @@ -225,7 +225,7 @@ private IEnumerable ParseMap(string xblock, IEnumerable e patrolData.ApproachAnims.TryGetValue(wayPointDict.Key, out string? approachAnimation); patrolData.ArriveAnims.TryGetValue(wayPointDict.Key, out string? arriveAnimation); patrolData.ArriveAnimsTime.TryGetValue(wayPointDict.Key, out uint arriveAnimationTime); - wayPoints.Add(new MS2WayPoint(wayPoint.EntityId, wayPoint.IsVisible, wayPoint.Position, wayPoint.Rotation, approachAnimation ?? "", arriveAnimation ?? "", (int) arriveAnimationTime)); + wayPoints.Add(new MS2WayPoint(wayPoint.EntityId, wayPoint.IsVisible, wayPoint.Position, wayPoint.Rotation, approachAnimation ?? "", arriveAnimation ?? "", (int) arriveAnimationTime, patrolData.IsAirWayPoint)); } diff --git a/Maple2.Model/Metadata/MapEntity/PatrolData.cs b/Maple2.Model/Metadata/MapEntity/PatrolData.cs index bb1f7e951..12fad9bce 100644 --- a/Maple2.Model/Metadata/MapEntity/PatrolData.cs +++ b/Maple2.Model/Metadata/MapEntity/PatrolData.cs @@ -19,5 +19,6 @@ public record MS2WayPoint( Vector3 Rotation, string ApproachAnimation, string ArriveAnimation, - int ArriveAnimationTime + int ArriveAnimationTime, + bool AirWayPoint ); diff --git a/Maple2.Server.Game/Manager/Field/AgentNavigation.cs b/Maple2.Server.Game/Manager/Field/AgentNavigation.cs index 12b536879..4e32ef499 100644 --- a/Maple2.Server.Game/Manager/Field/AgentNavigation.cs +++ b/Maple2.Server.Game/Manager/Field/AgentNavigation.cs @@ -72,7 +72,7 @@ public AgentNavigation(FieldNpc fieldNpc, DtCrowdAgent dtAgent, DtCrowd dtCrowd) while (pathIterPolysCount > 0 && smoothPath.Count < MAX_SMOOTH) { // Find location to steer towards. if (!DtPathUtils.GetSteerTarget(navMeshQuery, iterPos, endPos, DotRecastHelper.MIN_TARGET_DIST, - pathIterPolys, pathIterPolysCount, out var steerPos, out int steerPosFlag, out long steerPosRef)) { + pathIterPolys, pathIterPolysCount, out var steerPos, out int steerPosFlag, out long steerPosRef)) { break; } @@ -221,6 +221,27 @@ public Vector3 GetAgentPosition() { return (start, DotRecastHelper.FromNavMeshSpace(end)); } + /// + /// Advances the actor in a straight line towards the target position, ignoring navmesh. + /// + /// Current position + /// Target position + /// Movement speed + /// Time in seconds + /// Tuple of (new position, reachedTarget) + public (Vector3 newPosition, bool reachedTarget) FlyAdvance(Vector3 start, Vector3 target, float speed, float deltaTime) { + Vector3 direction = target - start; + float distance = direction.Length(); + if (distance == 0) return (target, true); + + float moveDist = speed * deltaTime; + if (moveDist >= distance) { + return (target, true); + } + Vector3 step = direction / distance * moveDist; + return (start + step, false); + } + public Vector3 GetRandomPatrolPoint() { if (!field.FindNearestPoly(npc.Origin, out long startRef, out RcVec3f startVec)) { return npc.Position; diff --git a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs index 04678a7d7..dd6515a8a 100644 --- a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs +++ b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs @@ -72,6 +72,19 @@ public NpcTask TryMoveTo(Vector3 position, bool isBattle, string sequence = "", }; } + public NpcTask TryFlyTo(Vector3 position, bool isBattle, string sequence = "", float speed = 0, bool lookAt = false) { + walkTask?.Cancel(); + + NpcTaskPriority priority = isBattle ? NpcTaskPriority.BattleWalk : NpcTaskPriority.IdleAction; + + return new NpcFlyToTask(actor.TaskState, priority, this) { + Position = position, + Sequence = sequence, + Speed = speed, + LookAt = lookAt, + }; + } + public NpcTask TryMoveTargetDistance(IActor target, float distance, bool isBattle, string sequence = "", float speed = 0) { walkTask?.Cancel(); diff --git a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs index 0bf75bf25..6df8de529 100644 --- a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs +++ b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs @@ -1,5 +1,4 @@ - -using Maple2.Model.Enum; +using Maple2.Model.Enum; using Maple2.Model.Metadata; using Maple2.Server.Game.Model.Enum; using System.Numerics; @@ -58,6 +57,30 @@ private void StartWalking(string sequence, NpcTask task) { } } + private void StartFlying(string sequence, NpcTask task) { + sequence = sequence == "" ? "Fly_A" : sequence; + walkSegmentSet = false; + walkSpeed = Speed; + + emoteActionTask?.Cancel(); + + bool isFlying = sequence.StartsWith("Fly_"); + + baseSpeed = isFlying ? actor.Value.Metadata.Action.WalkSpeed : actor.Value.Metadata.Action.RunSpeed; + + if (actor.Animation.PlayingSequence?.Name == sequence || actor.Animation.TryPlaySequence(sequence, aniSpeed * Speed, AnimationType.Misc)) { + stateSequence = actor.Animation.PlayingSequence; + walkSequence = stateSequence; + walkTask = task; + + SetState(ActorState.Walk); + } else { + task.Cancel(); + + Idle("Fly_A"); + } + } + public bool IsMovingToTarget() { return State == ActorState.Walk && walkType switch { WalkType.MoveTo => true, @@ -89,7 +112,26 @@ private void StateWalkUpdate(long tickCount, long tickDelta) { if (walkType == WalkType.Direction) { StateWalkDirectionUpdate(tickCount, tickDelta, delta); + return; + } + // --- FLYING ADVANCE LOGIC --- + // If we're flying (sequence starts with "Fly_"), use direct advance + if (walkSequence != null && walkSequence.Name.StartsWith("Fly_")) { + Vector3 target = walkTargetPosition; + (Vector3 newPos, bool reachedFlying) = actor.Navigation.FlyAdvance(actor.Position, target, Speed, delta); + + Velocity = (newPos - actor.Position) / delta; + actor.Position = newPos; + + if (walkLookWhenDone && (target - actor.Position).LengthSquared() > 0) { + actor.Transform.LookTo(Vector3.Normalize(target - actor.Position)); + } + + if (reachedFlying) { + Velocity = new Vector3(0, 0, 0); + walkTask?.Completed(); + } return; } @@ -180,3 +222,4 @@ public void StateWalkEvent(string keyName) { } } } + diff --git a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs index 82cd81126..f3f4d87c8 100644 --- a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs +++ b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs @@ -4,6 +4,7 @@ using static Maple2.Server.Game.Model.ActorStateComponent.TaskState; namespace Maple2.Server.Game.Model.ActorStateComponent; + public partial class MovementState { public class NpcMoveDirectionTask : NpcTask { @@ -75,6 +76,32 @@ protected override void TaskFinished(bool isCompleted) { } } + public class NpcFlyToTask : NpcTask { + private readonly MovementState movement; + public Vector3 Position { get; init; } + public string Sequence { get; init; } = ""; + public float Speed { get; init; } + public bool LookAt { get; init; } + public override bool CancelOnInterrupt => Priority == NpcTaskPriority.IdleAction; + + public NpcFlyToTask(TaskState taskState, NpcTaskPriority priority, MovementState movement) : base(taskState, priority) { + this.movement = movement; + } + + protected override void TaskResumed() { + movement.FlyTo(this, Position, Sequence, Speed, LookAt); + } + + protected override void TaskPaused() { + movement.Idle("Fly_A"); + } + + protected override void TaskFinished(bool isCompleted) { + movement.walkTask = null; + movement.Idle("Fly_A"); + } + } + private void MoveTo(NpcTask task, Vector3 position, string sequence, float speed, bool lookAt) { if (!CanTransitionToState(ActorState.Walk)) { task.Cancel(); @@ -107,6 +134,29 @@ private void MoveTo(NpcTask task, Vector3 position, string sequence, float speed StartWalking(sequence, task); } + private void FlyTo(NpcTask task, Vector3 position, string sequence, float speed, bool lookAt) { + if (!CanTransitionToState(ActorState.Walk)) { + task.Cancel(); + return; + } + + if (actor.Navigation is null) { + task.Cancel(); + + return; + } + + actor.AppendDebugMessage($"> Flying to position\n"); + + walkTargetPosition = position; + walkType = WalkType.MoveTo; + walkLookWhenDone = lookAt; + walkTask = task; + + UpdateMoveSpeed(speed); + StartFlying(sequence, task); + } + public class NpcMoveTargetDistanceTask : NpcTask { private readonly MovementState movement; public IActor Target { get; init; } diff --git a/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs b/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs index f64b11ae8..28a4c7db6 100644 --- a/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs +++ b/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs @@ -75,6 +75,7 @@ public short SequenceId { public readonly AnimationSequenceMetadata IdleSequenceMetadata; public readonly AnimationSequenceMetadata? JumpSequence; public readonly AnimationSequenceMetadata? WalkSequence; + public readonly AnimationSequenceMetadata? FlySequence; public readonly AnimationSequenceMetadata? SpawnSequence; private readonly WeightedSet defaultRoutines; public readonly AiState AiState; @@ -98,6 +99,7 @@ public FieldNpc(FieldManager field, int objectId, DtCrowdAgent? agent, Npc npc, IdleSequenceMetadata = npc.Animations.GetValueOrDefault("Idle_A") ?? new AnimationSequenceMetadata(string.Empty, -1, 1f, null); JumpSequence = npc.Animations.GetValueOrDefault("Jump_A") ?? npc.Animations.GetValueOrDefault("Jump_B"); WalkSequence = npc.Animations.GetValueOrDefault("Walk_A"); + FlySequence = npc.Animations.GetValueOrDefault("Fly_A"); SpawnSequence = npc.Animations.GetValueOrDefault(spawnAnimation); defaultRoutines = new WeightedSet(); foreach (NpcAction action in Value.Metadata.Action.Actions) { @@ -258,25 +260,39 @@ public override void KeyframeEvent(string keyName) { private NpcTask? NextWaypoint() { MS2WayPoint currentWaypoint = Patrol!.WayPoints[currentWaypointIndex]; + MS2WayPoint? waypointBefore = null; + if (currentWaypointIndex != 0) { + waypointBefore = Patrol.WayPoints[currentWaypointIndex - 1]; + } - if (!string.IsNullOrEmpty(currentWaypoint.ArriveAnimation) && idleTask is not MovementState.NpcEmoteTask) { - if (Value.Animations.TryGetValue(currentWaypoint.ArriveAnimation, out AnimationSequenceMetadata? arriveSequence)) { + if (waypointBefore is not null && !string.IsNullOrEmpty(waypointBefore.ArriveAnimation) && idleTask is not (MovementState.NpcEmoteTask or null)) { + if (Value.Animations.TryGetValue(waypointBefore.ArriveAnimation, out AnimationSequenceMetadata? arriveSequence)) { return MovementState.TryEmote(arriveSequence.Name, false); } } NpcTask? approachTask = null; - if (Navigation!.PathTo(currentWaypoint.Position)) { + if (currentWaypoint.AirWayPoint) { if (Value.Animations.TryGetValue(currentWaypoint.ApproachAnimation, out AnimationSequenceMetadata? patrolSequence)) { - approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: patrolSequence.Name); - } else if (WalkSequence is not null) { - approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, WalkSequence.Name); + approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, lookAt: true); + } else if (FlySequence is not null) { + approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, FlySequence.Name, lookAt: true); } else { Logger.Warning("No walk sequence found for npc {NpcId} in patrol {PatrolId}", Value.Metadata.Id, Patrol.Uuid); } } else { - Logger.Warning("Failed to path to waypoint id({Id}) coord {Coord} for npc {NpcName} - {NpcId} in patrol {PatrolId}", currentWaypoint.Id, currentWaypoint.Position, Value.Metadata.Name, Value.Metadata.Id, Patrol.Uuid); + if (Navigation!.PathTo(currentWaypoint.Position)) { + if (Value.Animations.TryGetValue(currentWaypoint.ApproachAnimation, out AnimationSequenceMetadata? patrolSequence)) { + approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: patrolSequence.Name); + } else if (WalkSequence is not null) { + approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, WalkSequence.Name); + } else { + Logger.Warning("No walk sequence found for npc {NpcId} in patrol {PatrolId}", Value.Metadata.Id, Patrol.Uuid); + } + } else { + Logger.Warning("Failed to path to waypoint id({Id}) coord {Coord} for npc {NpcName} - {NpcId} in patrol {PatrolId}", currentWaypoint.Id, currentWaypoint.Position, Value.Metadata.Name, Value.Metadata.Id, Patrol.Uuid); + } } MS2WayPoint lastWaypoint = Patrol.WayPoints.Last(); From 2867de7054354ef432c1d8f1509d080bd1a73737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=82ngelo=20Tadeucci?= Date: Tue, 29 Apr 2025 09:38:21 -0300 Subject: [PATCH 2/4] fix air waypoints --- .../MovementStateStates/MovementState.Walk.cs | 29 ++----------------- .../MovementState.WalkTask.cs | 8 +++-- .../Model/Field/Actor/FieldNpc.cs | 12 ++++---- 3 files changed, 15 insertions(+), 34 deletions(-) diff --git a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs index 6df8de529..ec8fcc1f7 100644 --- a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs +++ b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs @@ -24,6 +24,7 @@ private enum WalkType { private AnimationSequenceMetadata? walkSequence = null; private float walkSpeed; private NpcTask? walkTask = null; + private bool isFlying; private void UpdateMoveSpeed(float speed) { Stat moveSpeed = actor.Stats.Values[BasicAttribute.MovementSpeed]; @@ -57,30 +58,6 @@ private void StartWalking(string sequence, NpcTask task) { } } - private void StartFlying(string sequence, NpcTask task) { - sequence = sequence == "" ? "Fly_A" : sequence; - walkSegmentSet = false; - walkSpeed = Speed; - - emoteActionTask?.Cancel(); - - bool isFlying = sequence.StartsWith("Fly_"); - - baseSpeed = isFlying ? actor.Value.Metadata.Action.WalkSpeed : actor.Value.Metadata.Action.RunSpeed; - - if (actor.Animation.PlayingSequence?.Name == sequence || actor.Animation.TryPlaySequence(sequence, aniSpeed * Speed, AnimationType.Misc)) { - stateSequence = actor.Animation.PlayingSequence; - walkSequence = stateSequence; - walkTask = task; - - SetState(ActorState.Walk); - } else { - task.Cancel(); - - Idle("Fly_A"); - } - } - public bool IsMovingToTarget() { return State == ActorState.Walk && walkType switch { WalkType.MoveTo => true, @@ -116,8 +93,8 @@ private void StateWalkUpdate(long tickCount, long tickDelta) { } // --- FLYING ADVANCE LOGIC --- - // If we're flying (sequence starts with "Fly_"), use direct advance - if (walkSequence != null && walkSequence.Name.StartsWith("Fly_")) { + // If isFlying, use direct advance + if (walkSequence != null && isFlying) { Vector3 target = walkTargetPosition; (Vector3 newPos, bool reachedFlying) = actor.Navigation.FlyAdvance(actor.Position, target, Speed, delta); diff --git a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs index f3f4d87c8..084b08368 100644 --- a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs +++ b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateTasks/MovementState.WalkTask.cs @@ -93,12 +93,13 @@ protected override void TaskResumed() { } protected override void TaskPaused() { - movement.Idle("Fly_A"); + movement.Idle(); } protected override void TaskFinished(bool isCompleted) { movement.walkTask = null; - movement.Idle("Fly_A"); + movement.isFlying = false; + movement.Idle(); } } @@ -152,9 +153,10 @@ private void FlyTo(NpcTask task, Vector3 position, string sequence, float speed, walkType = WalkType.MoveTo; walkLookWhenDone = lookAt; walkTask = task; + isFlying = true; UpdateMoveSpeed(speed); - StartFlying(sequence, task); + StartWalking(sequence, task); } public class NpcMoveTargetDistanceTask : NpcTask { diff --git a/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs b/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs index 28a4c7db6..6c06120d9 100644 --- a/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs +++ b/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs @@ -261,7 +261,9 @@ public override void KeyframeEvent(string keyName) { private NpcTask? NextWaypoint() { MS2WayPoint currentWaypoint = Patrol!.WayPoints[currentWaypointIndex]; MS2WayPoint? waypointBefore = null; - if (currentWaypointIndex != 0) { + if (Patrol.IsLoop) { + waypointBefore = Patrol.WayPoints[(currentWaypointIndex - 1 + Patrol.WayPoints.Count) % Patrol.WayPoints.Count]; + } else if (currentWaypointIndex != 0) { waypointBefore = Patrol.WayPoints[currentWaypointIndex - 1]; } @@ -275,18 +277,18 @@ public override void KeyframeEvent(string keyName) { if (currentWaypoint.AirWayPoint) { if (Value.Animations.TryGetValue(currentWaypoint.ApproachAnimation, out AnimationSequenceMetadata? patrolSequence)) { - approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, lookAt: true); + approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, speed: Patrol.PatrolSpeed, lookAt: true); } else if (FlySequence is not null) { - approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, FlySequence.Name, lookAt: true); + approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: FlySequence.Name, speed: Patrol.PatrolSpeed, lookAt: true); } else { Logger.Warning("No walk sequence found for npc {NpcId} in patrol {PatrolId}", Value.Metadata.Id, Patrol.Uuid); } } else { if (Navigation!.PathTo(currentWaypoint.Position)) { if (Value.Animations.TryGetValue(currentWaypoint.ApproachAnimation, out AnimationSequenceMetadata? patrolSequence)) { - approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: patrolSequence.Name); + approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, speed: Patrol.PatrolSpeed); } else if (WalkSequence is not null) { - approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, WalkSequence.Name); + approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: WalkSequence.Name, speed: Patrol.PatrolSpeed); } else { Logger.Warning("No walk sequence found for npc {NpcId} in patrol {PatrolId}", Value.Metadata.Id, Patrol.Uuid); } From 54e9850aa3ab3d951f255d4156ec537ba5d65115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=82ngelo=20Tadeucci?= Date: Thu, 29 May 2025 19:19:48 -0300 Subject: [PATCH 3/4] fix delta --- .../Model/Field/Actor/ActorStateComponent/MovementState.cs | 2 +- .../MovementStateStates/MovementState.Walk.cs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs index dd6515a8a..5b2af2aa3 100644 --- a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs +++ b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementState.cs @@ -206,7 +206,7 @@ public void Update(long tickCount) { return; } - long tickDelta = Math.Min(lastTick == 0 ? 0 : tickCount - lastTick, 20); + long tickDelta = Math.Min(lastTick == 0 ? 0 : tickCount - lastTick, 200); RemoveDebugMarker(debugNpc, tickCount); RemoveDebugMarker(debugTarget, tickCount); diff --git a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs index ec8fcc1f7..e2090e22c 100644 --- a/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs +++ b/Maple2.Server.Game/Model/Field/Actor/ActorStateComponent/MovementStateStates/MovementState.Walk.cs @@ -14,6 +14,7 @@ private enum WalkType { ToTarget, FromTarget } + private Vector3 walkDirection; private Vector3 walkTargetPosition; private float walkTargetDistance; @@ -86,7 +87,6 @@ private void StateWalkUpdate(long tickCount, long tickDelta) { UpdateMoveSpeed(speedOverride); float delta = (float) tickDelta / 1000; - if (walkType == WalkType.Direction) { StateWalkDirectionUpdate(tickCount, tickDelta, delta); return; @@ -106,7 +106,7 @@ private void StateWalkUpdate(long tickCount, long tickDelta) { } if (reachedFlying) { - Velocity = new Vector3(0, 0, 0); + Velocity = Vector3.Zero; walkTask?.Completed(); } return; @@ -199,4 +199,3 @@ public void StateWalkEvent(string keyName) { } } } - From f23b6fd697eb659a77387cb5561cfb123127417a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=82ngelo=20Tadeucci?= Date: Thu, 29 May 2025 20:20:14 -0300 Subject: [PATCH 4/4] fix patrol speed --- Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs b/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs index 6c06120d9..49e2ab508 100644 --- a/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs +++ b/Maple2.Server.Game/Model/Field/Actor/FieldNpc.cs @@ -277,18 +277,18 @@ public override void KeyframeEvent(string keyName) { if (currentWaypoint.AirWayPoint) { if (Value.Animations.TryGetValue(currentWaypoint.ApproachAnimation, out AnimationSequenceMetadata? patrolSequence)) { - approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, speed: Patrol.PatrolSpeed, lookAt: true); + approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, speed: Patrol.PatrolSpeed / 2, lookAt: true); } else if (FlySequence is not null) { - approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: FlySequence.Name, speed: Patrol.PatrolSpeed, lookAt: true); + approachTask = MovementState.TryFlyTo(currentWaypoint.Position, false, sequence: FlySequence.Name, speed: Patrol.PatrolSpeed / 2, lookAt: true); } else { Logger.Warning("No walk sequence found for npc {NpcId} in patrol {PatrolId}", Value.Metadata.Id, Patrol.Uuid); } } else { if (Navigation!.PathTo(currentWaypoint.Position)) { if (Value.Animations.TryGetValue(currentWaypoint.ApproachAnimation, out AnimationSequenceMetadata? patrolSequence)) { - approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, speed: Patrol.PatrolSpeed); + approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: patrolSequence.Name, speed: 1); } else if (WalkSequence is not null) { - approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: WalkSequence.Name, speed: Patrol.PatrolSpeed); + approachTask = MovementState.TryMoveTo(currentWaypoint.Position, false, sequence: WalkSequence.Name, speed: 1); } else { Logger.Warning("No walk sequence found for npc {NpcId} in patrol {PatrolId}", Value.Metadata.Id, Patrol.Uuid); }