forked from liza/Questionable
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 Questionable.Model;
|
||||
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;
|
||||
|
||||
@ -62,7 +63,7 @@ internal sealed class QuestData
|
||||
|
||||
// workaround because the game doesn't require completion of the CT questline through normal means
|
||||
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)
|
||||
|
@ -494,7 +494,8 @@ internal sealed unsafe class QuestFunctions
|
||||
if (questInfo.PreviousQuests.Count == 0)
|
||||
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 &&
|
||||
questInfo.PreviousQuests.Count == completedQuests)
|
||||
return true;
|
||||
@ -504,6 +505,20 @@ internal sealed unsafe class QuestFunctions
|
||||
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)
|
||||
{
|
||||
if (questInfo.PreviousInstanceContent.Count == 0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using LLib.GameData;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Lumina.Excel.GeneratedSheets2;
|
||||
using Questionable.Model.Questing;
|
||||
|
||||
namespace Questionable.Model;
|
||||
@ -14,7 +14,7 @@ internal sealed class LeveInfo : IQuestInfo
|
||||
Level = leve.ClassJobLevel;
|
||||
JournalGenre = leve.JournalGenre.Row;
|
||||
SortKey = QuestId.Value;
|
||||
IssuerDataId = leve.LevelLevemete.Value!.Object;
|
||||
IssuerDataId = leve.LevelLevemete.Value!.Object.Row;
|
||||
ClassJobs = QuestInfoUtils.AsList(leve.ClassJobCategory.Value!);
|
||||
Expansion = (EExpansionVersion)leve.LevelLevemete.Value.Territory.Value!.ExVersion.Row;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using JetBrains.Annotations;
|
||||
using LLib.GameData;
|
||||
using Questionable.Model.Questing;
|
||||
using ExcelQuest = Lumina.Excel.GeneratedSheets.Quest;
|
||||
using ExcelQuest = Lumina.Excel.GeneratedSheets2.Quest;
|
||||
|
||||
namespace Questionable.Model;
|
||||
|
||||
@ -31,13 +31,18 @@ internal sealed class QuestInfo : IQuestInfo
|
||||
};
|
||||
|
||||
Name = $"{quest.Name}{suffix}";
|
||||
Level = quest.ClassJobLevel0;
|
||||
IssuerDataId = quest.IssuerStart;
|
||||
Level = quest.ClassJobLevel[0];
|
||||
IssuerDataId = quest.IssuerStart.Row;
|
||||
IsRepeatable = quest.IsRepeatable;
|
||||
PreviousQuests = quest.PreviousQuest
|
||||
.Select(x => new QuestId((ushort)(x.Row & 0xFFFF)))
|
||||
.Where(x => x.Value != 0)
|
||||
.ToImmutableList();
|
||||
PreviousQuests =
|
||||
new List<PreviousQuestInfo>
|
||||
{
|
||||
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;
|
||||
QuestLocks = quest.QuestLock
|
||||
.Select(x => new QuestId((ushort)(x.Row & 0xFFFFF)))
|
||||
@ -47,7 +52,7 @@ internal sealed class QuestInfo : IQuestInfo
|
||||
JournalGenre = quest.JournalGenre?.Row;
|
||||
SortKey = quest.SortKey;
|
||||
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();
|
||||
PreviousInstanceContentJoin = (QuestJoin)quest.InstanceContentJoin;
|
||||
GrandCompany = (GrandCompany)quest.GrandCompany.Row;
|
||||
@ -64,7 +69,7 @@ internal sealed class QuestInfo : IQuestInfo
|
||||
public ushort Level { get; }
|
||||
public uint IssuerDataId { get; }
|
||||
public bool IsRepeatable { get; }
|
||||
public ImmutableList<QuestId> PreviousQuests { get; set; }
|
||||
public ImmutableList<PreviousQuestInfo> PreviousQuests { get; set; }
|
||||
public QuestJoin PreviousQuestJoin { get; }
|
||||
public ImmutableList<QuestId> QuestLocks { get; }
|
||||
public QuestJoin QuestLockJoin { get; }
|
||||
@ -89,8 +94,10 @@ internal sealed class QuestInfo : IQuestInfo
|
||||
AtLeastOne = 2,
|
||||
}
|
||||
|
||||
public void AddPreviousQuest(QuestId questId)
|
||||
public void AddPreviousQuest(PreviousQuestInfo questId)
|
||||
{
|
||||
PreviousQuests = [..PreviousQuests, questId];
|
||||
}
|
||||
|
||||
public sealed record PreviousQuestInfo(QuestId QuestId, byte Sequence = 0);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LLib.GameData;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Lumina.Excel.GeneratedSheets2;
|
||||
|
||||
namespace Questionable.Model;
|
||||
|
||||
@ -57,8 +57,8 @@ internal static class QuestInfoUtils
|
||||
{ EClassJob.Dancer, classJobCategory.DNC },
|
||||
{ EClassJob.Reaper, classJobCategory.RPR },
|
||||
{ EClassJob.Sage, classJobCategory.SGE },
|
||||
{ EClassJob.Viper, classJobCategory.VPR },
|
||||
{ EClassJob.Pictomancer, classJobCategory.PCT }
|
||||
{ EClassJob.Viper, classJobCategory.Unknown1 },
|
||||
{ EClassJob.Pictomancer, classJobCategory.Unknown2 }
|
||||
}
|
||||
.Where(y => y.Value)
|
||||
.Select(y => y.Key)
|
||||
|
@ -19,19 +19,22 @@ internal sealed class QuestTooltipComponent
|
||||
private readonly TerritoryData _territoryData;
|
||||
private readonly QuestFunctions _questFunctions;
|
||||
private readonly UiUtils _uiUtils;
|
||||
private readonly Configuration _configuration;
|
||||
|
||||
public QuestTooltipComponent(
|
||||
QuestRegistry questRegistry,
|
||||
QuestData questData,
|
||||
TerritoryData territoryData,
|
||||
QuestFunctions questFunctions,
|
||||
UiUtils uiUtils)
|
||||
UiUtils uiUtils,
|
||||
Configuration configuration)
|
||||
{
|
||||
_questRegistry = questRegistry;
|
||||
_questData = questData;
|
||||
_territoryData = territoryData;
|
||||
_questFunctions = questFunctions;
|
||||
_uiUtils = uiUtils;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public void Draw(IQuestInfo quest)
|
||||
@ -105,13 +108,13 @@ internal sealed class QuestTooltipComponent
|
||||
|
||||
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))
|
||||
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))
|
||||
DrawQuestUnlocks(qstInfo, counter + 1);
|
||||
@ -188,11 +191,17 @@ internal sealed class QuestTooltipComponent
|
||||
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)
|
||||
return $"{questInfo.Name} ({questInfo.QuestId}, MSQ)";
|
||||
name += $" ({questInfo.QuestId}, MSQ)";
|
||||
else
|
||||
return $"{questInfo.Name} ({questInfo.QuestId})";
|
||||
name += $" {questInfo.Name} ({questInfo.QuestId})";
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user