Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement network actions for opening quest dialog and responding
- Loading branch information
1 parent
ca9611f
commit 6397611
Showing
10 changed files
with
379 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace EOLib.Domain.Interact.Quest | ||
{ | ||
public enum DialogReply | ||
{ | ||
Ok = 1, | ||
Link | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using AutomaticTypeMapper; | ||
using EOLib.Net; | ||
using EOLib.Net.Communication; | ||
|
||
namespace EOLib.Domain.Interact.Quest | ||
{ | ||
[AutoMappedType] | ||
public class QuestActions : IQuestActions | ||
{ | ||
private readonly IPacketSendService _packetSendService; | ||
private readonly IQuestDataProvider _questDataProvider; | ||
|
||
public QuestActions(IPacketSendService packetSendService, | ||
IQuestDataProvider questDataProvider) | ||
{ | ||
_packetSendService = packetSendService; | ||
_questDataProvider = questDataProvider; | ||
} | ||
|
||
public void RespondToQuestDialog(DialogReply reply, byte linkId = 0) | ||
{ | ||
_questDataProvider.QuestDialogData.MatchSome(data => | ||
{ | ||
var builder = new PacketBuilder(PacketFamily.Quest, PacketAction.Accept) | ||
.AddShort(data.SessionID) // ignored by eoserv | ||
.AddShort(data.DialogID) // ignored by eoserv | ||
.AddShort(data.QuestID) | ||
.AddShort(data.VendorID) // ignored by eoserv | ||
.AddChar((byte)reply); | ||
if (reply == DialogReply.Link) | ||
builder = builder.AddChar(linkId); | ||
var packet = builder.Build(); | ||
_packetSendService.SendPacket(packet); | ||
}); | ||
} | ||
} | ||
|
||
public interface IQuestActions | ||
{ | ||
void RespondToQuestDialog(DialogReply reply, byte linkId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using AutomaticTypeMapper; | ||
using Optional; | ||
|
||
namespace EOLib.Domain.Interact.Quest | ||
{ | ||
public interface IQuestDataRepository : IResettable | ||
{ | ||
Option<IQuestDialogData> QuestDialogData { get; set; } | ||
} | ||
|
||
public interface IQuestDataProvider : IResettable | ||
{ | ||
Option<IQuestDialogData> QuestDialogData { get; } | ||
} | ||
|
||
[AutoMappedType(IsSingleton = true)] | ||
public class QuestDataRepository : IQuestDataProvider, IQuestDataRepository | ||
{ | ||
public Option<IQuestDialogData> QuestDialogData { get; set; } | ||
|
||
public QuestDataRepository() | ||
{ | ||
ResetState(); | ||
} | ||
|
||
public void ResetState() | ||
{ | ||
QuestDialogData = Option.None<IQuestDialogData>(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace EOLib.Domain.Interact.Quest | ||
{ | ||
public class QuestDialogData : IQuestDialogData | ||
{ | ||
public short VendorID { get; private set; } | ||
|
||
public short QuestID { get; private set; } | ||
|
||
public short SessionID { get; private set; } | ||
|
||
public short DialogID { get; private set; } | ||
|
||
public IReadOnlyDictionary<short, string> DialogTitles { get; private set; } | ||
|
||
public IReadOnlyList<string> PageText { get; private set; } | ||
|
||
public IReadOnlyList<(short ActionID, string DisplayText)> Actions { get; private set; } | ||
|
||
public QuestDialogData() | ||
{ | ||
DialogTitles = new Dictionary<short, string>(); | ||
PageText = new List<string>(); | ||
Actions = new List<(short, string)>(); | ||
} | ||
|
||
private QuestDialogData(short vendorID, | ||
short questID, | ||
short sessionID, | ||
short dialogID, | ||
IReadOnlyDictionary<short, string> dialogTitles, | ||
IReadOnlyList<string> pageText, | ||
IReadOnlyList<(short, string)> actions) | ||
{ | ||
VendorID = vendorID; | ||
QuestID = questID; | ||
SessionID = sessionID; | ||
DialogID = dialogID; | ||
DialogTitles = dialogTitles; | ||
PageText = pageText; | ||
Actions = actions; | ||
} | ||
|
||
public IQuestDialogData WithVendorID(short vendorId) | ||
{ | ||
var copy = MakeCopy(this); | ||
copy.VendorID = vendorId; | ||
return copy; | ||
} | ||
|
||
public IQuestDialogData WithQuestID(short questId) | ||
{ | ||
var copy = MakeCopy(this); | ||
copy.QuestID = questId; | ||
return copy; | ||
} | ||
|
||
public IQuestDialogData WithSessionID(short sessionId) | ||
{ | ||
var copy = MakeCopy(this); | ||
copy.SessionID = sessionId; | ||
return copy; | ||
} | ||
|
||
public IQuestDialogData WithDialogID(short dialogId) | ||
{ | ||
var copy = MakeCopy(this); | ||
copy.DialogID = dialogId; | ||
return copy; | ||
} | ||
|
||
public IQuestDialogData WithDialogTitles(IReadOnlyDictionary<short, string> dialogTitles) | ||
{ | ||
var copy = MakeCopy(this); | ||
copy.DialogTitles = dialogTitles; | ||
return copy; | ||
} | ||
|
||
public IQuestDialogData WithPageText(IReadOnlyList<string> pageText) | ||
{ | ||
var copy = MakeCopy(this); | ||
copy.PageText = pageText; | ||
return copy; | ||
} | ||
|
||
public IQuestDialogData WithActions(IReadOnlyList<(short, string)> actions) | ||
{ | ||
var copy = MakeCopy(this); | ||
copy.Actions = actions; | ||
return copy; | ||
} | ||
|
||
private static QuestDialogData MakeCopy(IQuestDialogData other) | ||
{ | ||
return new QuestDialogData( | ||
other.VendorID, | ||
other.QuestID, | ||
other.SessionID, | ||
other.DialogID, | ||
other.DialogTitles.ToDictionary(k => k.Key, v => v.Value), | ||
new List<string>(other.PageText), | ||
new List<(short, string)>(other.Actions)); | ||
} | ||
|
||
public override bool Equals(object obj) | ||
{ | ||
var other = obj as QuestDialogData; | ||
if (other == null) return false; | ||
|
||
return other.VendorID == VendorID | ||
&& other.QuestID == QuestID | ||
&& other.SessionID == SessionID | ||
&& other.DialogID == DialogID | ||
&& other.DialogTitles.SequenceEqual(DialogTitles) | ||
&& other.PageText.SequenceEqual(PageText) | ||
&& other.Actions.SequenceEqual(Actions); | ||
} | ||
|
||
public override int GetHashCode() | ||
{ | ||
int hashCode = 170256730; | ||
hashCode = hashCode * -1521134295 + VendorID.GetHashCode(); | ||
hashCode = hashCode * -1521134295 + QuestID.GetHashCode(); | ||
hashCode = hashCode * -1521134295 + SessionID.GetHashCode(); | ||
hashCode = hashCode * -1521134295 + DialogID.GetHashCode(); | ||
hashCode = hashCode * -1521134295 + DialogTitles.Aggregate(170256730, (a, b) => a * -1521134295 + b.GetHashCode()); | ||
hashCode = hashCode * -1521134295 + PageText.Aggregate(170256730, (a, b) => a * -1521134295 + b.GetHashCode()); | ||
hashCode = hashCode * -1521134295 + Actions.Aggregate(170256730, (a, b) => a * -1521134295 + b.GetHashCode()); | ||
return hashCode; | ||
} | ||
} | ||
|
||
public interface IQuestDialogData | ||
{ | ||
/// <summary> | ||
/// NPC Vendor ID (<see cref="EOLib.IO.Pub.ENFRecord.VendorID" />) | ||
/// </summary> | ||
short VendorID { get; } | ||
|
||
/// <summary> | ||
/// Quest ID, for the current dialog being shown (part of quest state in EO+ parser) | ||
/// </summary> | ||
short QuestID { get; } | ||
|
||
/// <summary> | ||
/// Session ID, not used by eoserv | ||
/// </summary> | ||
short SessionID { get; } | ||
|
||
/// <summary> | ||
/// Dialog ID, not used by eoserv | ||
/// </summary> | ||
short DialogID { get; } | ||
|
||
/// <summary> | ||
/// Quest dialog titles for the current character, keyed on <see cref="VendorID" />. | ||
/// </summary> | ||
IReadOnlyDictionary<short, string> DialogTitles { get; } | ||
|
||
/// <summary> | ||
/// Text for the quest dialog, one entry per page. | ||
/// </summary> | ||
IReadOnlyList<string> PageText { get; } | ||
|
||
/// <summary> | ||
/// Links for the quest dialog, only shown on the last page. | ||
/// </summary> | ||
IReadOnlyList<(short ActionID, string DisplayText)> Actions { get; } | ||
|
||
IQuestDialogData WithVendorID(short vendorId); | ||
|
||
IQuestDialogData WithQuestID(short questId); | ||
|
||
IQuestDialogData WithSessionID(short sessionId); | ||
|
||
IQuestDialogData WithDialogID(short dialogId); | ||
|
||
IQuestDialogData WithDialogTitles(IReadOnlyDictionary<short, string> dialogTitles); | ||
|
||
IQuestDialogData WithPageText(IReadOnlyList<string> pageText); | ||
|
||
IQuestDialogData WithActions(IReadOnlyList<(short, string)> actions); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.