Skip to content

Commit

Permalink
Domain model and packet handling for skillmaster dialogs
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed Apr 20, 2022
1 parent d12b7a1 commit fbcdbc2
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 54 deletions.
11 changes: 11 additions & 0 deletions EOLib/Domain/Interact/MapNPCActions.cs
Expand Up @@ -54,6 +54,15 @@ public void RequestBank(INPC npc)

_packetSendService.SendPacket(packet);
}

public void RequestSkillmaster(INPC npc)
{
var packet = new PacketBuilder(PacketFamily.StatSkill, PacketAction.Open)
.AddShort((short)npc.Index)
.Build();

_packetSendService.SendPacket(packet);
}
}

public interface IMapNPCActions
Expand All @@ -63,5 +72,7 @@ public interface IMapNPCActions
void RequestQuest(INPC npc);

void RequestBank(INPC npc);

void RequestSkillmaster(INPC npc);
}
}
32 changes: 32 additions & 0 deletions EOLib/Domain/Interact/Skill/Skill.cs
@@ -0,0 +1,32 @@
using Amadevus.RecordGenerator;
using System.Collections.Generic;

namespace EOLib.Domain.Interact.Skill
{
[Record]
public sealed partial class Skill
{
public short Id { get; }

public byte LevelRequirement { get; }

public byte ClassRequirement { get; }

public int GoldRequirement { get; }

public IReadOnlyList<short> SkillRequirements { get; }

public short StrRequirement { get; }

public short IntRequirement { get; }

public short WisRequirement { get; }

public short AgiRequirement { get; }

public short ConRequirement { get; }

public short ChaRequirement { get; }
}

}
47 changes: 47 additions & 0 deletions EOLib/Domain/Interact/Skill/SkillDataRepository.cs
@@ -0,0 +1,47 @@
using AutomaticTypeMapper;
using System.Collections.Generic;

namespace EOLib.Domain.Interact.Skill
{
public interface ISkillDataRepository : IResettable
{
short ID { get; set; }

string Title { get; set; }

HashSet<Skill> Skills { get; set; }
}

public interface ISkillDataProvider : IResettable
{
short ID { get; }

string Title { get; }

IReadOnlyCollection<Skill> Skills { get; }
}

[AutoMappedType(IsSingleton = true)]
public class SkillDataRepository : ISkillDataRepository, ISkillDataProvider
{
public short ID { get; set; }

public string Title { get; set; }

public HashSet<Skill> Skills { get; set; }

IReadOnlyCollection<Skill> ISkillDataProvider.Skills => Skills;

public SkillDataRepository()
{
ResetState();
}

public void ResetState()
{
ID = 0;
Title = string.Empty;
Skills = new HashSet<Skill>();
}
}
}
12 changes: 12 additions & 0 deletions EOLib/Domain/Interact/Skill/SkillmasterReply.cs
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace EOLib.Domain.Interact.Skill
{
public enum SkillmasterReply
{
ErrorRemoveItems = 1,
ErrorWrongClass = 2
}
}
1 change: 1 addition & 0 deletions EOLib/EOLib.csproj
Expand Up @@ -19,6 +19,7 @@
<ProjectReference Include="..\EOLib.Logger\EOLib.Logger.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Amadevus.RecordGenerator" Version="0.6.0" />
<PackageReference Include="AutomaticTypeMapper" Version="1.4.1" />
<PackageReference Include="Optional" Version="4.0.0" />
</ItemGroup>
Expand Down
40 changes: 0 additions & 40 deletions EOLib/Net/API/StatSkill.cs
Expand Up @@ -60,27 +60,6 @@ internal Skill(OldPacket pkt)
}
}

public struct SkillmasterData
{
private readonly short m_id;
private readonly string m_title;

private readonly List<Skill> m_skills;

public short ID => m_id;
public string Title => m_title;
public IList<Skill> Skills => m_skills.AsReadOnly();

internal SkillmasterData(OldPacket pkt)
{
m_id = pkt.GetShort();
m_title = pkt.GetBreakString();
m_skills = new List<Skill>();
while(pkt.ReadPos < pkt.Length)
m_skills.Add(new Skill(pkt));
}
}

public struct StatResetData
{
private readonly short m_statpts, m_skillpts, m_hp, m_maxhp, m_tp, m_maxtp, m_maxsp;
Expand Down Expand Up @@ -138,30 +117,17 @@ internal StatResetData(OldPacket pkt)

partial class PacketAPI
{
public event Action<SkillmasterData> OnSkillmasterOpen;
public event SpellLearnErrorEvent OnSpellLearnError;
public event SpellForgetEvent OnSpellForget;
public event Action<StatResetData> OnCharacterStatsReset;

private void _createStatSkillMembers()
{
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.StatSkill, PacketAction.Open), _handleStatSkillOpen, true);
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.StatSkill, PacketAction.Reply), _handleStatSkillReply, true);
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.StatSkill, PacketAction.Remove), _handleStatSkillRemove, true);
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.StatSkill, PacketAction.Junk), _handleStatSkillJunk, true);
}

public bool RequestSkillmaster(short skillmasterIndex)
{
if (!m_client.ConnectedAndInitialized || !Initialized)
return false;

OldPacket pkt = new OldPacket(PacketFamily.StatSkill, PacketAction.Open);
pkt.AddShort(skillmasterIndex);

return m_client.SendPacket(pkt);
}

public bool LearnSpell(short spellID)
{
if (!m_client.ConnectedAndInitialized || !Initialized)
Expand Down Expand Up @@ -195,12 +161,6 @@ public bool ResetCharacterStatSkill()

//handlers

private void _handleStatSkillOpen(OldPacket pkt)
{
if (OnSkillmasterOpen != null)
OnSkillmasterOpen(new SkillmasterData(pkt));
}

//error learning a skill
private void _handleStatSkillReply(OldPacket pkt)
{
Expand Down
68 changes: 68 additions & 0 deletions EOLib/PacketHandlers/Skill/StatskillOpenHandler.cs
@@ -0,0 +1,68 @@
using AutomaticTypeMapper;
using EOLib.Domain.Interact;
using EOLib.Domain.Interact.Skill;
using EOLib.Domain.Login;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Skill
{
[AutoMappedType]
public class StatskillOpenHandler : InGameOnlyPacketHandler
{
private readonly ISkillDataRepository _skillDataRepository;
private readonly IEnumerable<INPCInteractionNotifier> _npcInteractionNotifiers;

public override PacketFamily Family => PacketFamily.StatSkill;

public override PacketAction Action => PacketAction.Open;

public StatskillOpenHandler(IPlayerInfoProvider playerInfoProvider,
ISkillDataRepository skillDataRepository,
IEnumerable<INPCInteractionNotifier> npcInteractionNotifiers)
: base(playerInfoProvider)
{
_skillDataRepository = skillDataRepository;
_npcInteractionNotifiers = npcInteractionNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
_skillDataRepository.ID = packet.ReadShort();
_skillDataRepository.Title = packet.ReadBreakString();
_skillDataRepository.Skills.Clear();

while (packet.ReadPosition < packet.Length)
{
var skill = new Domain.Interact.Skill.Skill.Builder
{
Id = packet.ReadShort(),
LevelRequirement = packet.ReadChar(),
ClassRequirement = packet.ReadChar(),
GoldRequirement = packet.ReadInt(),
SkillRequirements = new List<short>
{
packet.ReadShort(),
packet.ReadShort(),
packet.ReadShort(),
packet.ReadShort()
},
StrRequirement = packet.ReadShort(),
IntRequirement = packet.ReadShort(),
WisRequirement = packet.ReadShort(),
AgiRequirement = packet.ReadShort(),
ConRequirement = packet.ReadShort(),
ChaRequirement = packet.ReadShort()
}.ToImmutable();

_skillDataRepository.Skills.Add(skill);
}

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

return true;
}
}
}
Expand Up @@ -11,16 +11,16 @@ namespace EOLib.PacketHandlers.Skill
/// Sent when learning a skill, either via $learn command or from skillmaster
/// </summary>
[AutoMappedType]
public class StatskillTake : InGameOnlyPacketHandler
public class StatskillTakeHandler : InGameOnlyPacketHandler
{
private readonly ICharacterInventoryRepository _characterInventoryRepository;

public override PacketFamily Family => PacketFamily.StatSkill;

public override PacketAction Action => PacketAction.Take;

public StatskillTake(IPlayerInfoProvider playerInfoProvider,
ICharacterInventoryRepository characterInventoryRepository)
public StatskillTakeHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterInventoryRepository characterInventoryRepository)
: base(playerInfoProvider)
{
_characterInventoryRepository = characterInventoryRepository;
Expand Down
4 changes: 0 additions & 4 deletions EndlessClient/Old/OldWorld.cs
Expand Up @@ -283,11 +283,7 @@ public void Remap()

public static void IgnoreDialogs(XNAControl control)
{
control.IgnoreDialog(typeof(ChestDialog));
control.IgnoreDialog(typeof(BankAccountDialog));
control.IgnoreDialog(typeof(LockerDialog));
control.IgnoreDialog(typeof(TradeDialog));
control.IgnoreDialog(typeof(SkillmasterDialog));
}

public static Texture2D GetSpellIcon(short icon, bool hover)
Expand Down
7 changes: 0 additions & 7 deletions EndlessClient/Old/PacketAPICallbackManager.cs
Expand Up @@ -46,7 +46,6 @@ public void AssignCallbacks()
m_packetAPI.OnTradeCompleted += _tradeCompleted;

//skills
m_packetAPI.OnSkillmasterOpen += _skillmasterOpen;
m_packetAPI.OnSpellLearnError += _statskillLearnError;
m_packetAPI.OnSpellForget += _statskillForgetSpell;
m_packetAPI.OnCharacterStatsReset += _statskillReset;
Expand Down Expand Up @@ -176,12 +175,6 @@ private void _tradeCompleted(short id1, List<InventoryItem> items1, short id2, L
TradeDialog.Instance.CompleteTrade(id1, items1, id2, items2);
}

private void _skillmasterOpen(SkillmasterData data)
{
if (SkillmasterDialog.Instance != null)
SkillmasterDialog.Instance.SetSkillmasterData(data);
}

private void _statskillLearnError(SkillMasterReply reply, short id)
{
switch (reply)
Expand Down

0 comments on commit fbcdbc2

Please sign in to comment.