diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 209ed90de..9466cb083 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,8 +1,9 @@ name: Build Dalamud on: [push, pull_request, workflow_dispatch] +# Globally blocking because of git pushes in deploy step concurrency: - group: build_dalamud_${{ github.ref_name }} + group: build_dalamud_${{ github.repository_owner }} cancel-in-progress: false jobs: diff --git a/.github/workflows/rollup.yml b/.github/workflows/rollup.yml index f4e013258..8fe049ad7 100644 --- a/.github/workflows/rollup.yml +++ b/.github/workflows/rollup.yml @@ -1,8 +1,8 @@ name: Rollup changes to next version on: -# push: -# branches: -# - master + push: + branches: + - master workflow_dispatch: jobs: diff --git a/Dalamud/Game/UnlockState/ItemActionAction.cs b/Dalamud/Game/UnlockState/ItemActionType.cs similarity index 96% rename from Dalamud/Game/UnlockState/ItemActionAction.cs rename to Dalamud/Game/UnlockState/ItemActionType.cs index 0e86fcb67..8e3d79b84 100644 --- a/Dalamud/Game/UnlockState/ItemActionAction.cs +++ b/Dalamud/Game/UnlockState/ItemActionType.cs @@ -3,9 +3,9 @@ using Lumina.Excel.Sheets; namespace Dalamud.Game.UnlockState; /// -/// Enum for . +/// Enum for . /// -internal enum ItemActionAction : ushort +internal enum ItemActionType : ushort { /// /// No item action. diff --git a/Dalamud/Game/UnlockState/RecipeData.cs b/Dalamud/Game/UnlockState/RecipeData.cs index 7fa0d4b8f..c419ba4fd 100644 --- a/Dalamud/Game/UnlockState/RecipeData.cs +++ b/Dalamud/Game/UnlockState/RecipeData.cs @@ -158,23 +158,67 @@ internal unsafe class RecipeData : IInternalDisposableService { noteBookDivisionIndex++; - if (!noteBookDivisionRow.AllowedCraftTypes[craftType]) - continue; + // 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; - if (noteBookDivisionRow.RequiresSecretRecipeBookGroupUnlock) + // For future Lumina.Excel update, replace with: + // if (notebookDivisionRow.RequiresSecretRecipeBookGroupUnlock) + if (noteBookDivisionRow.Unknown1) { var secretRecipeBookUnlocked = false; - foreach (var secretRecipeBookGroup in noteBookDivisionRow.SecretRecipeBookGroups) + // For future Lumina.Excel update, iterate over notebookDivisionRow.SecretRecipeBookGroups + for (var i = 0; i < 2; i++) { - if (secretRecipeBookGroup.RowId == 0 || !secretRecipeBookGroup.IsValid) + // 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; - var bitIndex = secretRecipeBookGroup.Value.SecretRecipeBook[craftType].RowId; - if (PlayerState.Instance()->UnlockedSecretRecipeBooksBitArray.Get((int)bitIndex)) + 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; diff --git a/Dalamud/Game/UnlockState/UnlockState.cs b/Dalamud/Game/UnlockState/UnlockState.cs index cc70a524c..cd896ffb6 100644 --- a/Dalamud/Game/UnlockState/UnlockState.cs +++ b/Dalamud/Game/UnlockState/UnlockState.cs @@ -209,7 +209,7 @@ internal unsafe class UnlockState : IInternalDisposableService, IUnlockState /// public bool IsEmjVoiceNpcUnlocked(EmjVoiceNpc row) { - return this.IsUnlockLinkUnlocked(row.UnlockLink); + return this.IsUnlockLinkUnlocked(row.Unknown26); } /// @@ -217,7 +217,7 @@ internal unsafe class UnlockState : IInternalDisposableService, IUnlockState { return this.dataManager.GetExcelSheet().TryGetRow(row.RowId, out var emjVoiceNpcRow) && this.IsEmjVoiceNpcUnlocked(emjVoiceNpcRow) - && QuestManager.IsQuestComplete(row.UnlockQuest.RowId); + && QuestManager.IsQuestComplete(row.Unknown1); } /// @@ -264,47 +264,47 @@ internal unsafe class UnlockState : IInternalDisposableService, IUnlockState // 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 ((ItemActionAction)row.ItemAction.Value.Action.RowId) + switch ((ItemActionType)row.ItemAction.Value.Type) { - case ItemActionAction.Companion: + case ItemActionType.Companion: return UIState.Instance()->IsCompanionUnlocked(row.ItemAction.Value.Data[0]); - case ItemActionAction.BuddyEquip: + case ItemActionType.BuddyEquip: return UIState.Instance()->Buddy.CompanionInfo.IsBuddyEquipUnlocked(row.ItemAction.Value.Data[0]); - case ItemActionAction.Mount: + case ItemActionType.Mount: return PlayerState.Instance()->IsMountUnlocked(row.ItemAction.Value.Data[0]); - case ItemActionAction.SecretRecipeBook: + case ItemActionType.SecretRecipeBook: return PlayerState.Instance()->IsSecretRecipeBookUnlocked(row.ItemAction.Value.Data[0]); - case ItemActionAction.UnlockLink: - case ItemActionAction.OccultRecords: + case ItemActionType.UnlockLink: + case ItemActionType.OccultRecords: return UIState.Instance()->IsUnlockLinkUnlocked(row.ItemAction.Value.Data[0]); - case ItemActionAction.TripleTriadCard when row.AdditionalData.Is(): + case ItemActionType.TripleTriadCard when row.AdditionalData.Is(): return UIState.Instance()->IsTripleTriadCardUnlocked((ushort)row.AdditionalData.RowId); - case ItemActionAction.FolkloreTome: + case ItemActionType.FolkloreTome: return PlayerState.Instance()->IsFolkloreBookUnlocked(row.ItemAction.Value.Data[0]); - case ItemActionAction.OrchestrionRoll when row.AdditionalData.Is(): + case ItemActionType.OrchestrionRoll when row.AdditionalData.Is(): return PlayerState.Instance()->IsOrchestrionRollUnlocked(row.AdditionalData.RowId); - case ItemActionAction.FramersKit: + case ItemActionType.FramersKit: return PlayerState.Instance()->IsFramersKitUnlocked(row.AdditionalData.RowId); - case ItemActionAction.Ornament: + case ItemActionType.Ornament: return PlayerState.Instance()->IsOrnamentUnlocked(row.ItemAction.Value.Data[0]); - case ItemActionAction.Glasses: + case ItemActionType.Glasses: return PlayerState.Instance()->IsGlassesUnlocked((ushort)row.AdditionalData.RowId); - case ItemActionAction.SoulShards when PublicContentOccultCrescent.GetState() is var occultCrescentState && occultCrescentState != null: + 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 ItemActionAction.CompanySealVouchers: + case ItemActionType.CompanySealVouchers: return false; } @@ -327,7 +327,7 @@ internal unsafe class UnlockState : IInternalDisposableService, IUnlockState /// public bool IsMKDLoreUnlocked(MKDLore row) { - return this.IsUnlockLinkUnlocked(row.UnlockLink); + return this.IsUnlockLinkUnlocked(row.Unknown2); } /// @@ -414,20 +414,20 @@ internal unsafe class UnlockState : IInternalDisposableService, IUnlockState if (row.ItemAction.RowId == 0) return false; - return (ItemActionAction)row.ItemAction.Value.Action.RowId - is ItemActionAction.Companion - or ItemActionAction.BuddyEquip - or ItemActionAction.Mount - or ItemActionAction.SecretRecipeBook - or ItemActionAction.UnlockLink - or ItemActionAction.TripleTriadCard - or ItemActionAction.FolkloreTome - or ItemActionAction.OrchestrionRoll - or ItemActionAction.FramersKit - or ItemActionAction.Ornament - or ItemActionAction.Glasses - or ItemActionAction.OccultRecords - or ItemActionAction.SoulShards; + 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; } /// diff --git a/Directory.Packages.props b/Directory.Packages.props index 77a4035a4..06338efac 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -15,7 +15,7 @@ - + diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index 85e962dd9..305c1629e 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit 85e962dd959254c771bf9fa82832f4fbc7679a65 +Subproject commit 305c1629eed0b1cdca5efb102e37de93d592d155 diff --git a/lib/Lumina.Excel b/lib/Lumina.Excel index c74841abc..5d01489c3 160000 --- a/lib/Lumina.Excel +++ b/lib/Lumina.Excel @@ -1 +1 @@ -Subproject commit c74841abce0830ead4437ed2f560bceb6235a538 +Subproject commit 5d01489c34f33a3d645f49085d7fc0065a1ac801