Skip to content

Commit

Permalink
Merge pull request #167 from ethanmoffat/paperdoll_drag
Browse files Browse the repository at this point in the history
Add drag+drop between inventory and paperdoll for equip/unequip
  • Loading branch information
ethanmoffat committed Apr 1, 2022
2 parents ba0b8da + 2162c7d commit 781de8e
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 105 deletions.
2 changes: 1 addition & 1 deletion EOLib/Domain/Chat/ChatProcessor.cs
Expand Up @@ -40,7 +40,7 @@ public string RemoveFirstCharacterIfNeeded(string chat, ChatType chatType, strin

public string MakeDrunk(string input)
{
// implementation from Phorophor::notepad (thanks Apollo)
// implementation from Phorophor::notepad (thanks Blo)
// https://discord.com/channels/723989119503696013/785190349026492437/791376941822246953
var ret = new StringBuilder();

Expand Down
8 changes: 6 additions & 2 deletions EndlessClient/ControlSets/ControlSetFactory.cs
Expand Up @@ -2,6 +2,7 @@
using AutomaticTypeMapper;
using EndlessClient.Content;
using EndlessClient.Controllers;
using EndlessClient.Dialogs;
using EndlessClient.Dialogs.Factories;
using EndlessClient.GameExecution;
using EndlessClient.HUD.Controls;
Expand All @@ -26,6 +27,7 @@ public class ControlSetFactory : IControlSetFactory
private readonly ICharacterSelectorProvider _characterSelectorProvider;
private readonly IEndlessGameProvider _endlessGameProvider;
private readonly IUserInputRepository _userInputRepository;
private readonly IActiveDialogRepository _activeDialogRepository;
private IMainButtonController _mainButtonController;
private IAccountController _accountController;
private ILoginController _loginController;
Expand All @@ -40,7 +42,8 @@ public class ControlSetFactory : IControlSetFactory
ICharacterInfoPanelFactory characterInfoPanelFactory,
ICharacterSelectorProvider characterSelectorProvider,
IEndlessGameProvider endlessGameProvider,
IUserInputRepository userInputRepository)
IUserInputRepository userInputRepository,
IActiveDialogRepository activeDialogRepository)
{
_nativeGraphicsManager = nativeGraphicsManager;
_messageBoxFactory = messageBoxFactory;
Expand All @@ -52,6 +55,7 @@ public class ControlSetFactory : IControlSetFactory
_characterSelectorProvider = characterSelectorProvider;
_endlessGameProvider = endlessGameProvider;
_userInputRepository = userInputRepository;
_activeDialogRepository = activeDialogRepository;
}

public IControlSet CreateControlsForState(GameStates newState, IControlSet currentControlSet)
Expand Down Expand Up @@ -105,7 +109,7 @@ private IControlSet GetSetBasedOnState(GameStates newState)
_endlessGameProvider,
_userInputRepository);
case GameStates.PlayingTheGame:
return new InGameControlSet(_mainButtonController, _messageBoxFactory, _hudControlsFactory);
return new InGameControlSet(_mainButtonController, _messageBoxFactory, _hudControlsFactory, _activeDialogRepository);
default: throw new ArgumentOutOfRangeException(nameof(newState), newState, null);
}
}
Expand Down
17 changes: 15 additions & 2 deletions EndlessClient/ControlSets/InGameControlSet.cs
Expand Up @@ -8,6 +8,7 @@
using EndlessClient.HUD.Controls;
using EOLib.Localization;
using Microsoft.Xna.Framework;
using Optional;
using XNAControls;

namespace EndlessClient.ControlSets
Expand All @@ -16,18 +17,20 @@ public class InGameControlSet : BackButtonControlSet
{
private readonly IEOMessageBoxFactory _messageBoxFactory;
private readonly IHudControlsFactory _hudControlsFactory;

private readonly IActiveDialogRepository _activeDialogRepository;
private IReadOnlyDictionary<HudControlIdentifier, IGameComponent> _controls;

public override GameStates GameState => GameStates.PlayingTheGame;

public InGameControlSet(IMainButtonController mainButtonController,
IEOMessageBoxFactory messageBoxFactory,
IHudControlsFactory hudControlsFactory)
IHudControlsFactory hudControlsFactory,
IActiveDialogRepository activeDialogRepository)
: base(mainButtonController)
{
_messageBoxFactory = messageBoxFactory;
_hudControlsFactory = hudControlsFactory;
_activeDialogRepository = activeDialogRepository;
_controls = new Dictionary<HudControlIdentifier, IGameComponent>();
}

Expand Down Expand Up @@ -55,5 +58,15 @@ protected override async void DoBackButtonClick(object sender, EventArgs e)
if (result == XNADialogResult.OK)
_mainButtonController.GoToInitialStateAndDisconnect();
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
_activeDialogRepository.Dispose();
}

base.Dispose(disposing);
}
}
}
14 changes: 12 additions & 2 deletions EndlessClient/Dialogs/ActiveDialogRepository.cs
@@ -1,12 +1,13 @@
using AutomaticTypeMapper;
using Optional;
using System;
using System.Collections.Generic;
using System.Linq;
using XNAControls;

namespace EndlessClient.Dialogs
{
public interface IActiveDialogProvider
public interface IActiveDialogProvider : IDisposable
{
Option<ScrollingListDialog> FriendIgnoreDialog { get; }

Expand All @@ -15,7 +16,7 @@ public interface IActiveDialogProvider
IReadOnlyList<Option<IXNADialog>> ActiveDialogs { get; }
}

public interface IActiveDialogRepository
public interface IActiveDialogRepository : IDisposable
{
Option<ScrollingListDialog> FriendIgnoreDialog { get; set; }

Expand Down Expand Up @@ -46,5 +47,14 @@ IReadOnlyList<Option<IXNADialog>> ActiveDialogs
IReadOnlyList<Option<IXNADialog>> IActiveDialogRepository.ActiveDialogs => ActiveDialogs;

IReadOnlyList<Option<IXNADialog>> IActiveDialogProvider.ActiveDialogs => ActiveDialogs;

public void Dispose()
{
foreach (var dlg in ActiveDialogs)
dlg.MatchSome(d => d.Dispose());

FriendIgnoreDialog = Option.None<ScrollingListDialog>();
PaperdollDialog = Option.None<PaperdollDialog>();
}
}
}
32 changes: 32 additions & 0 deletions EndlessClient/Dialogs/Extensions/EquipLocationExtensions.cs
@@ -0,0 +1,32 @@
using EOLib.IO;
using Microsoft.Xna.Framework;
using System;

namespace EndlessClient.Dialogs.Extensions
{
public static class EquipLocationExtensions
{
public static Rectangle GetEquipLocationRectangle(this EquipLocation loc)
{
switch (loc)
{
case EquipLocation.Boots: return new Rectangle(87, 220, 56, 54);
case EquipLocation.Accessory: return new Rectangle(55, 250, 23, 23);
case EquipLocation.Gloves: return new Rectangle(22, 188, 56, 54);
case EquipLocation.Belt: return new Rectangle(87, 188, 56, 23);
case EquipLocation.Armor: return new Rectangle(86, 82, 56, 98);
case EquipLocation.Necklace: return new Rectangle(152, 51, 56, 23);
case EquipLocation.Hat: return new Rectangle(87, 21, 56, 54);
case EquipLocation.Shield: return new Rectangle(152, 82, 56, 98);
case EquipLocation.Weapon: return new Rectangle(22, 82, 56, 98);
case EquipLocation.Ring1: return new Rectangle(152, 190, 23, 23);
case EquipLocation.Ring2: return new Rectangle(185, 190, 23, 23);
case EquipLocation.Armlet1: return new Rectangle(152, 220, 23, 23);
case EquipLocation.Armlet2: return new Rectangle(185, 220, 23, 23);
case EquipLocation.Bracer1: return new Rectangle(152, 250, 23, 23);
case EquipLocation.Bracer2: return new Rectangle(185, 250, 23, 23);
default: throw new ArgumentOutOfRangeException(nameof(loc), "That is not a valid equipment location");
}
}
}
}
5 changes: 5 additions & 0 deletions EndlessClient/Dialogs/Factories/PaperdollDialogFactory.cs
@@ -1,5 +1,6 @@
using AutomaticTypeMapper;
using EndlessClient.Controllers;
using EndlessClient.ControlSets;
using EndlessClient.Dialogs.Services;
using EndlessClient.GameExecution;
using EndlessClient.HUD;
Expand All @@ -20,20 +21,23 @@ public class PaperdollDialogFactory : IPaperdollDialogFactory
private readonly IStatusLabelSetter _statusLabelSetter;
private readonly IPaperdollProvider _paperdollProvider;
private readonly IPubFileProvider _pubFileProvider;
private readonly IHudControlProvider _hudControlProvider;
private readonly INativeGraphicsManager _nativeGraphicsManager;
private IInventoryController _inventoryController;

public PaperdollDialogFactory(IGameStateProvider gameStateProvider,
INativeGraphicsManager nativeGraphicsManager,
IPaperdollProvider paperdollProvider,
IPubFileProvider pubFileProvider,
IHudControlProvider hudControlProvider,
IEODialogButtonService eoDialogButtonService,
IInventorySpaceValidator inventorySpaceValidator,
IEOMessageBoxFactory eoMessageBoxFactory,
IStatusLabelSetter statusLabelSetter)
{
_paperdollProvider = paperdollProvider;
_pubFileProvider = pubFileProvider;
_hudControlProvider = hudControlProvider;
_nativeGraphicsManager = nativeGraphicsManager;
_gameStateProvider = gameStateProvider;
_eoDialogButtonService = eoDialogButtonService;
Expand All @@ -49,6 +53,7 @@ public PaperdollDialog Create(ICharacter character, bool isMainCharacter)
_inventoryController,
_paperdollProvider,
_pubFileProvider,
_hudControlProvider,
_eoDialogButtonService,
_inventorySpaceValidator,
_eoMessageBoxFactory,
Expand Down
66 changes: 23 additions & 43 deletions EndlessClient/Dialogs/PaperdollDialog.cs
@@ -1,9 +1,13 @@
using EndlessClient.Controllers;
using EndlessClient.ControlSets;
using EndlessClient.Dialogs.Extensions;
using EndlessClient.Dialogs.Factories;
using EndlessClient.Dialogs.Services;
using EndlessClient.GameExecution;
using EndlessClient.HUD;
using EndlessClient.HUD.Controls;
using EndlessClient.HUD.Inventory;
using EndlessClient.HUD.Panels;
using EOLib;
using EOLib.Domain.Character;
using EOLib.Domain.Online;
Expand All @@ -17,6 +21,7 @@
using Optional;
using Optional.Unsafe;
using System;
using System.Collections.Generic;
using System.Linq;
using XNAControls;

Expand All @@ -37,9 +42,12 @@ public class PaperdollDialog : BaseEODialog
private readonly Texture2D _characterIconSheet;
private readonly Texture2D _background;
private Option<Rectangle> _characterIconSourceRect;
private readonly InventoryPanel _inventoryPanel;

private Option<IPaperdollData> _paperdollData;

private readonly List<PaperdollDialogItem> _childItems;

private readonly IXNALabel _name,
_home,
_class,
Expand All @@ -55,6 +63,7 @@ public class PaperdollDialog : BaseEODialog
IInventoryController inventoryController,
IPaperdollProvider paperdollProvider,
IPubFileProvider pubFileProvider,
IHudControlProvider hudControlProvider,
IEODialogButtonService eoDialogButtonService,
IInventorySpaceValidator inventorySpaceValidator,
IEOMessageBoxFactory eoMessageBoxFactory,
Expand All @@ -74,6 +83,10 @@ public class PaperdollDialog : BaseEODialog
_characterIconSheet = _nativeGraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 32, true);
_characterIconSourceRect = Option.None<Rectangle>();

_inventoryPanel = hudControlProvider.GetComponent<InventoryPanel>(HudControlIdentifier.InventoryPanel);

_childItems = new List<PaperdollDialogItem>();

_background = _nativeGraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 49);
SetSize(_background.Width, _background.Height / 2);

Expand Down Expand Up @@ -123,10 +136,10 @@ public class PaperdollDialog : BaseEODialog
_paperdollData = Option.None<IPaperdollData>();
}

public bool NoItemsDragging() => !_childItems.Any(x => x.IsBeingDragged);

protected override void OnUpdateControl(GameTime gameTime)
{
base.OnUpdateControl(gameTime);

_paperdollData = _paperdollData.FlatMap(paperdollData =>
paperdollData.NoneWhen(d => _paperdollProvider.VisibleCharacterPaperdolls.ContainsKey(Character.ID) &&
!_paperdollProvider.VisibleCharacterPaperdolls[Character.ID].Equals(d)));
Expand All @@ -141,19 +154,9 @@ protected override void OnUpdateControl(GameTime gameTime)
}
});

// todo: dragging to equip/unequip from inventory
/*
if (EOGame.Instance.Hud.IsInventoryDragging())
{
shouldClickDrag = false;
SuppressParentClickDrag(true);
}
else
{
shouldClickDrag = true;
SuppressParentClickDrag(false);
}
*/
SuppressClickDragEvent(!NoItemsDragging() || !_inventoryPanel.NoItemsDragging());

base.OnUpdateControl(gameTime);
}

protected override void OnDrawControl(GameTime gameTime)
Expand Down Expand Up @@ -198,9 +201,7 @@ private void UpdateDisplayedData(IPaperdollData paperdollData)
_guild.Text = Capitalize(paperdollData.Guild);
_rank.Text = Capitalize(paperdollData.Rank);

var paperdollDialogItems = ChildControls.OfType<PaperdollDialogItem>().ToList();

foreach (var control in paperdollDialogItems)
foreach (var control in _childItems)
{
control.SetControlUnparented();
control.Dispose();
Expand All @@ -213,9 +214,9 @@ private void UpdateDisplayedData(IPaperdollData paperdollData)

var id = paperdollData.Paperdoll[equipLocation];
var eifRecord = id.SomeWhen(i => i > 0).Map(i => _pubFileProvider.EIFFile[i]);
var paperdollItem = new PaperdollDialogItem(_nativeGraphicsManager, _isMainCharacter, equipLocation, eifRecord)
var paperdollItem = new PaperdollDialogItem(_nativeGraphicsManager, _inventoryPanel, this, _isMainCharacter, equipLocation, eifRecord)
{
DrawArea = GetEquipLocationRectangle(equipLocation)
DrawArea = equipLocation.GetEquipLocationRectangle()
};

paperdollItem.OnMouseEnter += (_, _) =>
Expand Down Expand Up @@ -271,6 +272,8 @@ private void UpdateDisplayedData(IPaperdollData paperdollData)

paperdollItem.SetParentControl(this);
paperdollItem.Initialize();

_childItems.Add(paperdollItem);
}

_characterIconSourceRect = Option.Some(GetOnlineIconSourceRectangle(paperdollData.Icon));
Expand All @@ -284,28 +287,5 @@ private static Rectangle GetOnlineIconSourceRectangle(OnlineIcon icon)
var (x, y, width, height) = icon.ToChatIcon().GetChatIconRectangleBounds().ValueOrDefault();
return new Rectangle(x, y, width, height);
}

private static Rectangle GetEquipLocationRectangle(EquipLocation loc)
{
switch (loc)
{
case EquipLocation.Boots: return new Rectangle(87, 220, 56, 54);
case EquipLocation.Accessory: return new Rectangle(55, 250, 23, 23);
case EquipLocation.Gloves: return new Rectangle(22, 188, 56, 54);
case EquipLocation.Belt: return new Rectangle(87, 188, 56, 23);
case EquipLocation.Armor: return new Rectangle(86, 82, 56, 98);
case EquipLocation.Necklace: return new Rectangle(152, 51, 56, 23);
case EquipLocation.Hat: return new Rectangle(87, 21, 56, 54);
case EquipLocation.Shield: return new Rectangle(152, 82, 56, 98);
case EquipLocation.Weapon: return new Rectangle(22, 82, 56, 98);
case EquipLocation.Ring1: return new Rectangle(152, 190, 23, 23);
case EquipLocation.Ring2: return new Rectangle(185, 190, 23, 23);
case EquipLocation.Armlet1: return new Rectangle(152, 220, 23, 23);
case EquipLocation.Armlet2: return new Rectangle(185, 220, 23, 23);
case EquipLocation.Bracer1: return new Rectangle(152, 250, 23, 23);
case EquipLocation.Bracer2: return new Rectangle(185, 250, 23, 23);
default: throw new ArgumentOutOfRangeException(nameof(loc), "That is not a valid equipment location");
}
}
}
}

0 comments on commit 781de8e

Please sign in to comment.