diff --git a/JotunnLib/Entities/CustomRoom.cs b/JotunnLib/Entities/CustomRoom.cs index a8c553947..e6f837a61 100644 --- a/JotunnLib/Entities/CustomRoom.cs +++ b/JotunnLib/Entities/CustomRoom.cs @@ -38,6 +38,12 @@ public class CustomRoom : CustomEntity /// public string ThemeName { get; set; } + /// + /// Indicator if room is added from SoftReferenceableAssets.
+ /// Used to delay mocking prefabs until DungeonGenerator loads the room. + ///
+ public bool SoftReference { get; set; } + /// /// Associated holding data used during generation. /// @@ -116,7 +122,44 @@ public CustomRoom(GameObject prefab, bool fixReference, RoomConfig roomConfig) : m_enabled = Room.m_enabled, m_theme = GetRoomTheme(ThemeName) }; - } + } + + /// + /// Custom room from a SoftReference prefab with a attached. Using SoftReference system.
+ /// The prefab is not loaded until the DungeonGenerator needs it during generation. + ///
+ /// A to the room prefab registered in a SoftRef manifest. + /// If true references for objects get resolved at runtime by Jötunn. + /// The config for this custom room. + public CustomRoom(SoftReference softReferencePrefab, bool fixReference, RoomConfig roomConfig) : base(Assembly.GetCallingAssembly()) + { + if (!softReferencePrefab.IsValid) + { + Logger.LogError($"SoftReference invalid for room prefab: {softReferencePrefab.Name}"); + return; + } + + AssetManager.Instance.ResolveMocksOnLoad(softReferencePrefab, DungeonManager.Instance.DungeonRoomContainer.transform, OnRoomResolve); + + Name = softReferencePrefab.Name; + ThemeName = roomConfig.ThemeName; + FixReference = fixReference; + SoftReference = true; + + RoomData = new DungeonDB.RoomData() + { + m_prefab = softReferencePrefab, + m_loadedRoom = null, + m_enabled = roomConfig.Enabled ?? true, + m_theme = GetRoomTheme(ThemeName) + }; + } + + private void OnRoomResolve(GameObject gameObject) + { + // Mock references resolved by MockResolutionContext. + // Room component lazy-loaded by vanilla's RoomData.RoomInPrefab. + } /// /// Helper method to determine if a prefab with a given name is a custom room created with Jötunn. diff --git a/JotunnLib/Managers/DungeonManager.cs b/JotunnLib/Managers/DungeonManager.cs index d425996e8..257ab1da5 100644 --- a/JotunnLib/Managers/DungeonManager.cs +++ b/JotunnLib/Managers/DungeonManager.cs @@ -46,7 +46,7 @@ public class DungeonManager : IManager /// /// Container for Jötunn's DungeonRooms in the DontDestroyOnLoad scene. /// - private GameObject DungeonRoomContainer; + internal GameObject DungeonRoomContainer; /// /// Hide .ctor @@ -127,8 +127,12 @@ public bool AddCustomRoom(CustomRoom customRoom) return false; } - customRoom.Prefab.transform.SetParent(DungeonRoomContainer.transform); - customRoom.Prefab.SetActive(true); + if (!customRoom.SoftReference) + { + customRoom.Prefab.transform.SetParent(DungeonRoomContainer.transform); + customRoom.Prefab.SetActive(true); + } + Rooms.Add(customRoom.Name, customRoom); return true; } @@ -230,7 +234,7 @@ private void GenerateHashes() foreach (CustomRoom room in Rooms.Values) { - int stableHashCode = room.Prefab.name.GetStableHashCode(); + int stableHashCode = room.Name.GetStableHashCode(); if (hashToName.ContainsKey(stableHashCode)) { Logger.LogWarning($"Room {room.Name} is already registered with hash {stableHashCode}"); @@ -272,7 +276,7 @@ private void OnDungeonDBStarted() try { Logger.LogDebug($"Adding custom room {customRoom.Name} with {customRoom.ThemeName} theme"); - if (customRoom.FixReference) + if (customRoom.FixReference && !customRoom.SoftReference) { customRoom.Prefab.FixReferences(true); customRoom.FixReference = false; @@ -314,7 +318,7 @@ private void OnDungeonGeneratorSetupAvailableRooms(DungeonGenerator self) Logger.LogDebug($"This dungeon generator has a custom theme = {proxy.m_themeName}, adding available rooms"); var selectedRooms = Rooms.Values - .Where(r => r.Room.m_enabled) + .Where(r => r.RoomData.m_enabled) .Where(r => r.ThemeName == proxy.m_themeName); foreach (var room in selectedRooms) @@ -329,7 +333,7 @@ private void OnDungeonGeneratorSetupAvailableRooms(DungeonGenerator self) Logger.LogDebug($"Adding additional rooms of type {self.m_themes} to available rooms"); var selectedRooms = Rooms.Values - .Where(r => r.Room.m_enabled) + .Where(r => r.RoomData.m_enabled) .Where(r => Enum.TryParse(r.ThemeName, false, out Room.Theme theme) ? theme != Room.Theme.None && self.m_themes.HasFlag(theme) : false); foreach (var room in selectedRooms)