diff --git a/Dalamud/Game/UnlockState/ItemActionType.cs b/Dalamud/Game/UnlockState/ItemActionType.cs deleted file mode 100644 index 8e3d79b84..000000000 --- a/Dalamud/Game/UnlockState/ItemActionType.cs +++ /dev/null @@ -1,95 +0,0 @@ -using Lumina.Excel.Sheets; - -namespace Dalamud.Game.UnlockState; - -/// -/// Enum for . -/// -internal enum ItemActionType : ushort -{ - /// - /// No item action. - /// - None = 0, - - /// - /// Unlocks a companion (minion). - /// - Companion = 853, - - /// - /// Unlocks a chocobo companion barding. - /// - BuddyEquip = 1013, - - /// - /// Unlocks a mount. - /// - Mount = 1322, - - /// - /// Unlocks recipes from a crafting recipe book. - /// - SecretRecipeBook = 2136, - - /// - /// Unlocks various types of content (e.g. Riding Maps, Blue Mage Totems, Emotes, Hairstyles). - /// - UnlockLink = 2633, - - /// - /// Unlocks a Triple Triad Card. - /// - TripleTriadCard = 3357, - - /// - /// Unlocks gathering nodes of a Folklore Tome. - /// - FolkloreTome = 4107, - - /// - /// Unlocks an Orchestrion Roll. - /// - OrchestrionRoll = 25183, - - /// - /// Unlocks portrait designs. - /// - FramersKit = 29459, - - /// - /// Unlocks Bozjan Field Notes. - /// - /// These are server-side but are cached client-side. - FieldNotes = 19743, - - /// - /// Unlocks an Ornament (fashion accessory). - /// - Ornament = 20086, - - /// - /// Unlocks Glasses. - /// - Glasses = 37312, - - /// - /// Company Seal Vouchers, which convert the item into Company Seals when used. - /// - CompanySealVouchers = 41120, - - /// - /// Unlocks Occult Records in Occult Crescent. - /// - OccultRecords = 43141, - - /// - /// Unlocks Phantom Jobs in Occult Crescent. - /// - SoulShards = 43142, - - /// - /// Star Contributor Certificate, which grants the Star Contributor status in Cosmic Exploration. - /// - StarContributorCertificate = 45189, -} diff --git a/Dalamud/Game/UnlockState/RecipeData.cs b/Dalamud/Game/UnlockState/RecipeData.cs deleted file mode 100644 index c419ba4fd..000000000 --- a/Dalamud/Game/UnlockState/RecipeData.cs +++ /dev/null @@ -1,283 +0,0 @@ -using System.Linq; - -using CommunityToolkit.HighPerformance; - -using Dalamud.Data; -using Dalamud.Game.Gui; - -using FFXIVClientStructs.FFXIV.Client.Game; -using FFXIVClientStructs.FFXIV.Client.Game.UI; -using FFXIVClientStructs.Interop; - -using Lumina.Excel.Sheets; - -namespace Dalamud.Game.UnlockState; - -/// -/// Represents recipe-related data for all crafting classes. -/// -[ServiceManager.EarlyLoadedService] -internal unsafe class RecipeData : IInternalDisposableService -{ - [ServiceManager.ServiceDependency] - private readonly DataManager dataManager = Service.Get(); - - [ServiceManager.ServiceDependency] - private readonly ClientState.ClientState clientState = Service.Get(); - - [ServiceManager.ServiceDependency] - private readonly GameGui gameGui = Service.Get(); - - private readonly ushort[] craftTypeLevels; - private readonly byte[] unlockedNoteBookDivisionsCount; - private readonly byte[] unlockedSecretNoteBookDivisionsCount; - private readonly ushort[,] noteBookDivisionIds; - private byte[]? cachedUnlockedSecretRecipeBooks; - private byte[]? cachedUnlockLinks; - private byte[]? cachedCompletedQuests; - - /// - /// Initializes a new instance of the class. - /// - [ServiceManager.ServiceConstructor] - public RecipeData() - { - var numCraftTypes = this.dataManager.GetExcelSheet().Count(); - var numSecretNotBookDivisions = this.dataManager.GetExcelSheet().Count(row => row.RowId is >= 1000 and < 2000); - - this.unlockedNoteBookDivisionsCount = new byte[numCraftTypes]; - this.unlockedSecretNoteBookDivisionsCount = new byte[numCraftTypes]; - this.noteBookDivisionIds = new ushort[numCraftTypes, numSecretNotBookDivisions]; - - this.craftTypeLevels = new ushort[numCraftTypes]; - - this.clientState.Login += this.Update; - this.clientState.Logout += this.OnLogout; - this.clientState.LevelChanged += this.OnlevelChanged; - this.gameGui.AgentUpdate += this.OnAgentUpdate; - } - - /// - void IInternalDisposableService.DisposeService() - { - this.clientState.Login -= this.Update; - this.clientState.Logout -= this.OnLogout; - this.clientState.LevelChanged -= this.OnlevelChanged; - this.gameGui.AgentUpdate -= this.OnAgentUpdate; - } - - /// - /// Determines whether the specified Recipe is unlocked. - /// - /// The Recipe row to check. - /// if unlocked; otherwise, . - public bool IsRecipeUnlocked(Recipe row) - { - // E8 ?? ?? ?? ?? 48 63 76 (2025.09.04) - var division = row.RecipeNotebookList.RowId != 0 && row.RecipeNotebookList.IsValid - ? (row.RecipeNotebookList.RowId - 1000) / 8 + 1000 - : ((uint)row.RecipeLevelTable.Value.ClassJobLevel - 1) / 5; - - // E8 ?? ?? ?? ?? 33 ED 84 C0 75 (2025.09.04) - foreach (var craftTypeRow in this.dataManager.GetExcelSheet()) - { - var craftType = (byte)craftTypeRow.RowId; - - if (division < this.unlockedNoteBookDivisionsCount[craftType]) - return true; - - if (this.unlockedNoteBookDivisionsCount[craftType] == 0) - continue; - - if (division is 5000 or 5001) - return true; - - if (division < 1000) - continue; - - if (this.unlockedSecretNoteBookDivisionsCount[craftType] == 0) - continue; - - if (this.noteBookDivisionIds.GetRowSpan(craftType).Contains((ushort)division)) - return true; - } - - return false; - } - - private void OnLogout(int type, int code) - { - this.cachedUnlockedSecretRecipeBooks = null; - this.cachedUnlockLinks = null; - this.cachedCompletedQuests = null; - } - - private void OnlevelChanged(uint classJobId, uint level) - { - if (this.dataManager.GetExcelSheet().TryGetRow(classJobId, out var classJobRow) && - classJobRow.ClassJobCategory.RowId == 33) // Crafter - { - this.Update(); - } - } - - private void OnAgentUpdate(AgentUpdateFlag agentUpdateFlag) - { - if (agentUpdateFlag.HasFlag(AgentUpdateFlag.UnlocksUpdate)) - this.Update(); - } - - private void Update() - { - // based on Client::Game::UI::RecipeNote.InitializeStructs - - if (!this.clientState.IsLoggedIn || !this.NeedsUpdate()) - return; - - Array.Clear(this.unlockedNoteBookDivisionsCount, 0, this.unlockedNoteBookDivisionsCount.Length); - Array.Clear(this.unlockedSecretNoteBookDivisionsCount, 0, this.unlockedSecretNoteBookDivisionsCount.Length); - Array.Clear(this.noteBookDivisionIds, 0, this.noteBookDivisionIds.Length); - - foreach (var craftTypeRow in this.dataManager.GetExcelSheet()) - { - var craftType = (byte)craftTypeRow.RowId; - var craftTypeLevel = RecipeNote.Instance()->GetCraftTypeLevel(craftType); - if (craftTypeLevel == 0) - continue; - - var noteBookDivisionIndex = -1; - - foreach (var noteBookDivisionRow in this.dataManager.GetExcelSheet()) - { - if (noteBookDivisionRow.RowId < 1000) - { - if (craftTypeLevel >= noteBookDivisionRow.CraftOpeningLevel) - this.unlockedNoteBookDivisionsCount[craftType]++; - } - else if (noteBookDivisionRow.RowId < 2000) - { - noteBookDivisionIndex++; - - // For future Lumina.Excel update, replace with: - // if (!notebookDivisionRow.AllowedCraftTypes[craftType]) - // continue; - - switch (craftTypeRow.RowId) - { - case 0 when !noteBookDivisionRow.CRPCraft: continue; - case 1 when !noteBookDivisionRow.BSMCraft: continue; - case 2 when !noteBookDivisionRow.ARMCraft: continue; - case 3 when !noteBookDivisionRow.GSMCraft: continue; - case 4 when !noteBookDivisionRow.LTWCraft: continue; - case 5 when !noteBookDivisionRow.WVRCraft: continue; - case 6 when !noteBookDivisionRow.ALCCraft: continue; - case 7 when !noteBookDivisionRow.CULCraft: continue; - } - - if (noteBookDivisionRow.GatheringOpeningLevel != byte.MaxValue) - continue; - - // For future Lumina.Excel update, replace with: - // if (notebookDivisionRow.RequiresSecretRecipeBookGroupUnlock) - if (noteBookDivisionRow.Unknown1) - { - var secretRecipeBookUnlocked = false; - - // For future Lumina.Excel update, iterate over notebookDivisionRow.SecretRecipeBookGroups - for (var i = 0; i < 2; i++) - { - // For future Lumina.Excel update, replace with: - // if (secretRecipeBookGroup.RowId == 0 || !secretRecipeBookGroup.IsValid) - // continue; - var secretRecipeBookGroupRowId = i switch - { - 0 => noteBookDivisionRow.Unknown2, - 1 => noteBookDivisionRow.Unknown2, - _ => default, - }; - - if (secretRecipeBookGroupRowId == 0) - continue; - - if (!this.dataManager.GetExcelSheet().TryGetRow(secretRecipeBookGroupRowId, out var secretRecipeBookGroupRow)) - continue; - - // For future Lumina.Excel update, replace with: - // var bitIndex = secretRecipeBookGroup.Value.UnlockBitIndex[craftType]; - - var bitIndex = craftType switch - { - 0 => secretRecipeBookGroupRow.Unknown0, - 1 => secretRecipeBookGroupRow.Unknown1, - 2 => secretRecipeBookGroupRow.Unknown2, - 3 => secretRecipeBookGroupRow.Unknown3, - 4 => secretRecipeBookGroupRow.Unknown4, - 5 => secretRecipeBookGroupRow.Unknown5, - 6 => secretRecipeBookGroupRow.Unknown6, - 7 => secretRecipeBookGroupRow.Unknown7, - _ => default, - }; - - if (PlayerState.Instance()->UnlockedSecretRecipeBooksBitArray.Get(bitIndex)) - { - secretRecipeBookUnlocked = true; - break; - } - } - - if (noteBookDivisionRow.CraftOpeningLevel > craftTypeLevel && !secretRecipeBookUnlocked) - continue; - } - else if (craftTypeLevel < noteBookDivisionRow.CraftOpeningLevel) - { - continue; - } - else if (noteBookDivisionRow.QuestUnlock.RowId != 0 && !UIState.Instance()->IsUnlockLinkUnlockedOrQuestCompleted(noteBookDivisionRow.QuestUnlock.RowId)) - { - continue; - } - - this.unlockedSecretNoteBookDivisionsCount[craftType]++; - this.noteBookDivisionIds[craftType, noteBookDivisionIndex] = (ushort)noteBookDivisionRow.RowId; - } - } - } - } - - private bool NeedsUpdate() - { - var changed = false; - - foreach (var craftTypeRow in this.dataManager.GetExcelSheet()) - { - var craftType = (byte)craftTypeRow.RowId; - var craftTypeLevel = RecipeNote.Instance()->GetCraftTypeLevel(craftType); - - if (this.craftTypeLevels[craftType] != craftTypeLevel) - { - this.craftTypeLevels[craftType] = craftTypeLevel; - changed |= true; - } - } - - if (this.cachedUnlockedSecretRecipeBooks == null || !PlayerState.Instance()->UnlockedSecretRecipeBooks.SequenceEqual(this.cachedUnlockedSecretRecipeBooks)) - { - this.cachedUnlockedSecretRecipeBooks = PlayerState.Instance()->UnlockedSecretRecipeBooks.ToArray(); - changed |= true; - } - - if (this.cachedUnlockLinks == null || !UIState.Instance()->UnlockLinks.SequenceEqual(this.cachedUnlockLinks)) - { - this.cachedUnlockLinks = UIState.Instance()->UnlockLinks.ToArray(); - changed |= true; - } - - if (this.cachedCompletedQuests == null || !QuestManager.Instance()->CompletedQuests.SequenceEqual(this.cachedCompletedQuests)) - { - this.cachedCompletedQuests = QuestManager.Instance()->CompletedQuests.ToArray(); - changed |= true; - } - - return changed; - } -} diff --git a/Dalamud/Game/UnlockState/UnlockState.cs b/Dalamud/Game/UnlockState/UnlockState.cs deleted file mode 100644 index a4b9381cc..000000000 --- a/Dalamud/Game/UnlockState/UnlockState.cs +++ /dev/null @@ -1,858 +0,0 @@ -using System.Collections.Concurrent; -using System.Collections.Generic; - -using Dalamud.Data; -using Dalamud.Game.Gui; -using Dalamud.IoC; -using Dalamud.IoC.Internal; -using Dalamud.Logging.Internal; -using Dalamud.Plugin.Services; - -using FFXIVClientStructs.FFXIV.Client.Game; -using FFXIVClientStructs.FFXIV.Client.Game.InstanceContent; -using FFXIVClientStructs.FFXIV.Client.Game.UI; -using FFXIVClientStructs.FFXIV.Component.Exd; - -using Lumina.Excel; -using Lumina.Excel.Sheets; - -using ActionSheet = Lumina.Excel.Sheets.Action; -using InstanceContentSheet = Lumina.Excel.Sheets.InstanceContent; -using PublicContentSheet = Lumina.Excel.Sheets.PublicContent; - -namespace Dalamud.Game.UnlockState; - -#pragma warning disable UnlockState - -/// -/// This class provides unlock state of various content in the game. -/// -[ServiceManager.EarlyLoadedService] -internal unsafe class UnlockState : IInternalDisposableService, IUnlockState -{ - private static readonly ModuleLog Log = new(nameof(UnlockState)); - - private readonly ConcurrentDictionary> cachedUnlockedRowIds = []; - - [ServiceManager.ServiceDependency] - private readonly DataManager dataManager = Service.Get(); - - [ServiceManager.ServiceDependency] - private readonly ClientState.ClientState clientState = Service.Get(); - - [ServiceManager.ServiceDependency] - private readonly GameGui gameGui = Service.Get(); - - [ServiceManager.ServiceDependency] - private readonly RecipeData recipeData = Service.Get(); - - [ServiceManager.ServiceConstructor] - private UnlockState() - { - this.clientState.Login += this.OnLogin; - this.clientState.Logout += this.OnLogout; - this.gameGui.AgentUpdate += this.OnAgentUpdate; - } - - /// - public event IUnlockState.UnlockDelegate Unlock; - - private bool IsLoaded => PlayerState.Instance()->IsLoaded; - - /// - void IInternalDisposableService.DisposeService() - { - this.clientState.Login -= this.OnLogin; - this.clientState.Logout -= this.OnLogout; - this.gameGui.AgentUpdate -= this.OnAgentUpdate; - } - - /// - public bool IsActionUnlocked(ActionSheet row) - { - return this.IsUnlockLinkUnlocked(row.UnlockLink.RowId); - } - - /// - public bool IsAetherCurrentUnlocked(AetherCurrent row) - { - if (!this.IsLoaded) - return false; - - return PlayerState.Instance()->IsAetherCurrentUnlocked(row.RowId); - } - - /// - public bool IsAetherCurrentCompFlgSetUnlocked(AetherCurrentCompFlgSet row) - { - if (!this.IsLoaded) - return false; - - return PlayerState.Instance()->IsAetherCurrentZoneComplete(row.RowId); - } - - /// - public bool IsAozActionUnlocked(AozAction row) - { - if (!this.IsLoaded) - return false; - - if (row.RowId == 0 || !row.Action.IsValid) - return false; - - return UIState.Instance()->IsUnlockLinkUnlockedOrQuestCompleted(row.Action.Value.UnlockLink.RowId); - } - - /// - public bool IsBannerBgUnlocked(BannerBg row) - { - return row.UnlockCondition.IsValid && this.IsBannerConditionUnlocked(row.UnlockCondition.Value); - } - - /// - public bool IsBannerConditionUnlocked(BannerCondition row) - { - if (row.RowId == 0) - return false; - - if (!this.IsLoaded) - return false; - - var rowPtr = ExdModule.GetBannerConditionByIndex(row.RowId); - if (rowPtr == null) - return false; - - return ExdModule.GetBannerConditionUnlockState(rowPtr) == 0; - } - - /// - public bool IsBannerDecorationUnlocked(BannerDecoration row) - { - return row.UnlockCondition.IsValid && this.IsBannerConditionUnlocked(row.UnlockCondition.Value); - } - - /// - public bool IsBannerFacialUnlocked(BannerFacial row) - { - return row.UnlockCondition.IsValid && this.IsBannerConditionUnlocked(row.UnlockCondition.Value); - } - - /// - public bool IsBannerFrameUnlocked(BannerFrame row) - { - return row.UnlockCondition.IsValid && this.IsBannerConditionUnlocked(row.UnlockCondition.Value); - } - - /// - public bool IsBannerTimelineUnlocked(BannerTimeline row) - { - return row.UnlockCondition.IsValid && this.IsBannerConditionUnlocked(row.UnlockCondition.Value); - } - - /// - public bool IsBuddyActionUnlocked(BuddyAction row) - { - return this.IsUnlockLinkUnlocked(row.UnlockLink); - } - - /// - public bool IsBuddyEquipUnlocked(BuddyEquip row) - { - if (!this.IsLoaded) - return false; - - return UIState.Instance()->Buddy.CompanionInfo.IsBuddyEquipUnlocked(row.RowId); - } - - /// - public bool IsCharaMakeCustomizeUnlocked(CharaMakeCustomize row) - { - return row.IsPurchasable && this.IsUnlockLinkUnlocked(row.UnlockLink); - } - - /// - public bool IsChocoboTaxiStandUnlocked(ChocoboTaxiStand row) - { - if (!this.IsLoaded) - return false; - - return UIState.Instance()->IsChocoboTaxiStandUnlocked(row.RowId); - } - - /// - public bool IsCompanionUnlocked(Companion row) - { - if (!this.IsLoaded) - return false; - - return UIState.Instance()->IsCompanionUnlocked(row.RowId); - } - - /// - public bool IsCraftActionUnlocked(CraftAction row) - { - return this.IsUnlockLinkUnlocked(row.QuestRequirement.RowId); - } - - /// - public bool IsCSBonusContentTypeUnlocked(CSBonusContentType row) - { - return this.IsUnlockLinkUnlocked(row.UnlockLink); - } - - /// - public bool IsEmoteUnlocked(Emote row) - { - return this.IsUnlockLinkUnlocked(row.UnlockLink); - } - - /// - public bool IsEmjVoiceNpcUnlocked(EmjVoiceNpc row) - { - return this.IsUnlockLinkUnlocked(row.Unknown26); - } - - /// - public bool IsEmjCostumeUnlocked(EmjCostume row) - { - return this.dataManager.GetExcelSheet().TryGetRow(row.RowId, out var emjVoiceNpcRow) - && this.IsEmjVoiceNpcUnlocked(emjVoiceNpcRow) - && QuestManager.IsQuestComplete(row.Unknown1); - } - - /// - public bool IsGeneralActionUnlocked(GeneralAction row) - { - return this.IsUnlockLinkUnlocked(row.UnlockLink); - } - - /// - public bool IsGlassesUnlocked(Glasses row) - { - if (!this.IsLoaded) - return false; - - return PlayerState.Instance()->IsGlassesUnlocked((ushort)row.RowId); - } - - /// - public bool IsHowToUnlocked(HowTo row) - { - if (!this.IsLoaded) - return false; - - return UIState.Instance()->IsHowToUnlocked(row.RowId); - } - - /// - public bool IsInstanceContentUnlocked(InstanceContentSheet row) - { - if (!this.IsLoaded) - return false; - - return UIState.IsInstanceContentUnlocked(row.RowId); - } - - /// - public unsafe bool IsItemUnlocked(Item row) - { - if (row.ItemAction.RowId == 0) - return false; - - if (!this.IsLoaded) - return false; - - // To avoid the ExdModule.GetItemRowById call, which can return null if the excel page - // is not loaded, we're going to imitate the IsItemActionUnlocked call first: - switch ((ItemActionType)row.ItemAction.Value.Type) - { - case ItemActionType.Companion: - return UIState.Instance()->IsCompanionUnlocked(row.ItemAction.Value.Data[0]); - - case ItemActionType.BuddyEquip: - return UIState.Instance()->Buddy.CompanionInfo.IsBuddyEquipUnlocked(row.ItemAction.Value.Data[0]); - - case ItemActionType.Mount: - return PlayerState.Instance()->IsMountUnlocked(row.ItemAction.Value.Data[0]); - - case ItemActionType.SecretRecipeBook: - return PlayerState.Instance()->IsSecretRecipeBookUnlocked(row.ItemAction.Value.Data[0]); - - case ItemActionType.UnlockLink: - case ItemActionType.OccultRecords: - return UIState.Instance()->IsUnlockLinkUnlocked(row.ItemAction.Value.Data[0]); - - case ItemActionType.TripleTriadCard when row.AdditionalData.Is(): - return UIState.Instance()->IsTripleTriadCardUnlocked((ushort)row.AdditionalData.RowId); - - case ItemActionType.FolkloreTome: - return PlayerState.Instance()->IsFolkloreBookUnlocked(row.ItemAction.Value.Data[0]); - - case ItemActionType.OrchestrionRoll when row.AdditionalData.Is(): - return PlayerState.Instance()->IsOrchestrionRollUnlocked(row.AdditionalData.RowId); - - case ItemActionType.FramersKit: - return PlayerState.Instance()->IsFramersKitUnlocked(row.AdditionalData.RowId); - - case ItemActionType.Ornament: - return PlayerState.Instance()->IsOrnamentUnlocked(row.ItemAction.Value.Data[0]); - - case ItemActionType.Glasses: - return PlayerState.Instance()->IsGlassesUnlocked((ushort)row.AdditionalData.RowId); - - case ItemActionType.SoulShards when PublicContentOccultCrescent.GetState() is var occultCrescentState && occultCrescentState != null: - var supportJobId = (byte)row.ItemAction.Value.Data[0]; - return supportJobId < occultCrescentState->SupportJobLevels.Length && occultCrescentState->SupportJobLevels[supportJobId] != 0; - - case ItemActionType.CompanySealVouchers: - return false; - } - - var nativeRow = ExdModule.GetItemRowById(row.RowId); - return nativeRow != null && UIState.Instance()->IsItemActionUnlocked(nativeRow) == 1; - } - - /// - public bool IsMcGuffinUnlocked(McGuffin row) - { - return PlayerState.Instance()->IsMcGuffinUnlocked(row.RowId); - } - - /// - public bool IsMJILandmarkUnlocked(MJILandmark row) - { - return this.IsUnlockLinkUnlocked(row.UnlockLink); - } - - /// - public bool IsMKDLoreUnlocked(MKDLore row) - { - return this.IsUnlockLinkUnlocked(row.Unknown2); - } - - /// - public bool IsMountUnlocked(Mount row) - { - if (!this.IsLoaded) - return false; - - return PlayerState.Instance()->IsMountUnlocked(row.RowId); - } - - /// - public bool IsNotebookDivisionUnlocked(NotebookDivision row) - { - return this.IsUnlockLinkUnlocked(row.QuestUnlock.RowId); - } - - /// - public bool IsOrchestrionUnlocked(Orchestrion row) - { - if (!this.IsLoaded) - return false; - - return PlayerState.Instance()->IsOrchestrionRollUnlocked(row.RowId); - } - - /// - public bool IsOrnamentUnlocked(Ornament row) - { - if (!this.IsLoaded) - return false; - - return PlayerState.Instance()->IsOrnamentUnlocked(row.RowId); - } - - /// - public bool IsPerformUnlocked(Perform row) - { - return this.IsUnlockLinkUnlocked((uint)row.UnlockLink); - } - - /// - public bool IsPublicContentUnlocked(PublicContentSheet row) - { - if (!this.IsLoaded) - return false; - - return UIState.IsPublicContentUnlocked(row.RowId); - } - - /// - public bool IsRecipeUnlocked(Recipe row) - { - return this.recipeData.IsRecipeUnlocked(row); - } - - /// - public bool IsSecretRecipeBookUnlocked(SecretRecipeBook row) - { - if (!this.IsLoaded) - return false; - - return PlayerState.Instance()->IsSecretRecipeBookUnlocked(row.RowId); - } - - /// - public bool IsTraitUnlocked(Trait row) - { - return this.IsUnlockLinkUnlocked(row.Quest.RowId); - } - - /// - public bool IsTripleTriadCardUnlocked(TripleTriadCard row) - { - if (!this.IsLoaded) - return false; - - return UIState.Instance()->IsTripleTriadCardUnlocked((ushort)row.RowId); - } - - /// - public bool IsItemUnlockable(Item row) - { - if (row.ItemAction.RowId == 0) - return false; - - return (ItemActionType)row.ItemAction.Value.Type - is ItemActionType.Companion - or ItemActionType.BuddyEquip - or ItemActionType.Mount - or ItemActionType.SecretRecipeBook - or ItemActionType.UnlockLink - or ItemActionType.TripleTriadCard - or ItemActionType.FolkloreTome - or ItemActionType.OrchestrionRoll - or ItemActionType.FramersKit - or ItemActionType.Ornament - or ItemActionType.Glasses - or ItemActionType.OccultRecords - or ItemActionType.SoulShards; - } - - /// - public bool IsRowRefUnlocked(RowRef rowRef) where T : struct, IExcelRow - { - return this.IsRowRefUnlocked((RowRef)rowRef); - } - - /// - public bool IsRowRefUnlocked(RowRef rowRef) - { - if (!this.IsLoaded || rowRef.IsUntyped) - return false; - - if (rowRef.TryGetValue(out var actionRow)) - return this.IsActionUnlocked(actionRow); - - if (rowRef.TryGetValue(out var aetherCurrentRow)) - return this.IsAetherCurrentUnlocked(aetherCurrentRow); - - if (rowRef.TryGetValue(out var aetherCurrentCompFlgSetRow)) - return this.IsAetherCurrentCompFlgSetUnlocked(aetherCurrentCompFlgSetRow); - - if (rowRef.TryGetValue(out var aozActionRow)) - return this.IsAozActionUnlocked(aozActionRow); - - if (rowRef.TryGetValue(out var bannerBgRow)) - return this.IsBannerBgUnlocked(bannerBgRow); - - if (rowRef.TryGetValue(out var bannerConditionRow)) - return this.IsBannerConditionUnlocked(bannerConditionRow); - - if (rowRef.TryGetValue(out var bannerDecorationRow)) - return this.IsBannerDecorationUnlocked(bannerDecorationRow); - - if (rowRef.TryGetValue(out var bannerFacialRow)) - return this.IsBannerFacialUnlocked(bannerFacialRow); - - if (rowRef.TryGetValue(out var bannerFrameRow)) - return this.IsBannerFrameUnlocked(bannerFrameRow); - - if (rowRef.TryGetValue(out var bannerTimelineRow)) - return this.IsBannerTimelineUnlocked(bannerTimelineRow); - - if (rowRef.TryGetValue(out var buddyActionRow)) - return this.IsBuddyActionUnlocked(buddyActionRow); - - if (rowRef.TryGetValue(out var buddyEquipRow)) - return this.IsBuddyEquipUnlocked(buddyEquipRow); - - if (rowRef.TryGetValue(out var csBonusContentTypeRow)) - return this.IsCSBonusContentTypeUnlocked(csBonusContentTypeRow); - - if (rowRef.TryGetValue(out var charaMakeCustomizeRow)) - return this.IsCharaMakeCustomizeUnlocked(charaMakeCustomizeRow); - - if (rowRef.TryGetValue(out var chocoboTaxiStandRow)) - return this.IsChocoboTaxiStandUnlocked(chocoboTaxiStandRow); - - if (rowRef.TryGetValue(out var companionRow)) - return this.IsCompanionUnlocked(companionRow); - - if (rowRef.TryGetValue(out var craftActionRow)) - return this.IsCraftActionUnlocked(craftActionRow); - - if (rowRef.TryGetValue(out var emoteRow)) - return this.IsEmoteUnlocked(emoteRow); - - if (rowRef.TryGetValue(out var generalActionRow)) - return this.IsGeneralActionUnlocked(generalActionRow); - - if (rowRef.TryGetValue(out var glassesRow)) - return this.IsGlassesUnlocked(glassesRow); - - if (rowRef.TryGetValue(out var howToRow)) - return this.IsHowToUnlocked(howToRow); - - if (rowRef.TryGetValue(out var instanceContentRow)) - return this.IsInstanceContentUnlocked(instanceContentRow); - - if (rowRef.TryGetValue(out var itemRow)) - return this.IsItemUnlocked(itemRow); - - if (rowRef.TryGetValue(out var mjiLandmarkRow)) - return this.IsMJILandmarkUnlocked(mjiLandmarkRow); - - if (rowRef.TryGetValue(out var mkdLoreRow)) - return this.IsMKDLoreUnlocked(mkdLoreRow); - - if (rowRef.TryGetValue(out var mcGuffinRow)) - return this.IsMcGuffinUnlocked(mcGuffinRow); - - if (rowRef.TryGetValue(out var mountRow)) - return this.IsMountUnlocked(mountRow); - - if (rowRef.TryGetValue(out var notebookDivisionRow)) - return this.IsNotebookDivisionUnlocked(notebookDivisionRow); - - if (rowRef.TryGetValue(out var orchestrionRow)) - return this.IsOrchestrionUnlocked(orchestrionRow); - - if (rowRef.TryGetValue(out var ornamentRow)) - return this.IsOrnamentUnlocked(ornamentRow); - - if (rowRef.TryGetValue(out var performRow)) - return this.IsPerformUnlocked(performRow); - - if (rowRef.TryGetValue(out var publicContentRow)) - return this.IsPublicContentUnlocked(publicContentRow); - - if (rowRef.TryGetValue(out var recipeRow)) - return this.IsRecipeUnlocked(recipeRow); - - if (rowRef.TryGetValue(out var secretRecipeBookRow)) - return this.IsSecretRecipeBookUnlocked(secretRecipeBookRow); - - if (rowRef.TryGetValue(out var traitRow)) - return this.IsTraitUnlocked(traitRow); - - if (rowRef.TryGetValue(out var tripleTriadCardRow)) - return this.IsTripleTriadCardUnlocked(tripleTriadCardRow); - - return false; - } - - /// - public bool IsUnlockLinkUnlocked(ushort unlockLink) - { - if (!this.IsLoaded) - return false; - - if (unlockLink == 0) - return false; - - return UIState.Instance()->IsUnlockLinkUnlocked(unlockLink); - } - - /// - public bool IsUnlockLinkUnlocked(uint unlockLink) - { - if (!this.IsLoaded) - return false; - - if (unlockLink == 0) - return false; - - return UIState.Instance()->IsUnlockLinkUnlockedOrQuestCompleted(unlockLink); - } - - private void OnLogin() - { - this.Update(); - } - - private void OnLogout(int type, int code) - { - this.cachedUnlockedRowIds.Clear(); - } - - private void OnAgentUpdate(AgentUpdateFlag agentUpdateFlag) - { - if (agentUpdateFlag.HasFlag(AgentUpdateFlag.UnlocksUpdate)) - this.Update(); - } - - private void Update() - { - if (!this.IsLoaded) - return; - - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - this.UpdateUnlocksForSheet(); - - // Not implemented: - // - DescriptionPage: quite complex - // - QuestAcceptAdditionCondition: ignored - - // For some other day: - // - FishingSpot - // - Spearfishing - // - Adventure (Sightseeing) - // - MinerFolkloreTome - // - BotanistFolkloreTome - // - FishingFolkloreTome - // - VVD or is that unlocked via quest? - // - VVDNotebookContents? - // - FramersKit (is that just an Item?) - // - ... more? - - // Subrow sheets, which are incompatible with the current Unlock event, since RowRef doesn't carry the SubrowId: - // - EmjCostume - - // Probably not happening, because it requires fetching data from server: - // - Achievements - // - Titles - // - Bozjan Field Notes - // - Support/Phantom Jobs, which require to be in Occult Crescent, because it checks the jobs level for != 0 - } - - private void UpdateUnlocksForSheet() where T : struct, IExcelRow - { - var unlockedRowIds = this.cachedUnlockedRowIds.GetOrAdd(typeof(T), _ => []); - - foreach (var row in this.dataManager.GetExcelSheet()) - { - if (unlockedRowIds.Contains(row.RowId)) - continue; - - var rowRef = LuminaUtils.CreateRef(row.RowId); - - if (!this.IsRowRefUnlocked(rowRef)) - continue; - - unlockedRowIds.Add(row.RowId); - - Log.Verbose($"Unlock detected: {typeof(T).Name}#{row.RowId}"); - - foreach (var action in Delegate.EnumerateInvocationList(this.Unlock)) - { - try - { - action((RowRef)rowRef); - } - catch (Exception ex) - { - Log.Error(ex, "Exception during raise of {handler}", action.Method); - } - } - } - } -} - -/// -/// Plugin-scoped version of a service. -/// -[PluginInterface] -[ServiceManager.ScopedService] -#pragma warning disable SA1015 -[ResolveVia] -#pragma warning restore SA1015 -internal class UnlockStatePluginScoped : IInternalDisposableService, IUnlockState -{ - [ServiceManager.ServiceDependency] - private readonly UnlockState unlockStateService = Service.Get(); - - /// - /// Initializes a new instance of the class. - /// - internal UnlockStatePluginScoped() - { - this.unlockStateService.Unlock += this.UnlockForward; - } - - /// - public event IUnlockState.UnlockDelegate? Unlock; - - /// - public bool IsActionUnlocked(ActionSheet row) => this.unlockStateService.IsActionUnlocked(row); - - /// - public bool IsAetherCurrentCompFlgSetUnlocked(AetherCurrentCompFlgSet row) => this.unlockStateService.IsAetherCurrentCompFlgSetUnlocked(row); - - /// - public bool IsAetherCurrentUnlocked(AetherCurrent row) => this.unlockStateService.IsAetherCurrentUnlocked(row); - - /// - public bool IsAozActionUnlocked(AozAction row) => this.unlockStateService.IsAozActionUnlocked(row); - - /// - public bool IsBannerBgUnlocked(BannerBg row) => this.unlockStateService.IsBannerBgUnlocked(row); - - /// - public bool IsBannerConditionUnlocked(BannerCondition row) => this.unlockStateService.IsBannerConditionUnlocked(row); - - /// - public bool IsBannerDecorationUnlocked(BannerDecoration row) => this.unlockStateService.IsBannerDecorationUnlocked(row); - - /// - public bool IsBannerFacialUnlocked(BannerFacial row) => this.unlockStateService.IsBannerFacialUnlocked(row); - - /// - public bool IsBannerFrameUnlocked(BannerFrame row) => this.unlockStateService.IsBannerFrameUnlocked(row); - - /// - public bool IsBannerTimelineUnlocked(BannerTimeline row) => this.unlockStateService.IsBannerTimelineUnlocked(row); - - /// - public bool IsBuddyActionUnlocked(BuddyAction row) => this.unlockStateService.IsBuddyActionUnlocked(row); - - /// - public bool IsBuddyEquipUnlocked(BuddyEquip row) => this.unlockStateService.IsBuddyEquipUnlocked(row); - - /// - public bool IsCharaMakeCustomizeUnlocked(CharaMakeCustomize row) => this.unlockStateService.IsCharaMakeCustomizeUnlocked(row); - - /// - public bool IsChocoboTaxiStandUnlocked(ChocoboTaxiStand row) => this.unlockStateService.IsChocoboTaxiStandUnlocked(row); - - /// - public bool IsCompanionUnlocked(Companion row) => this.unlockStateService.IsCompanionUnlocked(row); - - /// - public bool IsCraftActionUnlocked(CraftAction row) => this.unlockStateService.IsCraftActionUnlocked(row); - - /// - public bool IsCSBonusContentTypeUnlocked(CSBonusContentType row) => this.unlockStateService.IsCSBonusContentTypeUnlocked(row); - - /// - public bool IsEmoteUnlocked(Emote row) => this.unlockStateService.IsEmoteUnlocked(row); - - /// - public bool IsEmjVoiceNpcUnlocked(EmjVoiceNpc row) => this.unlockStateService.IsEmjVoiceNpcUnlocked(row); - - /// - public bool IsEmjCostumeUnlocked(EmjCostume row) => this.unlockStateService.IsEmjCostumeUnlocked(row); - - /// - public bool IsGeneralActionUnlocked(GeneralAction row) => this.unlockStateService.IsGeneralActionUnlocked(row); - - /// - public bool IsGlassesUnlocked(Glasses row) => this.unlockStateService.IsGlassesUnlocked(row); - - /// - public bool IsHowToUnlocked(HowTo row) => this.unlockStateService.IsHowToUnlocked(row); - - /// - public bool IsInstanceContentUnlocked(InstanceContentSheet row) => this.unlockStateService.IsInstanceContentUnlocked(row); - - /// - public bool IsItemUnlockable(Item row) => this.unlockStateService.IsItemUnlockable(row); - - /// - public bool IsItemUnlocked(Item row) => this.unlockStateService.IsItemUnlocked(row); - - /// - public bool IsMcGuffinUnlocked(McGuffin row) => this.unlockStateService.IsMcGuffinUnlocked(row); - - /// - public bool IsMJILandmarkUnlocked(MJILandmark row) => this.unlockStateService.IsMJILandmarkUnlocked(row); - - /// - public bool IsMKDLoreUnlocked(MKDLore row) => this.unlockStateService.IsMKDLoreUnlocked(row); - - /// - public bool IsMountUnlocked(Mount row) => this.unlockStateService.IsMountUnlocked(row); - - /// - public bool IsNotebookDivisionUnlocked(NotebookDivision row) => this.unlockStateService.IsNotebookDivisionUnlocked(row); - - /// - public bool IsOrchestrionUnlocked(Orchestrion row) => this.unlockStateService.IsOrchestrionUnlocked(row); - - /// - public bool IsOrnamentUnlocked(Ornament row) => this.unlockStateService.IsOrnamentUnlocked(row); - - /// - public bool IsPerformUnlocked(Perform row) => this.unlockStateService.IsPerformUnlocked(row); - - /// - public bool IsPublicContentUnlocked(PublicContentSheet row) => this.unlockStateService.IsPublicContentUnlocked(row); - - /// - public bool IsRecipeUnlocked(Recipe row) => this.unlockStateService.IsRecipeUnlocked(row); - - /// - public bool IsRowRefUnlocked(RowRef rowRef) => this.unlockStateService.IsRowRefUnlocked(rowRef); - - /// - public bool IsRowRefUnlocked(RowRef rowRef) where T : struct, IExcelRow => this.unlockStateService.IsRowRefUnlocked(rowRef); - - /// - public bool IsSecretRecipeBookUnlocked(SecretRecipeBook row) => this.unlockStateService.IsSecretRecipeBookUnlocked(row); - - /// - public bool IsTraitUnlocked(Trait row) => this.unlockStateService.IsTraitUnlocked(row); - - /// - public bool IsTripleTriadCardUnlocked(TripleTriadCard row) => this.unlockStateService.IsTripleTriadCardUnlocked(row); - - /// - public bool IsUnlockLinkUnlocked(uint unlockLink) => this.unlockStateService.IsUnlockLinkUnlocked(unlockLink); - - /// - public bool IsUnlockLinkUnlocked(ushort unlockLink) => this.unlockStateService.IsUnlockLinkUnlocked(unlockLink); - - /// - void IInternalDisposableService.DisposeService() - { - this.unlockStateService.Unlock -= this.UnlockForward; - } - - private void UnlockForward(RowRef rowRef) => this.Unlock?.Invoke(rowRef); -} diff --git a/Dalamud/Plugin/Services/IUnlockState.cs b/Dalamud/Plugin/Services/IUnlockState.cs deleted file mode 100644 index 00f2df190..000000000 --- a/Dalamud/Plugin/Services/IUnlockState.cs +++ /dev/null @@ -1,328 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -using Lumina.Excel; -using Lumina.Excel.Sheets; - -namespace Dalamud.Plugin.Services; - -#pragma warning disable SA1400 // Access modifier should be declared: Interface members are public by default - -/// -/// Interface for determining unlock state of various content in the game. -/// -[Experimental("UnlockState")] -public interface IUnlockState -{ - /// - /// A delegate type used for the event. - /// - /// A RowRef of the unlocked thing. - delegate void UnlockDelegate(RowRef rowRef); - - /// - /// Event triggered when something was unlocked. - /// - event UnlockDelegate? Unlock; - - /// - /// Determines whether the specified Action is unlocked. - /// - /// The Action row to check. - /// if unlocked; otherwise, . - bool IsActionUnlocked(Lumina.Excel.Sheets.Action row); - - /// - /// Determines whether the specified AetherCurrentCompFlgSet is unlocked. - /// - /// The AetherCurrentCompFlgSet row to check. - /// if unlocked; otherwise, . - bool IsAetherCurrentCompFlgSetUnlocked(AetherCurrentCompFlgSet row); - - /// - /// Determines whether the specified AetherCurrent is unlocked. - /// - /// The AetherCurrent row to check. - /// if unlocked; otherwise, . - bool IsAetherCurrentUnlocked(AetherCurrent row); - - /// - /// Determines whether the specified AozAction (Blue Mage Action) is unlocked. - /// - /// The AozAction row to check. - /// if unlocked; otherwise, . - bool IsAozActionUnlocked(AozAction row); - - /// - /// Determines whether the specified BannerBg (Portrait Backgrounds) is unlocked. - /// - /// The BannerBg row to check. - /// if unlocked; otherwise, . - bool IsBannerBgUnlocked(BannerBg row); - - /// - /// Determines whether the specified BannerCondition is unlocked. - /// - /// The BannerCondition row to check. - /// if unlocked; otherwise, . - bool IsBannerConditionUnlocked(BannerCondition row); - - /// - /// Determines whether the specified BannerDecoration (Portrait Accents) is unlocked. - /// - /// The BannerDecoration row to check. - /// if unlocked; otherwise, . - bool IsBannerDecorationUnlocked(BannerDecoration row); - - /// - /// Determines whether the specified BannerFacial (Portrait Expressions) is unlocked. - /// - /// The BannerFacial row to check. - /// if unlocked; otherwise, . - bool IsBannerFacialUnlocked(BannerFacial row); - - /// - /// Determines whether the specified BannerFrame (Portrait Frames) is unlocked. - /// - /// The BannerFrame row to check. - /// if unlocked; otherwise, . - bool IsBannerFrameUnlocked(BannerFrame row); - - /// - /// Determines whether the specified BannerTimeline (Portrait Poses) is unlocked. - /// - /// The BannerTimeline row to check. - /// if unlocked; otherwise, . - bool IsBannerTimelineUnlocked(BannerTimeline row); - - /// - /// Determines whether the specified BuddyAction (Action of the players Chocobo Companion) is unlocked. - /// - /// The BuddyAction row to check. - /// if unlocked; otherwise, . - bool IsBuddyActionUnlocked(BuddyAction row); - - /// - /// Determines whether the specified BuddyEquip (Equipment of the players Chocobo Companion) is unlocked. - /// - /// The BuddyEquip row to check. - /// if unlocked; otherwise, . - bool IsBuddyEquipUnlocked(BuddyEquip row); - - /// - /// Determines whether the specified CharaMakeCustomize (Hairstyles and Face Paint patterns) is unlocked. - /// - /// The CharaMakeCustomize row to check. - /// if unlocked; otherwise, . - bool IsCharaMakeCustomizeUnlocked(CharaMakeCustomize row); - - /// - /// Determines whether the specified ChocoboTaxiStand (Chocobokeeps of the Chocobo Porter service) is unlocked. - /// - /// The ChocoboTaxiStand row to check. - /// if unlocked; otherwise, . - bool IsChocoboTaxiStandUnlocked(ChocoboTaxiStand row); - - /// - /// Determines whether the specified Companion (Minions) is unlocked. - /// - /// The Companion row to check. - /// if unlocked; otherwise, . - bool IsCompanionUnlocked(Companion row); - - /// - /// Determines whether the specified CraftAction is unlocked. - /// - /// The CraftAction row to check. - /// if unlocked; otherwise, . - bool IsCraftActionUnlocked(CraftAction row); - - /// - /// Determines whether the specified CSBonusContentType is unlocked. - /// - /// The CSBonusContentType row to check. - /// if unlocked; otherwise, . - bool IsCSBonusContentTypeUnlocked(CSBonusContentType row); - - /// - /// Determines whether the specified Emote is unlocked. - /// - /// The Emote row to check. - /// if unlocked; otherwise, . - bool IsEmoteUnlocked(Emote row); - - /// - /// Determines whether the specified EmjVoiceNpc (Doman Mahjong Characters) is unlocked. - /// - /// The EmjVoiceNpc row to check. - /// if unlocked; otherwise, . - bool IsEmjVoiceNpcUnlocked(EmjVoiceNpc row); - - /// - /// Determines whether the specified EmjCostume (Doman Mahjong Character Costume) is unlocked. - /// - /// The EmjCostume row to check. - /// if unlocked; otherwise, . - bool IsEmjCostumeUnlocked(EmjCostume row); - - /// - /// Determines whether the specified GeneralAction is unlocked. - /// - /// The GeneralAction row to check. - /// if unlocked; otherwise, . - bool IsGeneralActionUnlocked(GeneralAction row); - - /// - /// Determines whether the specified Glasses is unlocked. - /// - /// The Glasses row to check. - /// if unlocked; otherwise, . - bool IsGlassesUnlocked(Glasses row); - - /// - /// Determines whether the specified HowTo is unlocked. - /// - /// The HowTo row to check. - /// if unlocked; otherwise, . - bool IsHowToUnlocked(HowTo row); - - /// - /// Determines whether the specified InstanceContent is unlocked. - /// - /// The InstanceContent row to check. - /// if unlocked; otherwise, . - bool IsInstanceContentUnlocked(InstanceContent row); - - /// - /// Determines whether the specified Item is considered unlockable. - /// - /// The Item row to check. - /// if unlockable; otherwise, . - bool IsItemUnlockable(Item row); - - /// - /// Determines whether the specified Item is unlocked. - /// - /// The Item row to check. - /// if unlocked; otherwise, . - bool IsItemUnlocked(Item row); - - /// - /// Determines whether the specified McGuffin is unlocked. - /// - /// The McGuffin row to check. - /// if unlocked; otherwise, . - bool IsMcGuffinUnlocked(McGuffin row); - - /// - /// Determines whether the specified MJILandmark (Island Sanctuary landmark) is unlocked. - /// - /// The MJILandmark row to check. - /// if unlocked; otherwise, . - bool IsMJILandmarkUnlocked(MJILandmark row); - - /// - /// Determines whether the specified MKDLore (Occult Record) is unlocked. - /// - /// The MKDLore row to check. - /// if unlocked; otherwise, . - bool IsMKDLoreUnlocked(MKDLore row); - - /// - /// Determines whether the specified Mount is unlocked. - /// - /// The Mount row to check. - /// if unlocked; otherwise, . - bool IsMountUnlocked(Mount row); - - /// - /// Determines whether the specified NotebookDivision (Categories in Crafting/Gathering Log) is unlocked. - /// - /// The NotebookDivision row to check. - /// if unlocked; otherwise, . - bool IsNotebookDivisionUnlocked(NotebookDivision row); - - /// - /// Determines whether the specified Orchestrion roll is unlocked. - /// - /// The Orchestrion row to check. - /// if unlocked; otherwise, . - bool IsOrchestrionUnlocked(Orchestrion row); - - /// - /// Determines whether the specified Ornament (Fashion Accessories) is unlocked. - /// - /// The Ornament row to check. - /// if unlocked; otherwise, . - bool IsOrnamentUnlocked(Ornament row); - - /// - /// Determines whether the specified Perform (Performance Instruments) is unlocked. - /// - /// The Perform row to check. - /// if unlocked; otherwise, . - bool IsPerformUnlocked(Perform row); - - /// - /// Determines whether the specified PublicContent is unlocked. - /// - /// The PublicContent row to check. - /// if unlocked; otherwise, . - bool IsPublicContentUnlocked(PublicContent row); - - /// - /// Determines whether the specified Recipe is unlocked. - /// - /// The Recipe row to check. - /// if unlocked; otherwise, . - bool IsRecipeUnlocked(Recipe row); - - /// - /// Determines whether the underlying RowRef type is unlocked. - /// - /// The RowRef to check. - /// if unlocked; otherwise, . - bool IsRowRefUnlocked(RowRef rowRef); - - /// - /// Determines whether the underlying RowRef type is unlocked. - /// - /// The type of the Excel row. - /// The RowRef to check. - /// if unlocked; otherwise, . - bool IsRowRefUnlocked(RowRef rowRef) where T : struct, IExcelRow; - - /// - /// Determines whether the specified SecretRecipeBook (Master Recipe Books) is unlocked. - /// - /// The SecretRecipeBook row to check. - /// if unlocked; otherwise, . - bool IsSecretRecipeBookUnlocked(SecretRecipeBook row); - - /// - /// Determines whether the specified Trait is unlocked. - /// - /// The Trait row to check. - /// if unlocked; otherwise, . - bool IsTraitUnlocked(Trait row); - - /// - /// Determines whether the specified TripleTriadCard is unlocked. - /// - /// The TripleTriadCard row to check. - /// if unlocked; otherwise, . - bool IsTripleTriadCardUnlocked(TripleTriadCard row); - - /// - /// Determines whether the specified unlock link is unlocked or quest is completed. - /// - /// The unlock link id or quest id (quest ids in this case are over 65536). - /// if unlocked; otherwise, . - bool IsUnlockLinkUnlocked(uint unlockLink); - - /// - /// Determines whether the specified unlock link is unlocked. - /// - /// The unlock link id. - /// if unlocked; otherwise, . - bool IsUnlockLinkUnlocked(ushort unlockLink); -} diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index 57f0da19c..0afa6b672 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit 57f0da19c95146b88e487260a94a29e6ef359b40 +Subproject commit 0afa6b67288e5e667da74c1d3ad582e6c964644c