Skip to content

Commit

Permalink
Don't show empty dialogs if there is no response from the server when…
Browse files Browse the repository at this point in the history
… interacting with an NPC
  • Loading branch information
ethanmoffat committed Apr 6, 2022
1 parent 64511fa commit 927c60d
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 32 deletions.
16 changes: 16 additions & 0 deletions EOLib/Domain/Interact/INPCInteractionNotifier.cs
@@ -0,0 +1,16 @@
using AutomaticTypeMapper;
using EOLib.IO;

namespace EOLib.Domain.Interact
{
public interface INPCInteractionNotifier
{
void NotifyInteractionFromNPC(NPCType npcType);
}

[AutoMappedType]
public class NoOpNPCInteractionNotifier : INPCInteractionNotifier
{
public void NotifyInteractionFromNPC(NPCType npcType) { }
}
}
23 changes: 15 additions & 8 deletions EOLib/Domain/Interact/MapNPCActions.cs
@@ -1,4 +1,6 @@
using AutomaticTypeMapper;
using EOLib.Domain.NPC;
using EOLib.IO.Repositories;
using EOLib.Net;
using EOLib.Net.Communication;

Expand All @@ -8,26 +10,31 @@ namespace EOLib.Domain.Interact
public class MapNPCActions : IMapNPCActions
{
private readonly IPacketSendService _packetSendService;
private readonly IENFFileProvider _enfFileProvider;

public MapNPCActions(IPacketSendService packetSendService)
public MapNPCActions(IPacketSendService packetSendService,
IENFFileProvider enfFileProvider)
{
_packetSendService = packetSendService;
_enfFileProvider = enfFileProvider;
}

public void RequestShop(byte index)
public void RequestShop(INPC npc)
{
var packet = new PacketBuilder(PacketFamily.Shop, PacketAction.Open)
.AddShort(index)
.AddShort(npc.Index)
.Build();

_packetSendService.SendPacket(packet);
}

public void RequestQuest(short index, short vendorId)
public void RequestQuest(INPC npc)
{
var data = _enfFileProvider.ENFFile[npc.ID];

var packet = new PacketBuilder(PacketFamily.Quest, PacketAction.Use)
.AddShort(index)
.AddShort(vendorId)
.AddShort(npc.Index)
.AddShort(data.VendorID)
.Build();

_packetSendService.SendPacket(packet);
Expand All @@ -36,8 +43,8 @@ public void RequestQuest(short index, short vendorId)

public interface IMapNPCActions
{
void RequestShop(byte index);
void RequestShop(INPC npc);

void RequestQuest(short index, short vendorId);
void RequestQuest(INPC npc);
}
}
7 changes: 7 additions & 0 deletions EOLib/Domain/Interact/Quest/QuestDataRepository.cs
@@ -1,21 +1,28 @@
using AutomaticTypeMapper;
using EOLib.Domain.NPC;
using Optional;

namespace EOLib.Domain.Interact.Quest
{
public interface IQuestDataRepository : IResettable
{
INPC RequestedNPC { get; set; }

Option<IQuestDialogData> QuestDialogData { get; set; }
}

public interface IQuestDataProvider : IResettable
{
INPC RequestedNPC { get; }

Option<IQuestDialogData> QuestDialogData { get; }
}

[AutoMappedType(IsSingleton = true)]
public class QuestDataRepository : IQuestDataProvider, IQuestDataRepository
{
public INPC RequestedNPC { get; set; }

public Option<IQuestDialogData> QuestDialogData { get; set; }

public QuestDataRepository()
Expand Down
9 changes: 8 additions & 1 deletion EOLib/PacketHandlers/Interact/Shop/ShopOpenHandler.cs
@@ -1,4 +1,5 @@
using AutomaticTypeMapper;
using EOLib.Domain.Interact;
using EOLib.Domain.Interact.Shop;
using EOLib.Domain.Login;
using EOLib.Net;
Expand All @@ -11,16 +12,19 @@ namespace EOLib.PacketHandlers.Interact.Shop
public class ShopOpenHandler : InGameOnlyPacketHandler
{
private readonly IShopDataRepository _shopDataRepository;
private readonly IEnumerable<INPCInteractionNotifier> _npcInteractionNotifiers;

public override PacketFamily Family => PacketFamily.Shop;

public override PacketAction Action => PacketAction.Open;

public ShopOpenHandler(IPlayerInfoProvider playerInfoProvider,
IShopDataRepository shopDataRepository)
IShopDataRepository shopDataRepository,
IEnumerable<INPCInteractionNotifier> npcInteractionNotifiers)
: base(playerInfoProvider)
{
_shopDataRepository = shopDataRepository;
_npcInteractionNotifiers = npcInteractionNotifiers;
}

public override bool HandlePacket(IPacket packet)
Expand Down Expand Up @@ -62,6 +66,9 @@ public override bool HandlePacket(IPacket packet)

_shopDataRepository.CraftItems = craftItems;

foreach (var notifier in _npcInteractionNotifiers)
notifier.NotifyInteractionFromNPC(IO.NPCType.Shop);

return true;
}
}
Expand Down
9 changes: 8 additions & 1 deletion EOLib/PacketHandlers/Quest/QuestDialogHandler.cs
@@ -1,4 +1,5 @@
using AutomaticTypeMapper;
using EOLib.Domain.Interact;
using EOLib.Domain.Interact.Quest;
using EOLib.Domain.Login;
using EOLib.Net;
Expand All @@ -12,6 +13,7 @@ namespace EOLib.PacketHandlers.Quest
public class QuestDialogHandler : InGameOnlyPacketHandler
{
private readonly IQuestDataRepository _questDataRepository;
private readonly IEnumerable<INPCInteractionNotifier> _npcInteractionNotifiers;

private enum DialogEntryType : byte
{
Expand All @@ -24,10 +26,12 @@ private enum DialogEntryType : byte
public override PacketAction Action => PacketAction.Dialog;

public QuestDialogHandler(IPlayerInfoProvider playerInfoProvider,
IQuestDataRepository questDataRepository)
IQuestDataRepository questDataRepository,
IEnumerable<INPCInteractionNotifier> npcInteractionNotifiers)
: base(playerInfoProvider)
{
_questDataRepository = questDataRepository;
_npcInteractionNotifiers = npcInteractionNotifiers;
}

public override bool HandlePacket(IPacket packet)
Expand Down Expand Up @@ -70,6 +74,9 @@ public override bool HandlePacket(IPacket packet)

_questDataRepository.QuestDialogData = Option.Some(questData);

foreach (var notifier in _npcInteractionNotifiers)
notifier.NotifyInteractionFromNPC(IO.NPCType.Quest);

return true;
}
}
Expand Down
10 changes: 2 additions & 8 deletions EndlessClient/Controllers/NPCInteractionController.cs
@@ -1,5 +1,4 @@
using AutomaticTypeMapper;
using EndlessClient.Dialogs.Actions;
using EOLib.Domain.Interact;
using EOLib.Domain.NPC;
using EOLib.IO.Repositories;
Expand All @@ -10,15 +9,12 @@ namespace EndlessClient.Controllers
public class NPCInteractionController : INPCInteractionController
{
private readonly IMapNPCActions _mapNpcActions;
private readonly IInGameDialogActions _inGameDialogActions;
private readonly IENFFileProvider _enfFileProvider;

public NPCInteractionController(IMapNPCActions mapNpcActions,
IInGameDialogActions inGameDialogActions,
IENFFileProvider enfFileProvider)
{
_mapNpcActions = mapNpcActions;
_inGameDialogActions = inGameDialogActions;
_enfFileProvider = enfFileProvider;
}

Expand All @@ -29,12 +25,10 @@ public void ShowNPCDialog(INPC npc)
switch(data.Type)
{
case EOLib.IO.NPCType.Shop:
_mapNpcActions.RequestShop(npc.Index);
_inGameDialogActions.ShowShopDialog();
_mapNpcActions.RequestShop(npc);
break;
case EOLib.IO.NPCType.Quest:
_mapNpcActions.RequestQuest(npc.Index, data.VendorID);
_inGameDialogActions.ShowQuestDialog(npc);
_mapNpcActions.RequestQuest(npc);
break;
}
}
Expand Down
23 changes: 19 additions & 4 deletions EndlessClient/Dialogs/Actions/InGameDialogActions.cs
@@ -1,15 +1,17 @@
using AutomaticTypeMapper;
using EndlessClient.Dialogs.Factories;
using EOLib.Domain.Character;
using EOLib.Domain.Interact;
using EOLib.Domain.Interact.Quest;
using EOLib.Domain.Interact.Shop;
using EOLib.Domain.NPC;
using EOLib.IO;
using Optional;

namespace EndlessClient.Dialogs.Actions
{
[AutoMappedType]
public class InGameDialogActions : IInGameDialogActions
public class InGameDialogActions : IInGameDialogActions, INPCInteractionNotifier
{
private readonly IFriendIgnoreListDialogFactory _friendIgnoreListDialogFactory;
private readonly IPaperdollDialogFactory _paperdollDialogFactory;
Expand Down Expand Up @@ -72,6 +74,19 @@ public void ShowPaperdollDialog(ICharacter character, bool isMainCharacter)
});
}

public void NotifyInteractionFromNPC(NPCType npcType)
{
// originally, these methods were called directly from NPCInteractionController
// however, this resulted in empty responses (e.g. no shop or quest) showing an empty dialog
// instead, wait for the response packet to notify this class and then show the dialog
// once data has been received from the server
switch (npcType)
{
case NPCType.Shop: ShowShopDialog(); break;
case NPCType.Quest: ShowQuestDialog(); break;
}
}

public void ShowShopDialog()
{
_activeDialogRepository.ShopDialog.MatchNone(() =>
Expand All @@ -88,11 +103,11 @@ public void ShowShopDialog()
});
}

public void ShowQuestDialog(INPC npc)
public void ShowQuestDialog()
{
_activeDialogRepository.QuestDialog.MatchNone(() =>
{
var dlg = _questDialogFactory.Create(npc);
var dlg = _questDialogFactory.Create();
dlg.DialogClosed += (_, _) =>
{
_activeDialogRepository.QuestDialog = Option.None<QuestDialog>();
Expand All @@ -115,6 +130,6 @@ public interface IInGameDialogActions

void ShowShopDialog();

void ShowQuestDialog(INPC npc);
void ShowQuestDialog();
}
}
8 changes: 3 additions & 5 deletions EndlessClient/Dialogs/Factories/QuestDialogFactory.cs
Expand Up @@ -2,7 +2,6 @@
using EndlessClient.Content;
using EndlessClient.Dialogs.Services;
using EOLib.Domain.Interact.Quest;
using EOLib.Domain.NPC;
using EOLib.Graphics;
using EOLib.IO.Repositories;

Expand Down Expand Up @@ -33,20 +32,19 @@ public class QuestDialogFactory : IQuestDialogFactory
_contentProvider = contentProvider;
}

public QuestDialog Create(INPC npc)
public QuestDialog Create()
{
return new QuestDialog(_nativeGraphicsManager,
_questActions,
_dialogButtonService,
_questDataProvider,
_enfFileProvider,
_contentProvider,
npc);
_contentProvider);
}
}

public interface IQuestDialogFactory
{
QuestDialog Create(INPC npc);
QuestDialog Create();
}
}
7 changes: 2 additions & 5 deletions EndlessClient/Dialogs/QuestDialog.cs
Expand Up @@ -19,7 +19,6 @@ public class QuestDialog : ScrollingListDialog
private readonly IQuestDataProvider _questDataProvider;
private readonly IENFFileProvider _enfFileProvider;
private readonly IContentProvider _contentProvider;
private readonly INPC _questNpc;

private Option<IQuestDialogData> _cachedData;

Expand All @@ -30,15 +29,13 @@ public class QuestDialog : ScrollingListDialog
IEODialogButtonService dialogButtonService,
IQuestDataProvider questDataProvider,
IENFFileProvider enfFileProvider,
IContentProvider contentProvider,
INPC questNpc)
IContentProvider contentProvider)
: base(nativeGraphicsManager, dialogButtonService, dialogSize: ScrollingListDialogSize.SmallDialog)
{
_questActions = questActions;
_questDataProvider = questDataProvider;
_enfFileProvider = enfFileProvider;
_contentProvider = contentProvider;
_questNpc = questNpc;

_cachedData = Option.None<IQuestDialogData>();

Expand Down Expand Up @@ -86,7 +83,7 @@ private void UpdateDialogControls(IQuestDialogData repoData)

private void UpdateTitle(IQuestDialogData repoData)
{
var npcName = _enfFileProvider.ENFFile[_questNpc.ID].Name;
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]}";
Expand Down

0 comments on commit 927c60d

Please sign in to comment.