Skip to content

Commit

Permalink
Implement Barber Dialog and packets (#355)
Browse files Browse the repository at this point in the history
Co-authored-by: Ethan Moffat <[email protected]>
  • Loading branch information
sjbmcg and ethanmoffat authored Jun 5, 2024
1 parent 83b3fd4 commit 7c88f02
Show file tree
Hide file tree
Showing 20 changed files with 580 additions and 46 deletions.
9 changes: 7 additions & 2 deletions EOLib.Localization/EOResourceID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,13 @@ public enum EOResourceID
DIALOG_SHOP_CRAFT_MISSING_INGREDIENTS = 158,
DIALOG_SHOP_CRAFT_PUT_INGREDIENTS_TOGETHER = 159,

DIALOG_BARBER_CHANGE_MODAL = 160,
DIALOG_BARBER_CHANGE_HAIR_COLOR = 161,
DIALOG_BARBER_BUY_HAIRSTYLE = 162,
DIALOG_WORD_CURRENT = 163,

DIALOG_BARBER_DO_YOU_WANT_TO_BUY_A_NEW_HAIRSTYLE = 164,


DIALOG_TRADE_BOTH_PLAYERS_OFFER_ONE_ITEM = 165,

DIALOG_TRANSFER_TRANSFER = 176,
Expand Down Expand Up @@ -342,6 +347,6 @@ public enum EOResourceID
STATUS_LABEL_IS_ONLINE_NOT_FOUND = 430,
DIALOG_BANK_LOCKER_UPGRADE = 431,
DIALOG_BANK_MORE_SPACE = 432,
STATUS_LABEL_LOCKER_SPACE_INCREASED = 433
STATUS_LABEL_LOCKER_SPACE_INCREASED = 433,
}
}
37 changes: 37 additions & 0 deletions EOLib/Domain/Interact/Barber/BarberActions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using AutomaticTypeMapper;
using EOLib.Net;
using EOLib.Net.Communication;
using System.Diagnostics;
using EOLib.Domain.Character;
namespace EOLib.Domain.Interact.Barber
{
[AutoMappedType]
public class BarberActions : IBarberActions
{
private readonly IPacketSendService _packetSendService;
private readonly IBarberDataRepository _barberDataRepository;

public BarberActions(IPacketSendService packetSendService,
IBarberDataRepository barberDataRepository)
{
_packetSendService = packetSendService;
_barberDataRepository = barberDataRepository;
}

public void Purchase(int hairStyle, int hairColor)
{
var packet = new PacketBuilder(PacketFamily.Barber, PacketAction.Buy)
.AddChar((char)hairStyle)
.AddChar((char)hairColor)
.AddInt(_barberDataRepository.SessionID)
.Build();

_packetSendService.SendPacket(packet);
}
}

public interface IBarberActions
{
void Purchase(int hairStyle, int hairColor);
}
}
30 changes: 30 additions & 0 deletions EOLib/Domain/Interact/Barber/BarberDataRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using AutomaticTypeMapper;

namespace EOLib.Domain.Interact.Barber
{
public interface IBarberDataRepository : IResettable
{
int SessionID { get; set; }
}

public interface IBarberDataProvider : IResettable
{
int SessionID { get; }
}

[AutoMappedType(IsSingleton = true)]
public class BarberDataRepository : IBarberDataRepository, IBarberDataProvider
{
public int SessionID { get; set; }

public BarberDataRepository()
{
ResetState();
}

public void ResetState()
{
SessionID = 0;
}
}
}
17 changes: 11 additions & 6 deletions EOLib/Domain/Interact/MapNPCActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,27 @@ public void RequestPriest(NPC.NPC npc)

_packetSendService.SendPacket(packet);
}

public void RequestBarber(NPC.NPC npc)
{
var packet = new PacketBuilder(PacketFamily.Barber, PacketAction.Open)
.AddInt(npc.Index)
.Build();

_packetSendService.SendPacket(packet);
}
}

public interface IMapNPCActions
{
void RequestShop(NPC.NPC npc);

void RequestQuest(NPC.NPC npc);

void RequestBank(NPC.NPC npc);

void RequestSkillmaster(NPC.NPC npc);

void RequestInnkeeper(NPC.NPC npc);

void RequestLaw(NPC.NPC npc);

void RequestPriest(NPC.NPC npc);
void RequestBarber(NPC.NPC npc); // Corrected here
}

}
97 changes: 97 additions & 0 deletions EOLib/PacketHandlers/Barber/BarberAgreeHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using AutomaticTypeMapper;
using EOLib.Domain.Interact;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;
using EOLib.Domain.Interact.Barber;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;

namespace EOLib.PacketHandlers.Barber
{
[AutoMappedType]
public class BarberAgreeHandler : InGameOnlyPacketHandler
{
private readonly IBarberDataRepository _barberDataRepository;
private readonly IEnumerable<INPCInteractionNotifier> _npcInteractionNotifiers;
private readonly ICharacterRepository _characterRepository;
private readonly ICurrentMapStateRepository _currentMapStateRepository;
private readonly ICharacterInventoryRepository _characterInventoryRepository;

public override PacketFamily Family => PacketFamily.Barber;
public override PacketAction Action => PacketAction.Agree;

public BarberAgreeHandler(
IPlayerInfoProvider playerInfoProvider,
IEnumerable<INPCInteractionNotifier> npcInteractionNotifiers,
IBarberDataRepository barberDataRepository,
ICharacterRepository characterRepository,
ICurrentMapStateRepository currentMapStateRepository,
ICharacterInventoryRepository characterInventoryRepository)
: base(playerInfoProvider)
{
_npcInteractionNotifiers = npcInteractionNotifiers;
_barberDataRepository = barberDataRepository;
_characterRepository = characterRepository;
_currentMapStateRepository = currentMapStateRepository;
_characterInventoryRepository = characterInventoryRepository;
}

public override bool HandlePacket(IPacket packet)
{
var amount = packet.ReadInt();
var gold = new InventoryItem(1, amount);
var playerID = packet.ReadShort();

_characterInventoryRepository.ItemInventory.RemoveWhere(x => x.ItemID == 1);
_characterInventoryRepository.ItemInventory.Add(gold);

var currentCharacter = _characterRepository.MainCharacter.ID == playerID
? _characterRepository.MainCharacter
: null;

if (currentCharacter == null)
{
return false;
}

var currentRenderProps = currentCharacter.RenderProperties;
var slot = (AvatarSlot)packet.ReadChar();

switch (slot)
{
case AvatarSlot.Hair:
if (packet.ReadChar() != 0)
throw new MalformedPacketException("Missing expected 0 byte in updating hair packet", packet);

currentRenderProps = currentRenderProps
.WithHairStyle(packet.ReadChar())
.WithHairColor(packet.ReadChar());
break;

case AvatarSlot.HairColor:
if (packet.ReadChar() != 0)
throw new MalformedPacketException("Missing expected 0 byte in updating hair color packet", packet);

currentRenderProps = currentRenderProps
.WithHairColor(packet.ReadChar());
break;
}

var updatedCharacter = currentCharacter.WithRenderProperties(currentRenderProps);

if (_characterRepository.MainCharacter.ID == playerID)
{
_characterRepository.MainCharacter = updatedCharacter;
}
else
{
_currentMapStateRepository.Characters.Update(currentCharacter, updatedCharacter);
}

return true;
}
}
}
44 changes: 44 additions & 0 deletions EOLib/PacketHandlers/Barber/BarberOpenHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using AutomaticTypeMapper;
using EOLib.Domain.Interact;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;
using EOLib.Domain.Interact.Barber;
using EOLib.Domain.Character;
using EOLib.Domain.Login;

namespace EOLib.PacketHandlers.Barber
{
[AutoMappedType]
public class BarberOpenHandler : InGameOnlyPacketHandler
{
private readonly IBarberDataRepository _barberDataRepository;
private readonly IEnumerable<INPCInteractionNotifier> _npcInteractionNotifiers;

public override PacketFamily Family => PacketFamily.Barber;
public override PacketAction Action => PacketAction.Open;

public BarberOpenHandler(
IPlayerInfoProvider playerInfoProvider,
IEnumerable<INPCInteractionNotifier> npcInteractionNotifiers,
IBarberDataRepository barberDataRepository)
: base(playerInfoProvider)
{
_npcInteractionNotifiers = npcInteractionNotifiers;
_barberDataRepository = barberDataRepository;
}

public override bool HandlePacket(IPacket packet)
{
var sessionId = packet.ReadInt();
_barberDataRepository.SessionID = sessionId;

foreach (var notifier in _npcInteractionNotifiers)
{
notifier.NotifyInteractionFromNPC(IO.NPCType.Barber);
}

return true;
}
}
}
3 changes: 3 additions & 0 deletions EndlessClient/Controllers/NPCInteractionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ public void ShowNPCDialog(NPC npc)
case EOLib.IO.NPCType.Priest:
_mapNpcActions.RequestPriest(npc);
break;
case EOLib.IO.NPCType.Barber:
_mapNpcActions.RequestBarber(npc);
break;
}
}
}
Expand Down
24 changes: 23 additions & 1 deletion EndlessClient/Dialogs/Actions/InGameDialogActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class InGameDialogActions : IInGameDialogActions
private readonly IStatusLabelSetter _statusLabelSetter;
private readonly IShopDialogFactory _shopDialogFactory;
private readonly IQuestDialogFactory _questDialogFactory;
private readonly IBarberDialogFactory _barberDialogFactory;

public InGameDialogActions(IFriendIgnoreListDialogFactory friendIgnoreListDialogFactory,
IPaperdollDialogFactory paperdollDialogFactory,
Expand All @@ -69,7 +70,8 @@ public InGameDialogActions(IFriendIgnoreListDialogFactory friendIgnoreListDialog
ILawDialogFactory lawDialogFactory,
IHelpDialogFactory helpDialogFactory,
ISfxPlayer sfxPlayer,
IStatusLabelSetter statusLabelSetter)
IStatusLabelSetter statusLabelSetter,
IBarberDialogFactory barberDialogFactory)
{
_friendIgnoreListDialogFactory = friendIgnoreListDialogFactory;
_paperdollDialogFactory = paperdollDialogFactory;
Expand All @@ -96,6 +98,7 @@ public InGameDialogActions(IFriendIgnoreListDialogFactory friendIgnoreListDialog
_statusLabelSetter = statusLabelSetter;
_shopDialogFactory = shopDialogFactory;
_questDialogFactory = questDialogFactory;
_barberDialogFactory = barberDialogFactory;
}

public void ShowFriendListDialog()
Expand Down Expand Up @@ -449,6 +452,23 @@ public void ShowHelpDialog()
UseDefaultDialogSounds(dlg);
});
}

public void ShowBarberDialog()
{
_activeDialogRepository.BarberDialog.MatchNone(() =>
{
var dlg = _barberDialogFactory.Create();
dlg.DialogClosed += (_, _) =>
{
_activeDialogRepository.BarberDialog = Option.None<BarberDialog>();
};
_activeDialogRepository.BarberDialog = Option.Some(dlg);

UseDefaultDialogSounds(dlg);

dlg.Show();
});
}

private void UseDefaultDialogSounds(ScrollingListDialog dialog)
{
Expand Down Expand Up @@ -522,5 +542,7 @@ public interface IInGameDialogActions
void ShowLawDialog();

void ShowHelpDialog();

void ShowBarberDialog();
}
}
2 changes: 2 additions & 0 deletions EndlessClient/Dialogs/Actions/NpcInteractionActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System;
using XNAControls;


namespace EndlessClient.Dialogs.Actions
{
[AutoMappedType]
Expand Down Expand Up @@ -58,6 +59,7 @@ public void NotifyInteractionFromNPC(NPCType npcType)
case NPCType.Skills: _inGameDialogActions.ShowSkillmasterDialog(); break;
case NPCType.Inn: _inGameDialogActions.ShowInnkeeperDialog(); break;
case NPCType.Law: _inGameDialogActions.ShowLawDialog(); break;
case NPCType.Barber: _inGameDialogActions.ShowBarberDialog(); break;
case NPCType.Priest: ShowPriestDialog(); break;
}
}
Expand Down
8 changes: 8 additions & 0 deletions EndlessClient/Dialogs/ActiveDialogRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public interface IActiveDialogProvider : IDisposable

Option<LawDialog> LawDialog { get; }

Option<BarberDialog> BarberDialog { get; }

Option<ScrollingListDialog> HelpDialog { get; }

IReadOnlyList<Option<IXNADialog>> ActiveDialogs { get; }
Expand Down Expand Up @@ -92,6 +94,8 @@ public interface IActiveDialogRepository : IDisposable

Option<LawDialog> LawDialog { get; set; }

Option<BarberDialog> BarberDialog { get; set; }

Option<ScrollingListDialog> HelpDialog { get; set; }

IReadOnlyList<Option<IXNADialog>> ActiveDialogs { get; }
Expand Down Expand Up @@ -138,6 +142,8 @@ public class ActiveDialogRepository : IActiveDialogRepository, IActiveDialogProv

public Option<LawDialog> LawDialog { get; set; }

public Option<BarberDialog> BarberDialog { get; set; }

public Option<ScrollingListDialog> HelpDialog { get; set; }

IReadOnlyList<Option<IXNADialog>> ActiveDialogs
Expand Down Expand Up @@ -165,6 +171,7 @@ IReadOnlyList<Option<IXNADialog>> ActiveDialogs
JukeboxDialog.Map(Map),
InnkeeperDialog.Map(Map),
LawDialog.Map(Map),
BarberDialog.Map(Map),
HelpDialog.Map(Map),
}.ToList();

Expand Down Expand Up @@ -203,6 +210,7 @@ public void Dispose()
JukeboxDialog = Option.None<JukeboxDialog>();
InnkeeperDialog = Option.None<InnkeeperDialog>();
LawDialog = Option.None<LawDialog>();
BarberDialog = Option.None<BarberDialog>();
HelpDialog = Option.None<ScrollingListDialog>();
}
}
Expand Down
Loading

0 comments on commit 7c88f02

Please sign in to comment.