Skip to content

Commit

Permalink
Update all animation timing to use tick-based approach. Fixes animati…
Browse files Browse the repository at this point in the history
…on timing issues and makes behavior more consistent with vanilla client
  • Loading branch information
ethanmoffat committed May 9, 2023
1 parent 2ff8af3 commit 859365f
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 180 deletions.
18 changes: 9 additions & 9 deletions EOLib/Domain/Character/CharacterActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ public class CharacterActions : ICharacterActions
private readonly IPacketSendService _packetSendService;
private readonly ICharacterRepository _characterRepository;
private readonly IESFFileProvider _spellFileProvider;
private readonly IGameStartTimeProvider _gameStartTimeProvider;
private readonly IFixedTimeStepRepository _fixedTimeStepRepository;

public CharacterActions(IPacketSendService packetSendService,
ICharacterRepository characterRepository,
IESFFileProvider spellFileProvider,
IGameStartTimeProvider gameStartTimeProvider)
IFixedTimeStepRepository fixedTimeStepRepository)
{
_packetSendService = packetSendService;
_characterRepository = characterRepository;
_spellFileProvider = spellFileProvider;
_gameStartTimeProvider = gameStartTimeProvider;
_fixedTimeStepRepository = fixedTimeStepRepository;
}

public void Face(EODirection direction)
Expand All @@ -46,7 +46,7 @@ public void Walk()

var packet = new PacketBuilder(PacketFamily.Walk, admin ? PacketAction.Admin : PacketAction.Player)
.AddChar((int)renderProperties.Direction)
.AddThree(_gameStartTimeProvider.TimeStamp)
.AddThree((int)_fixedTimeStepRepository.TickCount)
.AddChar(renderProperties.GetDestinationX())
.AddChar(renderProperties.GetDestinationY())
.Build();
Expand All @@ -62,7 +62,7 @@ public void Attack()

var packet = new PacketBuilder(PacketFamily.Attack, PacketAction.Use)
.AddChar((int) _characterRepository.MainCharacter.RenderProperties.Direction)
.AddThree(_gameStartTimeProvider.TimeStamp)
.AddThree((int)_fixedTimeStepRepository.TickCount)
.Build();

_packetSendService.SendPacket(packet);
Expand Down Expand Up @@ -103,7 +103,7 @@ public void PrepareCastSpell(int spellId)
{
var packet = new PacketBuilder(PacketFamily.Spell, PacketAction.Request)
.AddShort(spellId)
.AddThree(_gameStartTimeProvider.TimeStamp)
.AddThree((int)_fixedTimeStepRepository.TickCount)
.Build();

_packetSendService.SendPacket(packet);
Expand Down Expand Up @@ -131,7 +131,7 @@ public void CastSpell(int spellId, ISpellTargetable target)
{
builder = builder
.AddShort(spellId)
.AddThree(_gameStartTimeProvider.TimeStamp);
.AddThree((int)_fixedTimeStepRepository.TickCount);
}
else
{
Expand All @@ -149,13 +149,13 @@ public void CastSpell(int spellId, ISpellTargetable target)
.AddShort(1) // unknown
.AddShort(spellId)
.AddShort(target.Index)
.AddThree(_gameStartTimeProvider.TimeStamp);
.AddThree((int)_fixedTimeStepRepository.TickCount);
}
else
{
builder = builder
.AddShort(spellId)
.AddInt(_gameStartTimeProvider.TimeStamp);
.AddInt((int)_fixedTimeStepRepository.TickCount);
}
}

Expand Down
28 changes: 28 additions & 0 deletions EOLib/FixedTimeStepRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using AutomaticTypeMapper;

namespace EOLib
{
[AutoMappedType(IsSingleton = true)]
public class FixedTimeStepRepository : IFixedTimeStepRepository
{
public const double TICK_TIME_MS = 10.0;

public ulong TickCount { get; private set; }

public bool IsWalkUpdateFrame => TickCount % 4 == 0;

public void Tick()
{
TickCount++;
}
}

public interface IFixedTimeStepRepository
{
public ulong TickCount { get; }

bool IsWalkUpdateFrame { get; }

void Tick();
}
}
20 changes: 0 additions & 20 deletions EOLib/GameStartTimeRepository.cs

This file was deleted.

6 changes: 1 addition & 5 deletions EndlessClient/ControlSets/ControlSetFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public class ControlSetFactory : IControlSetFactory
private readonly IUserInputRepository _userInputRepository;
private readonly IActiveDialogRepository _activeDialogRepository;
private readonly IClientWindowSizeRepository _clientWindowSizeRepository;
private readonly IFixedTimeStepRepository _fixedTimeStepRepository;

private IMainButtonController _mainButtonController;
private IAccountController _accountController;
Expand All @@ -46,8 +45,7 @@ public ControlSetFactory(INativeGraphicsManager nativeGraphicsManager,
IEndlessGameProvider endlessGameProvider,
IUserInputRepository userInputRepository,
IActiveDialogRepository activeDialogRepository,
IClientWindowSizeRepository clientWindowSizeRepository,
IFixedTimeStepRepository fixedTimeStepRepository)
IClientWindowSizeRepository clientWindowSizeRepository)
{
_nativeGraphicsManager = nativeGraphicsManager;
_messageBoxFactory = messageBoxFactory;
Expand All @@ -60,7 +58,6 @@ public ControlSetFactory(INativeGraphicsManager nativeGraphicsManager,
_userInputRepository = userInputRepository;
_activeDialogRepository = activeDialogRepository;
_clientWindowSizeRepository = clientWindowSizeRepository;
_fixedTimeStepRepository = fixedTimeStepRepository;
}

public IControlSet CreateControlsForState(GameStates newState, IControlSet currentControlSet)
Expand Down Expand Up @@ -105,7 +102,6 @@ private IControlSet GetSetBasedOnState(GameStates newState)
_accountController,
_endlessGameProvider,
_userInputRepository,
_fixedTimeStepRepository,
_clientWindowSizeRepository);
case GameStates.PlayingTheGame:
return new InGameControlSet(_mainButtonController, _messageBoxFactory, _hudControlsFactory, _activeDialogRepository, _clientWindowSizeRepository);
Expand Down
5 changes: 1 addition & 4 deletions EndlessClient/ControlSets/LoggedInControlSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class LoggedInControlSet : IntermediateControlSet
private readonly IAccountController _accountController;
private readonly IEndlessGameProvider _endlessGameProvider;
private readonly IUserInputRepository _userInputRepository;
private readonly IFixedTimeStepRepository _fixedTimeStepRepository;
private readonly List<CharacterInfoPanel> _characterInfoPanels;

private IXNAButton _changePasswordButton;
Expand All @@ -36,7 +35,6 @@ public LoggedInControlSet(IMainButtonController mainButtonController,
IAccountController accountController,
IEndlessGameProvider endlessGameProvider,
IUserInputRepository userInputRepository,
IFixedTimeStepRepository fixedTimeStepRepository,
IClientWindowSizeRepository clientWindowSizeRepository)
: base(mainButtonController, clientWindowSizeRepository)
{
Expand All @@ -46,7 +44,6 @@ public LoggedInControlSet(IMainButtonController mainButtonController,
_accountController = accountController;
_endlessGameProvider = endlessGameProvider;
_userInputRepository = userInputRepository;
_fixedTimeStepRepository = fixedTimeStepRepository;
_characterInfoPanels = new List<CharacterInfoPanel>();
}

Expand All @@ -58,7 +55,7 @@ protected override void InitializeControlsHelper(IControlSet currentControlSet)
_characterInfoPanels.AddRange(_characterInfoPanelFactory.CreatePanels(_characterSelectorProvider.Characters));

_allComponents.Add(new CurrentUserInputTracker(_endlessGameProvider, _userInputRepository));
_allComponents.Add(new PreviousUserInputTracker(_endlessGameProvider, _userInputRepository, _fixedTimeStepRepository));
_allComponents.Add(new PreviousUserInputTracker(_endlessGameProvider, _userInputRepository));
_allComponents.Add(_changePasswordButton);
_allComponents.AddRange(_characterInfoPanels);
}
Expand Down
20 changes: 12 additions & 8 deletions EndlessClient/GameExecution/EndlessGame.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using AutomaticTypeMapper;
using AutomaticTypeMapper;
using EndlessClient.Audio;
using EndlessClient.Content;
using EndlessClient.ControlSets;
Expand All @@ -22,6 +17,11 @@
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Input;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

namespace EndlessClient.GameExecution
{
Expand All @@ -42,6 +42,7 @@ public class EndlessGame : Game, IEndlessGame
private readonly IConfigurationProvider _configurationProvider;
private readonly IMfxPlayer _mfxPlayer;
private readonly IXnaControlSoundMapper _soundMapper;
private readonly IFixedTimeStepRepository _fixedTimeStepRepository;
private GraphicsDeviceManager _graphicsDeviceManager;

private KeyboardState _previousKeyState;
Expand All @@ -67,7 +68,8 @@ public EndlessGame(IClientWindowSizeRepository windowSizeRepository,
IShaderRepository shaderRepository,
IConfigurationProvider configurationProvider,
IMfxPlayer mfxPlayer,
IXnaControlSoundMapper soundMapper)
IXnaControlSoundMapper soundMapper,
IFixedTimeStepRepository fixedTimeStepRepository)
{
_windowSizeRepository = windowSizeRepository;
_contentProvider = contentProvider;
Expand All @@ -83,6 +85,7 @@ public EndlessGame(IClientWindowSizeRepository windowSizeRepository,
_configurationProvider = configurationProvider;
_mfxPlayer = mfxPlayer;
_soundMapper = soundMapper;
_fixedTimeStepRepository = fixedTimeStepRepository;
_graphicsDeviceManager = new GraphicsDeviceManager(this)
{
PreferredBackBufferWidth = ClientWindowSizeRepository.DEFAULT_BACKBUFFER_WIDTH,
Expand Down Expand Up @@ -183,7 +186,7 @@ protected override void Update(GameTime gameTime)
// Some game components rely on slower update times. 60FPS was the original, but 12ms factors nicely in 120ms "ticks"
// See: https://github.com/ethanmoffat/EndlessClient/issues/199
// Using IsFixedTimeStep = true with TargetUpdateTime set to 60FPS also limits the draw rate, which is not desired
if ((gameTime.TotalGameTime - _lastFrameUpdate).TotalMilliseconds >= 12.0)
if ((gameTime.TotalGameTime - _lastFrameUpdate).TotalMilliseconds >= FixedTimeStepRepository.TICK_TIME_MS)
{
#if DEBUG
var currentKeyState = Keyboard.GetState();
Expand All @@ -194,6 +197,7 @@ protected override void Update(GameTime gameTime)

_previousKeyState = currentKeyState;
#endif
_fixedTimeStepRepository.Tick();

try
{
Expand Down
12 changes: 6 additions & 6 deletions EndlessClient/HUD/Controls/HudControlsFactory.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AutomaticTypeMapper;
using AutomaticTypeMapper;
using EndlessClient.Audio;
using EndlessClient.Content;
using EndlessClient.Controllers;
Expand All @@ -28,6 +25,9 @@
using EOLib.Localization;
using EOLib.Net.Communication;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using XNAControls;

namespace EndlessClient.HUD.Controls
Expand Down Expand Up @@ -566,7 +566,7 @@ private ICharacterAnimator CreateCharacterAnimator()

private INPCAnimator CreateNPCAnimator()
{
return new NPCAnimator(_endlessGameProvider, _currentMapStateRepository);
return new NPCAnimator(_endlessGameProvider, _currentMapStateRepository, _fixedTimeStepRepository);
}

private IPeriodicEmoteHandler CreatePeriodicEmoteHandler(ICharacterAnimator characterAnimator)
Expand All @@ -576,7 +576,7 @@ private IPeriodicEmoteHandler CreatePeriodicEmoteHandler(ICharacterAnimator char

private PreviousUserInputTracker CreatePreviousUserInputTracker()
{
return new PreviousUserInputTracker(_endlessGameProvider, _userInputRepository, _fixedTimeStepRepository);
return new PreviousUserInputTracker(_endlessGameProvider, _userInputRepository);
}
}
}
9 changes: 1 addition & 8 deletions EndlessClient/Input/PreviousUserInputTracker.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
using EndlessClient.GameExecution;
using EndlessClient.Rendering;
using Microsoft.Xna.Framework;

namespace EndlessClient.Input
{
public class PreviousUserInputTracker : GameComponent
{
private readonly IUserInputRepository _userInputRepository;
private readonly IFixedTimeStepRepository _fixedTimeStepRepository;

public PreviousUserInputTracker(
IEndlessGameProvider endlessGameProvider,
IUserInputRepository userInputRepository,
IFixedTimeStepRepository fixedTimeStepRepository)
IUserInputRepository userInputRepository)
: base((Game)endlessGameProvider.Game)
{
_userInputRepository = userInputRepository;
_fixedTimeStepRepository = fixedTimeStepRepository;
UpdateOrder = int.MaxValue;
}

Expand All @@ -25,9 +21,6 @@ public override void Update(GameTime gameTime)
_userInputRepository.PreviousKeyState = _userInputRepository.CurrentKeyState;
_userInputRepository.PreviousMouseState = _userInputRepository.CurrentMouseState;

if (_fixedTimeStepRepository.IsUpdateFrame)
_fixedTimeStepRepository.RestartTimer();

base.Update(gameTime);
}
}
Expand Down
Loading

0 comments on commit 859365f

Please sign in to comment.