From 8734c3a428044eab3ef731b2b4b451a61bfb7280 Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sat, 5 Mar 2022 22:36:04 -0800 Subject: [PATCH] Fix other character walk animations Pass target x/y coordinate and direction to animation notifier(s) instead of updating state in the packet handler directly. Relies on animator to control where the character is positioned. --- EOBot/Program.cs | 3 +- .../IOtherCharacterAnimationNotifier.cs | 4 +-- EOLib/PacketHandlers/PlayerWalkHandler.cs | 28 +------------------ .../Character/CharacterAnimationActions.cs | 5 ++-- .../Rendering/Character/CharacterAnimator.cs | 24 ++++++++++------ 5 files changed, 24 insertions(+), 40 deletions(-) diff --git a/EOBot/Program.cs b/EOBot/Program.cs index 87d5fb294..d7c96f022 100644 --- a/EOBot/Program.cs +++ b/EOBot/Program.cs @@ -1,5 +1,6 @@ using AutomaticTypeMapper; using EOBot.Interpreter; +using EOLib; using EOLib.Domain.Character; using EOLib.Domain.Extensions; using EOLib.Domain.Map; @@ -151,7 +152,7 @@ public void NotifySelfSpellCast(short playerId, short spellId, int spellHp, byte public void NotifyStartSpellCast(short playerId, short spellId) { } public void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerID, short spellId, int recoveredHP, byte targetPercentHealth) { } public void StartOtherCharacterAttackAnimation(int characterID) { } - public void StartOtherCharacterWalkAnimation(int characterID) { } + public void StartOtherCharacterWalkAnimation(int characterID, byte destinationX, byte destinationY, EODirection direction) { } } static async Task Main(string[] args) diff --git a/EOLib/Domain/Notifiers/IOtherCharacterAnimationNotifier.cs b/EOLib/Domain/Notifiers/IOtherCharacterAnimationNotifier.cs index f06a97b49..a096be63f 100644 --- a/EOLib/Domain/Notifiers/IOtherCharacterAnimationNotifier.cs +++ b/EOLib/Domain/Notifiers/IOtherCharacterAnimationNotifier.cs @@ -4,7 +4,7 @@ namespace EOLib.Domain.Notifiers { public interface IOtherCharacterAnimationNotifier { - void StartOtherCharacterWalkAnimation(int characterID); + void StartOtherCharacterWalkAnimation(int characterID, byte destinationX, byte destinationY, EODirection direction); void StartOtherCharacterAttackAnimation(int characterID); @@ -18,7 +18,7 @@ public interface IOtherCharacterAnimationNotifier [AutoMappedType] public class NoOpOtherCharacterAnimationNotifier : IOtherCharacterAnimationNotifier { - public void StartOtherCharacterWalkAnimation(int characterID) { } + public void StartOtherCharacterWalkAnimation(int characterID, byte destinationX, byte destinationY, EODirection direction) { } public void StartOtherCharacterAttackAnimation(int characterID) { } diff --git a/EOLib/PacketHandlers/PlayerWalkHandler.cs b/EOLib/PacketHandlers/PlayerWalkHandler.cs index 6232bf0e5..496a0da34 100644 --- a/EOLib/PacketHandlers/PlayerWalkHandler.cs +++ b/EOLib/PacketHandlers/PlayerWalkHandler.cs @@ -38,36 +38,10 @@ public override bool HandlePacket(IPacket packet) var x = packet.ReadChar(); var y = packet.ReadChar(); - ICharacter character; - try - { - character = _currentMapStateRepository.Characters.Single(cc => cc.ID == characterID); - } - catch (InvalidOperationException) { return false; } - - var renderProperties = character.RenderProperties.WithDirection(dir); - renderProperties = EnsureCorrectXAndY(renderProperties, x, y); - var newCharacter = character.WithRenderProperties(renderProperties); - - _currentMapStateRepository.Characters.Remove(character); - _currentMapStateRepository.Characters.Add(newCharacter); - foreach (var notifier in _otherCharacterAnimationNotifiers) - notifier.StartOtherCharacterWalkAnimation(characterID); + notifier.StartOtherCharacterWalkAnimation(characterID, x, y, dir); return true; } - - private static ICharacterRenderProperties EnsureCorrectXAndY(ICharacterRenderProperties renderProperties, byte x, byte y) - { - var opposite = renderProperties.Direction.Opposite(); - var tempRenderProperties = renderProperties - .WithDirection(opposite) - .WithMapX(x) - .WithMapY(y); - return renderProperties - .WithMapX(tempRenderProperties.GetDestinationX()) - .WithMapY(tempRenderProperties.GetDestinationY()); - } } } diff --git a/EndlessClient/Rendering/Character/CharacterAnimationActions.cs b/EndlessClient/Rendering/Character/CharacterAnimationActions.cs index 9a741b3c7..2b695b5c1 100644 --- a/EndlessClient/Rendering/Character/CharacterAnimationActions.cs +++ b/EndlessClient/Rendering/Character/CharacterAnimationActions.cs @@ -81,12 +81,13 @@ public void StartAttacking() _characterRendererProvider.MainCharacterRenderer); } - public void StartOtherCharacterWalkAnimation(int characterID) + public void StartOtherCharacterWalkAnimation(int characterID, byte destinationX, byte destinationY, EODirection direction) { if (!_hudControlProvider.IsInGame) return; - Animator.StartOtherCharacterWalkAnimation(characterID); + Animator.StartOtherCharacterWalkAnimation(characterID, destinationX, destinationY, direction); + ShowWaterSplashiesIfNeeded(CharacterActionState.Walking, _currentMapStateProvider.Characters.Single(x => x.ID == characterID), _characterRendererProvider.CharacterRenderers[characterID]); diff --git a/EndlessClient/Rendering/Character/CharacterAnimator.cs b/EndlessClient/Rendering/Character/CharacterAnimator.cs index edf55bbab..744539e13 100644 --- a/EndlessClient/Rendering/Character/CharacterAnimator.cs +++ b/EndlessClient/Rendering/Character/CharacterAnimator.cs @@ -23,6 +23,7 @@ public class CharacterAnimator : GameComponent, ICharacterAnimator private readonly ICharacterActions _characterActions; private readonly Dictionary _queuedDirections; + private readonly Dictionary _queuedPositions; private readonly Dictionary _otherPlayerStartWalkingTimes; private readonly Dictionary _otherPlayerStartAttackingTimes; private readonly Dictionary _otherPlayerStartSpellCastTimes; @@ -40,6 +41,7 @@ public class CharacterAnimator : GameComponent, ICharacterAnimator _characterActions = characterActions; _queuedDirections = new Dictionary(); + _queuedPositions = new Dictionary(); _otherPlayerStartWalkingTimes = new Dictionary(); _otherPlayerStartAttackingTimes = new Dictionary(); _otherPlayerStartSpellCastTimes = new Dictionary(); @@ -100,16 +102,14 @@ public void StartMainCharacterAttackAnimation() _otherPlayerStartAttackingTimes.Add(_characterRepository.MainCharacter.ID, startAttackingTime); } - public void StartOtherCharacterWalkAnimation(int characterID) + public void StartOtherCharacterWalkAnimation(int characterID, byte destinationX, byte destinationY, EODirection direction) { - if (_otherPlayerStartWalkingTimes.ContainsKey(characterID) || - _otherPlayerStartSpellCastTimes.ContainsKey(characterID)) - return; - if (_otherPlayerStartWalkingTimes.TryGetValue(characterID, out var _)) { - ResetCharacterAnimationFrames(characterID); - _otherPlayerStartWalkingTimes.Remove(characterID); + _otherPlayerStartWalkingTimes[characterID].Replay = true; + _queuedDirections[characterID] = direction; + _queuedPositions[characterID] = new MapCoordinate(destinationX, destinationY); + return; } var startWalkingTimeAndID = new RenderFrameActionTime(characterID); @@ -202,6 +202,14 @@ private void AnimateCharacterWalking() } else { + if (_queuedPositions.ContainsKey(pair.UniqueID)) + { + nextFrameRenderProperties = nextFrameRenderProperties + .WithMapX(_queuedPositions[pair.UniqueID].X) + .WithMapY(_queuedPositions[pair.UniqueID].Y); + _queuedPositions.Remove(pair.UniqueID); + } + playersDoneWalking.Add(pair.UniqueID); } } @@ -365,7 +373,7 @@ public interface ICharacterAnimator : IGameComponent void StartMainCharacterAttackAnimation(); - void StartOtherCharacterWalkAnimation(int characterID); + void StartOtherCharacterWalkAnimation(int characterID, byte targetX, byte targetY, EODirection direction); void StartOtherCharacterAttackAnimation(int characterID);