Skip to content

Commit

Permalink
Ensure clicks don't trigger multiple handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed Apr 10, 2022
1 parent 0afed66 commit 0d3ff9c
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 31 deletions.
1 change: 1 addition & 0 deletions EndlessClient/ControlSets/BackButtonControlSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
};
Expand Down
2 changes: 1 addition & 1 deletion EndlessClient/ControlSets/ControlSetFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
8 changes: 7 additions & 1 deletion EndlessClient/ControlSets/InGameControlSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -18,19 +19,22 @@ public class InGameControlSet : BackButtonControlSet
private readonly IEOMessageBoxFactory _messageBoxFactory;
private readonly IHudControlsFactory _hudControlsFactory;
private readonly IActiveDialogRepository _activeDialogRepository;
private readonly IUserInputRepository _userInputRepository;
private IReadOnlyDictionary<HudControlIdentifier, IGameComponent> _controls;

public override GameStates GameState => GameStates.PlayingTheGame;

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<HudControlIdentifier, IGameComponent>();
}

Expand All @@ -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);
Expand Down
9 changes: 8 additions & 1 deletion EndlessClient/Controllers/NPCInteractionController.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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)
Expand All @@ -38,16 +42,19 @@ 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);
// note: the npc action types rely on a server response to show the dialog because they are driven
// 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;
}
}
Expand Down
23 changes: 9 additions & 14 deletions EndlessClient/Rendering/Character/CharacterRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -91,7 +91,8 @@ public CharacterRenderer(INativeGraphicsManager nativeGraphicsmanager,
ICharacterSpriteCalculator characterSpriteCalculator,
ICharacter character,
IGameStateProvider gameStateProvider,
ICurrentMapProvider currentMapProvider)
ICurrentMapProvider currentMapProvider,
IUserInputProvider userInputProvider)
: base(game)
{
_mapInteractionController = mapInteractionController;
Expand All @@ -106,6 +107,7 @@ public CharacterRenderer(INativeGraphicsManager nativeGraphicsmanager,
_character = character;
_gameStateProvider = gameStateProvider;
_currentMapProvider = currentMapProvider;
_userInputProvider = userInputProvider;
_effectRenderer = new EffectRenderer(nativeGraphicsmanager, this);
_chatBubble = new Lazy<IChatBubble>(() => _chatBubbleFactory.CreateChatBubble(this));
}
Expand Down Expand Up @@ -140,9 +142,6 @@ public override void Initialize()
_healthBarRenderer = _healthBarRendererFactory.CreateHealthBarRenderer(this);
}

_previousMouseState = _currentMouseState = Mouse.GetState();


base.Initialize();
}

Expand All @@ -166,8 +165,6 @@ public override void Update(GameTime gameTime)
if (!Visible)
return;

_currentMouseState = Mouse.GetState();

if (_textureUpdateRequired)
{
_characterTextures.Refresh(_character.RenderProperties);
Expand All @@ -183,18 +180,16 @@ 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) });
}

_healthBarRenderer.Update(gameTime);
}

_previousMouseState = _currentMouseState;

base.Update(gameTime);
}

Expand Down Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions EndlessClient/Rendering/Factories/CharacterRendererFactory.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -41,7 +43,8 @@ public CharacterRendererFactory(INativeGraphicsManager nativeGraphicsManager,
ICharacterTextures characterTextures,
ICharacterSpriteCalculator characterSpriteCalculator,
IGameStateProvider gameStateProvider,
ICurrentMapProvider currentMapProvider)
ICurrentMapProvider currentMapProvider,
IUserInputProvider userInputProvider)
{
_nativeGraphicsManager = nativeGraphicsManager;
_gameProvider = gameProvider;
Expand All @@ -56,6 +59,7 @@ public CharacterRendererFactory(INativeGraphicsManager nativeGraphicsManager,
_characterSpriteCalculator = characterSpriteCalculator;
_gameStateProvider = gameStateProvider;
_currentMapProvider = currentMapProvider;
_userInputProvider = userInputProvider;
}

public ICharacterRenderer CreateCharacterRenderer(ICharacter character)
Expand All @@ -74,7 +78,8 @@ public ICharacterRenderer CreateCharacterRenderer(ICharacter character)
_characterSpriteCalculator,
character,
_gameStateProvider,
_currentMapProvider);
_currentMapProvider,
_userInputProvider);
}
}
}
21 changes: 10 additions & 11 deletions EndlessClient/Rendering/NPC/NPCRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -75,6 +75,7 @@ public NPCRenderer(INativeGraphicsManager nativeGraphicsManager,
IHealthBarRendererFactory healthBarRendererFactory,
IChatBubbleFactory chatBubbleFactory,
INPCInteractionController npcInteractionController,
IUserInputProvider userInputProvider,
INPC initialNPC)
: base((Game)endlessGameProvider.Game)
{
Expand All @@ -87,6 +88,8 @@ public NPCRenderer(INativeGraphicsManager nativeGraphicsManager,
_healthBarRendererFactory = healthBarRendererFactory;
_chatBubbleFactory = chatBubbleFactory;
_npcInteractionController = npcInteractionController;
_userInputProvider = userInputProvider;

_baseTextureFrameRectangle = GetStandingFrameRectangle();
_readonlyTopPixel = GetTopPixel();
_readonlyBottomPixel = GetBottomPixel();
Expand Down Expand Up @@ -120,7 +123,6 @@ public override void Initialize()
_nameLabel.Game.Components.Add(_nameLabel);

_nameLabel.DrawPosition = GetNameLabelPosition();
_previousMouseState = _currentMouseState = Mouse.GetState();

base.Initialize();
}
Expand All @@ -129,27 +131,24 @@ 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);
}

_effectRenderer.Update();
_healthBarRenderer.Update(gameTime);

_previousMouseState = _currentMouseState;

base.Update(gameTime);
}

Expand Down
7 changes: 6 additions & 1 deletion EndlessClient/Rendering/NPC/NPCRendererFactory.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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,
Expand All @@ -32,7 +34,8 @@ public NPCRendererFactory(INativeGraphicsManager nativeGraphicsManager,
IRenderOffsetCalculator renderOffsetCalculator,
IHealthBarRendererFactory healthBarRendererFactory,
IChatBubbleFactory chatBubbleFactory,
INPCInteractionController npcInteractionController)
INPCInteractionController npcInteractionController,
IUserInputProvider userInputProvider)
{
_nativeGraphicsManager = nativeGraphicsManager;
_endlessGameProvider = endlessGameProvider;
Expand All @@ -43,6 +46,7 @@ public NPCRendererFactory(INativeGraphicsManager nativeGraphicsManager,
_healthBarRendererFactory = healthBarRendererFactory;
_chatBubbleFactory = chatBubbleFactory;
_npcInteractionController = npcInteractionController;
_userInputProvider = userInputProvider;
}

public INPCRenderer CreateRendererFor(INPC npc)
Expand All @@ -56,6 +60,7 @@ public INPCRenderer CreateRendererFor(INPC npc)
_healthBarRendererFactory,
_chatBubbleFactory,
_npcInteractionController,
_userInputProvider,
npc);
}
}
Expand Down

0 comments on commit 0d3ff9c

Please sign in to comment.