From 57578e1106e5ba3a14cf3e07ac042dabcc14fb89 Mon Sep 17 00:00:00 2001 From: drcarademono <73616371+drcarademono@users.noreply.github.com> Date: Sun, 12 Jan 2025 10:59:09 -0800 Subject: [PATCH 1/7] Change AssignNextIndex to AssignNewIndex AssignNewIndex assigns RMB blocks static BlockIndices from the RMB.json file rather than assigning BlockIndices dynamically --- .../AssetInjection/WorldDataReplacement.cs | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs index 0db917568d..ddf38abe97 100644 --- a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs +++ b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs @@ -486,7 +486,7 @@ private static bool AssignBlockIndices(ref DFLocation dfLocation) // RMB blocks foreach (string blockName in dfLocation.Exterior.ExteriorData.BlockNames) if (blocksFile.GetBlockIndex(blockName) == -1) - AssignNextIndex(blockName); + AssignNewIndex(blockName); // RDB blocks if (dfLocation.Dungeon.Blocks != null) @@ -495,7 +495,7 @@ private static bool AssignBlockIndices(ref DFLocation dfLocation) { string blockName = dungeonBlock.BlockName; if (blocksFile.GetBlockIndex(blockName) == -1) - AssignNextIndex(blockName); + AssignNewIndex(blockName); } } return true; @@ -504,12 +504,40 @@ private static bool AssignBlockIndices(ref DFLocation dfLocation) return false; } - private static void AssignNextIndex(string blockName) + public static void AssignNewIndex(string blockName) { - newBlockNames[nextBlockIndex] = blockName; - newBlockIndices[blockName] = nextBlockIndex; - Debug.LogFormat("Found a new DFBlock: {0}, (assigned index: {1})", blockName, nextBlockIndex); - nextBlockIndex++; + string fileName = GetDFBlockReplacementFilename(blockName, WorldDataVariants.NoVariant); + + int jsonBlockIndex; + DFBlock? dfBlock = null; // Make blockData nullable + TextAsset blockReplacementJsonAsset; + + // Seek from loose files + if (File.Exists(Path.Combine(worldDataPath, fileName))) + { + string blockReplacementJson = File.ReadAllText(Path.Combine(worldDataPath, fileName)); + dfBlock = (DFBlock)SaveLoadManager.Deserialize(typeof(DFBlock), blockReplacementJson); + } + // Seek from mods + else if (ModManager.Instance != null && ModManager.Instance.TryGetAsset(fileName, false, out blockReplacementJsonAsset)) + { + dfBlock = (DFBlock)SaveLoadManager.Deserialize(typeof(DFBlock), blockReplacementJsonAsset.text); + } + + // Ensure blockData was successfully assigned + if (!dfBlock.HasValue) // Check if blockData has a value + { + Debug.LogError($"Failed to load block data for blockName: {blockName}"); + throw new System.Exception($"Block {blockName} does not have a valid Index in its JSON file."); + } + + // Check for the "Index" field and assign its value + jsonBlockIndex = dfBlock.Value.Index; // Use .Value to access the DFBlock inside the nullable + + // Add to cache + newBlockNames[jsonBlockIndex] = blockName; + newBlockIndices[blockName] = jsonBlockIndex; + Debug.LogFormat("Found a new DFBlock: {0}, (assigned index: {1})", blockName, jsonBlockIndex); } #endregion From 16a8a694bc119cf8206f406a7add897d8a2209b1 Mon Sep 17 00:00:00 2001 From: drcarademono <73616371+drcarademono@users.noreply.github.com> Date: Wed, 5 Feb 2025 11:49:10 -0800 Subject: [PATCH 2/7] Update WorldDataReplacement.cs --- .../AssetInjection/WorldDataReplacement.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs index ddf38abe97..07813b6694 100644 --- a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs +++ b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs @@ -525,14 +525,21 @@ public static void AssignNewIndex(string blockName) } // Ensure blockData was successfully assigned - if (!dfBlock.HasValue) // Check if blockData has a value + if (!dfBlock.HasValue) { Debug.LogError($"Failed to load block data for blockName: {blockName}"); throw new System.Exception($"Block {blockName} does not have a valid Index in its JSON file."); } // Check for the "Index" field and assign its value - jsonBlockIndex = dfBlock.Value.Index; // Use .Value to access the DFBlock inside the nullable + jsonBlockIndex = dfBlock.Value.Index; + + // If jsonBlockIndex is invalid (less than or equal to blocksFile.BsaFile.Count), use fallback method + if (jsonBlockIndex <= blocksFile.BsaFile.Count) + { + AssignNextIndex(blockName); + return; + } // Add to cache newBlockNames[jsonBlockIndex] = blockName; @@ -540,6 +547,14 @@ public static void AssignNewIndex(string blockName) Debug.LogFormat("Found a new DFBlock: {0}, (assigned index: {1})", blockName, jsonBlockIndex); } + private static void AssignNextIndex(string blockName) + { + newBlockNames[nextBlockIndex] = blockName; + newBlockIndices[blockName] = nextBlockIndex; + Debug.LogFormat("Found a new DFBlock: {0}, (assigned index: {1})", blockName, nextBlockIndex); + nextBlockIndex++; + } + #endregion } } From c72f28132c44c3f7ece89d9720bbc1255f0be18b Mon Sep 17 00:00:00 2001 From: drcarademono <73616371+drcarademono@users.noreply.github.com> Date: Fri, 14 Mar 2025 15:57:34 -0700 Subject: [PATCH 3/7] Fix out-of-scope declaration error --- Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs index 07813b6694..5db50a8a0b 100644 --- a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs +++ b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs @@ -534,8 +534,8 @@ public static void AssignNewIndex(string blockName) // Check for the "Index" field and assign its value jsonBlockIndex = dfBlock.Value.Index; - // If jsonBlockIndex is invalid (less than or equal to blocksFile.BsaFile.Count), use fallback method - if (jsonBlockIndex <= blocksFile.BsaFile.Count) + // If jsonBlockIndex is invalid (less than or equal to nextBlockIndex), use fallback method + if (jsonBlockIndex <= nextBlockIndex) { AssignNextIndex(blockName); return; From 27a0ee3b40c53de445b2f6824249f54f4062c259 Mon Sep 17 00:00:00 2001 From: drcarademono <73616371+drcarademono@users.noreply.github.com> Date: Fri, 23 May 2025 08:35:53 -0700 Subject: [PATCH 4/7] Cache modded DFBlock on deserialization --- .../Utility/AssetInjection/WorldDataReplacement.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs index 5db50a8a0b..f5564ef712 100644 --- a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs +++ b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs @@ -531,6 +531,9 @@ public static void AssignNewIndex(string blockName) throw new System.Exception($"Block {blockName} does not have a valid Index in its JSON file."); } + // Grab the variant key + string blockKey = blockName + WorldDataVariants.NoVariant; + // Check for the "Index" field and assign its value jsonBlockIndex = dfBlock.Value.Index; @@ -538,6 +541,11 @@ public static void AssignNewIndex(string blockName) if (jsonBlockIndex <= nextBlockIndex) { AssignNextIndex(blockName); + + // Cache the full DFBlock + if (!blocks.ContainsKey(blockKey)) + blocks[blockKey] = dfBlock.Value; + return; } @@ -545,6 +553,10 @@ public static void AssignNewIndex(string blockName) newBlockNames[jsonBlockIndex] = blockName; newBlockIndices[blockName] = jsonBlockIndex; Debug.LogFormat("Found a new DFBlock: {0}, (assigned index: {1})", blockName, jsonBlockIndex); + + // Cache the full DFBlock + if (!blocks.ContainsKey(blockKey)) + blocks[blockKey] = dfBlock.Value; } private static void AssignNextIndex(string blockName) From b4cfb0029e62ccdcec65699c52d49991072aab95 Mon Sep 17 00:00:00 2001 From: drcarademono <73616371+drcarademono@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:37:01 -0700 Subject: [PATCH 5/7] Introduce WorldDataReplacementException and catch InvalidCastException during JSON deserialize --- .../AssetInjection/WorldDataReplacement.cs | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs index f5564ef712..cc272c4ae8 100644 --- a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs +++ b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs @@ -17,6 +17,15 @@ namespace DaggerfallWorkshop.Utility.AssetInjection { + /// + /// Thrown when WorldDataReplacement can’t load or parse the expected JSON for a block. + /// + public class WorldDataReplacementException : System.Exception + { + public WorldDataReplacementException(string message) : base(message) { } + public WorldDataReplacementException(string message, System.Exception inner) : base(message, inner) { } + } + public struct BlockRecordKey { public int blockIndex; @@ -516,19 +525,41 @@ public static void AssignNewIndex(string blockName) if (File.Exists(Path.Combine(worldDataPath, fileName))) { string blockReplacementJson = File.ReadAllText(Path.Combine(worldDataPath, fileName)); - dfBlock = (DFBlock)SaveLoadManager.Deserialize(typeof(DFBlock), blockReplacementJson); + try + { + dfBlock = (DFBlock)SaveLoadManager.Deserialize(typeof(DFBlock), blockReplacementJson); + } + catch (System.InvalidCastException e) + { + Debug.LogError($"Invalid JSON format for block '{blockName}': {e.Message}"); + throw new WorldDataReplacementException( + $"Block '{blockName}' JSON could not be cast to DFBlock.", e + ); + } } // Seek from mods else if (ModManager.Instance != null && ModManager.Instance.TryGetAsset(fileName, false, out blockReplacementJsonAsset)) { - dfBlock = (DFBlock)SaveLoadManager.Deserialize(typeof(DFBlock), blockReplacementJsonAsset.text); + try + { + dfBlock = (DFBlock)SaveLoadManager.Deserialize(typeof(DFBlock), blockReplacementJsonAsset.text); + } + catch (System.InvalidCastException e) + { + Debug.LogError($"Invalid JSON format for block '{blockName}': {e.Message}"); + throw new WorldDataReplacementException( + $"Block '{blockName}' JSON could not be cast to DFBlock.", e + ); + } } // Ensure blockData was successfully assigned if (!dfBlock.HasValue) { Debug.LogError($"Failed to load block data for blockName: {blockName}"); - throw new System.Exception($"Block {blockName} does not have a valid Index in its JSON file."); + throw new WorldDataReplacementException( + $"Block '{blockName}' does not have a valid Index in its JSON file." + ); } // Grab the variant key From 6b98dbde25abfab28eee1896cbc9b9576d9c3eb6 Mon Sep 17 00:00:00 2001 From: drcarademono <73616371+drcarademono@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:16:30 -0700 Subject: [PATCH 6/7] Update internal Index value for cached DFBlocks, additional fallback --- .../AssetInjection/WorldDataReplacement.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs index cc272c4ae8..d4c157d46f 100644 --- a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs +++ b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs @@ -571,18 +571,32 @@ public static void AssignNewIndex(string blockName) // If jsonBlockIndex is invalid (less than or equal to nextBlockIndex), use fallback method if (jsonBlockIndex <= nextBlockIndex) { + int newIndex = nextBlockIndex; + AssignNextIndex(blockName); - // Cache the full DFBlock if (!blocks.ContainsKey(blockKey)) - blocks[blockKey] = dfBlock.Value; + { + // Update DFBlock index + DFBlock block = dfBlock.Value; + block.Index = newIndex; + blocks[blockKey] = block; + } return; } - // Add to cache - newBlockNames[jsonBlockIndex] = blockName; - newBlockIndices[blockName] = jsonBlockIndex; + // Add to cache, but if that jsonBlockIndex or blockName is already taken, fallback again + if (newBlockNames.ContainsKey(jsonBlockIndex) || newBlockIndices.ContainsKey(blockName)) + { + AssignNextIndex(blockName); + } + else + { + newBlockNames[jsonBlockIndex] = blockName; + newBlockIndices[blockName] = jsonBlockIndex; + } + Debug.LogFormat("Found a new DFBlock: {0}, (assigned index: {1})", blockName, jsonBlockIndex); // Cache the full DFBlock From 2af7e31f98bb598c1b1574fa570237456924cf56 Mon Sep 17 00:00:00 2001 From: drcarademono <73616371+drcarademono@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:43:02 -0700 Subject: [PATCH 7/7] Moved fallback up --- .../AssetInjection/WorldDataReplacement.cs | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs index d4c157d46f..f452dc8683 100644 --- a/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs +++ b/Assets/Scripts/Utility/AssetInjection/WorldDataReplacement.cs @@ -568,8 +568,10 @@ public static void AssignNewIndex(string blockName) // Check for the "Index" field and assign its value jsonBlockIndex = dfBlock.Value.Index; - // If jsonBlockIndex is invalid (less than or equal to nextBlockIndex), use fallback method - if (jsonBlockIndex <= nextBlockIndex) + // If jsonBlockIndex is invalid (less than or equal to nextBlockIndex) or index is already taken, use fallback method + if (jsonBlockIndex <= nextBlockIndex + || newBlockNames.ContainsKey(jsonBlockIndex) + || newBlockIndices.ContainsKey(blockName)) { int newIndex = nextBlockIndex; @@ -586,17 +588,9 @@ public static void AssignNewIndex(string blockName) return; } - // Add to cache, but if that jsonBlockIndex or blockName is already taken, fallback again - if (newBlockNames.ContainsKey(jsonBlockIndex) || newBlockIndices.ContainsKey(blockName)) - { - AssignNextIndex(blockName); - } - else - { - newBlockNames[jsonBlockIndex] = blockName; - newBlockIndices[blockName] = jsonBlockIndex; - } - + // Add to cache + newBlockNames[jsonBlockIndex] = blockName; + newBlockIndices[blockName] = jsonBlockIndex; Debug.LogFormat("Found a new DFBlock: {0}, (assigned index: {1})", blockName, jsonBlockIndex); // Cache the full DFBlock