Skip to content

Commit

Permalink
Merge pull request #179 from ethanmoffat/clickable_map_entities
Browse files Browse the repository at this point in the history
Bug fixes and behavior improvements for clicking stuff
  • Loading branch information
ethanmoffat committed Apr 11, 2022
2 parents 6c05472 + 749a333 commit 56d71d3
Show file tree
Hide file tree
Showing 24 changed files with 229 additions and 52 deletions.
1 change: 0 additions & 1 deletion EOLib/Domain/Interact/Quest/QuestDataRepository.cs
Expand Up @@ -49,7 +49,6 @@ public QuestDataRepository()

public void ResetState()
{
RequestedNPC = null;
QuestDialogData = Option.None<IQuestDialogData>();
QuestProgress = new List<IQuestProgressData>();
QuestHistory = new List<string>();
Expand Down
1 change: 1 addition & 0 deletions EndlessClient/ControlSets/BackButtonControlSet.cs
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
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
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
23 changes: 19 additions & 4 deletions EndlessClient/Controllers/MapInteractionController.cs
Expand Up @@ -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,
Expand All @@ -59,7 +60,8 @@ public class MapInteractionController : IMapInteractionController
IUserInputTimeRepository userInputTimeRepository,
IEOMessageBoxFactory messageBoxFactory,
IContextMenuRendererFactory contextMenuRendererFactory,
IActiveDialogProvider activeDialogProvider)
IActiveDialogProvider activeDialogProvider,
IUserInputRepository userInputRepository)
{
_mapActions = mapActions;
_characterActions = characterActions;
Expand All @@ -77,9 +79,10 @@ public class MapInteractionController : IMapInteractionController
_messageBoxFactory = messageBoxFactory;
_contextMenuRendererFactory = contextMenuRendererFactory;
_activeDialogProvider = activeDialogProvider;
_userInputRepository = userInputRepository;
}

public void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRenderer)
public void LeftClick(IMapCellState cellState, Option<IMouseCursorRenderer> mouseRenderer)
{
if (!InventoryPanel.NoItemsDragging() || _activeDialogProvider.ActiveDialogs.Any(x => x.HasValue))
return;
Expand All @@ -92,16 +95,22 @@ public void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRendere
_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))
{
Expand All @@ -115,22 +124,28 @@ public void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRendere
{
_mapActions.OpenChest((byte)cellState.Coordinate.X, (byte)cellState.Coordinate.Y);
_inGameDialogActions.ShowChestDialog();

_userInputRepository.ClickHandled = true;
}
break;
case TileSpec.BankVault:
if (unwalkableAction == UnwalkableTileAction.Locker)
{
_mapActions.OpenLocker((byte)cellState.Coordinate.X, (byte)cellState.Coordinate.Y);
_inGameDialogActions.ShowLockerDialog();

_userInputRepository.ClickHandled = true;
}
break;
}
}
else if (cellState.InBounds && !cellState.Character.HasValue && !cellState.NPC.HasValue)
{
mouseRenderer.AnimateClick();
mouseRenderer.MatchSome(r => r.AnimateClick());
_hudControlProvider.GetComponent<ICharacterAnimator>(HudControlIdentifier.CharacterAnimator)
.StartMainCharacterWalkAnimation(Option.Some(cellState.Coordinate));

_userInputRepository.ClickHandled = true;
}

_userInputTimeRepository.LastInputTime = DateTime.Now;
Expand Down Expand Up @@ -229,7 +244,7 @@ private bool CharacterIsCloseEnough(MapCoordinate coordinate)

public interface IMapInteractionController
{
void LeftClick(IMapCellState cellState, IMouseCursorRenderer mouseRenderer);
void LeftClick(IMapCellState cellState, Option<IMouseCursorRenderer> mouseRenderer);

void RightClick(IMapCellState cellState);
}
Expand Down
17 changes: 16 additions & 1 deletion EndlessClient/Controllers/NPCInteractionController.cs
@@ -1,9 +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
Expand All @@ -13,18 +16,24 @@ 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)
IActiveDialogProvider activeDialogProvider,
IUserInputRepository userInputRepository)
{
_mapNpcActions = mapNpcActions;
_inGameDialogActions = inGameDialogActions;
_statusLabelSetter = statusLabelSetter;
_enfFileProvider = enfFileProvider;
_activeDialogProvider = activeDialogProvider;
_userInputRepository = userInputRepository;
}

public void ShowNPCDialog(INPC npc)
Expand All @@ -34,20 +43,26 @@ 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:
_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
3 changes: 2 additions & 1 deletion EndlessClient/Dialogs/QuestDialog.cs
Expand Up @@ -9,6 +9,7 @@
using Optional;
using System;
using System.Collections.Generic;
using System.Linq;
using XNAControls;

namespace EndlessClient.Dialogs
Expand Down Expand Up @@ -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]}";

Expand Down
4 changes: 2 additions & 2 deletions EndlessClient/HUD/Controls/HudControlsFactory.cs
Expand Up @@ -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))
Expand All @@ -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))
Expand Down
7 changes: 5 additions & 2 deletions 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);
}
}
9 changes: 7 additions & 2 deletions 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;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions EndlessClient/Input/IUserInputRepository.cs
Expand Up @@ -12,6 +12,8 @@ public interface IUserInputRepository
MouseState PreviousMouseState { get; set; }

MouseState CurrentMouseState { get; set; }

bool ClickHandled { get; set; }
}

public interface IUserInputProvider
Expand All @@ -23,6 +25,8 @@ public interface IUserInputProvider
MouseState PreviousMouseState { get; }

MouseState CurrentMouseState { get; }

bool ClickHandled { get; }
}

[MappedType(BaseType = typeof(IUserInputRepository), IsSingleton = true)]
Expand All @@ -36,5 +40,7 @@ public class KeyStateRepository : IUserInputRepository, IUserInputProvider
public MouseState PreviousMouseState { get; set; }

public MouseState CurrentMouseState { get; set; }

public bool ClickHandled { get; set; }
}
}
1 change: 1 addition & 0 deletions EndlessClient/Input/PreviousUserInputTracker.cs
Expand Up @@ -21,6 +21,7 @@ public override void Update(GameTime gameTime)
{
_userInputRepository.PreviousKeyState = _userInputRepository.CurrentKeyState;
_userInputRepository.PreviousMouseState = _userInputRepository.CurrentMouseState;
_userInputRepository.ClickHandled = false;

base.Update(gameTime);
}
Expand Down
7 changes: 6 additions & 1 deletion EndlessClient/Rendering/Character/CharacterAnimator.cs
Expand Up @@ -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<MapCoordinate>();
return _pathFinder.FindPath(characterCoord, tc);
},
none: () => new Queue<MapCoordinate>());
if (_walkPath.Any())
Expand Down

0 comments on commit 56d71d3

Please sign in to comment.