diff --git a/LethalLevelLoader/LethalLevelLoader.csproj b/LethalLevelLoader/LethalLevelLoader.csproj index 33364f7..b05116b 100644 --- a/LethalLevelLoader/LethalLevelLoader.csproj +++ b/LethalLevelLoader/LethalLevelLoader.csproj @@ -91,17 +91,17 @@ - + - + - + diff --git a/LethalLevelLoader/Patches/DungeonManager.cs b/LethalLevelLoader/Patches/DungeonManager.cs index f4ddf6c..e0f6924 100644 --- a/LethalLevelLoader/Patches/DungeonManager.cs +++ b/LethalLevelLoader/Patches/DungeonManager.cs @@ -65,7 +65,7 @@ public static List GetValidExtendedDungeonFlows(E debugString += "Info For ExtendedLevel: " + extendedLevel.name + " | Planet Name: " + extendedLevel.NumberlessPlanetName + " | Content Tags: "; foreach (ContentTag tag in extendedLevel.ContentTags) debugString += tag.contentTagName + ", "; - debugString = debugString.Remove(debugString.LastIndexOf(", ")); + debugString = debugString.TrimEnd([',', ' ']); debugString += " | Route Price: " + extendedLevel.RoutePrice + " | Current Weather: " + extendedLevel.SelectableLevel.currentWeather.ToString(); debugString += "\n"; @@ -74,7 +74,7 @@ public static List GetValidExtendedDungeonFlows(E foreach (ExtendedDungeonFlowWithRarity extendedDungeonFlowWithRarity in potentialExtendedDungeonFlowsList) if (!viableDungeonFlows.Contains(extendedDungeonFlowWithRarity.extendedDungeonFlow)) debugString += extendedDungeonFlowWithRarity.extendedDungeonFlow.DungeonName + ", "; - debugString = debugString.Remove(debugString.LastIndexOf(", ")); + debugString = debugString.TrimEnd([',', ' ']); debugString += "\n"; returnExtendedDungeonFlowsList = returnExtendedDungeonFlowsList.OrderBy(e => e.rarity).Reverse().ToList(); @@ -82,7 +82,7 @@ public static List GetValidExtendedDungeonFlows(E debugString += "Viable ExtendedDungeonFlows: "; foreach (ExtendedDungeonFlowWithRarity extendedDungeonFlowWithRarity in returnExtendedDungeonFlowsList) debugString += extendedDungeonFlowWithRarity.extendedDungeonFlow.DungeonName + " (" + extendedDungeonFlowWithRarity.rarity + ")" + ", "; - debugString = debugString.Remove(debugString.LastIndexOf(", ")); + debugString = debugString.TrimEnd([',', ' ']); DebugHelper.Log(debugString + "\n", DebugType.User); } diff --git a/LethalLevelLoader/Tools/ConfigHelper.cs b/LethalLevelLoader/Tools/ConfigHelper.cs index daa8a59..6961784 100644 --- a/LethalLevelLoader/Tools/ConfigHelper.cs +++ b/LethalLevelLoader/Tools/ConfigHelper.cs @@ -33,7 +33,7 @@ public static List ConvertToStringWithRarityList(string newInp rarity = value; if (clampRarity != Vector2.zero) - Math.Clamp(rarity, Mathf.RoundToInt(clampRarity.x), Mathf.RoundToInt(clampRarity.y)); + rarity = Math.Clamp(rarity, Mathf.RoundToInt(clampRarity.x), Mathf.RoundToInt(clampRarity.y)); returnList.Add(new StringWithRarity(levelName, rarity)); } @@ -62,7 +62,7 @@ public static List ConvertToVector2WithRarityList(string newI rarity = value; if (clampRarity != Vector2.zero) - Math.Clamp(rarity, Mathf.RoundToInt(clampRarity.x), Mathf.RoundToInt(clampRarity.y)); + rarity = Math.Clamp(rarity, Mathf.RoundToInt(clampRarity.x), Mathf.RoundToInt(clampRarity.y)); returnList.Add(new Vector2WithRarity(new Vector2(x,y), rarity)); } @@ -74,8 +74,9 @@ public static List ConvertToSpawnableEnemyWithRarityLi List stringList = ConvertToStringWithRarityList(newInputString, clampRarity); List returnList = new List(); - foreach (EnemyType enemyType in OriginalContent.Enemies.Concat(PatchedContent.Enemies)) + foreach (ExtendedEnemyType extendedEnemyType in PatchedContent.ExtendedEnemyTypes) { + EnemyType enemyType = extendedEnemyType.EnemyType; foreach (StringWithRarity stringString in new List(stringList)) { if (enemyType.enemyName.ToLower().Contains(stringString.Name.ToLower())) @@ -90,8 +91,9 @@ public static List ConvertToSpawnableEnemyWithRarityLi } //Incase the user put in the real name (eg. Bracken) instead of the internal name (Flowerman) we go through the scannode texts which has the more updated name. - foreach (EnemyType enemyType in OriginalContent.Enemies.Concat(PatchedContent.Enemies)) + foreach (ExtendedEnemyType extendedEnemyType in PatchedContent.ExtendedEnemyTypes) { + EnemyType enemyType = extendedEnemyType.EnemyType; foreach (StringWithRarity stringString in new List(stringList)) { if (enemyType.enemyPrefab != null) @@ -119,8 +121,9 @@ public static List ConvertToSpawnableItemWithRarityList List stringList = ConvertToStringWithRarityList(newInputString, clampRarity); List returnList = new List(); - foreach (Item item in OriginalContent.Items.Concat(PatchedContent.Items)) + foreach (ExtendedItem extendedItem in PatchedContent.ExtendedItems) { + Item item = extendedItem.Item; foreach (StringWithRarity stringString in new List(stringList)) { if (SanitizeString(item.itemName).Contains(SanitizeString(stringString.Name)) || SanitizeString(stringString.Name).Contains(SanitizeString(item.itemName))) diff --git a/LethalLevelLoader/Tools/ContentRestore.cs b/LethalLevelLoader/Tools/ContentRestore.cs new file mode 100644 index 0000000..6198dc6 --- /dev/null +++ b/LethalLevelLoader/Tools/ContentRestore.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.Audio; +using UnityEngine.Rendering; +using Object = UnityEngine.Object; + +namespace LethalLevelLoader.Tools +{ + public abstract class ContentRestore + { + public abstract void Flush(); + } + public abstract class ContentRestore : ContentRestore + { + protected List restoredContentDestroyList = new List(); + + // List Of New Content, List Of Original Comparisons + public virtual void TryRestoreContents(List originalContents, ref List newContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int i = 0; i < newContents.Count; i++) + newContents[i] = TryRestoreContent(newContents[i], originalContents, debugAction, destroyOnRestore); + } + + // 1 New Content : List Of Orignal Comparisons + public virtual T TryRestoreContent(T newContent, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + if (newContent == null) return newContent; + + for (int i = 0; i < originalContents.Count; i++) + if (originalContents[i] != null && CompareContent(originalContents[i], newContent)) + return (RestoreContent(originalContents[i], newContent, debugAction, destroyOnRestore)); + + return (newContent); + } + + // 1 New Content : 1 Original Content Comparison + public virtual T TryRestoreContent(T originalContent, T newContent, bool debugAction = false, bool destroyOnReplace = true) + { + if (originalContent == null || newContent == null) return originalContent; + + if (CompareContent(originalContent, newContent)) + return (RestoreContent(originalContent, newContent, debugAction, destroyOnReplace)); + else + return (originalContent); + } + + public abstract bool CompareContent(T originalContent, T newContent); + + protected virtual T RestoreContent(T originalContent, T newContent, bool debugAction = false, bool destroyOnReplace = true) + { + if (originalContent != null && newContent != null) + { + if (debugAction == true && originalContent.ToString() != null) + DebugHelper.Log("Restoring " + originalContent.GetType().ToString() + ": Old Asset Name: " + originalContent + " , New Asset Name: ", DebugType.Developer); + + if (destroyOnReplace == true) + if (!restoredContentDestroyList.Contains(originalContent)) + restoredContentDestroyList.Add(originalContent); + } + else + DebugHelper.LogWarning("Asset Restoration Failed, Null Reference Found!", DebugType.Developer); + return (newContent); + } + } + + public class UnityContentRestore : ContentRestore where T : Object + { + public override bool CompareContent(T originalContent, T newContent) + { + if (originalContent.name != null && newContent.name != null) + return (originalContent.name == newContent.name); + else + return (false); + } + + public override void Flush() + { + for (int i = 0; i < restoredContentDestroyList.Count; i++) + Object.Destroy(restoredContentDestroyList[i]); + restoredContentDestroyList.Clear(); + } + } + + public class ItemRestore : UnityContentRestore + { + public void TryRestoreContents(List newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int i = 0; i < newContents.Count; i++) + newContents[i].spawnableItem = TryRestoreContent(newContents[i].spawnableItem, originalContents, debugAction, destroyOnRestore); + } + } + + public class EnemyRestore : UnityContentRestore + { + public void TryRestoreContents(List newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int i = 0; i < newContents.Count; i++) + newContents[i].enemyType = TryRestoreContent(newContents[i].enemyType, originalContents, debugAction, destroyOnRestore); + } + } + + public class SpawnableMapObjectRestore : UnityContentRestore + { + public void TryRestoreContents(SpawnableMapObject[] newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int i = 0; i < newContents.Length; i++) + newContents[i].prefabToSpawn = TryRestoreContent(newContents[i].prefabToSpawn, originalContents, debugAction, destroyOnRestore); + } + + public void TryRestoreContents(List newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int i = 0; i < newContents.Count; i++) + for (int j = 0; j < newContents[i].spawnablePrefabs.Count; j++) + newContents[i].spawnablePrefabs[j] = TryRestoreContent(newContents[i].spawnablePrefabs[j], originalContents, debugAction, destroyOnRestore); + } + + public void TryRestoreContents(RandomMapObject newContent, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int j = 0; j < newContent.spawnablePrefabs.Count; j++) + newContent.spawnablePrefabs[j] = TryRestoreContent(newContent.spawnablePrefabs[j], originalContents, debugAction, destroyOnRestore); + } + } + + public class SpawnableOutsideObjectRestore : UnityContentRestore + { + public void TryRestoreContents(SpawnableOutsideObjectWithRarity[] newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + List prefabs = originalContents.Select(p => p.prefabToSpawn).ToList(); + for (int i = 0; i < newContents.Length; i++) + newContents[i].spawnableObject.prefabToSpawn = TryRestoreContent(newContents[i].spawnableObject.prefabToSpawn, prefabs, debugAction, destroyOnRestore); + } + } + + public class ItemGroupRestore : UnityContentRestore + { + public void TryRestoreContents(List newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int i = 0; i < newContents.Count; i++) + newContents[i].spawnableItems = TryRestoreContent(newContents[i].spawnableItems, originalContents, debugAction, destroyOnRestore); + } + } + + public class ReverbPresetRestore : UnityContentRestore + { + public void TryRestoreContents(AudioReverbTrigger[] newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true ) + { + for (int i = 0; i < newContents.Length; i++) + newContents[i].reverbPreset = TryRestoreContent(newContents[i].reverbPreset, originalContents, debugAction, destroyOnRestore); + } + } + + public class AudioMixerGroupRestore : UnityContentRestore + { + public void TryRestoreContents(AudioSource[] newContents, List originalContents, bool debugAction = false, bool destroyOnRestore = true) + { + for (int i = 0; i < newContents.Length; i++) + newContents[i].outputAudioMixerGroup = TryRestoreContent(newContents[i].outputAudioMixerGroup, originalContents, debugAction, destroyOnRestore); + } + } +} diff --git a/LethalLevelLoader/Tools/NewContentRestorer.cs b/LethalLevelLoader/Tools/NewContentRestorer.cs new file mode 100644 index 0000000..e55378b --- /dev/null +++ b/LethalLevelLoader/Tools/NewContentRestorer.cs @@ -0,0 +1,81 @@ +using DunGen; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.Audio; +using Object = UnityEngine.Object; + +namespace LethalLevelLoader.Tools +{ + public static class NewContentRestorer + { + public static ItemRestore ItemRestore { get; private set; } = new ItemRestore(); + public static EnemyRestore EnemyRestore { get; private set; } = new EnemyRestore(); + public static SpawnableMapObjectRestore SpawnableMapObjectRestore { get; private set; } = new SpawnableMapObjectRestore(); + public static SpawnableOutsideObjectRestore SpawnableOutsideObjectRestore { get; private set; } = new SpawnableOutsideObjectRestore(); + public static UnityContentRestore LevelAmbienceRestore { get; private set; } = new UnityContentRestore(); + public static ItemGroupRestore ItemGroupRestore { get; private set; } = new ItemGroupRestore(); + + public static AudioMixerGroupRestore AudioMixerGroupRestore { get; private set; } = new AudioMixerGroupRestore(); + public static ReverbPresetRestore ReverbPresetRestore { get; private set; } = new ReverbPresetRestore(); + + internal static List ContentRestores = new List() + { + ItemRestore, EnemyRestore, SpawnableMapObjectRestore, SpawnableOutsideObjectRestore, LevelAmbienceRestore, + ItemGroupRestore, AudioMixerGroupRestore, ReverbPresetRestore + }; + + internal static void RestoreVanillaLevelAssetReferences(ExtendedLevel extendedLevel) + { + SelectableLevel selectableLevel = extendedLevel.SelectableLevel; + + foreach (SpawnableItemWithRarity spawnableItem in new List(selectableLevel.spawnableScrap)) + if (spawnableItem.spawnableItem == null) + selectableLevel.spawnableScrap.Remove(spawnableItem); + + ItemRestore.TryRestoreContents(selectableLevel.spawnableScrap, OriginalContent.Items); + + EnemyRestore.TryRestoreContents(selectableLevel.Enemies, OriginalContent.Enemies); + EnemyRestore.TryRestoreContents(selectableLevel.DaytimeEnemies, OriginalContent.Enemies); + EnemyRestore.TryRestoreContents(selectableLevel.OutsideEnemies, OriginalContent.Enemies); + + SpawnableMapObjectRestore.TryRestoreContents(selectableLevel.spawnableMapObjects, OriginalContent.SpawnableMapObjects); + + SpawnableOutsideObjectRestore.TryRestoreContents(selectableLevel.spawnableOutsideObjects, OriginalContent.SpawnableOutsideObjects); + + selectableLevel.levelAmbienceClips = LevelAmbienceRestore.TryRestoreContent(selectableLevel.levelAmbienceClips, OriginalContent.LevelAmbienceLibraries); + } + + internal static void RestoreVanillaInteriorAssetReferences(ExtendedDungeonFlow extendedDungeonFlow) + { + foreach (Tile tile in extendedDungeonFlow.DungeonFlow.GetTiles()) + RestoreVanillaTileAssetReferences(tile); + } + + internal static void RestoreVanillaTileAssetReferences(Tile tile) + { + foreach (RandomScrapSpawn spawn in tile.GetComponentsInChildren()) + spawn.spawnableItems = ItemGroupRestore.TryRestoreContent(spawn.spawnableItems, OriginalContent.ItemGroups); + + foreach (RandomMapObject spawn in tile.GetComponentsInChildren()) + SpawnableMapObjectRestore.TryRestoreContents(spawn, OriginalContent.SpawnableMapObjects); + } + + internal static void RestoreVanillaParentAudioAssetReferences(GameObject parent) + { + AudioSource[] allAudioSources = parent.GetComponentsInChildren(true); + AudioReverbTrigger[] allReverbTriggers = parent.GetComponentsInChildren(true); + + AudioMixerGroupRestore.TryRestoreContents(allAudioSources, OriginalContent.AudioMixerGroups, destroyOnRestore: false); + ReverbPresetRestore.TryRestoreContents(allReverbTriggers, OriginalContent.ReverbPresets); + } + + internal static void FlushAll() + { + foreach (ContentRestore contentRestore in ContentRestores) + contentRestore.Flush(); + } + } +} diff --git a/assets/thunderstore.toml b/assets/thunderstore.toml index 436c468..e76960d 100644 --- a/assets/thunderstore.toml +++ b/assets/thunderstore.toml @@ -14,7 +14,6 @@ containsNsfwContent = false [package.dependencies] BepInEx-BepInExPack = "5.4.2100" -Evaisa-LethalLib = "0.16.0" Evaisa-FixPluginTypesSerialization = "1.1.1" MaxWasUnavailable-LethalModDataLib = "1.2.2"