mirror of
https://github.com/sebastian-heinz/Arrowgene.DragonsDogmaOnline
synced 2026-08-03 11:12:41 -04:00
Added handlers and required packets for: - QuestAddPackageQuestPointHandler - QuestGetPackageQuestInfoDetailHandler - QuestGetPackageQuestInfoHandler Added new quests - q10300102.csx - q60300030.csx Added a new settings file substory.csx to describe the mission requirements. Database 56 -> 57 Co-authored-by: @hankhotspur
186 lines
8.5 KiB
C#
186 lines
8.5 KiB
C#
using Arrowgene.Ddon.GameServer.Characters;
|
|
using Arrowgene.Ddon.GameServer.Dump;
|
|
using Arrowgene.Ddon.Server;
|
|
using Arrowgene.Ddon.Shared.Entity;
|
|
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
|
|
using Arrowgene.Ddon.Shared.Entity.Structure;
|
|
using Arrowgene.Ddon.Shared.Model;
|
|
using Arrowgene.Ddon.Shared.Model.Quest;
|
|
using Arrowgene.Logging;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Arrowgene.Ddon.GameServer.Handler
|
|
{
|
|
public class QuestGetCycleContentsStateListHandler : GameRequestPacketHandler<C2SQuestGetCycleContentsStateListReq, S2CQuestGetCycleContentsStateListRes>
|
|
{
|
|
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(QuestGetCycleContentsStateListHandler));
|
|
|
|
public QuestGetCycleContentsStateListHandler(DdonGameServer server) : base(server)
|
|
{
|
|
}
|
|
|
|
public override S2CQuestGetCycleContentsStateListRes Handle(GameClient client, C2SQuestGetCycleContentsStateListReq request)
|
|
{
|
|
S2CQuestJoinLobbyQuestInfoNtc pcap = EntitySerializer.Get<S2CQuestJoinLobbyQuestInfoNtc>().Read(InGameDump.data_Dump_20B);
|
|
S2CQuestJoinLobbyQuestInfoNtc ntc = new S2CQuestJoinLobbyQuestInfoNtc();
|
|
|
|
ntc.WorldManageQuestOrderList = pcap.WorldManageQuestOrderList; // Recover paths + change vocation
|
|
|
|
// TODO: Eventually populate all flags based player state for q7* quests
|
|
foreach (var quest in ntc.WorldManageQuestOrderList)
|
|
{
|
|
quest.Param.QuestFlagList.Clear();
|
|
quest.Param.QuestLayoutFlagList.Clear();
|
|
quest.Param.QuestFlagList = client.Character.GetWorldManageQuestUnlocks((QuestId) quest.Param.QuestId);
|
|
quest.Param.QuestLayoutFlagList = client.Character.GetWorldManageLayoutUnlocks((QuestId)quest.Param.QuestId);
|
|
}
|
|
|
|
ntc.QuestDefine = pcap.QuestDefine; // Recover quest log data to be able to accept quests
|
|
ntc.QuestDefine.OrderMaxNum = Server.GameSettings.GameServerSettings.QuestOrderMax;
|
|
ntc.QuestDefine.RewardBoxMaxNum = Server.GameSettings.GameServerSettings.RewardBoxMax;
|
|
|
|
// pcap.MainQuestIdList; (this will add back all missing functionality which depends on complete MSQ)
|
|
var completedMsq = client.Character.CompletedQuests.Values.Where(x => x.QuestType == QuestType.Main);
|
|
foreach (var msq in completedMsq)
|
|
{
|
|
ntc.MainQuestIdList.Add(new CDataQuestId() { QuestId = (uint)msq.QuestId });
|
|
}
|
|
|
|
var completedTutorials = client.Character.CompletedQuests.Values.Where(x => x.QuestType == QuestType.Tutorial);
|
|
foreach (var tut in completedTutorials)
|
|
{
|
|
ntc.TutorialQuestIdList.Add(new CDataQuestId() { QuestId = (uint)tut.QuestId });
|
|
}
|
|
|
|
// Add special quests not normally part of DDON
|
|
foreach (var questId in new List<QuestId>() {QuestId.WorldManageMonsterCaution , QuestId.WorldManageJobTutorial, QuestId.WorldManageDebug})
|
|
{
|
|
var customWorldManageQuest = QuestManager.GetQuestByQuestId(questId);
|
|
ntc.WorldManageQuestOrderList.Add(customWorldManageQuest.ToCDataWorldManageQuestOrderList(0));
|
|
}
|
|
|
|
List<QuestProgress> allQuestsInProgress = new();
|
|
List<uint> priorityQuests = new();
|
|
List<uint> decayedQuests = new();
|
|
Server.Database.ExecuteInTransaction(connection =>
|
|
{
|
|
allQuestsInProgress = Server.Database.GetQuestProgressByType(client.Character.CommonId, QuestType.All, connection);
|
|
priorityQuests = client.Party is not null ? Server.Database.GetPriorityQuestScheduleIds(client.Party.Leader.Client.Character.CommonId, connection) : new();
|
|
|
|
decayedQuests = Server.LightQuestManager.HandleQuestDecay(client.Character, allQuestsInProgress, priorityQuests, connection).ToList();
|
|
});
|
|
|
|
foreach(var decayedScheduleId in decayedQuests)
|
|
{
|
|
var quest = QuestManager.GetQuestByScheduleId(decayedScheduleId);
|
|
if (quest is null)
|
|
{
|
|
continue;
|
|
}
|
|
ntc.ExpiredQuestList.Add(new()
|
|
{
|
|
QuestId = quest.QuestId,
|
|
QuestScheduleId = quest.QuestScheduleId,
|
|
});
|
|
}
|
|
|
|
foreach (var questProgress in allQuestsInProgress)
|
|
{
|
|
var quest = QuestManager.GetQuestByScheduleId(questProgress.QuestScheduleId);
|
|
if (quest == null || !quest.IsActive(client))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
switch (questProgress.QuestType)
|
|
{
|
|
case QuestType.Tutorial:
|
|
var tutorialQuest = quest.ToCDataTutorialQuestOrderList(questProgress.Step);
|
|
ntc.TutorialQuestOrderList.Add(tutorialQuest);
|
|
break;
|
|
case QuestType.WildHunt:
|
|
var mobHuntQuest = quest.ToCDataMobHuntQuestOrderList(questProgress.Step);
|
|
ntc.MobHuntQuestOrderList.Add(mobHuntQuest);
|
|
break;
|
|
case QuestType.Light:
|
|
var lightQuest = quest.ToCDataLightQuestOrderList(questProgress.Step);
|
|
if (lightQuest.Detail.BoardType == 1 && lightQuest.Detail.GetAp == 0)
|
|
{
|
|
lightQuest.Detail.GetAp = AreaRankManager.GetAreaPointReward(quest);
|
|
}
|
|
ntc.LightQuestOrderList.Add(lightQuest);
|
|
break;
|
|
}
|
|
}
|
|
|
|
Dictionary<QuestSubstoryGroupId, Dictionary<uint, List<CDataQuestOrderList>>> substoryGroups = new();
|
|
foreach (var questProgress in allQuestsInProgress)
|
|
{
|
|
if (questProgress.QuestType != QuestType.Substory) continue;
|
|
|
|
var quest = QuestManager.GetQuestByScheduleId(questProgress.QuestScheduleId);
|
|
if (quest == null || !quest.IsActive(client)) continue;
|
|
|
|
var props = QuestManager.GetSubstoryQuestProperties(Server, quest.QuestId);
|
|
if (props.SubstoryGroupId == QuestSubstoryGroupId.Invalid) continue;
|
|
|
|
if (!substoryGroups.ContainsKey(props.SubstoryGroupId))
|
|
substoryGroups[props.SubstoryGroupId] = new();
|
|
if (!substoryGroups[props.SubstoryGroupId].ContainsKey(props.SeqNo))
|
|
substoryGroups[props.SubstoryGroupId][props.SeqNo] = new();
|
|
|
|
substoryGroups[props.SubstoryGroupId][props.SeqNo].Add(quest.ToCDataQuestOrderList(questProgress.Step));
|
|
}
|
|
|
|
foreach (var (substoryGroupId, seqData) in substoryGroups)
|
|
{
|
|
var entry = new CDataSubstoryQuestOrderList() { SubstoryGroupId = substoryGroupId };
|
|
foreach (var (seqNo, questList) in seqData)
|
|
{
|
|
entry.Details.Add(new CDataS2CQuestJoinLobbyQuestInfoNtcUnk0Unk1()
|
|
{
|
|
SequenceNo = seqNo,
|
|
Unk1 = 0,
|
|
Unk2 = 0,
|
|
Unk3 = [],
|
|
Unk4 = false,
|
|
QuestList = questList
|
|
});
|
|
}
|
|
ntc.SubstoryQuestOrderList.Add(entry);
|
|
}
|
|
|
|
if (client.Party != null)
|
|
{
|
|
foreach (var questScheduleId in priorityQuests)
|
|
{
|
|
var quest = QuestManager.GetQuestByScheduleId(questScheduleId);
|
|
if (quest == null || !quest.IsActive(client))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
ntc.PriorityQuestList.Add(new CDataPriorityQuest()
|
|
{
|
|
QuestId = (uint)quest.QuestId,
|
|
QuestScheduleId = (uint)quest.QuestScheduleId
|
|
});
|
|
}
|
|
}
|
|
|
|
if (decayedQuests.Count > 0)
|
|
{
|
|
client.Send(new S2CLobbyChatMsgNotice()
|
|
{
|
|
Type = LobbyChatMsgType.ManagementAlertC,
|
|
Message = "A quest has been canceled because the\ndelivery time period has ended."
|
|
});
|
|
}
|
|
|
|
client.Send(ntc);
|
|
|
|
return new();
|
|
}
|
|
}
|
|
}
|