From b0e6f14362ce39fb19b2deee3360f5d9985f45df Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 12:08:17 -0700 Subject: [PATCH 1/9] Add check for clicks based on the bounds of the graphic associated with a map sign --- .../Controllers/MapInteractionController.cs | 6 +-- .../Rendering/Map/DynamicMapObjectUpdater.cs | 52 ++++++++++++++++++- .../Map/MapObjectBoundsCalculator.cs | 45 ++++++++++++++++ .../BaseMapEntityRenderer.cs | 3 +- .../MapEntityRenderers/GroundLayerRenderer.cs | 4 +- .../Rendering/MouseCursorRenderer.cs | 2 +- 6 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 EndlessClient/Rendering/Map/MapObjectBoundsCalculator.cs diff --git a/EndlessClient/Controllers/MapInteractionController.cs b/EndlessClient/Controllers/MapInteractionController.cs index c18cbef4e..04aa10d5e 100644 --- a/EndlessClient/Controllers/MapInteractionController.cs +++ b/EndlessClient/Controllers/MapInteractionController.cs @@ -79,7 +79,7 @@ public class MapInteractionController : IMapInteractionController _activeDialogProvider = activeDialogProvider; } - public void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRenderer) + public void LeftClick(IMapCellState cellState, Option mouseRenderer) { if (!InventoryPanel.NoItemsDragging() || _activeDialogProvider.ActiveDialogs.Any(x => x.HasValue)) return; @@ -128,7 +128,7 @@ public void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRendere } else if (cellState.InBounds && !cellState.Character.HasValue && !cellState.NPC.HasValue) { - mouseRenderer.AnimateClick(); + mouseRenderer.MatchSome(r => r.AnimateClick()); _hudControlProvider.GetComponent(HudControlIdentifier.CharacterAnimator) .StartMainCharacterWalkAnimation(Option.Some(cellState.Coordinate)); } @@ -229,7 +229,7 @@ private bool CharacterIsCloseEnough(MapCoordinate coordinate) public interface IMapInteractionController { - void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRenderer); + void LeftClick(IMapCellState cellState, Option mouseRenderer); void RightClick(IMapCellState cellState); } diff --git a/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs b/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs index f98976713..a1239fd26 100644 --- a/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs +++ b/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs @@ -1,7 +1,12 @@ using AutomaticTypeMapper; +using EndlessClient.Controllers; +using EndlessClient.Input; using EOLib.Domain.Character; using EOLib.Domain.Map; +using EOLib.IO.Map; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using Optional; using System; using System.Collections.Generic; using System.Linq; @@ -21,14 +26,25 @@ private class DoorTimePair private readonly ICharacterProvider _characterProvider; private readonly ICurrentMapStateRepository _currentMapStateRepository; + private readonly IUserInputProvider _userInputProvider; + private readonly ICurrentMapProvider _currentMapProvider; + private readonly IMapObjectBoundsCalculator _mapObjectBoundsCalculator; + private readonly IMapInteractionController _mapInteractionController; private readonly List _cachedDoorState; public DynamicMapObjectUpdater(ICharacterProvider characterProvider, - ICurrentMapStateRepository currentMapStateRepository) + ICurrentMapStateRepository currentMapStateRepository, + IUserInputProvider userInputProvider, + ICurrentMapProvider currentMapProvider, + IMapObjectBoundsCalculator mapObjectBoundsCalculator, + IMapInteractionController mapInteractionController) { _characterProvider = characterProvider; _currentMapStateRepository = currentMapStateRepository; - + _userInputProvider = userInputProvider; + _currentMapProvider = currentMapProvider; + _mapObjectBoundsCalculator = mapObjectBoundsCalculator; + _mapInteractionController = mapInteractionController; _cachedDoorState = new List(); } @@ -39,6 +55,8 @@ public void UpdateMapObjects(GameTime gameTime) CloseExpiredDoors(now); RemoveStaleSpikeTraps(); + + CheckForObjectClicks(); } private void OpenNewDoors(DateTime now) @@ -75,6 +93,36 @@ private void RemoveStaleSpikeTraps() _currentMapStateRepository.VisibleSpikeTraps.RemoveWhere(staleTraps.Contains); } + + private void CheckForObjectClicks() + { + var mouseClicked = _userInputProvider.PreviousMouseState.LeftButton == ButtonState.Pressed && + _userInputProvider.CurrentMouseState.LeftButton == ButtonState.Released; + + if (mouseClicked) + { + foreach (var sign in _currentMapProvider.CurrentMap.Signs) + { + var gfx = _currentMapProvider.CurrentMap.GFX[MapLayer.Objects][sign.Y, sign.X]; + if (gfx > 0) + { + var bounds = _mapObjectBoundsCalculator.GetMapObjectBounds(sign.X, sign.Y, gfx); + if (bounds.Contains(_userInputProvider.CurrentMouseState.Position)) + { + var cellState = new MapCellState + { + Sign = Option.Some(new Sign(sign)), + Coordinate = new MapCoordinate(sign.X, sign.Y) + }; + _mapInteractionController.LeftClick(cellState, Option.None()); + break; + } + } + } + + // todo: check for board object clicks + } + } } public interface IDynamicMapObjectUpdater diff --git a/EndlessClient/Rendering/Map/MapObjectBoundsCalculator.cs b/EndlessClient/Rendering/Map/MapObjectBoundsCalculator.cs new file mode 100644 index 000000000..55225b203 --- /dev/null +++ b/EndlessClient/Rendering/Map/MapObjectBoundsCalculator.cs @@ -0,0 +1,45 @@ +using AutomaticTypeMapper; +using EndlessClient.Rendering.MapEntityRenderers; +using EOLib.Domain.Character; +using EOLib.Graphics; +using Microsoft.Xna.Framework; +using System.Linq; + +namespace EndlessClient.Rendering.Map +{ + [AutoMappedType] + public class MapObjectBoundsCalculator : IMapObjectBoundsCalculator + { + private readonly INativeGraphicsManager _nativeGraphicsManager; + private readonly ICharacterProvider _characterProvider; + private readonly IRenderOffsetCalculator _renderOffsetCalculator; + private readonly MapObjectLayerRenderer _objectRenderer; + + public MapObjectBoundsCalculator(INativeGraphicsManager nativeGraphicsManager, + ICharacterProvider characterProvider, + IRenderOffsetCalculator renderOffsetCalculator, + IMapEntityRendererProvider mapEntityRendererProvider) + { + _nativeGraphicsManager = nativeGraphicsManager; + _characterProvider = characterProvider; + _renderOffsetCalculator = renderOffsetCalculator; + + _objectRenderer = mapEntityRendererProvider.MapEntityRenderers.OfType().Single(); + } + + public Rectangle GetMapObjectBounds(int gridX, int gridY, int gfxNum) + { + var gfx = _nativeGraphicsManager.TextureFromResource(GFXTypes.MapObjects, gfxNum, transparent: true); + var drawPosition = _objectRenderer.GetDrawCoordinatesFromGridUnits(gridX, gridY); + // see: MapObjectLayerRenderer + // todo: more centralized way of representing this + drawPosition -= new Vector2(gfx.Width / 2, gfx.Height - 32); + return gfx.Bounds.WithPosition(drawPosition); + } + } + + public interface IMapObjectBoundsCalculator + { + Rectangle GetMapObjectBounds(int gridX, int gridY, int gfxNum); + } +} \ No newline at end of file diff --git a/EndlessClient/Rendering/MapEntityRenderers/BaseMapEntityRenderer.cs b/EndlessClient/Rendering/MapEntityRenderers/BaseMapEntityRenderer.cs index d08f6f458..1d4ce09de 100644 --- a/EndlessClient/Rendering/MapEntityRenderers/BaseMapEntityRenderer.cs +++ b/EndlessClient/Rendering/MapEntityRenderers/BaseMapEntityRenderer.cs @@ -72,7 +72,8 @@ public virtual void RenderElementAt(SpriteBatch spriteBatch, int row, int col, i } } - protected virtual Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY) + // todo: this shouldn't be public, move to another service that's responsible for calculating the offsets for map entities + public virtual Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY) { const int ViewportWidthFactor = 320; // 640 * (1/2) const int ViewportHeightFactor = 144; // 480 * (3/10) diff --git a/EndlessClient/Rendering/MapEntityRenderers/GroundLayerRenderer.cs b/EndlessClient/Rendering/MapEntityRenderers/GroundLayerRenderer.cs index d9e997aa6..d51b05aa0 100644 --- a/EndlessClient/Rendering/MapEntityRenderers/GroundLayerRenderer.cs +++ b/EndlessClient/Rendering/MapEntityRenderers/GroundLayerRenderer.cs @@ -29,7 +29,7 @@ public class GroundLayerRenderer : BaseMapEntityRenderer _currentMapProvider = currentMapProvider; } - protected override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY) + public override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY) { // the height is used to offset the 0 point of the grid, which is 32 units per tile in the height of the map var height = CurrentMap.Properties.Height; @@ -97,7 +97,7 @@ protected override bool ElementExistsAt(int row, int col) return tileExists && _nativeGraphicsManager.TextureFromResource(GFXTypes.MapTiles, tileId, true).Width > TILE_FRAME_WIDTH; } - protected override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY) + public override Vector2 GetDrawCoordinatesFromGridUnits(int gridX, int gridY) { var offsetX = _renderOffsetCalculator.CalculateOffsetX(_characterProvider.MainCharacter.RenderProperties) - 288; var offsetY = _renderOffsetCalculator.CalculateOffsetY(_characterProvider.MainCharacter.RenderProperties) - 144; diff --git a/EndlessClient/Rendering/MouseCursorRenderer.cs b/EndlessClient/Rendering/MouseCursorRenderer.cs index 6cf589125..3b30829d1 100644 --- a/EndlessClient/Rendering/MouseCursorRenderer.cs +++ b/EndlessClient/Rendering/MouseCursorRenderer.cs @@ -294,7 +294,7 @@ private void CheckForClicks(IMapCellState cellState) if (currentMouseState.LeftButton == ButtonState.Released && previousMouseState.LeftButton == ButtonState.Pressed) { - _mapInteractionController.LeftClick(cellState, this); + _mapInteractionController.LeftClick(cellState, Option.Some(this)); } } From 0afed66596a7b914dedbd4f80271e1b7d2f30793 Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 12:21:19 -0700 Subject: [PATCH 2/9] Ensure clicking a sign does not invoke the MouseCursorRenderer click handler --- .../Controllers/MapInteractionController.cs | 17 ++++++++++++++++- EndlessClient/Input/IUserInputRepository.cs | 6 ++++++ EndlessClient/Input/PreviousUserInputTracker.cs | 1 + .../Rendering/Map/DynamicMapObjectUpdater.cs | 16 ++++++++++------ EndlessClient/Rendering/MouseCursorRenderer.cs | 3 +++ 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/EndlessClient/Controllers/MapInteractionController.cs b/EndlessClient/Controllers/MapInteractionController.cs index 04aa10d5e..67785398f 100644 --- a/EndlessClient/Controllers/MapInteractionController.cs +++ b/EndlessClient/Controllers/MapInteractionController.cs @@ -43,6 +43,7 @@ public class MapInteractionController : IMapInteractionController private readonly IEOMessageBoxFactory _messageBoxFactory; private readonly IContextMenuRendererFactory _contextMenuRendererFactory; private readonly IActiveDialogProvider _activeDialogProvider; + private readonly IUserInputRepository _userInputRepository; public MapInteractionController(IMapActions mapActions, ICharacterActions characterActions, @@ -59,7 +60,8 @@ public class MapInteractionController : IMapInteractionController IUserInputTimeRepository userInputTimeRepository, IEOMessageBoxFactory messageBoxFactory, IContextMenuRendererFactory contextMenuRendererFactory, - IActiveDialogProvider activeDialogProvider) + IActiveDialogProvider activeDialogProvider, + IUserInputRepository userInputRepository) { _mapActions = mapActions; _characterActions = characterActions; @@ -77,6 +79,7 @@ public class MapInteractionController : IMapInteractionController _messageBoxFactory = messageBoxFactory; _contextMenuRendererFactory = contextMenuRendererFactory; _activeDialogProvider = activeDialogProvider; + _userInputRepository = userInputRepository; } public void LeftClick(IMapCellState cellState, Option mouseRenderer) @@ -92,16 +95,22 @@ public void LeftClick(IMapCellState cellState, Option mous _statusLabelSetter.SetStatusLabel(EOResourceID.STATUS_LABEL_TYPE_INFORMATION, EOResourceID.STATUS_LABEL_ITEM_PICKUP_NO_SPACE_LEFT); else HandlePickupResult(_mapActions.PickUpItem(item), item); + + _userInputRepository.ClickHandled = true; } else if (cellState.Sign.HasValue) { var sign = cellState.Sign.ValueOr(Sign.None); var messageBox = _messageBoxFactory.CreateMessageBox(sign.Message, sign.Title); messageBox.ShowDialog(); + + _userInputRepository.ClickHandled = true; } else if (_characterProvider.MainCharacter.RenderProperties.SitState != SitState.Standing) { _characterActions.ToggleSit(); + + _userInputRepository.ClickHandled = true; } else if (InteractableTileSpec(cellState.TileSpec) && CharacterIsCloseEnough(cellState.Coordinate)) { @@ -115,6 +124,8 @@ public void LeftClick(IMapCellState cellState, Option mous { _mapActions.OpenChest((byte)cellState.Coordinate.X, (byte)cellState.Coordinate.Y); _inGameDialogActions.ShowChestDialog(); + + _userInputRepository.ClickHandled = true; } break; case TileSpec.BankVault: @@ -122,6 +133,8 @@ public void LeftClick(IMapCellState cellState, Option mous { _mapActions.OpenLocker((byte)cellState.Coordinate.X, (byte)cellState.Coordinate.Y); _inGameDialogActions.ShowLockerDialog(); + + _userInputRepository.ClickHandled = true; } break; } @@ -131,6 +144,8 @@ public void LeftClick(IMapCellState cellState, Option mous mouseRenderer.MatchSome(r => r.AnimateClick()); _hudControlProvider.GetComponent(HudControlIdentifier.CharacterAnimator) .StartMainCharacterWalkAnimation(Option.Some(cellState.Coordinate)); + + _userInputRepository.ClickHandled = true; } _userInputTimeRepository.LastInputTime = DateTime.Now; diff --git a/EndlessClient/Input/IUserInputRepository.cs b/EndlessClient/Input/IUserInputRepository.cs index 127b912f3..a772d60db 100644 --- a/EndlessClient/Input/IUserInputRepository.cs +++ b/EndlessClient/Input/IUserInputRepository.cs @@ -12,6 +12,8 @@ public interface IUserInputRepository MouseState PreviousMouseState { get; set; } MouseState CurrentMouseState { get; set; } + + bool ClickHandled { get; set; } } public interface IUserInputProvider @@ -23,6 +25,8 @@ public interface IUserInputProvider MouseState PreviousMouseState { get; } MouseState CurrentMouseState { get; } + + bool ClickHandled { get; } } [MappedType(BaseType = typeof(IUserInputRepository), IsSingleton = true)] @@ -36,5 +40,7 @@ public class KeyStateRepository : IUserInputRepository, IUserInputProvider public MouseState PreviousMouseState { get; set; } public MouseState CurrentMouseState { get; set; } + + public bool ClickHandled { get; set; } } } diff --git a/EndlessClient/Input/PreviousUserInputTracker.cs b/EndlessClient/Input/PreviousUserInputTracker.cs index 04c7f38ee..78b47817a 100644 --- a/EndlessClient/Input/PreviousUserInputTracker.cs +++ b/EndlessClient/Input/PreviousUserInputTracker.cs @@ -21,6 +21,7 @@ public override void Update(GameTime gameTime) { _userInputRepository.PreviousKeyState = _userInputRepository.CurrentKeyState; _userInputRepository.PreviousMouseState = _userInputRepository.CurrentMouseState; + _userInputRepository.ClickHandled = false; base.Update(gameTime); } diff --git a/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs b/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs index a1239fd26..902e8d4d3 100644 --- a/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs +++ b/EndlessClient/Rendering/Map/DynamicMapObjectUpdater.cs @@ -26,7 +26,7 @@ private class DoorTimePair private readonly ICharacterProvider _characterProvider; private readonly ICurrentMapStateRepository _currentMapStateRepository; - private readonly IUserInputProvider _userInputProvider; + private readonly IUserInputRepository _userInputRepository; private readonly ICurrentMapProvider _currentMapProvider; private readonly IMapObjectBoundsCalculator _mapObjectBoundsCalculator; private readonly IMapInteractionController _mapInteractionController; @@ -34,14 +34,14 @@ private class DoorTimePair public DynamicMapObjectUpdater(ICharacterProvider characterProvider, ICurrentMapStateRepository currentMapStateRepository, - IUserInputProvider userInputProvider, + IUserInputRepository userInputRepository, ICurrentMapProvider currentMapProvider, IMapObjectBoundsCalculator mapObjectBoundsCalculator, IMapInteractionController mapInteractionController) { _characterProvider = characterProvider; _currentMapStateRepository = currentMapStateRepository; - _userInputProvider = userInputProvider; + _userInputRepository = userInputRepository; _currentMapProvider = currentMapProvider; _mapObjectBoundsCalculator = mapObjectBoundsCalculator; _mapInteractionController = mapInteractionController; @@ -96,8 +96,11 @@ private void RemoveStaleSpikeTraps() private void CheckForObjectClicks() { - var mouseClicked = _userInputProvider.PreviousMouseState.LeftButton == ButtonState.Pressed && - _userInputProvider.CurrentMouseState.LeftButton == ButtonState.Released; + if (_userInputRepository.ClickHandled) + return; + + var mouseClicked = _userInputRepository.PreviousMouseState.LeftButton == ButtonState.Pressed && + _userInputRepository.CurrentMouseState.LeftButton == ButtonState.Released; if (mouseClicked) { @@ -107,7 +110,7 @@ private void CheckForObjectClicks() if (gfx > 0) { var bounds = _mapObjectBoundsCalculator.GetMapObjectBounds(sign.X, sign.Y, gfx); - if (bounds.Contains(_userInputProvider.CurrentMouseState.Position)) + if (bounds.Contains(_userInputRepository.CurrentMouseState.Position)) { var cellState = new MapCellState { @@ -115,6 +118,7 @@ private void CheckForObjectClicks() Coordinate = new MapCoordinate(sign.X, sign.Y) }; _mapInteractionController.LeftClick(cellState, Option.None()); + _userInputRepository.ClickHandled = true; break; } } diff --git a/EndlessClient/Rendering/MouseCursorRenderer.cs b/EndlessClient/Rendering/MouseCursorRenderer.cs index 3b30829d1..a39f6f1fe 100644 --- a/EndlessClient/Rendering/MouseCursorRenderer.cs +++ b/EndlessClient/Rendering/MouseCursorRenderer.cs @@ -287,6 +287,9 @@ private void UpdateCursorIndexForTileSpec(TileSpec tileSpec) private void CheckForClicks(IMapCellState cellState) { + if (_userInputProvider.ClickHandled) + return; + var currentMouseState = _userInputProvider.CurrentMouseState; var previousMouseState = _userInputProvider.PreviousMouseState; From 0d3ff9cae27990d1850affed1bb89b9e90c4a1b5 Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 15:26:03 -0700 Subject: [PATCH 3/9] Ensure clicks don't trigger multiple handlers --- .../ControlSets/BackButtonControlSet.cs | 1 + .../ControlSets/ControlSetFactory.cs | 2 +- EndlessClient/ControlSets/InGameControlSet.cs | 8 ++++++- .../Controllers/NPCInteractionController.cs | 9 +++++++- .../Rendering/Character/CharacterRenderer.cs | 23 ++++++++----------- .../Factories/CharacterRendererFactory.cs | 9 ++++++-- EndlessClient/Rendering/NPC/NPCRenderer.cs | 21 ++++++++--------- .../Rendering/NPC/NPCRendererFactory.cs | 7 +++++- 8 files changed, 49 insertions(+), 31 deletions(-) diff --git a/EndlessClient/ControlSets/BackButtonControlSet.cs b/EndlessClient/ControlSets/BackButtonControlSet.cs index 01dbdb4e3..3b3f359d8 100644 --- a/EndlessClient/ControlSets/BackButtonControlSet.cs +++ b/EndlessClient/ControlSets/BackButtonControlSet.cs @@ -43,6 +43,7 @@ private XNAButton GetBackButton() new Rectangle(0, 0, _backButtonTexture.Width, _backButtonTexture.Height / 2), new Rectangle(0, _backButtonTexture.Height / 2, _backButtonTexture.Width, _backButtonTexture.Height / 2)) { + UpdateOrder = -1, DrawOrder = 100, ClickArea = new Rectangle(4, 16, 16, 16) }; diff --git a/EndlessClient/ControlSets/ControlSetFactory.cs b/EndlessClient/ControlSets/ControlSetFactory.cs index 941526442..01503406c 100644 --- a/EndlessClient/ControlSets/ControlSetFactory.cs +++ b/EndlessClient/ControlSets/ControlSetFactory.cs @@ -109,7 +109,7 @@ private IControlSet GetSetBasedOnState(GameStates newState) _endlessGameProvider, _userInputRepository); case GameStates.PlayingTheGame: - return new InGameControlSet(_mainButtonController, _messageBoxFactory, _hudControlsFactory, _activeDialogRepository); + return new InGameControlSet(_mainButtonController, _messageBoxFactory, _hudControlsFactory, _activeDialogRepository, _userInputRepository); default: throw new ArgumentOutOfRangeException(nameof(newState), newState, null); } } diff --git a/EndlessClient/ControlSets/InGameControlSet.cs b/EndlessClient/ControlSets/InGameControlSet.cs index e3257d2c2..6f59e8f69 100644 --- a/EndlessClient/ControlSets/InGameControlSet.cs +++ b/EndlessClient/ControlSets/InGameControlSet.cs @@ -6,6 +6,7 @@ using EndlessClient.Dialogs.Factories; using EndlessClient.GameExecution; using EndlessClient.HUD.Controls; +using EndlessClient.Input; using EOLib.Localization; using Microsoft.Xna.Framework; using Optional; @@ -18,6 +19,7 @@ public class InGameControlSet : BackButtonControlSet private readonly IEOMessageBoxFactory _messageBoxFactory; private readonly IHudControlsFactory _hudControlsFactory; private readonly IActiveDialogRepository _activeDialogRepository; + private readonly IUserInputRepository _userInputRepository; private IReadOnlyDictionary _controls; public override GameStates GameState => GameStates.PlayingTheGame; @@ -25,12 +27,14 @@ public class InGameControlSet : BackButtonControlSet public InGameControlSet(IMainButtonController mainButtonController, IEOMessageBoxFactory messageBoxFactory, IHudControlsFactory hudControlsFactory, - IActiveDialogRepository activeDialogRepository) + IActiveDialogRepository activeDialogRepository, + IUserInputRepository userInputRepository) : base(mainButtonController) { _messageBoxFactory = messageBoxFactory; _hudControlsFactory = hudControlsFactory; _activeDialogRepository = activeDialogRepository; + _userInputRepository = userInputRepository; _controls = new Dictionary(); } @@ -50,6 +54,8 @@ protected override void InitializeControlsHelper(IControlSet currentControlSet) protected override async void DoBackButtonClick(object sender, EventArgs e) { + _userInputRepository.ClickHandled = true; + var messageBox = _messageBoxFactory.CreateMessageBox( DialogResourceID.EXIT_GAME_ARE_YOU_SURE, EODialogButtons.OkCancel); diff --git a/EndlessClient/Controllers/NPCInteractionController.cs b/EndlessClient/Controllers/NPCInteractionController.cs index b4f0e5914..9f1c30be3 100644 --- a/EndlessClient/Controllers/NPCInteractionController.cs +++ b/EndlessClient/Controllers/NPCInteractionController.cs @@ -1,6 +1,7 @@ using AutomaticTypeMapper; using EndlessClient.Dialogs; using EndlessClient.Dialogs.Actions; +using EndlessClient.Input; using EOLib.Domain.Interact; using EOLib.Domain.NPC; using EOLib.IO.Repositories; @@ -15,16 +16,19 @@ public class NPCInteractionController : INPCInteractionController private readonly IInGameDialogActions _inGameDialogActions; private readonly IENFFileProvider _enfFileProvider; private readonly IActiveDialogProvider _activeDialogProvider; + private readonly IUserInputRepository _userInputRepository; public NPCInteractionController(IMapNPCActions mapNpcActions, IInGameDialogActions inGameDialogActions, IENFFileProvider enfFileProvider, - IActiveDialogProvider activeDialogProvider) + IActiveDialogProvider activeDialogProvider, + IUserInputRepository userInputRepository) { _mapNpcActions = mapNpcActions; _inGameDialogActions = inGameDialogActions; _enfFileProvider = enfFileProvider; _activeDialogProvider = activeDialogProvider; + _userInputRepository = userInputRepository; } public void ShowNPCDialog(INPC npc) @@ -38,9 +42,11 @@ public void ShowNPCDialog(INPC npc) { case EOLib.IO.NPCType.Shop: _mapNpcActions.RequestShop(npc); + _userInputRepository.ClickHandled = true; break; case EOLib.IO.NPCType.Quest: _mapNpcActions.RequestQuest(npc); + _userInputRepository.ClickHandled = true; break; case EOLib.IO.NPCType.Bank: _mapNpcActions.RequestBank(npc); @@ -48,6 +54,7 @@ public void ShowNPCDialog(INPC npc) // by config data on the server. Bank account dialog does not have this restriction; // interaction with the NPC should *always* show the dialog _inGameDialogActions.ShowBankAccountDialog(); + _userInputRepository.ClickHandled = true; break; } } diff --git a/EndlessClient/Rendering/Character/CharacterRenderer.cs b/EndlessClient/Rendering/Character/CharacterRenderer.cs index 8a866cb48..0c7b949a6 100644 --- a/EndlessClient/Rendering/Character/CharacterRenderer.cs +++ b/EndlessClient/Rendering/Character/CharacterRenderer.cs @@ -2,6 +2,7 @@ using System.Linq; using EndlessClient.Controllers; using EndlessClient.GameExecution; +using EndlessClient.Input; using EndlessClient.Rendering.CharacterProperties; using EndlessClient.Rendering.Chat; using EndlessClient.Rendering.Effects; @@ -35,12 +36,11 @@ public class CharacterRenderer : DrawableGameComponent, ICharacterRenderer private readonly ICharacterSpriteCalculator _characterSpriteCalculator; private readonly IGameStateProvider _gameStateProvider; private readonly ICurrentMapProvider _currentMapProvider; + private readonly IUserInputProvider _userInputProvider; private readonly IEffectRenderer _effectRenderer; private ICharacter _character; private bool _textureUpdateRequired, _positionIsRelative = true; - private MouseState _previousMouseState; - private MouseState _currentMouseState; private SpriteBatch _sb; private RenderTarget2D _charRenderTarget; @@ -91,7 +91,8 @@ public Rectangle EffectTargetArea ICharacterSpriteCalculator characterSpriteCalculator, ICharacter character, IGameStateProvider gameStateProvider, - ICurrentMapProvider currentMapProvider) + ICurrentMapProvider currentMapProvider, + IUserInputProvider userInputProvider) : base(game) { _mapInteractionController = mapInteractionController; @@ -106,6 +107,7 @@ public Rectangle EffectTargetArea _character = character; _gameStateProvider = gameStateProvider; _currentMapProvider = currentMapProvider; + _userInputProvider = userInputProvider; _effectRenderer = new EffectRenderer(nativeGraphicsmanager, this); _chatBubble = new Lazy(() => _chatBubbleFactory.CreateChatBubble(this)); } @@ -140,9 +142,6 @@ public override void Initialize() _healthBarRenderer = _healthBarRendererFactory.CreateHealthBarRenderer(this); } - _previousMouseState = _currentMouseState = Mouse.GetState(); - - base.Initialize(); } @@ -166,8 +165,6 @@ public override void Update(GameTime gameTime) if (!Visible) return; - _currentMouseState = Mouse.GetState(); - if (_textureUpdateRequired) { _characterTextures.Refresh(_character.RenderProperties); @@ -183,9 +180,9 @@ public override void Update(GameTime gameTime) { UpdateNameLabel(gameTime); - if (DrawArea.ContainsPoint(_currentMouseState.X, _currentMouseState.Y) && - _currentMouseState.RightButton == ButtonState.Released && - _previousMouseState.RightButton == ButtonState.Pressed) + if (DrawArea.Contains(_userInputProvider.CurrentMouseState.Position) && + _userInputProvider.CurrentMouseState.RightButton == ButtonState.Released && + _userInputProvider.PreviousMouseState.RightButton == ButtonState.Pressed) { _mapInteractionController.RightClick(new MapCellState { Character = Option.Some(Character) }); } @@ -193,8 +190,6 @@ public override void Update(GameTime gameTime) _healthBarRenderer.Update(gameTime); } - _previousMouseState = _currentMouseState; - base.Update(gameTime); } @@ -341,7 +336,7 @@ private void UpdateNameLabel(GameTime gameTime) { _nameLabel.Visible = false; } - else if (DrawArea.Contains(_currentMouseState.Position)) + else if (DrawArea.Contains(_userInputProvider.CurrentMouseState.Position)) { _nameLabel.Visible = true; _nameLabel.BlinkRate = null; diff --git a/EndlessClient/Rendering/Factories/CharacterRendererFactory.cs b/EndlessClient/Rendering/Factories/CharacterRendererFactory.cs index 6f4b7053e..b6015b1af 100644 --- a/EndlessClient/Rendering/Factories/CharacterRendererFactory.cs +++ b/EndlessClient/Rendering/Factories/CharacterRendererFactory.cs @@ -1,6 +1,7 @@ using AutomaticTypeMapper; using EndlessClient.Controllers; using EndlessClient.GameExecution; +using EndlessClient.Input; using EndlessClient.Rendering.Character; using EndlessClient.Rendering.CharacterProperties; using EndlessClient.Rendering.Chat; @@ -28,6 +29,7 @@ public class CharacterRendererFactory : ICharacterRendererFactory private readonly ICharacterSpriteCalculator _characterSpriteCalculator; private readonly IGameStateProvider _gameStateProvider; private readonly ICurrentMapProvider _currentMapProvider; + private readonly IUserInputProvider _userInputProvider; public CharacterRendererFactory(INativeGraphicsManager nativeGraphicsManager, IEndlessGameProvider gameProvider, @@ -41,7 +43,8 @@ public class CharacterRendererFactory : ICharacterRendererFactory ICharacterTextures characterTextures, ICharacterSpriteCalculator characterSpriteCalculator, IGameStateProvider gameStateProvider, - ICurrentMapProvider currentMapProvider) + ICurrentMapProvider currentMapProvider, + IUserInputProvider userInputProvider) { _nativeGraphicsManager = nativeGraphicsManager; _gameProvider = gameProvider; @@ -56,6 +59,7 @@ public class CharacterRendererFactory : ICharacterRendererFactory _characterSpriteCalculator = characterSpriteCalculator; _gameStateProvider = gameStateProvider; _currentMapProvider = currentMapProvider; + _userInputProvider = userInputProvider; } public ICharacterRenderer CreateCharacterRenderer(ICharacter character) @@ -74,7 +78,8 @@ public ICharacterRenderer CreateCharacterRenderer(ICharacter character) _characterSpriteCalculator, character, _gameStateProvider, - _currentMapProvider); + _currentMapProvider, + _userInputProvider); } } } \ No newline at end of file diff --git a/EndlessClient/Rendering/NPC/NPCRenderer.cs b/EndlessClient/Rendering/NPC/NPCRenderer.cs index d6bfe02bb..b5f576549 100644 --- a/EndlessClient/Rendering/NPC/NPCRenderer.cs +++ b/EndlessClient/Rendering/NPC/NPCRenderer.cs @@ -2,6 +2,7 @@ using System.Linq; using EndlessClient.Controllers; using EndlessClient.GameExecution; +using EndlessClient.Input; using EndlessClient.Rendering.Character; using EndlessClient.Rendering.Chat; using EndlessClient.Rendering.Effects; @@ -33,6 +34,7 @@ public class NPCRenderer : DrawableGameComponent, INPCRenderer private readonly IHealthBarRendererFactory _healthBarRendererFactory; private readonly IChatBubbleFactory _chatBubbleFactory; private readonly INPCInteractionController _npcInteractionController; + private readonly IUserInputProvider _userInputProvider; private readonly Rectangle _baseTextureFrameRectangle; private readonly int _readonlyTopPixel, _readonlyBottomPixel; private readonly bool _hasStandingAnimation; @@ -42,8 +44,6 @@ public class NPCRenderer : DrawableGameComponent, INPCRenderer private DateTime _lastStandingAnimation; private int _fadeAwayAlpha; private bool _isDying; - private MouseState _previousMouseState; - private MouseState _currentMouseState; private XNALabel _nameLabel; private IChatBubble _chatBubble; @@ -75,6 +75,7 @@ public class NPCRenderer : DrawableGameComponent, INPCRenderer IHealthBarRendererFactory healthBarRendererFactory, IChatBubbleFactory chatBubbleFactory, INPCInteractionController npcInteractionController, + IUserInputProvider userInputProvider, INPC initialNPC) : base((Game)endlessGameProvider.Game) { @@ -87,6 +88,8 @@ public class NPCRenderer : DrawableGameComponent, INPCRenderer _healthBarRendererFactory = healthBarRendererFactory; _chatBubbleFactory = chatBubbleFactory; _npcInteractionController = npcInteractionController; + _userInputProvider = userInputProvider; + _baseTextureFrameRectangle = GetStandingFrameRectangle(); _readonlyTopPixel = GetTopPixel(); _readonlyBottomPixel = GetBottomPixel(); @@ -120,7 +123,6 @@ public override void Initialize() _nameLabel.Game.Components.Add(_nameLabel); _nameLabel.DrawPosition = GetNameLabelPosition(); - _previousMouseState = _currentMouseState = Mouse.GetState(); base.Initialize(); } @@ -129,18 +131,17 @@ public override void Update(GameTime gameTime) { if (!Visible) return; - _currentMouseState = Mouse.GetState(); - UpdateDrawAreas(); UpdateStandingFrameAnimation(); UpdateDeadState(); - _nameLabel.Visible = DrawArea.Contains(_currentMouseState.Position) && !_healthBarRenderer.Visible && !_isDying; + _nameLabel.Visible = DrawArea.Contains(_userInputProvider.CurrentMouseState.Position) && !_healthBarRenderer.Visible && !_isDying; _nameLabel.DrawPosition = GetNameLabelPosition(); - if (DrawArea.ContainsPoint(_currentMouseState.X, _currentMouseState.Y) && - _currentMouseState.LeftButton == ButtonState.Released && - _previousMouseState.LeftButton == ButtonState.Pressed) + if (DrawArea.Contains(_userInputProvider.CurrentMouseState.Position) && + _userInputProvider.CurrentMouseState.LeftButton == ButtonState.Released && + _userInputProvider.PreviousMouseState.LeftButton == ButtonState.Pressed && + !_userInputProvider.ClickHandled) { _npcInteractionController.ShowNPCDialog(NPC); } @@ -148,8 +149,6 @@ public override void Update(GameTime gameTime) _effectRenderer.Update(); _healthBarRenderer.Update(gameTime); - _previousMouseState = _currentMouseState; - base.Update(gameTime); } diff --git a/EndlessClient/Rendering/NPC/NPCRendererFactory.cs b/EndlessClient/Rendering/NPC/NPCRendererFactory.cs index a67f1e404..bee40ba1c 100644 --- a/EndlessClient/Rendering/NPC/NPCRendererFactory.cs +++ b/EndlessClient/Rendering/NPC/NPCRendererFactory.cs @@ -1,6 +1,7 @@ using AutomaticTypeMapper; using EndlessClient.Controllers; using EndlessClient.GameExecution; +using EndlessClient.Input; using EndlessClient.Rendering.Character; using EndlessClient.Rendering.Chat; using EndlessClient.Rendering.Factories; @@ -23,6 +24,7 @@ public class NPCRendererFactory : INPCRendererFactory private readonly IHealthBarRendererFactory _healthBarRendererFactory; private readonly IChatBubbleFactory _chatBubbleFactory; private readonly INPCInteractionController _npcInteractionController; + private readonly IUserInputProvider _userInputProvider; public NPCRendererFactory(INativeGraphicsManager nativeGraphicsManager, IEndlessGameProvider endlessGameProvider, @@ -32,7 +34,8 @@ public class NPCRendererFactory : INPCRendererFactory IRenderOffsetCalculator renderOffsetCalculator, IHealthBarRendererFactory healthBarRendererFactory, IChatBubbleFactory chatBubbleFactory, - INPCInteractionController npcInteractionController) + INPCInteractionController npcInteractionController, + IUserInputProvider userInputProvider) { _nativeGraphicsManager = nativeGraphicsManager; _endlessGameProvider = endlessGameProvider; @@ -43,6 +46,7 @@ public class NPCRendererFactory : INPCRendererFactory _healthBarRendererFactory = healthBarRendererFactory; _chatBubbleFactory = chatBubbleFactory; _npcInteractionController = npcInteractionController; + _userInputProvider = userInputProvider; } public INPCRenderer CreateRendererFor(INPC npc) @@ -56,6 +60,7 @@ public INPCRenderer CreateRendererFor(INPC npc) _healthBarRendererFactory, _chatBubbleFactory, _npcInteractionController, + _userInputProvider, npc); } } From 8ed169919b2885dc3e01f4644dd469d125086e35 Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 15:53:18 -0700 Subject: [PATCH 4/9] Don't reset quest NPC. Fixes title bug where quest shows multiple dialogs --- EOLib/Domain/Interact/Quest/QuestDataRepository.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/EOLib/Domain/Interact/Quest/QuestDataRepository.cs b/EOLib/Domain/Interact/Quest/QuestDataRepository.cs index 07722cc0b..be3f453a0 100644 --- a/EOLib/Domain/Interact/Quest/QuestDataRepository.cs +++ b/EOLib/Domain/Interact/Quest/QuestDataRepository.cs @@ -49,7 +49,6 @@ public QuestDataRepository() public void ResetState() { - RequestedNPC = null; QuestDialogData = Option.None(); QuestProgress = new List(); QuestHistory = new List(); From 43de64b9494ee6ce238cb4c7df40cc85bfb375af Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 15:53:34 -0700 Subject: [PATCH 5/9] Ensure E/Q buttons for HUD use transparent background --- EndlessClient/HUD/Controls/HudControlsFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EndlessClient/HUD/Controls/HudControlsFactory.cs b/EndlessClient/HUD/Controls/HudControlsFactory.cs index b42e1817c..0c494ae99 100644 --- a/EndlessClient/HUD/Controls/HudControlsFactory.cs +++ b/EndlessClient/HUD/Controls/HudControlsFactory.cs @@ -308,7 +308,7 @@ private IGameComponent CreateStatePanel(InGameStates whichState) private IGameComponent CreateSessionExpButton() { var btn = new XNAButton( - _nativeGraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 58), + _nativeGraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 58, transparent: true), new Vector2(55, 0), new Rectangle(331, 30, 22, 14), new Rectangle(331, 30, 22, 14)) @@ -323,7 +323,7 @@ private IGameComponent CreateSessionExpButton() private IGameComponent CreateQuestButton() { var btn = new XNAButton( - _nativeGraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 58), + _nativeGraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 58, transparent: true), new Vector2(77, 0), new Rectangle(353, 30, 22, 14), new Rectangle(353, 30, 22, 14)) From 4fb9f5cddd63256f5da6fa4fbb2f858266487f12 Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 16:23:14 -0700 Subject: [PATCH 6/9] Prevent clicks on map NPCs behind context menu items from triggering both context menu and NPC click handler --- EndlessClient/Rendering/ContextMenuRenderer.cs | 12 +++++++++++- .../Factories/ContextMenuRendererFactory.cs | 7 ++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/EndlessClient/Rendering/ContextMenuRenderer.cs b/EndlessClient/Rendering/ContextMenuRenderer.cs index 2ff7b152f..4ad9c3614 100644 --- a/EndlessClient/Rendering/ContextMenuRenderer.cs +++ b/EndlessClient/Rendering/ContextMenuRenderer.cs @@ -4,6 +4,7 @@ using EndlessClient.Dialogs.Actions; using EndlessClient.HUD; using EndlessClient.HUD.Controls; +using EndlessClient.Input; using EndlessClient.Rendering.Character; using EndlessClient.Services; using EndlessClient.UIControls; @@ -44,6 +45,7 @@ private enum MenuAction private readonly IFriendIgnoreListService _friendIgnoreListService; private readonly IHudControlProvider _hudControlProvider; private readonly IContextMenuRepository _contextMenuRepository; + private readonly IUserInputRepository _userInputRepository; private readonly ICharacterRenderer _characterRenderer; //private DateTime? m_lastPartyRequestedTime, m_lastTradeRequestedTime; @@ -55,6 +57,7 @@ private enum MenuAction IFriendIgnoreListService friendIgnoreListService, IHudControlProvider hudControlProvider, IContextMenuRepository contextMenuRepository, + IUserInputRepository userInputRepository, ICharacterRenderer characterRenderer) { _menuActions = new Dictionary(); @@ -64,6 +67,7 @@ private enum MenuAction _friendIgnoreListService = friendIgnoreListService; _hudControlProvider = hudControlProvider; _contextMenuRepository = contextMenuRepository; + _userInputRepository = userInputRepository; _characterRenderer = characterRenderer; //first, load up the images. split in half: the right half is the 'over' text @@ -88,6 +92,9 @@ private enum MenuAction SetPositionBasedOnCharacterRenderer(_characterRenderer); SetSize(W, H); + + // Update this before map renderer so that clicks are handled first + UpdateOrder = -20; } public override void Initialize() @@ -152,8 +159,11 @@ protected override void OnUpdateControl(GameTime gameTime) _overRect = Option.Some(sourceRect); found = true; - if (leftClicked) + if (leftClicked && !_userInputRepository.ClickHandled) + { menuAction(); + _userInputRepository.ClickHandled = true; + } break; } diff --git a/EndlessClient/Rendering/Factories/ContextMenuRendererFactory.cs b/EndlessClient/Rendering/Factories/ContextMenuRendererFactory.cs index fb4ad09cc..6331b25c2 100644 --- a/EndlessClient/Rendering/Factories/ContextMenuRendererFactory.cs +++ b/EndlessClient/Rendering/Factories/ContextMenuRendererFactory.cs @@ -2,6 +2,7 @@ using EndlessClient.ControlSets; using EndlessClient.Dialogs.Actions; using EndlessClient.HUD; +using EndlessClient.Input; using EndlessClient.Rendering.Character; using EndlessClient.Services; using EOLib.Domain.Interact; @@ -19,6 +20,7 @@ public class ContextMenuRendererFactory : IContextMenuRendererFactory private readonly IFriendIgnoreListService _friendIgnoreListService; private readonly IHudControlProvider _hudControlProvider; private readonly IContextMenuRepository _contextMenuRepository; + private readonly IUserInputRepository _userInputRepository; public ContextMenuRendererFactory(INativeGraphicsManager nativeGraphicsManager, IInGameDialogActions inGameDialogActions, @@ -26,7 +28,8 @@ public class ContextMenuRendererFactory : IContextMenuRendererFactory IStatusLabelSetter statusLabelSetter, IFriendIgnoreListService friendIgnoreListService, IHudControlProvider hudControlProvider, - IContextMenuRepository contextMenuRepository) + IContextMenuRepository contextMenuRepository, + IUserInputRepository userInputRepository) { _nativeGraphicsManager = nativeGraphicsManager; _inGameDialogActions = inGameDialogActions; @@ -35,6 +38,7 @@ public class ContextMenuRendererFactory : IContextMenuRendererFactory _friendIgnoreListService = friendIgnoreListService; _hudControlProvider = hudControlProvider; _contextMenuRepository = contextMenuRepository; + _userInputRepository = userInputRepository; } public IContextMenuRenderer CreateContextMenuRenderer(ICharacterRenderer characterRenderer) @@ -46,6 +50,7 @@ public IContextMenuRenderer CreateContextMenuRenderer(ICharacterRenderer charact _friendIgnoreListService, _hudControlProvider, _contextMenuRepository, + _userInputRepository, characterRenderer); } } From 3e0b86e6bb54e560deafee8dbc9460e26b9b9b0f Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 16:23:36 -0700 Subject: [PATCH 7/9] Use Single() in place of erroneous accessor for dialog titles --- EndlessClient/Dialogs/QuestDialog.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EndlessClient/Dialogs/QuestDialog.cs b/EndlessClient/Dialogs/QuestDialog.cs index fd53c5132..ed5fcfb72 100644 --- a/EndlessClient/Dialogs/QuestDialog.cs +++ b/EndlessClient/Dialogs/QuestDialog.cs @@ -9,6 +9,7 @@ using Optional; using System; using System.Collections.Generic; +using System.Linq; using XNAControls; namespace EndlessClient.Dialogs @@ -86,7 +87,7 @@ private void UpdateTitle(IQuestDialogData repoData) var npcName = _enfFileProvider.ENFFile[_questDataProvider.RequestedNPC.ID].Name; var titleText = npcName; if (!repoData.DialogTitles.ContainsKey(repoData.VendorID) && repoData.DialogTitles.Count == 1) - titleText += $" - {repoData.DialogTitles[0]}"; + titleText += $" - {repoData.DialogTitles.Single().Value}"; else if (repoData.DialogTitles.ContainsKey(repoData.VendorID)) titleText += $" - {repoData.DialogTitles[repoData.VendorID]}"; From a3e4d9f3fb81ebcbf64939e71832221754329a1c Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 16:34:29 -0700 Subject: [PATCH 8/9] Show NPC name in status bar when clicking the NPC --- EndlessClient/Controllers/NPCInteractionController.cs | 8 ++++++++ EndlessClient/HUD/IStatusLabelSetter.cs | 7 +++++-- EndlessClient/HUD/StatusLabelSetter.cs | 9 +++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/EndlessClient/Controllers/NPCInteractionController.cs b/EndlessClient/Controllers/NPCInteractionController.cs index 9f1c30be3..5d5a4e27d 100644 --- a/EndlessClient/Controllers/NPCInteractionController.cs +++ b/EndlessClient/Controllers/NPCInteractionController.cs @@ -1,10 +1,12 @@ using AutomaticTypeMapper; using EndlessClient.Dialogs; using EndlessClient.Dialogs.Actions; +using EndlessClient.HUD; using EndlessClient.Input; using EOLib.Domain.Interact; using EOLib.Domain.NPC; using EOLib.IO.Repositories; +using EOLib.Localization; using System.Linq; namespace EndlessClient.Controllers @@ -14,18 +16,21 @@ public class NPCInteractionController : INPCInteractionController { private readonly IMapNPCActions _mapNpcActions; private readonly IInGameDialogActions _inGameDialogActions; + private readonly IStatusLabelSetter _statusLabelSetter; private readonly IENFFileProvider _enfFileProvider; private readonly IActiveDialogProvider _activeDialogProvider; private readonly IUserInputRepository _userInputRepository; public NPCInteractionController(IMapNPCActions mapNpcActions, IInGameDialogActions inGameDialogActions, + IStatusLabelSetter statusLabelSetter, IENFFileProvider enfFileProvider, IActiveDialogProvider activeDialogProvider, IUserInputRepository userInputRepository) { _mapNpcActions = mapNpcActions; _inGameDialogActions = inGameDialogActions; + _statusLabelSetter = statusLabelSetter; _enfFileProvider = enfFileProvider; _activeDialogProvider = activeDialogProvider; _userInputRepository = userInputRepository; @@ -38,6 +43,9 @@ public void ShowNPCDialog(INPC npc) var data = _enfFileProvider.ENFFile[npc.ID]; + // there is no "NPC" text in the localized files + _statusLabelSetter.SetStatusLabel($"[ NPC ] {data.Name}"); + switch(data.Type) { case EOLib.IO.NPCType.Shop: diff --git a/EndlessClient/HUD/IStatusLabelSetter.cs b/EndlessClient/HUD/IStatusLabelSetter.cs index bae49c721..424789e7b 100644 --- a/EndlessClient/HUD/IStatusLabelSetter.cs +++ b/EndlessClient/HUD/IStatusLabelSetter.cs @@ -1,13 +1,16 @@ -using EOLib.Localization; +using EOLib.Domain.Interact.Quest; +using EOLib.Localization; namespace EndlessClient.HUD { - public interface IStatusLabelSetter + public interface IStatusLabelSetter : IStatusLabelNotifier { void SetStatusLabel(EOResourceID type, EOResourceID text, string appended = ""); void SetStatusLabel(EOResourceID type, string prepended, EOResourceID text); void SetStatusLabel(EOResourceID type, string text); + + void SetStatusLabel(string text); } } diff --git a/EndlessClient/HUD/StatusLabelSetter.cs b/EndlessClient/HUD/StatusLabelSetter.cs index 8627bc17a..c36de056a 100644 --- a/EndlessClient/HUD/StatusLabelSetter.cs +++ b/EndlessClient/HUD/StatusLabelSetter.cs @@ -1,12 +1,11 @@ using System; using AutomaticTypeMapper; -using EOLib.Domain.Interact.Quest; using EOLib.Localization; namespace EndlessClient.HUD { [AutoMappedType] - public class StatusLabelSetter : IStatusLabelSetter, IStatusLabelNotifier + public class StatusLabelSetter : IStatusLabelSetter { private readonly IStatusLabelTextRepository _statusLabelTextRepository; private readonly ILocalizedStringFinder _localizedStringFinder; @@ -41,6 +40,12 @@ public void SetStatusLabel(EOResourceID type, string text) SetStatusLabelText(_localizedStringFinder.GetString(type), text); } + public void SetStatusLabel(string text) + { + _statusLabelTextRepository.StatusText = text; + _statusLabelTextRepository.SetTime = DateTime.Now; + } + public void ShowWarning(string message) { SetStatusLabel(EOResourceID.STATUS_LABEL_TYPE_WARNING, message); From 749a3338f35f4186816495f8d8ab1ae82ec3ed47 Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Sun, 10 Apr 2022 16:44:32 -0700 Subject: [PATCH 9/9] Clicking adjacent square no longer walks two squares --- EndlessClient/Rendering/Character/CharacterAnimator.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/EndlessClient/Rendering/Character/CharacterAnimator.cs b/EndlessClient/Rendering/Character/CharacterAnimator.cs index 30c0f3f98..247cb5613 100644 --- a/EndlessClient/Rendering/Character/CharacterAnimator.cs +++ b/EndlessClient/Rendering/Character/CharacterAnimator.cs @@ -266,7 +266,12 @@ private void AnimateCharacterWalking() var characterCoord = new MapCoordinate(nextFrameRenderProperties.MapX, nextFrameRenderProperties.MapY); _walkPath = _targetCoordinate.Match( - some: tc => _pathFinder.FindPath(characterCoord, tc), + some: tc => + { + if (tc.Equals(characterCoord)) + return new Queue(); + return _pathFinder.FindPath(characterCoord, tc); + }, none: () => new Queue()); if (_walkPath.Any())