Skip to content

Commit

Permalink
Implement quest book packets and UI
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed May 23, 2023
1 parent c9cb43b commit 5a0d7c0
Show file tree
Hide file tree
Showing 14 changed files with 428 additions and 61 deletions.
7 changes: 6 additions & 1 deletion EOLib/Domain/Character/PaperdollData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace EOLib.Domain.Character
{
[Record]
public sealed partial class PaperdollData : IPlayerInfoData
public sealed partial class PaperdollData
{
public string Name { get; }

Expand All @@ -26,13 +26,18 @@ public sealed partial class PaperdollData : IPlayerInfoData

public int Gender { get; }

public AdminLevel AdminLevel { get; }

public IReadOnlyDictionary<EquipLocation, int> Paperdoll { get; }

public IReadOnlyList<string> QuestNames { get; }

public OnlineIcon Icon { get; }

public PaperdollData()
{
Paperdoll = new Dictionary<EquipLocation, int>();
QuestNames = new List<string>();
}
}
}
30 changes: 30 additions & 0 deletions EOLib/Domain/Interact/BookActions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using AutomaticTypeMapper;
using EOLib.Net;
using EOLib.Net.Communication;

namespace EOLib.Domain.Interact
{
[AutoMappedType]
public class BookActions : IBookActions
{
private readonly IPacketSendService _packetSendService;

public BookActions(IPacketSendService packetSendService)
{
_packetSendService = packetSendService;
}

public void RequestBook(int characterId)
{
var packet = new PacketBuilder(PacketFamily.Book, PacketAction.Request)
.AddShort(characterId)
.Build();
_packetSendService.SendPacket(packet);
}
}

public interface IBookActions
{
void RequestBook(int characterId);
}
}
78 changes: 78 additions & 0 deletions EOLib/PacketHandlers/Book/BookReplyHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Online;
using EOLib.Net;
using EOLib.Net.Handlers;
using System;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Paperdoll
{
/// <summary>
/// Sets book information for a given player
/// </summary>
[AutoMappedType]
internal class BookReplyHandler : InGameOnlyPacketHandler
{
private readonly IPaperdollRepository _paperdollRepository;

public override PacketFamily Family => PacketFamily.Book;

public override PacketAction Action => PacketAction.Reply;

public BookReplyHandler(IPlayerInfoProvider playerInfoProvider,
IPaperdollRepository paperdollRepository)
: base(playerInfoProvider)
{
_paperdollRepository = paperdollRepository;
}

public override bool HandlePacket(IPacket packet)
{
var name = packet.ReadBreakString();
var home = packet.ReadBreakString();
var partner = packet.ReadBreakString();
var title = packet.ReadBreakString();
var guild = packet.ReadBreakString();
var rank = packet.ReadBreakString();

var playerID = packet.ReadShort();
var clas = packet.ReadChar();
var gender = packet.ReadChar();

var adminLevel = packet.ReadChar();

var iconType = (OnlineIcon)packet.ReadChar();

if (packet.ReadByte() != 255)
return false;

var questNames = new List<string>();
while (packet.ReadPosition < packet.Length)
questNames.Add(packet.ReadBreakString());

var paperdollData = _paperdollRepository.VisibleCharacterPaperdolls.ContainsKey(playerID)
? _paperdollRepository.VisibleCharacterPaperdolls[playerID]
: new PaperdollData();

paperdollData = paperdollData
.WithName(name)
.WithHome(home)
.WithPartner(partner)
.WithTitle(title)
.WithGuild(guild)
.WithRank(rank)
.WithPlayerID(playerID)
.WithClass(clas)
.WithGender(gender)
.WithAdminLevel((AdminLevel)adminLevel)
.WithIcon(iconType)
.WithQuestNames(questNames);

_paperdollRepository.VisibleCharacterPaperdolls[playerID] = paperdollData;

return true;
}
}
}
11 changes: 8 additions & 3 deletions EOLib/PacketHandlers/Paperdoll/PaperdollReplyHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,20 @@ public override bool HandlePacket(IPacket packet)
var clas = packet.ReadChar();
var gender = packet.ReadChar();

if (packet.ReadChar() != 0)
return false;
var adminLevel = packet.ReadChar();

var paperdoll = new Dictionary<EquipLocation, int>((int)EquipLocation.PAPERDOLL_MAX);
for (var loc = (EquipLocation)0; loc < EquipLocation.PAPERDOLL_MAX; ++loc)
paperdoll[loc] = packet.ReadShort();

var iconType = (OnlineIcon)packet.ReadChar();

var paperdollData = new PaperdollData()

var paperdollData = _paperdollRepository.VisibleCharacterPaperdolls.ContainsKey(playerID)
? _paperdollRepository.VisibleCharacterPaperdolls[playerID]
: new PaperdollData();

paperdollData = paperdollData
.WithName(name)
.WithHome(home)
.WithPartner(partner)
Expand All @@ -60,6 +64,7 @@ public override bool HandlePacket(IPacket packet)
.WithPlayerID(playerID)
.WithClass(clas)
.WithGender(gender)
.WithAdminLevel((AdminLevel)adminLevel)
.WithPaperdoll(paperdoll)
.WithIcon(iconType);

Expand Down
19 changes: 19 additions & 0 deletions EndlessClient/Dialogs/Actions/InGameDialogActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class InGameDialogActions : IInGameDialogActions
{
private readonly IFriendIgnoreListDialogFactory _friendIgnoreListDialogFactory;
private readonly IPaperdollDialogFactory _paperdollDialogFactory;
private readonly IBookDialogFactory _bookDialogFactory;
private readonly ISessionExpDialogFactory _sessionExpDialogFactory;
private readonly IQuestStatusDialogFactory _questStatusDialogFactory;
private readonly IActiveDialogRepository _activeDialogRepository;
Expand All @@ -43,6 +44,7 @@ public class InGameDialogActions : IInGameDialogActions

public InGameDialogActions(IFriendIgnoreListDialogFactory friendIgnoreListDialogFactory,
IPaperdollDialogFactory paperdollDialogFactory,
IBookDialogFactory bookDialogFactory,
ISessionExpDialogFactory sessionExpDialogFactory,
IQuestStatusDialogFactory questStatusDialogFactory,
IShopDialogFactory shopDialogFactory,
Expand All @@ -65,6 +67,7 @@ public InGameDialogActions(IFriendIgnoreListDialogFactory friendIgnoreListDialog
{
_friendIgnoreListDialogFactory = friendIgnoreListDialogFactory;
_paperdollDialogFactory = paperdollDialogFactory;
_bookDialogFactory = bookDialogFactory;
_sessionExpDialogFactory = sessionExpDialogFactory;
_questStatusDialogFactory = questStatusDialogFactory;
_activeDialogRepository = activeDialogRepository;
Expand Down Expand Up @@ -156,6 +159,20 @@ public void ShowPaperdollDialog(Character character, bool isMainCharacter)
});
}

public void ShowBookDialog(Character character, bool isMainCharacter)
{
_activeDialogRepository.BookDialog.MatchNone(() =>
{
var dlg = _bookDialogFactory.Create(character, isMainCharacter);
dlg.DialogClosed += (_, _) => _activeDialogRepository.BookDialog = Option.None<BookDialog>();
_activeDialogRepository.BookDialog = Option.Some(dlg);

UseDefaultDialogSounds(dlg);

dlg.Show();
});
}

public void ShowShopDialog()
{
_activeDialogRepository.ShopDialog.MatchNone(() =>
Expand Down Expand Up @@ -390,6 +407,8 @@ public interface IInGameDialogActions

void ShowPaperdollDialog(Character character, bool isMainCharacter);

void ShowBookDialog(Character character, bool isMainCharacter);

void ShowShopDialog();

void ShowQuestDialog();
Expand Down
8 changes: 8 additions & 0 deletions EndlessClient/Dialogs/ActiveDialogRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public interface IActiveDialogProvider : IDisposable

Option<PaperdollDialog> PaperdollDialog { get; }

Option<BookDialog> BookDialog { get; }

Option<ShopDialog> ShopDialog { get; }

Option<QuestDialog> QuestDialog { get; }
Expand Down Expand Up @@ -54,6 +56,8 @@ public interface IActiveDialogRepository : IDisposable

Option<PaperdollDialog> PaperdollDialog { get; set; }

Option<BookDialog> BookDialog { get; set; }

Option<ShopDialog> ShopDialog { get; set; }

Option<QuestDialog> QuestDialog { get; set; }
Expand Down Expand Up @@ -92,6 +96,8 @@ public class ActiveDialogRepository : IActiveDialogRepository, IActiveDialogProv

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

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

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

public Option<QuestDialog> QuestDialog { get; set; }
Expand Down Expand Up @@ -126,6 +132,7 @@ IReadOnlyList<Option<IXNADialog>> ActiveDialogs
SessionExpDialog.Map(Map),
QuestStatusDialog.Map(Map),
PaperdollDialog.Map(Map),
BookDialog.Map(Map),
ShopDialog.Map(Map),
QuestDialog.Map(Map),
ChestDialog.Map(Map),
Expand Down Expand Up @@ -160,6 +167,7 @@ public void Dispose()
SessionExpDialog = Option.None<SessionExpDialog>();
QuestStatusDialog = Option.None<QuestStatusDialog>();
PaperdollDialog = Option.None<PaperdollDialog>();
BookDialog = Option.None<BookDialog>();
ShopDialog = Option.None<ShopDialog>();
QuestDialog = Option.None<QuestDialog>();
ChestDialog = Option.None<ChestDialog>();
Expand Down
132 changes: 132 additions & 0 deletions EndlessClient/Dialogs/BookDialog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using EndlessClient.Content;
using EndlessClient.Dialogs.Services;
using EndlessClient.UIControls;
using EOLib;
using EOLib.Domain.Character;
using EOLib.Graphics;
using EOLib.IO.Repositories;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using XNAControls;
using static EndlessClient.Dialogs.QuestStatusListDialogItem;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;

namespace EndlessClient.Dialogs
{
public class BookDialog : PlayerInfoDialog
{
private readonly IPaperdollProvider _paperdollProvider;

private readonly List<XNALabel> _childItems;
private ScrollBar _scrollBar;

private int _lastScrollOffset;

public BookDialog(INativeGraphicsManager graphicsManager,
IEODialogButtonService eoDialogButtonService,
IPubFileProvider pubFileProvider,
IPaperdollProvider paperdollProvider,
Character character,
bool isMainCharacter)
: base(graphicsManager, eoDialogButtonService, pubFileProvider, paperdollProvider, character, isMainCharacter)
{
_paperdollProvider = paperdollProvider;

_childItems = new List<XNALabel>();

var backgroundTexture = graphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 27);
_scrollBar = new ScrollBar(new Vector2(188, 34), backgroundTexture, new Rectangle(303, 2, 20, 237), ScrollBarColors.DarkOnDark, graphicsManager)
{
LinesToRender = 14
};
_scrollBar.SetParentControl(this);
SetScrollWheelHandler(_scrollBar);

BackgroundTexture = GraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 69);

CenterInGameView();

if (!Game.Window.AllowUserResizing)
DrawPosition = new Vector2(DrawPosition.X, 15);
}

public override void Initialize()
{
_scrollBar.Initialize();

base.Initialize();
}

protected override void OnUnconditionalUpdateControl(GameTime gameTime)
{
if (_childItems.Count > _scrollBar.LinesToRender && _lastScrollOffset != _scrollBar.ScrollOffset)
{
_lastScrollOffset = _scrollBar.ScrollOffset;

for (int i = 0; i < _childItems.Count; i++)
{
_childItems[i].DrawPosition = new Vector2(_childItems[i].DrawPosition.X, 42 + (i - _lastScrollOffset) * 16);
_childItems[i].Visible = (i - _lastScrollOffset) >= 0 && (i - _lastScrollOffset) < _scrollBar.LinesToRender;
}
}

base.OnUnconditionalUpdateControl(gameTime);
}

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

var iconTexture = GraphicsManager.TextureFromResource(GFXTypes.PostLoginUI, 68, true);

_spriteBatch.Begin();

for (int i = 0; i < Math.Min(_childItems.Count, _scrollBar.LinesToRender); i++)
{
_spriteBatch.Draw(iconTexture, DrawPositionWithParentOffset + new Vector2(26, 41 + i * 16), GetIconSourceRectangle(QuestStatusIcon.None2), Color.White);
}

_spriteBatch.End();
}

protected override void UpdateDisplayedData(PaperdollData paperdollData)
{
base.UpdateDisplayedData(paperdollData);

foreach (var item in _childItems)
item.Dispose();

_childItems.Clear();

for (int i = 0; i < paperdollData.QuestNames.Count; i++)
{
var quest = paperdollData.QuestNames[i];

var nextLabel = new XNALabel(Constants.FontSize08pt5)
{
Text = quest,
ForeColor = ColorConstants.LightGrayText,
AutoSize = true,
DrawPosition = new Vector2(50, 42 + i * 16),
Visible = i < _scrollBar.LinesToRender
};
nextLabel.SetScrollWheelHandler(_scrollBar);
nextLabel.ResizeBasedOnText();
nextLabel.SetParentControl(this);
nextLabel.Initialize();

_childItems.Add(nextLabel);
}

_scrollBar.ScrollToTop();
_scrollBar.UpdateDimensions(paperdollData.QuestNames.Count);
}

// copied from QuestStatusListDialogItem
private static Rectangle GetIconSourceRectangle(QuestStatusIcon index)
{
return new Rectangle((int)index * 15, 0, 15, 15);
}
}
}
Loading

0 comments on commit 5a0d7c0

Please sign in to comment.