Handle quests that are unlocked when a previous quest isn't complete yet
This commit is contained in:
parent
abee323d2b
commit
d310c9ff1b
@ -8,7 +8,8 @@ using LLib.GameData;
|
|||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Questionable.Model;
|
using Questionable.Model;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
using Quest = Lumina.Excel.GeneratedSheets.Quest;
|
using Leve = Lumina.Excel.GeneratedSheets2.Leve;
|
||||||
|
using Quest = Lumina.Excel.GeneratedSheets2.Quest;
|
||||||
|
|
||||||
namespace Questionable.Data;
|
namespace Questionable.Data;
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ internal sealed class QuestData
|
|||||||
|
|
||||||
// workaround because the game doesn't require completion of the CT questline through normal means
|
// workaround because the game doesn't require completion of the CT questline through normal means
|
||||||
QuestInfo aTimeToEveryPurpose = (QuestInfo)_quests[new QuestId(425)];
|
QuestInfo aTimeToEveryPurpose = (QuestInfo)_quests[new QuestId(425)];
|
||||||
aTimeToEveryPurpose.AddPreviousQuest(new QuestId(495));
|
aTimeToEveryPurpose.AddPreviousQuest(new QuestInfo.PreviousQuestInfo(new QuestId(495)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQuestInfo GetQuestInfo(ElementId elementId)
|
public IQuestInfo GetQuestInfo(ElementId elementId)
|
||||||
|
@ -494,7 +494,8 @@ internal sealed unsafe class QuestFunctions
|
|||||||
if (questInfo.PreviousQuests.Count == 0)
|
if (questInfo.PreviousQuests.Count == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var completedQuests = questInfo.PreviousQuests.Count(x => IsQuestComplete(x) || x.Equals(extraCompletedQuest));
|
var completedQuests = questInfo.PreviousQuests.Count(x =>
|
||||||
|
HasEnoughProgressOnPreviousQuest(x) || x.QuestId.Equals(extraCompletedQuest));
|
||||||
if (questInfo.PreviousQuestJoin == QuestInfo.QuestJoin.All &&
|
if (questInfo.PreviousQuestJoin == QuestInfo.QuestJoin.All &&
|
||||||
questInfo.PreviousQuests.Count == completedQuests)
|
questInfo.PreviousQuests.Count == completedQuests)
|
||||||
return true;
|
return true;
|
||||||
@ -504,6 +505,20 @@ internal sealed unsafe class QuestFunctions
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HasEnoughProgressOnPreviousQuest(QuestInfo.PreviousQuestInfo previousQuestInfo)
|
||||||
|
{
|
||||||
|
if (IsQuestComplete(previousQuestInfo.QuestId))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (previousQuestInfo.Sequence != 0 && IsQuestAccepted(previousQuestInfo.QuestId))
|
||||||
|
{
|
||||||
|
var progress = GetQuestProgressInfo(previousQuestInfo.QuestId);
|
||||||
|
return progress != null && progress.Sequence >= previousQuestInfo.Sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool HasCompletedPreviousInstances(QuestInfo questInfo)
|
private static bool HasCompletedPreviousInstances(QuestInfo questInfo)
|
||||||
{
|
{
|
||||||
if (questInfo.PreviousInstanceContent.Count == 0)
|
if (questInfo.PreviousInstanceContent.Count == 0)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using LLib.GameData;
|
using LLib.GameData;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets2;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
|
|
||||||
namespace Questionable.Model;
|
namespace Questionable.Model;
|
||||||
@ -14,7 +14,7 @@ internal sealed class LeveInfo : IQuestInfo
|
|||||||
Level = leve.ClassJobLevel;
|
Level = leve.ClassJobLevel;
|
||||||
JournalGenre = leve.JournalGenre.Row;
|
JournalGenre = leve.JournalGenre.Row;
|
||||||
SortKey = QuestId.Value;
|
SortKey = QuestId.Value;
|
||||||
IssuerDataId = leve.LevelLevemete.Value!.Object;
|
IssuerDataId = leve.LevelLevemete.Value!.Object.Row;
|
||||||
ClassJobs = QuestInfoUtils.AsList(leve.ClassJobCategory.Value!);
|
ClassJobs = QuestInfoUtils.AsList(leve.ClassJobCategory.Value!);
|
||||||
Expansion = (EExpansionVersion)leve.LevelLevemete.Value.Territory.Value!.ExVersion.Row;
|
Expansion = (EExpansionVersion)leve.LevelLevemete.Value.Territory.Value!.ExVersion.Row;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using LLib.GameData;
|
using LLib.GameData;
|
||||||
using Questionable.Model.Questing;
|
using Questionable.Model.Questing;
|
||||||
using ExcelQuest = Lumina.Excel.GeneratedSheets.Quest;
|
using ExcelQuest = Lumina.Excel.GeneratedSheets2.Quest;
|
||||||
|
|
||||||
namespace Questionable.Model;
|
namespace Questionable.Model;
|
||||||
|
|
||||||
@ -31,13 +31,18 @@ internal sealed class QuestInfo : IQuestInfo
|
|||||||
};
|
};
|
||||||
|
|
||||||
Name = $"{quest.Name}{suffix}";
|
Name = $"{quest.Name}{suffix}";
|
||||||
Level = quest.ClassJobLevel0;
|
Level = quest.ClassJobLevel[0];
|
||||||
IssuerDataId = quest.IssuerStart;
|
IssuerDataId = quest.IssuerStart.Row;
|
||||||
IsRepeatable = quest.IsRepeatable;
|
IsRepeatable = quest.IsRepeatable;
|
||||||
PreviousQuests = quest.PreviousQuest
|
PreviousQuests =
|
||||||
.Select(x => new QuestId((ushort)(x.Row & 0xFFFF)))
|
new List<PreviousQuestInfo>
|
||||||
.Where(x => x.Value != 0)
|
{
|
||||||
.ToImmutableList();
|
new(new QuestId((ushort)(quest.PreviousQuest[0].Row & 0xFFFF)), quest.Unknown7),
|
||||||
|
new(new QuestId((ushort)(quest.PreviousQuest[1].Row & 0xFFFF))),
|
||||||
|
new(new QuestId((ushort)(quest.PreviousQuest[1].Row & 0xFFFF)))
|
||||||
|
}
|
||||||
|
.Where(x => x.QuestId.Value != 0)
|
||||||
|
.ToImmutableList();
|
||||||
PreviousQuestJoin = (QuestJoin)quest.PreviousQuestJoin;
|
PreviousQuestJoin = (QuestJoin)quest.PreviousQuestJoin;
|
||||||
QuestLocks = quest.QuestLock
|
QuestLocks = quest.QuestLock
|
||||||
.Select(x => new QuestId((ushort)(x.Row & 0xFFFFF)))
|
.Select(x => new QuestId((ushort)(x.Row & 0xFFFFF)))
|
||||||
@ -47,7 +52,7 @@ internal sealed class QuestInfo : IQuestInfo
|
|||||||
JournalGenre = quest.JournalGenre?.Row;
|
JournalGenre = quest.JournalGenre?.Row;
|
||||||
SortKey = quest.SortKey;
|
SortKey = quest.SortKey;
|
||||||
IsMainScenarioQuest = quest.JournalGenre?.Value?.JournalCategory?.Value?.JournalSection?.Row is 0 or 1;
|
IsMainScenarioQuest = quest.JournalGenre?.Value?.JournalCategory?.Value?.JournalSection?.Row is 0 or 1;
|
||||||
CompletesInstantly = quest.ToDoCompleteSeq[0] == 0;
|
CompletesInstantly = quest.TodoParams[0].ToDoCompleteSeq == 0;
|
||||||
PreviousInstanceContent = quest.InstanceContent.Select(x => (ushort)x.Row).Where(x => x != 0).ToList();
|
PreviousInstanceContent = quest.InstanceContent.Select(x => (ushort)x.Row).Where(x => x != 0).ToList();
|
||||||
PreviousInstanceContentJoin = (QuestJoin)quest.InstanceContentJoin;
|
PreviousInstanceContentJoin = (QuestJoin)quest.InstanceContentJoin;
|
||||||
GrandCompany = (GrandCompany)quest.GrandCompany.Row;
|
GrandCompany = (GrandCompany)quest.GrandCompany.Row;
|
||||||
@ -64,7 +69,7 @@ internal sealed class QuestInfo : IQuestInfo
|
|||||||
public ushort Level { get; }
|
public ushort Level { get; }
|
||||||
public uint IssuerDataId { get; }
|
public uint IssuerDataId { get; }
|
||||||
public bool IsRepeatable { get; }
|
public bool IsRepeatable { get; }
|
||||||
public ImmutableList<QuestId> PreviousQuests { get; set; }
|
public ImmutableList<PreviousQuestInfo> PreviousQuests { get; set; }
|
||||||
public QuestJoin PreviousQuestJoin { get; }
|
public QuestJoin PreviousQuestJoin { get; }
|
||||||
public ImmutableList<QuestId> QuestLocks { get; }
|
public ImmutableList<QuestId> QuestLocks { get; }
|
||||||
public QuestJoin QuestLockJoin { get; }
|
public QuestJoin QuestLockJoin { get; }
|
||||||
@ -89,8 +94,10 @@ internal sealed class QuestInfo : IQuestInfo
|
|||||||
AtLeastOne = 2,
|
AtLeastOne = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddPreviousQuest(QuestId questId)
|
public void AddPreviousQuest(PreviousQuestInfo questId)
|
||||||
{
|
{
|
||||||
PreviousQuests = [..PreviousQuests, questId];
|
PreviousQuests = [..PreviousQuests, questId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed record PreviousQuestInfo(QuestId QuestId, byte Sequence = 0);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using LLib.GameData;
|
using LLib.GameData;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets2;
|
||||||
|
|
||||||
namespace Questionable.Model;
|
namespace Questionable.Model;
|
||||||
|
|
||||||
@ -57,8 +57,8 @@ internal static class QuestInfoUtils
|
|||||||
{ EClassJob.Dancer, classJobCategory.DNC },
|
{ EClassJob.Dancer, classJobCategory.DNC },
|
||||||
{ EClassJob.Reaper, classJobCategory.RPR },
|
{ EClassJob.Reaper, classJobCategory.RPR },
|
||||||
{ EClassJob.Sage, classJobCategory.SGE },
|
{ EClassJob.Sage, classJobCategory.SGE },
|
||||||
{ EClassJob.Viper, classJobCategory.VPR },
|
{ EClassJob.Viper, classJobCategory.Unknown1 },
|
||||||
{ EClassJob.Pictomancer, classJobCategory.PCT }
|
{ EClassJob.Pictomancer, classJobCategory.Unknown2 }
|
||||||
}
|
}
|
||||||
.Where(y => y.Value)
|
.Where(y => y.Value)
|
||||||
.Select(y => y.Key)
|
.Select(y => y.Key)
|
||||||
|
@ -19,19 +19,22 @@ internal sealed class QuestTooltipComponent
|
|||||||
private readonly TerritoryData _territoryData;
|
private readonly TerritoryData _territoryData;
|
||||||
private readonly QuestFunctions _questFunctions;
|
private readonly QuestFunctions _questFunctions;
|
||||||
private readonly UiUtils _uiUtils;
|
private readonly UiUtils _uiUtils;
|
||||||
|
private readonly Configuration _configuration;
|
||||||
|
|
||||||
public QuestTooltipComponent(
|
public QuestTooltipComponent(
|
||||||
QuestRegistry questRegistry,
|
QuestRegistry questRegistry,
|
||||||
QuestData questData,
|
QuestData questData,
|
||||||
TerritoryData territoryData,
|
TerritoryData territoryData,
|
||||||
QuestFunctions questFunctions,
|
QuestFunctions questFunctions,
|
||||||
UiUtils uiUtils)
|
UiUtils uiUtils,
|
||||||
|
Configuration configuration)
|
||||||
{
|
{
|
||||||
_questRegistry = questRegistry;
|
_questRegistry = questRegistry;
|
||||||
_questData = questData;
|
_questData = questData;
|
||||||
_territoryData = territoryData;
|
_territoryData = territoryData;
|
||||||
_questFunctions = questFunctions;
|
_questFunctions = questFunctions;
|
||||||
_uiUtils = uiUtils;
|
_uiUtils = uiUtils;
|
||||||
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(IQuestInfo quest)
|
public void Draw(IQuestInfo quest)
|
||||||
@ -105,13 +108,13 @@ internal sealed class QuestTooltipComponent
|
|||||||
|
|
||||||
foreach (var q in quest.PreviousQuests)
|
foreach (var q in quest.PreviousQuests)
|
||||||
{
|
{
|
||||||
if (_questData.TryGetQuestInfo(q, out var qInfo))
|
if (_questData.TryGetQuestInfo(q.QuestId, out var qInfo))
|
||||||
{
|
{
|
||||||
var (iconColor, icon, _) = _uiUtils.GetQuestStyle(q);
|
var (iconColor, icon, _) = _uiUtils.GetQuestStyle(q.QuestId);
|
||||||
if (!_questRegistry.IsKnownQuest(qInfo.QuestId))
|
if (!_questRegistry.IsKnownQuest(qInfo.QuestId))
|
||||||
iconColor = ImGuiColors.DalamudGrey;
|
iconColor = ImGuiColors.DalamudGrey;
|
||||||
|
|
||||||
_uiUtils.ChecklistItem(FormatQuestUnlockName(qInfo), iconColor, icon);
|
_uiUtils.ChecklistItem(FormatQuestUnlockName(qInfo, _questFunctions.IsQuestComplete(q.QuestId) ? byte.MinValue : q.Sequence), iconColor, icon);
|
||||||
|
|
||||||
if (qInfo is QuestInfo qstInfo && (counter <= 2 || icon != FontAwesomeIcon.Check))
|
if (qInfo is QuestInfo qstInfo && (counter <= 2 || icon != FontAwesomeIcon.Check))
|
||||||
DrawQuestUnlocks(qstInfo, counter + 1);
|
DrawQuestUnlocks(qstInfo, counter + 1);
|
||||||
@ -188,11 +191,17 @@ internal sealed class QuestTooltipComponent
|
|||||||
ImGui.Unindent();
|
ImGui.Unindent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string FormatQuestUnlockName(IQuestInfo questInfo)
|
private string FormatQuestUnlockName(IQuestInfo questInfo, byte sequence = 0)
|
||||||
{
|
{
|
||||||
|
string name = questInfo.Name;
|
||||||
|
if (_configuration.Advanced.AdditionalStatusInformation && sequence != 0)
|
||||||
|
name += $" {SeIconChar.ItemLevel.ToIconString()}";
|
||||||
|
|
||||||
if (questInfo.IsMainScenarioQuest)
|
if (questInfo.IsMainScenarioQuest)
|
||||||
return $"{questInfo.Name} ({questInfo.QuestId}, MSQ)";
|
name += $" ({questInfo.QuestId}, MSQ)";
|
||||||
else
|
else
|
||||||
return $"{questInfo.Name} ({questInfo.QuestId})";
|
name += $" {questInfo.Name} ({questInfo.QuestId})";
|
||||||
|
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user