From ea1f3f83aed52e1ef91f8ac4c0107805e7da64b4 Mon Sep 17 00:00:00 2001 From: XuuXiao Date: Mon, 24 Mar 2025 14:06:58 +0000 Subject: [PATCH 1/6] added LLL compat for content tags. Started checking for content tags in enemies and item registration. --- LethalLib/Compats/LethalLevelLoaderCompat.cs | 46 ++++++++++++++++++++ LethalLib/LethalLib.csproj | 3 ++ LethalLib/Modules/Enemies.cs | 19 +++++--- LethalLib/Modules/Items.cs | 16 ++++--- LethalLib/Modules/Levels.cs | 22 ++++++++++ 5 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 LethalLib/Compats/LethalLevelLoaderCompat.cs diff --git a/LethalLib/Compats/LethalLevelLoaderCompat.cs b/LethalLib/Compats/LethalLevelLoaderCompat.cs new file mode 100644 index 0000000..2ae7540 --- /dev/null +++ b/LethalLib/Compats/LethalLevelLoaderCompat.cs @@ -0,0 +1,46 @@ +using BepInEx.Bootstrap; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace LethalLib.Compats; +internal static class LethalLevelLoaderCompat +{ + public static bool LethalLevelLoaderExists = Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader"); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + public static List TryGetLLLTagsFromLevels(SelectableLevel level) + { + if (LethalLevelLoaderExists) + { + return GetLLLTagsFromLevel(level); // do i need to make another method? i forgor + } + return new(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static List GetLLLTagsFromLevel(SelectableLevel level) + { + List tagsForLevel = []; + foreach (LethalLevelLoader.ExtendedLevel extendedLevel in LethalLevelLoader.PatchedContent.CustomExtendedLevels) + { + if (extendedLevel.SelectableLevel != level) continue; + foreach (LethalLevelLoader.ContentTag tag in extendedLevel.ContentTags) + { + tagsForLevel.Add(tag.contentTagName.Trim().ToLowerInvariant()); + } + break; + } + + foreach (LethalLevelLoader.ExtendedLevel extendedLevel in LethalLevelLoader.PatchedContent.VanillaExtendedLevels) + { + if (extendedLevel.SelectableLevel != level) continue; + foreach (LethalLevelLoader.ContentTag tag in extendedLevel.ContentTags) + { + tagsForLevel.Add(tag.contentTagName.Trim().ToLowerInvariant()); + } + break; + } + + return tagsForLevel; + } +} \ No newline at end of file diff --git a/LethalLib/LethalLib.csproj b/LethalLib/LethalLib.csproj index c5eeab3..ac11884 100644 --- a/LethalLib/LethalLib.csproj +++ b/LethalLib/LethalLib.csproj @@ -49,6 +49,9 @@ $(TestProfileDir)BepInEx/plugins/MMHOOK/MMHOOK_Assembly-CSharp.dll + + $(TestProfileDir)BepInEx/plugins/IAmBatby-LethalLevelLoader/LethalLevelLoader.dll + diff --git a/LethalLib/Modules/Enemies.cs b/LethalLib/Modules/Enemies.cs index c06130a..901f176 100644 --- a/LethalLib/Modules/Enemies.cs +++ b/LethalLib/Modules/Enemies.cs @@ -180,7 +180,7 @@ private static void RegisterLethalLibEnemiesForAllLevels() foreach (SelectableLevel level in StartOfRound.Instance.levels) { - if(levelsAlreadyAddedTo.Contains(level)) + if (levelsAlreadyAddedTo.Contains(level)) continue; foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies) { @@ -206,10 +206,12 @@ private static void AddEnemyToLevel(SpawnableEnemy spawnableEnemy, SelectableLev name = customName; } + string tagName = string.Empty; bool enemyValidToAdd = spawnableEnemy.levelRarities.ContainsKey(Levels.LevelTypes.All) + || (spawnableEnemy.customLevelRarities != null && Levels.Compatibility.ContentIncludedToLevelViaTag(spawnableEnemy.customLevelRarities.Keys.ToArray(), level, out tagName)) || (isCurrentLevelFromVanilla && spawnableEnemy.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) - || (isCurrentLevelFromVanilla && spawnableEnemy.levelRarities.ContainsKey(currentLevelType)) || (!isCurrentLevelFromVanilla && spawnableEnemy.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) + || (isCurrentLevelFromVanilla && spawnableEnemy.levelRarities.ContainsKey(currentLevelType)) || (!isCurrentLevelFromVanilla && spawnableEnemy.customLevelRarities != null && spawnableEnemy.customLevelRarities.ContainsKey(customName)); if (Plugin.extendedLogging.Value) @@ -223,14 +225,18 @@ private static void AddEnemyToLevel(SpawnableEnemy spawnableEnemy, SelectableLev { rarity = spawnableEnemy.levelRarities[currentLevelType]; } - else if (isCurrentLevelFromVanilla && spawnableEnemy.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) - { - rarity = spawnableEnemy.levelRarities[Levels.LevelTypes.Vanilla]; - } else if (spawnableEnemy.customLevelRarities != null && spawnableEnemy.customLevelRarities.ContainsKey(name)) { rarity = spawnableEnemy.customLevelRarities[name]; } + else if (spawnableEnemy.customLevelRarities != null && tagName != string.Empty && spawnableEnemy.customLevelRarities.ContainsKey(tagName)) + { + rarity = spawnableEnemy.customLevelRarities[tagName]; + } + else if (isCurrentLevelFromVanilla && spawnableEnemy.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) + { + rarity = spawnableEnemy.levelRarities[Levels.LevelTypes.Vanilla]; + } else if (!isCurrentLevelFromVanilla && spawnableEnemy.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) { rarity = spawnableEnemy.levelRarities[Levels.LevelTypes.Modded]; @@ -557,5 +563,4 @@ public static void RemoveEnemyFromLevels(EnemyType enemyType, Levels.LevelTypes } } } - } diff --git a/LethalLib/Modules/Items.cs b/LethalLib/Modules/Items.cs index 5beee30..4c891ff 100644 --- a/LethalLib/Modules/Items.cs +++ b/LethalLib/Modules/Items.cs @@ -189,10 +189,12 @@ private static void AddScrapItemToLevel(ScrapItem scrapItem, SelectableLevel lev name = customName; } + string tagName = string.Empty; bool itemValidToAdd = scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.All) + || (scrapItem.customLevelRarities != null && Levels.Compatibility.ContentIncludedToLevelViaTag(scrapItem.customLevelRarities.Keys.ToArray(), level, out tagName)) || (isCurrentLevelFromVanilla && scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) - || (isCurrentLevelFromVanilla && scrapItem.levelRarities.ContainsKey(currentLevelType)) || (!isCurrentLevelFromVanilla && scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) + || (isCurrentLevelFromVanilla && scrapItem.levelRarities.ContainsKey(currentLevelType)) || (!isCurrentLevelFromVanilla && scrapItem.customLevelRarities != null && scrapItem.customLevelRarities.ContainsKey(customName)); if (Plugin.extendedLogging.Value) @@ -206,14 +208,18 @@ private static void AddScrapItemToLevel(ScrapItem scrapItem, SelectableLevel lev { rarity = scrapItem.levelRarities[currentLevelType]; } - else if (isCurrentLevelFromVanilla && scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) - { - rarity = scrapItem.levelRarities[Levels.LevelTypes.Vanilla]; - } else if (scrapItem.customLevelRarities != null && scrapItem.customLevelRarities.ContainsKey(name)) { rarity = scrapItem.customLevelRarities[name]; } + else if (scrapItem.customLevelRarities != null && tagName != string.Empty && scrapItem.customLevelRarities.ContainsKey(tagName)) + { + rarity = scrapItem.customLevelRarities[tagName]; + } + else if (isCurrentLevelFromVanilla && scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) + { + rarity = scrapItem.levelRarities[Levels.LevelTypes.Vanilla]; + } else if (!isCurrentLevelFromVanilla && scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) { rarity = scrapItem.levelRarities[Levels.LevelTypes.Modded]; diff --git a/LethalLib/Modules/Levels.cs b/LethalLib/Modules/Levels.cs index cbb4707..82867ff 100644 --- a/LethalLib/Modules/Levels.cs +++ b/LethalLib/Modules/Levels.cs @@ -103,5 +103,27 @@ internal static Dictionary LLLifyLevelRarityDictionary(Dictionary levelsCurrentTags = LethalLib.Compats.LethalLevelLoaderCompat.TryGetLLLTagsFromLevels(level); + foreach (string levelTag in levelsCurrentTags) + { + foreach (string potentialTag in potentialTags) + { + string cleanedTag = potentialTag.Remove(potentialTag.Length - 5); + if (levelTag == cleanedTag) + { + chosenTag = levelTag; + if (Plugin.extendedLogging.Value) + Plugin.logger.LogInfo($"Level {level.name} has valid tag {cleanedTag}"); + return true; + } + } + } + return false; + } } } \ No newline at end of file From 22c8cafcb9c09311a18e9d204c901d3cb1d69772 Mon Sep 17 00:00:00 2001 From: XuuXiao Date: Mon, 24 Mar 2025 14:56:03 +0000 Subject: [PATCH 2/6] also did the same thing i did with items and enemies to mapobjects --- LethalLib/Modules/MapObjects.cs | 170 ++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 74 deletions(-) diff --git a/LethalLib/Modules/MapObjects.cs b/LethalLib/Modules/MapObjects.cs index a131a42..25da5d8 100644 --- a/LethalLib/Modules/MapObjects.cs +++ b/LethalLib/Modules/MapObjects.cs @@ -95,85 +95,107 @@ private static void StartOfRound_Awake(On.StartOfRound.orig_Awake orig, StartOfR { foreach (SelectableLevel level in self.levels) { - var name = level.name; - var alwaysValid = mapObject.levels.HasFlag(Levels.LevelTypes.All) || (mapObject.spawnLevelOverrides != null && mapObject.spawnLevelOverrides.Any(item => item.ToLowerInvariant() == name.ToLowerInvariant())); - var isModded = mapObject.levels.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name); + AddMapObjectToLevel(mapObject, level); + } + } + } - if (isModded) - { - alwaysValid = true; - } + private static void AddMapObjectToLevel(RegisteredMapObject mapObject, SelectableLevel level) + { + string name = level.name; + string customName = Levels.Compatibility.GetLLLNameOfLevel(name); + Levels.LevelTypes currentLevelType = Levels.LevelTypes.None; + bool isCurrentLevelFromVanilla = false; - if (Enum.IsDefined(typeof(Levels.LevelTypes), name) || alwaysValid) - { - var levelEnum = alwaysValid ? Levels.LevelTypes.All : (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name); + if (Enum.TryParse(name, true, out currentLevelType)) // It'd be weird if a level was called "Modded" or "All" so I think im good to not check that lol + { + isCurrentLevelFromVanilla = true; + } + else + { + name = customName; + } + string tagName = string.Empty; + bool mapObjectValidToAdd = mapObject.levels.HasFlag(Levels.LevelTypes.All) + || Levels.Compatibility.ContentIncludedToLevelViaTag(mapObject.spawnLevelOverrides.ToArray(), level, out tagName) + || (isCurrentLevelFromVanilla && mapObject.levels.HasFlag(Levels.LevelTypes.Vanilla)) + || (!isCurrentLevelFromVanilla && mapObject.levels.HasFlag(Levels.LevelTypes.Modded)) + || (isCurrentLevelFromVanilla && mapObject.levels.HasFlag(currentLevelType)) + || (!isCurrentLevelFromVanilla && mapObject.spawnLevelOverrides.Contains(customName)); - if (alwaysValid || mapObject.levels.HasFlag(levelEnum)) - { - if (mapObject.mapObject != null) - { - // Remove existing object if it exists - if (level.spawnableMapObjects.Any(x => x.prefabToSpawn == mapObject.mapObject.prefabToSpawn)) - { - var list = level.spawnableMapObjects.ToList(); - list.RemoveAll(x => x.prefabToSpawn == mapObject.mapObject.prefabToSpawn); - level.spawnableMapObjects = list.ToArray(); - } - - // Create a new instance so it can have its own `numberToSpawn` value - SpawnableMapObject spawnableMapObject = new() - { - prefabToSpawn = mapObject.mapObject.prefabToSpawn, - spawnFacingAwayFromWall = mapObject.mapObject.spawnFacingAwayFromWall, - spawnFacingWall = mapObject.mapObject.spawnFacingWall, - spawnWithBackToWall = mapObject.mapObject.spawnWithBackToWall, - spawnWithBackFlushAgainstWall = mapObject.mapObject.spawnWithBackFlushAgainstWall, - requireDistanceBetweenSpawns = mapObject.mapObject.requireDistanceBetweenSpawns, - disallowSpawningNearEntrances = mapObject.mapObject.disallowSpawningNearEntrances, - }; - - if (mapObject.spawnRateFunction != null) - { - spawnableMapObject.numberToSpawn = mapObject.spawnRateFunction(level); - } - - var mapObjectsList = level.spawnableMapObjects.ToList(); - mapObjectsList.Add(spawnableMapObject); - level.spawnableMapObjects = mapObjectsList.ToArray(); - - if (Plugin.extendedLogging.Value) - Plugin.logger.LogInfo($"Added {spawnableMapObject.prefabToSpawn.name} to {name}"); - } - else if (mapObject.outsideObject != null) - { - if (level.spawnableOutsideObjects.Any(x => x.spawnableObject.prefabToSpawn == mapObject.outsideObject.spawnableObject.prefabToSpawn)) - { - var list = level.spawnableOutsideObjects.ToList(); - list.RemoveAll(x => x.spawnableObject.prefabToSpawn == mapObject.outsideObject.spawnableObject.prefabToSpawn); - level.spawnableOutsideObjects = list.ToArray(); - } - - SpawnableOutsideObjectWithRarity spawnableOutsideObject = new() - { - spawnableObject = mapObject.outsideObject.spawnableObject - }; - - if (mapObject.spawnRateFunction != null) - { - spawnableOutsideObject.randomAmount = mapObject.spawnRateFunction(level); - } - - var mapObjectsList = level.spawnableOutsideObjects.ToList(); - mapObjectsList.Add(spawnableOutsideObject); - level.spawnableOutsideObjects = mapObjectsList.ToArray(); - - if (Plugin.extendedLogging.Value) - Plugin.logger.LogInfo($"Added {spawnableOutsideObject.spawnableObject.prefabToSpawn.name} to {name}"); - } - } - } + string mapObjectName = "invalid!"; + if (mapObject.mapObject != null) + { + mapObjectName = mapObject.mapObject.prefabToSpawn.name; + } + else if (mapObject.outsideObject != null && mapObject.outsideObject != null) + { + mapObjectName = mapObject.outsideObject.spawnableObject.prefabToSpawn.name; + } + if (Plugin.extendedLogging.Value) + Plugin.logger.LogInfo($"{name} for mapObject: {mapObjectName}, isCurrentLevelFromVanilla: {isCurrentLevelFromVanilla}, Found valid: {mapObjectValidToAdd}"); + + if (!mapObjectValidToAdd) return; + if (mapObject.mapObject != null) + { + // Remove existing object if it exists + if (level.spawnableMapObjects.Any(x => x.prefabToSpawn == mapObject.mapObject.prefabToSpawn)) + { + var list = level.spawnableMapObjects.ToList(); + list.RemoveAll(x => x.prefabToSpawn == mapObject.mapObject.prefabToSpawn); + level.spawnableMapObjects = list.ToArray(); } + + // Create a new instance so it can have its own `numberToSpawn` value + SpawnableMapObject spawnableMapObject = new() + { + prefabToSpawn = mapObject.mapObject.prefabToSpawn, + spawnFacingAwayFromWall = mapObject.mapObject.spawnFacingAwayFromWall, + spawnFacingWall = mapObject.mapObject.spawnFacingWall, + spawnWithBackToWall = mapObject.mapObject.spawnWithBackToWall, + spawnWithBackFlushAgainstWall = mapObject.mapObject.spawnWithBackFlushAgainstWall, + requireDistanceBetweenSpawns = mapObject.mapObject.requireDistanceBetweenSpawns, + disallowSpawningNearEntrances = mapObject.mapObject.disallowSpawningNearEntrances, + }; + + if (mapObject.spawnRateFunction != null) + { + spawnableMapObject.numberToSpawn = mapObject.spawnRateFunction(level); + } + + var mapObjectsList = level.spawnableMapObjects.ToList(); + mapObjectsList.Add(spawnableMapObject); + level.spawnableMapObjects = mapObjectsList.ToArray(); + + if (Plugin.extendedLogging.Value) + Plugin.logger.LogInfo($"Added {spawnableMapObject.prefabToSpawn.name} to {name}"); + } + else if (mapObject.outsideObject != null) + { + if (level.spawnableOutsideObjects.Any(x => x.spawnableObject.prefabToSpawn == mapObject.outsideObject.spawnableObject.prefabToSpawn)) + { + var list = level.spawnableOutsideObjects.ToList(); + list.RemoveAll(x => x.spawnableObject.prefabToSpawn == mapObject.outsideObject.spawnableObject.prefabToSpawn); + level.spawnableOutsideObjects = list.ToArray(); + } + + SpawnableOutsideObjectWithRarity spawnableOutsideObject = new() + { + spawnableObject = mapObject.outsideObject.spawnableObject + }; + + if (mapObject.spawnRateFunction != null) + { + spawnableOutsideObject.randomAmount = mapObject.spawnRateFunction(level); + } + + var mapObjectsList = level.spawnableOutsideObjects.ToList(); + mapObjectsList.Add(spawnableOutsideObject); + level.spawnableOutsideObjects = mapObjectsList.ToArray(); + + if (Plugin.extendedLogging.Value) + Plugin.logger.LogInfo($"Added {spawnableOutsideObject.spawnableObject.prefabToSpawn.name} to {name}"); } } From 672109d7c071f90c0be9fb049e2718d7f972585f Mon Sep 17 00:00:00 2001 From: XuuXiao Date: Mon, 24 Mar 2025 15:00:38 +0000 Subject: [PATCH 3/6] updated changelog --- CHANGELOG.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49a8fb2..78dadbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## LethalLib [0.16.5] + +### Added +- Ability for items, levels, outside and inside mapobjects to register to levels through their content tag. + +### Fixed +- mapobjects maybe having the same issues that items and enemies had the previous two versions with case sensitivity and leveltype validation. + ## LethalLib [0.16.4] -- Fixed `AddEnemyToLevel` needing a `LevelType` to validate custom moon enemy rarities. -- Fixed `AddScrapItemToLevel` having the same issue as above. + +### Fixed +- `AddEnemyToLevel` needing a `LevelType` to validate custom moon enemy rarities. +- `AddScrapItemToLevel` having the same issue as above. ## LethalLib [0.16.3] From 3015fb38f98f42a6e30e0aab7f398d2d9ff288dc Mon Sep 17 00:00:00 2001 From: XuuXiao Date: Tue, 25 Mar 2025 03:52:47 +0000 Subject: [PATCH 4/6] added aaron's nuget feed thing to reference LLL instead of through runtime dependency --- LethalLib/LethalLib.csproj | 4 +--- NuGet.Config | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/LethalLib/LethalLib.csproj b/LethalLib/LethalLib.csproj index ac11884..f912585 100644 --- a/LethalLib/LethalLib.csproj +++ b/LethalLib/LethalLib.csproj @@ -24,6 +24,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + all @@ -49,9 +50,6 @@ $(TestProfileDir)BepInEx/plugins/MMHOOK/MMHOOK_Assembly-CSharp.dll - - $(TestProfileDir)BepInEx/plugins/IAmBatby-LethalLevelLoader/LethalLevelLoader.dll - diff --git a/NuGet.Config b/NuGet.Config index 1864ded..cc9dd6a 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -2,5 +2,6 @@ + \ No newline at end of file From bd99109e150c25f8489c0657450f5c1f4598ad9b Mon Sep 17 00:00:00 2001 From: XuuXiao Date: Tue, 25 Mar 2025 03:55:43 +0000 Subject: [PATCH 5/6] added private assets and removed publicise on lll nuget --- LethalLib/LethalLib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LethalLib/LethalLib.csproj b/LethalLib/LethalLib.csproj index f912585..5acc290 100644 --- a/LethalLib/LethalLib.csproj +++ b/LethalLib/LethalLib.csproj @@ -24,7 +24,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all From 92ab66ee1bc5f34ef8939c78a9b601bfb0f852ff Mon Sep 17 00:00:00 2001 From: XuuXiao Date: Tue, 25 Mar 2025 03:59:28 +0000 Subject: [PATCH 6/6] changed LLLExists into a getter --- LethalLib/Compats/LethalLevelLoaderCompat.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LethalLib/Compats/LethalLevelLoaderCompat.cs b/LethalLib/Compats/LethalLevelLoaderCompat.cs index 2ae7540..6554afd 100644 --- a/LethalLib/Compats/LethalLevelLoaderCompat.cs +++ b/LethalLib/Compats/LethalLevelLoaderCompat.cs @@ -5,7 +5,7 @@ namespace LethalLib.Compats; internal static class LethalLevelLoaderCompat { - public static bool LethalLevelLoaderExists = Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader"); + public static bool LethalLevelLoaderExists => Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static List TryGetLLLTagsFromLevels(SelectableLevel level)