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)