qstbak/Questionable/Questionable.Functions/QuestFunctions.cs
2025-10-09 07:47:19 +10:00

959 lines
29 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using Dalamud.Game.ClientState.Aetherytes;
using Dalamud.Game.Text;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Application.Network.WorkDefinitions;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using LLib.GameData;
using LLib.GameUI;
using Lumina.Excel.Sheets;
using Questionable.Controller;
using Questionable.Data;
using Questionable.Model;
using Questionable.Model.Common;
using Questionable.Model.Questing;
namespace Questionable.Functions;
internal sealed class QuestFunctions
{
private readonly QuestRegistry _questRegistry;
private readonly QuestData _questData;
private readonly AetheryteFunctions _aetheryteFunctions;
private readonly AlliedSocietyQuestFunctions _alliedSocietyQuestFunctions;
private readonly AlliedSocietyData _alliedSocietyData;
private readonly Configuration _configuration;
private readonly IDataManager _dataManager;
private readonly IClientState _clientState;
private readonly IGameGui _gameGui;
private readonly IAetheryteList _aetheryteList;
public QuestFunctions(QuestRegistry questRegistry, QuestData questData, AetheryteFunctions aetheryteFunctions, AlliedSocietyQuestFunctions alliedSocietyQuestFunctions, AlliedSocietyData alliedSocietyData, Configuration configuration, IDataManager dataManager, IClientState clientState, IGameGui gameGui, IAetheryteList aetheryteList)
{
_questRegistry = questRegistry;
_questData = questData;
_aetheryteFunctions = aetheryteFunctions;
_alliedSocietyQuestFunctions = alliedSocietyQuestFunctions;
_alliedSocietyData = alliedSocietyData;
_configuration = configuration;
_dataManager = dataManager;
_clientState = clientState;
_gameGui = gameGui;
_aetheryteList = aetheryteList;
}
public unsafe QuestReference GetCurrentQuest(bool allowNewMsq = true)
{
QuestReference currentQuestInternal = GetCurrentQuestInternal(allowNewMsq);
currentQuestInternal.Deconstruct(out ElementId CurrentQuest, out byte Sequence, out MainScenarioQuestState State);
ElementId elementId = CurrentQuest;
byte sequence = Sequence;
MainScenarioQuestState state = State;
PlayerState* ptr = PlayerState.Instance();
if (elementId == null || elementId.Value == 0)
{
if (_clientState.TerritoryType == 181)
{
return new QuestReference(new QuestId(107), 0, MainScenarioQuestState.Available);
}
if (_clientState.TerritoryType == 182)
{
return new QuestReference(new QuestId(594), 0, MainScenarioQuestState.Available);
}
if (_clientState.TerritoryType == 183)
{
return new QuestReference(new QuestId(39), 0, MainScenarioQuestState.Available);
}
return QuestReference.NoQuest(state);
}
if (elementId.Value == 681)
{
if (IsQuestAccepted(elementId) || IsQuestComplete(elementId))
{
return new QuestReference(elementId, sequence, state);
}
return _configuration.General.GrandCompany switch
{
FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany.TwinAdder => new QuestReference(new QuestId(680), 0, state),
FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany.Maelstrom => new QuestReference(new QuestId(681), 0, state),
FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany.ImmortalFlames => new QuestReference(new QuestId(682), 0, state),
_ => QuestReference.NoQuest(MainScenarioQuestState.Unavailable),
};
}
if (elementId.Value == 3856 && !ptr->IsMountUnlocked(1u))
{
ushort num = (FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany)ptr->GrandCompany switch
{
FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany.TwinAdder => 700,
FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany.Maelstrom => 701,
FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany.ImmortalFlames => 702,
_ => 0,
};
if (num != 0 && !QuestManager.IsQuestComplete(num))
{
return new QuestReference(new QuestId(num), QuestManager.GetQuestSequence(num), state);
}
}
else if (elementId.Value == 801)
{
QuestId questId = new QuestId(802);
if (IsQuestAccepted(questId))
{
return new QuestReference(questId, QuestManager.GetQuestSequence(questId.Value), state);
}
}
return currentQuestInternal;
}
public unsafe QuestReference GetCurrentQuestInternal(bool allowNewMsq)
{
QuestManager* ptr = QuestManager.Instance();
if (ptr == null)
{
return QuestReference.NoQuest(MainScenarioQuestState.Unavailable);
}
QuestReference questReference = GetMainScenarioQuest().Item1;
if (questReference.CurrentQuest != null && !_questRegistry.IsKnownQuest(questReference.CurrentQuest))
{
questReference = QuestReference.NoQuest(questReference.State);
}
if (questReference.CurrentQuest != null && !IsQuestAccepted(questReference.CurrentQuest))
{
if (allowNewMsq)
{
return questReference;
}
questReference = QuestReference.NoQuest(questReference.State);
}
List<(ElementId, byte)> list = new List<(ElementId, byte)>();
for (int num = ptr->TrackedQuests.Length - 1; num >= 0; num--)
{
TrackingWork trackingWork = ptr->TrackedQuests[num];
switch (trackingWork.QuestType)
{
case 1:
{
ElementId elementId = new QuestId(ptr->NormalQuests[trackingWork.Index].QuestId);
if (_questRegistry.IsKnownQuest(elementId))
{
list.Add((elementId, QuestManager.GetQuestSequence(elementId.Value)));
}
break;
}
}
}
if (_configuration.General.SkipLowPriorityDuties && list.Count > 0)
{
IReadOnlyList<(uint ContentFinderConditionId, ElementId QuestId, int Sequence)> lowPriorityQuests = _questRegistry.LowPriorityContentFinderConditionQuests;
list.RemoveAll(((ElementId Quest, byte Sequence) x) => lowPriorityQuests.Any<(uint, ElementId, int)>(((uint ContentFinderConditionId, ElementId QuestId, int Sequence) y) => x.Quest == y.QuestId && x.Sequence == y.Sequence));
}
if (list.Count > 0)
{
(ElementId, byte) tuple = list.First();
ElementId item = tuple.Item1;
byte item2 = tuple.Item2;
EAlliedSociety firstTrackedAlliedSociety = _alliedSocietyData.GetCommonAlliedSocietyTurnIn(item);
if (firstTrackedAlliedSociety != EAlliedSociety.None)
{
List<(ElementId, byte)> list2 = (from quest in list.Skip(1)
where _alliedSocietyData.GetCommonAlliedSocietyTurnIn(quest.Quest) == firstTrackedAlliedSociety
select quest).ToList();
if (list2.Count > 0)
{
if (item2 == byte.MaxValue)
{
foreach (var (currentQuest, b) in list2)
{
if (b != byte.MaxValue)
{
return new QuestReference(currentQuest, b, questReference.State);
}
}
}
else if (!IsOnAlliedSocietyMount())
{
list2.Insert(0, (item, item2));
_alliedSocietyData.GetCommonAlliedSocietyNpcs(firstTrackedAlliedSociety, out uint[] normalNpcs, out uint[] _);
if (normalNpcs.Length != 0)
{
(ElementId, byte)? tuple3 = (from x in list2
where x.Sequence < byte.MaxValue
where IsInteractSequence(x.Quest, x.Sequence, normalNpcs)
select x).Cast<(ElementId, byte)?>().FirstOrDefault();
if (tuple3.HasValue)
{
return new QuestReference(tuple3.Value.Item1, tuple3.Value.Item2, questReference.State);
}
}
}
}
}
return new QuestReference(item, item2, questReference.State);
}
ElementId elementId2 = (from x in GetNextPriorityQuestsThatCanBeAccepted()
where x.IsAvailable
select x.QuestId).FirstOrDefault();
if (elementId2 != null)
{
return new QuestReference(elementId2, QuestManager.GetQuestSequence(elementId2.Value), questReference.State);
}
if (questReference.CurrentQuest != null)
{
return questReference;
}
return QuestReference.NoQuest(questReference.State);
}
public unsafe (QuestReference, string?) GetMainScenarioQuest()
{
if (QuestManager.IsQuestComplete(3759))
{
AgentInterface* agentByInternalId = AgentModule.Instance()->GetAgentByInternalId(AgentId.QuestRedoHud);
if (agentByInternalId != null && agentByInternalId->IsAgentActive())
{
AtkUnitBase* addonPtr;
bool flag = _gameGui.TryGetAddonByName<AtkUnitBase>("QuestRedoHud", out addonPtr) && addonPtr->AtkValuesCount == 4;
if (flag)
{
uint uInt = addonPtr->AtkValues->UInt;
bool flag2 = ((uInt == 0 || uInt - 2 <= 2) ? true : false);
flag = flag2;
}
if (flag)
{
ushort num = MemoryHelper.Read<ushort>((nint)((byte*)agentByInternalId + 46));
return (new QuestReference(new QuestId(num), QuestManager.GetQuestSequence(num), MainScenarioQuestState.Available), "NG+");
}
}
}
AgentScenarioTree* ptr = AgentScenarioTree.Instance();
if (ptr == null)
{
return (QuestReference.NoQuest(MainScenarioQuestState.Unavailable), "No Scenario Tree");
}
if (ptr->Data == null)
{
return (QuestReference.NoQuest(MainScenarioQuestState.LoadingScreen), "Scenario Tree Data is null");
}
QuestId questId = new QuestId(ptr->Data->CurrentScenarioQuest);
string item = $"sq: {questId}";
if (questId.Value == 0)
{
if (IsMainScenarioQuestComplete())
{
return (QuestReference.NoQuest(MainScenarioQuestState.Complete), "Main Scenario is complete");
}
PlayerState* playerState = PlayerState.Instance();
List<QuestInfo> list = (from q in _questData.MainScenarioQuests
where q.StartingCity == 0 || q.StartingCity == playerState->StartTown
where IsReadyToAcceptQuest(q.QuestId, ignoreLevel: true)
select q).ToList();
if (list.Count == 0)
{
return (QuestReference.NoQuest(MainScenarioQuestState.Unavailable), "No potential quests found");
}
if (list.Count > 1)
{
if (list.All(delegate(QuestInfo x)
{
ushort value = x.QuestId.Value;
return (uint)(value - 680) <= 2u;
}))
{
questId = new QuestId(681);
}
else if (list.Any((QuestInfo x) => x.QuestId.Value == 1583))
{
questId = new QuestId(1583);
}
else if (list.Any((QuestInfo x) => x.QuestId.Value == 2451))
{
questId = new QuestId(2451);
}
else if (list.Any((QuestInfo x) => x.QuestId.Value == 3282))
{
questId = new QuestId(3282);
}
else if (list.Any((QuestInfo x) => x.QuestId.Value == 4359))
{
questId = new QuestId(4359);
}
else if (list.Any((QuestInfo x) => x.QuestId.Value == 4865))
{
questId = new QuestId(4865);
}
if (list.Count != 1)
{
return (QuestReference.NoQuest(MainScenarioQuestState.Unavailable), "Multiple potential quests found: " + string.Join(", ", list.Select((QuestInfo x) => x.QuestId.Value)));
}
}
else
{
questId = (QuestId)list.Single().QuestId;
}
}
QuestManager* ptr2 = QuestManager.Instance();
if (IsQuestAccepted(questId) && ptr2->GetQuestById(questId.Value)->IsHidden)
{
return (QuestReference.NoQuest(MainScenarioQuestState.Available), "Quest accepted but hidden");
}
if (IsQuestComplete(questId))
{
return (new QuestReference(questId, byte.MaxValue, MainScenarioQuestState.Available), $"Quest {questId.Value} complete");
}
if (!IsReadyToAcceptQuest(questId))
{
return (QuestReference.NoQuest(MainScenarioQuestState.Unavailable), $"Not readdy to accept quest {questId.Value}");
}
byte? b = _clientState.LocalPlayer?.Level;
if (!b.HasValue)
{
return (QuestReference.NoQuest(MainScenarioQuestState.LoadingScreen), "In loading screen");
}
if (_questRegistry.TryGetQuest(questId, out Questionable.Model.Quest quest) && quest.Info.Level > b)
{
return (QuestReference.NoQuest(MainScenarioQuestState.Unavailable), "Low level");
}
return (new QuestReference(questId, QuestManager.GetQuestSequence(questId.Value), MainScenarioQuestState.Available), item);
}
private unsafe bool IsOnAlliedSocietyMount()
{
BattleChara* ptr = (BattleChara*)(_clientState.LocalPlayer?.Address ?? 0);
if (ptr != null && ptr->Mount.MountId != 0)
{
return _alliedSocietyData.Mounts.ContainsKey(ptr->Mount.MountId);
}
return false;
}
private bool IsInteractSequence(ElementId questId, byte sequenceNo, uint[] dataIds)
{
if (_questRegistry.TryGetQuest(questId, out Questionable.Model.Quest quest))
{
return quest.FindSequence(sequenceNo)?.Steps.All(delegate(QuestStep x)
{
if (x == null || x.InteractionType != EInteractionType.WalkTo)
{
if (x != null && x.InteractionType == EInteractionType.Interact)
{
uint? dataId = x.DataId;
if (dataId.HasValue)
{
uint valueOrDefault = dataId.GetValueOrDefault();
return dataIds.Contains(valueOrDefault);
}
}
return false;
}
return true;
}) ?? false;
}
return false;
}
public unsafe QuestProgressInfo? GetQuestProgressInfo(ElementId elementId)
{
if (elementId is QuestId questId)
{
QuestWork* questById = QuestManager.Instance()->GetQuestById(questId.Value);
if (questById == null)
{
return null;
}
return new QuestProgressInfo(*questById);
}
return null;
}
public unsafe List<PriorityQuestInfo> GetNextPriorityQuestsThatCanBeAccepted()
{
InventoryManager* ptr = InventoryManager.Instance();
int gil = ptr->GetItemCountInContainer(1u, InventoryType.Currency, isHq: false, 0);
return (from x in GetPriorityQuests()
where IsReadyToAcceptQuest(x)
select x).Select(delegate(ElementId x)
{
if (!_questRegistry.TryGetQuest(x, out Questionable.Model.Quest quest))
{
return new PriorityQuestInfo(x, "Unknown quest");
}
QuestStep questStep = quest.FindSequence(0)?.FindStep(0);
if (questStep == null)
{
return new PriorityQuestInfo(x, "No sequence 0 with steps");
}
if (!_aetheryteFunctions.IsTeleportUnlocked())
{
return new PriorityQuestInfo(x, "Teleport not unlocked");
}
if (!questStep.IsTeleportableForPriorityQuests())
{
return new PriorityQuestInfo(x, "Can't teleport to start");
}
DefaultInterpolatedStringHandler handler;
if (gil < EstimateTeleportCosts(quest))
{
IFormatProvider invariantCulture = CultureInfo.InvariantCulture;
handler = new DefaultInterpolatedStringHandler(32, 2, invariantCulture);
handler.AppendLiteral("Not enough gil, estimated cost: ");
handler.AppendFormatted(EstimateTeleportCosts(quest), "N0");
handler.AppendFormatted(SeIconChar.Gil.ToIconString());
return new PriorityQuestInfo(x, string.Create(invariantCulture, ref handler));
}
EAetheryteLocation? value = quest.AllSteps().Select<(QuestSequence, int, QuestStep), EAetheryteLocation?>(delegate((QuestSequence Sequence, int StepId, QuestStep Step) y)
{
EAetheryteLocation? aetheryteShortcut = y.Step.AetheryteShortcut;
if (aetheryteShortcut.HasValue)
{
EAetheryteLocation valueOrDefault = aetheryteShortcut.GetValueOrDefault();
if (!_aetheryteFunctions.IsAetheryteUnlocked(valueOrDefault))
{
SkipConditions? skipConditions = y.Step.SkipConditions;
if (skipConditions == null || skipConditions.AetheryteShortcutIf?.AetheryteLocked != valueOrDefault)
{
return valueOrDefault;
}
}
}
AethernetShortcut aethernetShortcut = y.Step.AethernetShortcut;
if (aethernetShortcut != null)
{
if (!_aetheryteFunctions.IsAetheryteUnlocked(aethernetShortcut.From))
{
return aethernetShortcut.From;
}
if (!_aetheryteFunctions.IsAetheryteUnlocked(aethernetShortcut.To))
{
return aethernetShortcut.To;
}
}
return (EAetheryteLocation?)null;
}).FirstOrDefault((EAetheryteLocation? y) => y.HasValue);
if (value.HasValue)
{
handler = new DefaultInterpolatedStringHandler(18, 1);
handler.AppendLiteral("Aetheryte locked: ");
handler.AppendFormatted(value);
return new PriorityQuestInfo(x, handler.ToStringAndClear());
}
return new PriorityQuestInfo(x);
}).ToList();
}
private int EstimateTeleportCosts(Questionable.Model.Quest quest)
{
Dictionary<EAetheryteLocation, float> cheapTeleports = _aetheryteList.Where((IAetheryteEntry x) => x.IsFavourite || _aetheryteFunctions.IsFreeAetheryte((EAetheryteLocation)x.AetheryteId)).ToDictionary((IAetheryteEntry x) => (EAetheryteLocation)x.AetheryteId, (IAetheryteEntry x) => _aetheryteFunctions.IsFreeAetheryte((EAetheryteLocation)x.AetheryteId) ? 0f : 0.5f);
int baseCost = ((quest.Info.Expansion == EExpansionVersion.ARealmReborn) ? 300 : 1000);
return (from x in quest.AllSteps()
where x.Step.AetheryteShortcut.HasValue
select x).Sum<(QuestSequence, int, QuestStep)>(((QuestSequence Sequence, int StepId, QuestStep Step) x) => (int)((float)baseCost * cheapTeleports.GetValueOrDefault(x.Step.AetheryteShortcut.Value, 1f)));
}
public List<ElementId> GetPriorityQuests(bool onlyClassAndRoleQuests = false)
{
List<ElementId> list = new List<ElementId>();
if (!onlyClassAndRoleQuests)
{
if (!_configuration.Advanced.SkipARealmRebornHardModePrimals)
{
list.AddRange(QuestData.HardModePrimals.Skip(1));
}
if (!_configuration.Advanced.SkipCrystalTowerRaids)
{
list.AddRange(QuestData.CrystalTowerQuests);
}
}
if (!_configuration.Advanced.SkipClassJobQuests)
{
EClassJob valueOrDefault = ((EClassJob?)_clientState.LocalPlayer?.ClassJob.RowId).GetValueOrDefault();
uint[] shadowbringersRoleQuestChapters = QuestData.AllRoleQuestChapters.Select((IReadOnlyList<uint> x) => x[0]).ToArray();
if (valueOrDefault != EClassJob.Adventurer)
{
list.AddRange(from x in _questRegistry.GetKnownClassJobQuests(valueOrDefault).Where(delegate(QuestInfo x)
{
if (_questRegistry.TryGetQuest(x.QuestId, out Questionable.Model.Quest quest))
{
IQuestInfo info = quest.Info;
QuestInfo questInfo = info as QuestInfo;
if (questInfo != null)
{
if (shadowbringersRoleQuestChapters.Contains(questInfo.NewGamePlusChapter))
{
return !QuestData.FinalShadowbringersRoleQuests.Any(IsQuestComplete);
}
if (QuestData.AllRoleQuestChapters.Any((IReadOnlyList<uint> y) => y.Contains(questInfo.NewGamePlusChapter)))
{
return false;
}
return true;
}
}
return false;
})
select x.QuestId);
}
}
return list.Where(_questRegistry.IsKnownQuest).ToList();
}
public unsafe bool IsReadyToAcceptQuest(ElementId questId, bool ignoreLevel = false)
{
_questRegistry.TryGetQuest(questId, out Questionable.Model.Quest quest);
if (quest != null)
{
IQuestInfo info = quest.Info;
if (info != null && info.IsRepeatable)
{
if (IsQuestAccepted(questId))
{
return false;
}
if (questId is QuestId questId2 && IsDailyAlliedSocietyQuest(questId2))
{
if (QuestManager.Instance()->IsDailyQuestCompleted(questId.Value))
{
return false;
}
if (!IsDailyAlliedSocietyQuestAndAvailableToday(questId2))
{
return false;
}
}
else if (IsQuestComplete(questId))
{
return false;
}
goto IL_0077;
}
}
if (IsQuestAcceptedOrComplete(questId))
{
return false;
}
goto IL_0077;
IL_0077:
if (IsQuestLocked(questId))
{
return false;
}
if (!ignoreLevel)
{
byte b = _clientState.LocalPlayer?.Level ?? 0;
if (b != 0 && quest != null && quest.Info.Level > b)
{
return false;
}
}
return true;
}
public bool IsQuestAcceptedOrComplete(ElementId elementId)
{
if (!IsQuestComplete(elementId))
{
return IsQuestAccepted(elementId);
}
return true;
}
public bool IsQuestAccepted(ElementId elementId)
{
if (elementId is QuestId questId)
{
return IsQuestAccepted(questId);
}
if (elementId is SatisfactionSupplyNpcId)
{
return false;
}
if (elementId is AlliedSocietyDailyId)
{
return false;
}
if (elementId is UnlockLinkId)
{
return false;
}
throw new ArgumentOutOfRangeException("elementId");
}
public unsafe bool IsQuestAccepted(QuestId questId)
{
return QuestManager.Instance()->IsQuestAccepted(questId.Value);
}
public bool IsQuestComplete(ElementId elementId)
{
if (elementId is QuestId questId)
{
return IsQuestComplete(questId);
}
if (elementId is SatisfactionSupplyNpcId)
{
return false;
}
if (elementId is AlliedSocietyDailyId)
{
return false;
}
if (elementId is UnlockLinkId unlockLinkId)
{
return IsQuestComplete(unlockLinkId);
}
throw new ArgumentOutOfRangeException("elementId");
}
public bool IsQuestComplete(QuestId questId)
{
return QuestManager.IsQuestComplete(questId.Value);
}
public unsafe bool IsQuestComplete(UnlockLinkId unlockLinkId)
{
return UIState.Instance()->IsUnlockLinkUnlocked(unlockLinkId.Value);
}
public bool IsQuestLocked(ElementId elementId, ElementId? extraCompletedQuest = null)
{
if (elementId is QuestId questId)
{
return IsQuestLocked(questId, extraCompletedQuest);
}
if (elementId is SatisfactionSupplyNpcId satisfactionSupplyNpcId)
{
return IsQuestLocked(satisfactionSupplyNpcId);
}
if (elementId is AlliedSocietyDailyId alliedSocietyDailyId)
{
return IsQuestLocked(alliedSocietyDailyId);
}
if (elementId is UnlockLinkId unlockLinkId)
{
return IsQuestLocked(unlockLinkId);
}
throw new ArgumentOutOfRangeException("elementId");
}
private unsafe bool IsQuestLocked(QuestId questId, ElementId? extraCompletedQuest = null)
{
if (IsQuestUnobtainable(questId, extraCompletedQuest))
{
return true;
}
QuestInfo questInfo = (QuestInfo)_questData.GetQuestInfo(questId);
if (questInfo.GrandCompany != FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany.None && questInfo.GrandCompany != GetGrandCompany())
{
return true;
}
if (questInfo.AlliedSociety != EAlliedSociety.None && questInfo.IsRepeatable)
{
return !IsDailyAlliedSocietyQuestAndAvailableToday(questId);
}
if (questInfo.IsMoogleDeliveryQuest)
{
byte b = PlayerState.Instance()->DeliveryLevel;
if (extraCompletedQuest != null && _questData.TryGetQuestInfo(extraCompletedQuest, out IQuestInfo questInfo2) && questInfo2 is QuestInfo { IsMoogleDeliveryQuest: not false })
{
b++;
}
if (questInfo.MoogleDeliveryLevel > b)
{
return true;
}
}
if (HasCompletedPreviousQuests(questInfo, extraCompletedQuest))
{
return !HasCompletedPreviousInstances(questInfo);
}
return true;
}
private bool IsQuestLocked(SatisfactionSupplyNpcId satisfactionSupplyNpcId)
{
SatisfactionSupplyInfo questInfo = (SatisfactionSupplyInfo)_questData.GetQuestInfo(satisfactionSupplyNpcId);
return !HasCompletedPreviousQuests(questInfo, null);
}
private unsafe bool IsQuestLocked(AlliedSocietyDailyId alliedSocietyDailyId)
{
byte beastTribeRank = PlayerState.Instance()->GetBeastTribeRank(alliedSocietyDailyId.AlliedSociety);
if (beastTribeRank != 0)
{
return beastTribeRank < alliedSocietyDailyId.Rank;
}
return true;
}
private static bool IsQuestLocked(UnlockLinkId unlockLinkId)
{
return IsQuestUnobtainable(unlockLinkId);
}
public bool IsDailyAlliedSocietyQuest(QuestId questId)
{
QuestInfo questInfo = (QuestInfo)_questData.GetQuestInfo(questId);
if (questInfo.AlliedSociety != EAlliedSociety.None)
{
return questInfo.IsRepeatable;
}
return false;
}
public bool IsDailyAlliedSocietyQuestAndAvailableToday(QuestId questId)
{
if (!IsDailyAlliedSocietyQuest(questId))
{
return false;
}
QuestInfo questInfo = (QuestInfo)_questData.GetQuestInfo(questId);
return _alliedSocietyQuestFunctions.GetAvailableAlliedSocietyQuests(questInfo.AlliedSociety).Contains(questId);
}
public bool IsQuestUnobtainable(ElementId elementId, ElementId? extraCompletedQuest = null)
{
if (elementId is QuestId questId)
{
return IsQuestUnobtainable(questId, extraCompletedQuest);
}
if (elementId is UnlockLinkId unlockLinkId)
{
return IsQuestUnobtainable(unlockLinkId);
}
return false;
}
public unsafe bool IsQuestUnobtainable(QuestId questId, ElementId? extraCompletedQuest = null)
{
QuestInfo questInfo = (QuestInfo)_questData.GetQuestInfo(questId);
if ((int)questInfo.Expansion > (int)PlayerState.Instance()->MaxExpansion)
{
return true;
}
if (questInfo.QuestLocks.Count > 0)
{
int num = questInfo.QuestLocks.Count((QuestId x) => IsQuestComplete(x) || x.Equals(extraCompletedQuest));
if (questInfo.QuestLockJoin == EQuestJoin.All && questInfo.QuestLocks.Count == num)
{
return true;
}
if (questInfo.QuestLockJoin == EQuestJoin.AtLeastOne && num > 0)
{
return true;
}
}
if (_questData.GetLockedClassQuests().Contains(questId))
{
return true;
}
byte startTown = PlayerState.Instance()->StartTown;
if (questInfo.StartingCity > 0 && questInfo.StartingCity != startTown)
{
return true;
}
if (questId.Value == 674 && startTown == 3)
{
return true;
}
if (questId.Value == 673 && startTown != 3)
{
return true;
}
Dictionary<ushort, EClassJob> dictionary = new Dictionary<ushort, EClassJob>
{
{
108,
EClassJob.Marauder
},
{
109,
EClassJob.Arcanist
},
{
85,
EClassJob.Lancer
},
{
123,
EClassJob.Archer
},
{
124,
EClassJob.Conjurer
},
{
568,
EClassJob.Gladiator
},
{
569,
EClassJob.Pugilist
},
{
570,
EClassJob.Thaumaturge
}
};
if (dictionary.TryGetValue(questId.Value, out var value) && dictionary.Any((KeyValuePair<ushort, EClassJob> x) => IsQuestAcceptedOrComplete(new QuestId(x.Key))) && (EClassJob)PlayerState.Instance()->FirstClass != value)
{
return true;
}
if (IsQuestRemoved(questId))
{
return true;
}
return false;
}
private static bool IsQuestUnobtainable(UnlockLinkId unlockLinkId)
{
if (unlockLinkId.Value == 506)
{
return !IsFestivalActive(160, (ushort)2);
}
if (unlockLinkId.Value == 568)
{
return !IsFestivalActive(160, (ushort)3);
}
return true;
}
private unsafe static bool IsFestivalActive(ushort id, ushort? phase = null)
{
for (int i = 0; i < GameMain.Instance()->ActiveFestivals.Length; i++)
{
GameMain.Festival festival = GameMain.Instance()->ActiveFestivals[i];
if (festival.Id == id)
{
if (phase.HasValue)
{
return festival.Phase == phase;
}
return true;
}
}
return false;
}
public bool IsQuestRemoved(ElementId elementId)
{
if (elementId is QuestId questId)
{
return IsQuestRemoved(questId);
}
return false;
}
private bool IsQuestRemoved(QuestId questId)
{
ushort value = questId.Value;
if (value == 487 || (uint)(value - 1428) <= 1u)
{
return true;
}
return false;
}
private bool HasCompletedPreviousQuests(IQuestInfo questInfo, ElementId? extraCompletedQuest)
{
if (questInfo.PreviousQuests.Count == 0)
{
return true;
}
int num = questInfo.PreviousQuests.Count((PreviousQuestInfo x) => HasEnoughProgressOnPreviousQuest(x) || x.QuestId.Equals(extraCompletedQuest));
if (questInfo.PreviousQuestJoin == EQuestJoin.All && questInfo.PreviousQuests.Count == num)
{
return true;
}
if (questInfo.PreviousQuestJoin == EQuestJoin.AtLeastOne && num > 0)
{
return true;
}
return false;
}
private bool HasEnoughProgressOnPreviousQuest(PreviousQuestInfo previousQuestInfo)
{
if (IsQuestComplete(previousQuestInfo.QuestId))
{
return true;
}
if (previousQuestInfo.Sequence != 0 && IsQuestAccepted(previousQuestInfo.QuestId))
{
QuestProgressInfo questProgressInfo = GetQuestProgressInfo(previousQuestInfo.QuestId);
if (questProgressInfo != null)
{
return questProgressInfo.Sequence >= previousQuestInfo.Sequence;
}
return false;
}
return false;
}
private static bool HasCompletedPreviousInstances(QuestInfo questInfo)
{
if (questInfo.PreviousInstanceContent.Count == 0)
{
return true;
}
int num = questInfo.PreviousInstanceContent.Count((ushort x) => UIState.IsInstanceContentCompleted(x));
if (questInfo.PreviousInstanceContentJoin == EQuestJoin.All && questInfo.PreviousInstanceContent.Count == num)
{
return true;
}
if (questInfo.PreviousInstanceContentJoin == EQuestJoin.AtLeastOne && num > 0)
{
return true;
}
return false;
}
public unsafe bool IsClassJobUnlocked(EClassJob classJob)
{
ClassJob row = _dataManager.GetExcelSheet<ClassJob>().GetRow((uint)classJob);
ushort num = (ushort)row.UnlockQuest.RowId;
if (num != 0)
{
return IsQuestComplete(new QuestId(num));
}
PlayerState* ptr = PlayerState.Instance();
if (ptr != null)
{
return ptr->ClassJobLevels[row.ExpArrayIndex] > 0;
}
return false;
}
public bool IsJobUnlocked(EClassJob classJob)
{
return IsClassJobUnlocked((EClassJob)_dataManager.GetExcelSheet<ClassJob>().GetRow((uint)classJob).ClassJobParent.RowId);
}
public unsafe FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany GetGrandCompany()
{
return (FFXIVClientStructs.FFXIV.Client.UI.Agent.GrandCompany)PlayerState.Instance()->GrandCompany;
}
public bool IsMainScenarioQuestComplete()
{
return IsQuestComplete(_questData.LastMainScenarioQuestId);
}
}