SDM_LethalCompany_Mod/ScarletMansion/ScarletMansion/GamePatch/LoadAssetsIntoLevelPatch.cs
LadyAliceMargatroid 523e7ed898 Added BrachTileBoost system
Added the new coilhead behaviour to the knight
Added treasure room puzzle for bedroom
Changed many LogInfo into LogDebug
Removed jank animator override stuff (no offense)
Changed how treasure rooms lock their doors to work in multiplayer
Removed basement scripts
2024-08-19 02:44:15 -07:00

172 lines
7.8 KiB
C#

using HarmonyLib;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System.Reflection.Emit;
using System.Reflection;
namespace ScarletMansion.GamePatch {
public class LoadAssetsIntoLevelPatch {
// alright new strat
// at the start, we create an alternate enemy (and item) list
// we highjack the enemy (and item) list variable where ever it is called (base game or advanced company)
// if the highjacked list matches the one we created, which it should (and we grab from advanced company too if needed)
// then we replace
public static InjectionDictionary enemiesInjection = new InjectionDictionary(
"Enemies",
typeof(LoadAssetsIntoLevelPatch).GetMethod("GetEnemies", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public),
new CodeInstruction(OpCodes.Ldfld, typeof(SelectableLevel).GetField("Enemies"))
);
public static InjectionDictionary itemsInjection = new InjectionDictionary(
"Items",
typeof(LoadAssetsIntoLevelPatch).GetMethod("GetItems", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public),
new CodeInstruction(OpCodes.Ldfld, typeof(SelectableLevel).GetField("spawnableScrap"))
);
[HarmonyTranspiler]
[HarmonyPatch(typeof(EnemyVent), "SyncVentSpawnTimeClientRpc")]
public static IEnumerable<CodeInstruction> SyncVentSpawnTimeClientRpcPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, enemiesInjection, "SyncVentSpawnTimeClientRpc", 1);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RoundManager), "AssignRandomEnemyToVent")]
public static IEnumerable<CodeInstruction> AssignRandomEnemyToVentPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, enemiesInjection, "AssignRandomEnemyToVent", 10);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RoundManager), "EnemyCannotBeSpawned")]
public static IEnumerable<CodeInstruction> EnemyCannotBeSpawnedPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, enemiesInjection, "EnemyCannotBeSpawned", 4);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RoundManager), "ResetEnemyTypesSpawnedCounts")]
public static IEnumerable<CodeInstruction> ResetEnemyTypesSpawnedCountsPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, enemiesInjection, "ResetEnemyTypesSpawnedCounts", 4);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RoundManager), "SetChallengeFileRandomModifiers")]
public static IEnumerable<CodeInstruction> SetChallengeFileRandomModifiersPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, enemiesInjection, "SetChallengeFileRandomModifiersEnemy", 3);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RoundManager), "SpawnEnemyGameObject")]
public static IEnumerable<CodeInstruction> SpawnEnemyGameObjectPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, enemiesInjection, "SpawnEnemyGameObject", 3);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(GiftBoxItem), "Start")]
public static IEnumerable<CodeInstruction> GiftBoxItemStartPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, itemsInjection, "GiftBoxItem", 5);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RoundManager), "SetChallengeFileRandomModifiers")]
public static IEnumerable<CodeInstruction> SetChallengeFileRandomModifiersItemPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, itemsInjection, "SetChallengeFileRandomModifiersItem", 1);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
public static IEnumerable<CodeInstruction> SpawnScrapInLevelPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, itemsInjection, "SpawnScrapInLevel", 4);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(DunGenPlus.Patches.RoundManagerPatch), "waitForScrapToSpawnToSyncPatch")]
public static IEnumerable<CodeInstruction> waitForScrapToSpawnToSyncPatch(IEnumerable<CodeInstruction> instructions){
return TranspilerUtilities.InjectMethod(instructions, itemsInjection, "waitForScrapToSpawnToSyncPatch", 1);
}
public static List<SpawnableEnemyWithRarity> lastEnemiesRarity;
public static List<SpawnableEnemyWithRarity> currentEnemiesRarity;
public static List<SpawnableItemWithRarity> lastItemsRarity;
public static List<SpawnableItemWithRarity> currentItemsRarity;
public static void ModifyLevel(SelectableLevel level){
lastEnemiesRarity = level.Enemies;
lastItemsRarity = level.spawnableScrap;
currentEnemiesRarity = lastEnemiesRarity.ToList();
currentItemsRarity = lastItemsRarity.ToList();
void AddEnemy(Assets.Enemy enemy, string sourceEnemyName, string targetEnemyName, int baseWeight, int minBaseWeight, float weightStealPercentage) {
if (enemy != null) {
var target = currentEnemiesRarity
.Where(c => c.enemyType.name.ToLowerInvariant() == targetEnemyName)
.FirstOrDefault();
if (target == null){
Plugin.logger.LogDebug($"No enemy {targetEnemyName} in level, using default rarity of {minBaseWeight}.");
var entry = enemy.GetItemEntry(baseWeight + minBaseWeight);
Plugin.logger.LogDebug($"Adding enemy {sourceEnemyName} with weight {entry.rarity}");
currentEnemiesRarity.Add(entry);
} else {
currentEnemiesRarity.Remove(target);
var entryRarity = Mathf.RoundToInt(target.rarity * weightStealPercentage);
var prevEntry = new SpawnableEnemyWithRarity();
prevEntry.enemyType = target.enemyType;
prevEntry.rarity = target.rarity - entryRarity;
var newEntry = enemy.GetItemEntry(baseWeight + entryRarity);
Plugin.logger.LogDebug($"Adding enemy {sourceEnemyName} with weight {newEntry.rarity}");
Plugin.logger.LogDebug($"Setting enemy {targetEnemyName} with weight {prevEntry.rarity}");
currentEnemiesRarity.Add(newEntry);
currentEnemiesRarity.Add(prevEntry);
}
} else {
Plugin.logger.LogError($"Failed to load custom enemy {sourceEnemyName} as their reference is missing");
}
}
AddEnemy(Assets.knight, "knight", "springman", PluginConfig.Instance.knightWeightBaseValue, 10, PluginConfig.Instance.knightWeightStealPercentageValue);
AddEnemy(Assets.maid, "maid", "butler", PluginConfig.Instance.maidWeightBaseValue, 10, PluginConfig.Instance.maidWeightStealPercentageValue);
foreach(var i in Assets.scrapItems){
var entry = i.GetItemRarity();
if (entry.rarity > 0) {
Plugin.logger.LogDebug($"Adding item {entry.spawnableItem.itemName} with weight {entry.rarity}");
currentItemsRarity.Add(entry);
}
}
Plugin.logger.LogDebug($"Loaded custom enemies and items for {level.sceneName}");
Components.ScarletBedroom.CreateRandomEnemyList(currentEnemiesRarity);
}
public static List<SpawnableEnemyWithRarity> GetEnemies(List<SpawnableEnemyWithRarity> target){
if (DunGenPatch.Patch.active && target == lastEnemiesRarity) return currentEnemiesRarity;
return target;
}
public static List<SpawnableItemWithRarity> GetItems(List<SpawnableItemWithRarity> target){
if (DunGenPatch.Patch.active && target == lastItemsRarity) return currentItemsRarity;
return target;
}
}
}