Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BerserkerEnemies Reborn v1.6.0
BerserkerEnemies_Reborn/BerserkerEnemies_Reborn.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using REPOLib.Modules; using UnityEngine; using UnityEngine.Animations; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: TargetFramework(".NETFramework,Version=v4.8")] [assembly: AssemblyVersion("0.0.0.0")] internal class ModPatch { public static bool enableBerserker = true; public static int startingLevel = 9; public static int minHealth = 400; public static int maxHealth = 5000; public static int berserkerHealth = 2000; public static bool enableHealthScaling = true; public static int healthScalingFactor = 10; public static bool enableDamageMultiplier = true; public static float damageMultiplier = 1.5f; public static bool enableDamageScaling = false; public static int damageScalingFactor = 10; public static bool _masterEnableDamageMultiplier = false; public static float _masterDamageMultiplier = 1.5f; public static bool _masterEnableDamageScaling = false; public static int _masterDamageScalingFactor = 10; public static bool berserkerUnkillable = false; public static bool canBeStunned = false; public static bool enableGrabImmunity = true; public static bool enableAnimal = true; public static bool enableApexPredator = true; public static bool enableBowtie = true; public static bool enableChef = true; public static bool enableClown = true; public static bool enableHeadman = true; public static bool enableHidden = true; public static bool enableHuntsman = true; public static bool enableMentalist = true; public static bool enableReaper = true; public static bool enableRobe = true; public static bool enableRugrat = true; public static bool enableShadowChild = true; public static bool enableSpewer = true; public static bool enableTrudge = true; public static bool enableUpscream = true; public static bool enableBella = true; public static bool enableElsa = true; public static bool enableBirthdayBoy = true; public static bool enableTick = true; public static bool enableOogly = true; public static bool enableHeartHugger = true; public static bool enableHeadgrab = true; public static bool enableLoom = true; public static bool enablePeeper = true; public static bool enableGambit = true; public static bool containModded = true; public static bool enableGusher = true; public static bool enableRoaster = true; public static bool enableDroid = true; public static bool enableDestroyer = true; public static bool enableSoldier = true; public static bool enableFreddyFazbear = true; public static bool enableBaldi = true; public static bool enableMoon = true; public static bool enableRobot = true; public static bool enableRollingGiant = true; public static bool enableZombie = true; public static bool enableDriller = true; public static int maxBerserkersAllowed = 1; public static float berserkerSpawnChance = 10f; public static float berserkerSpawnChancePerLevel = 5f; public static bool enableBerserkerScaling = false; public static bool forceSpawnWhenScaling = false; public static int berserkerScalingLevel = 10; public static int maxScalingBerserkers = 3; public static BerserkerManager berserkerScript; public static EnemyParent _berserkerChosen; public static bool showDebugLogs = false; public static bool _masterUnkillable = false; public static bool _masterCanBeStunned = true; public static AssetBundle _assetBundle = null; public static float _orbValueMax = 0f; public static float _orbValueMin = 0f; private static float currentBerserkerValuableMax = 0f; private static float currentBerserkerValuableMin = 0f; private static float minimumOrbValue = 8000f; private static float minOrbValueSubtract = 1000f; private static float maximumOrbValue = 50000f; private static float maxOrbValueSubtract = 10000f; public static List<int> enemyIndexes = new List<int>(); [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] [HarmonyPostfix] public static void GenerateDonePostfix(LevelGenerator __instance) { if (!SemiFunc.RunIsLevel()) { return; } _berserkerChosen = null; berserkerScript = ((Component)LevelGenerator.Instance).gameObject.GetComponent<BerserkerManager>(); if ((Object)(object)berserkerScript == (Object)null) { berserkerScript = ((Component)LevelGenerator.Instance).gameObject.AddComponent<BerserkerManager>(); } PhotonView component = ((Component)LevelGenerator.Instance).GetComponent<PhotonView>(); if (!enableBerserker || RunManager.instance.levelsCompleted + 1 < startingLevel || !SemiFunc.IsMasterClientOrSingleplayer()) { return; } List<string> enemyTypes = GetEnemyTypes(); if (enableHealthScaling) { berserkerHealth = CalculateHealthScaling(berserkerHealth); } CalculateOrbValue(berserkerHealth, out currentBerserkerValuableMax, out currentBerserkerValuableMin); float num = Mathf.Clamp(berserkerSpawnChance + (float)(RunManager.instance.levelsCompleted + 1 - startingLevel) * berserkerSpawnChancePerLevel, 0f, 100f); if (showDebugLogs) { Log.Info($"Current level: {RunManager.instance.levelsCompleted + 1} - Base chance: {berserkerSpawnChance}% - Level chance: {num}%"); } int num2 = 0; if (enableBerserkerScaling) { maxBerserkersAllowed = GetScalingBerserkers(); if (showDebugLogs) { Log.Info($"Level {RunManager.instance.levelsCompleted + 1} allows {maxBerserkersAllowed} berserker(s) out of {maxScalingBerserkers} maximum."); } } foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned) { if (num2 >= maxBerserkersAllowed) { continue; } float num3 = Random.Range(0, 100); float num4 = num; if (enableBerserkerScaling && forceSpawnWhenScaling) { num4 = 100f; } if (showDebugLogs) { if (enableBerserkerScaling && forceSpawnWhenScaling) { Log.Info($"Enemy: {item.enemyName} - Bypass forced - Berserker? {num3 <= num4 && enemyTypes.Contains(item.enemyName)} - In list? {enemyTypes.Contains(item.enemyName)}"); } else { Log.Info($"Enemy: {item.enemyName} - Chance {num3}% of {num4}% - Berserker? {num3 <= num4 && enemyTypes.Contains(item.enemyName)} - In list? {enemyTypes.Contains(item.enemyName)}"); } } if (!(num3 <= num4) || !enemyTypes.Contains(item.enemyName)) { continue; } Log.Info("Berserker Spawned!"); _berserkerChosen = item; enemyIndexes.Add(((Component)item).transform.GetSiblingIndex()); ((Component)_berserkerChosen).GetComponent<BerserkerController>().isBerserkerFlag = true; num2++; if (SemiFunc.IsMultiplayer()) { if ((Object)(object)component != (Object)null) { component.RPC("StartBerserker", (RpcTarget)0, new object[2] { berserkerHealth, ((Component)item).transform.GetSiblingIndex() }); component.RPC("GetCanBeStunnedFromMaster", (RpcTarget)1, new object[1] { canBeStunned }); component.RPC("GetUnkillableVariableFromMaster", (RpcTarget)1, new object[1] { berserkerUnkillable }); component.RPC("GetOrbValuableFromMaster", (RpcTarget)1, new object[2] { currentBerserkerValuableMax, currentBerserkerValuableMin }); component.RPC("GetDamageSettingsFromMaster", (RpcTarget)1, new object[4] { enableDamageMultiplier, damageMultiplier, enableDamageScaling, damageScalingFactor }); } if (showDebugLogs) { Log.Info((!SemiFunc.IsMasterClient()) ? $"Berserker: {item.enemyName} - HP: {berserkerHealth} - Unkillable: {_masterUnkillable} - Stunnable: {_masterCanBeStunned}" : $"Berserker: {item.enemyName} - HP: {berserkerHealth} - Unkillable: {berserkerUnkillable} - Stunnable: {canBeStunned}"); } } else { berserkerScript.StartBerserker(berserkerHealth, ((Component)item).transform.GetSiblingIndex()); if (showDebugLogs) { Log.Info($"Berserker: {item.enemyName} - HP: {berserkerHealth} - Unkillable: {berserkerUnkillable} - Stunnable: {canBeStunned}"); } } if (!containModded || _berserkerChosen.enemyName != "Soldier") { continue; } foreach (EnemyParent item2 in EnemyDirector.instance.enemiesSpawned.Where((EnemyParent g) => g.enemyName == "Soldier Ghost").ToList()) { EnemyParent val = (_berserkerChosen = item2); enemyIndexes.Add(((Component)val).transform.GetSiblingIndex()); ((Component)_berserkerChosen).GetComponent<BerserkerController>().isBerserkerFlag = true; if (SemiFunc.IsMultiplayer()) { if ((Object)(object)component != (Object)null) { component.RPC("StartBerserker", (RpcTarget)0, new object[2] { berserkerHealth, ((Component)val).transform.GetSiblingIndex() }); component.RPC("GetCanBeStunnedFromMaster", (RpcTarget)1, new object[1] { canBeStunned }); component.RPC("GetUnkillableVariableFromMaster", (RpcTarget)1, new object[1] { berserkerUnkillable }); component.RPC("GetOrbValuableFromMaster", (RpcTarget)1, new object[2] { currentBerserkerValuableMax, currentBerserkerValuableMin }); component.RPC("GetDamageSettingsFromMaster", (RpcTarget)1, new object[4] { enableDamageMultiplier, damageMultiplier, enableDamageScaling, damageScalingFactor }); } } else { berserkerScript.StartBerserker(berserkerHealth, ((Component)val).transform.GetSiblingIndex()); } } } if ((Object)(object)_berserkerChosen == (Object)null) { Log.Info("Berserker not spawned!"); } } [HarmonyPatch(typeof(HurtCollider), "EnemyHurt")] [HarmonyPrefix] private static bool EnemyHurt(ref bool __result, HurtCollider __instance, Enemy _enemy) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Expected O, but got Unknown //IL_0338: Unknown result type (might be due to invalid IL or missing references) BerserkerController componentInMainParent = ModPatch.GetComponentInMainParent<BerserkerController>(((Component)_enemy).transform); if (!enableBerserker || !componentInMainParent.isBerserkerFlag) { return true; } FieldInfo fieldInfo = AccessTools.Field(typeof(Enemy), "EnemyParent"); EnemyParent val = (EnemyParent)fieldInfo.GetValue(_enemy); FieldInfo fieldInfo2 = AccessTools.Field(typeof(Enemy), "HasHealth"); FieldInfo fieldInfo3 = AccessTools.Field(typeof(Enemy), "Health"); FieldInfo fieldInfo4 = AccessTools.Field(typeof(Enemy), "HasStateDespawn"); FieldInfo fieldInfo5 = AccessTools.Field(typeof(Enemy), "HasStateStunned"); FieldInfo fieldInfo6 = AccessTools.Field(typeof(Enemy), "StateStunned"); FieldInfo fieldInfo7 = AccessTools.Field(typeof(Enemy), "HasRigidbody"); FieldInfo fieldInfo8 = AccessTools.Field(typeof(Enemy), "Rigidbody"); FieldInfo fieldInfo9 = AccessTools.Field(typeof(EnemyRigidbody), "physGrabObject"); FieldInfo fieldInfo10 = AccessTools.Field(typeof(HurtCollider), "applyForce"); FieldInfo fieldInfo11 = AccessTools.Field(typeof(HurtCollider), "applyTorque"); EnemyRigidbody val2 = (EnemyRigidbody)fieldInfo8.GetValue(_enemy); EnemyHealth val3 = (EnemyHealth)fieldInfo3.GetValue(_enemy); if (_enemy == __instance.enemyHost) { __result = false; return false; } if (!__instance.enemyLogic) { __result = false; return false; } bool masterUnkillable = berserkerUnkillable; if (SemiFunc.IsMultiplayer() && SemiFunc.IsNotMasterClient()) { masterUnkillable = _masterUnkillable; } bool flag = false; if (__instance.enemyKill && !masterUnkillable) { if ((bool)fieldInfo2.GetValue(_enemy)) { val3.Hurt(val3.health, ((Component)__instance).transform.forward); } else if ((bool)fieldInfo4.GetValue(_enemy)) { val.SpawnedTimerSet(0f); _enemy.CurrentState = (EnemyState)11; flag = true; } } if (!flag) { bool masterCanBeStunned = canBeStunned; if (SemiFunc.IsMultiplayer() && SemiFunc.IsNotMasterClient()) { masterCanBeStunned = _masterCanBeStunned; } if (__instance.enemyStun && (bool)fieldInfo5.GetValue(_enemy) && _enemy.Type <= __instance.enemyStunType && masterCanBeStunned) { ((EnemyStateStunned)fieldInfo6.GetValue(_enemy)).Set(__instance.enemyStunTime); } if (__instance.enemyFreezeTime > 0f) { _enemy.Freeze(__instance.enemyFreezeTime); } if ((bool)fieldInfo7.GetValue(_enemy) && !masterUnkillable) { MethodInfo methodInfo = null; MethodInfo[] methods = typeof(HurtCollider).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name == "PhysObjectHurt") { methodInfo = methodInfo2; break; } } if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; if (parameters.Length >= 1) { array[0] = (object)(PhysGrabObject)fieldInfo9.GetValue(val2); } if (parameters.Length >= 2) { array[1] = __instance.enemyImpact; } if (parameters.Length >= 3) { array[2] = __instance.enemyHitForce; } if (parameters.Length >= 4) { array[3] = __instance.enemyHitTorque; } if (parameters.Length >= 5) { array[4] = true; } if (parameters.Length >= 6) { array[5] = false; } for (int j = 6; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; array[j] = ((!parameterType.IsValueType) ? null : Activator.CreateInstance(parameterType)); } try { methodInfo.Invoke(__instance, array); } catch { } } if (__instance.enemyFreezeTime > 0f) { Vector3 val4 = (Vector3)fieldInfo10.GetValue(__instance); Vector3 val5 = (Vector3)fieldInfo11.GetValue(__instance); val2.FreezeForces(val4, val5); } } if (__instance.enemyDamage > 0 && (bool)fieldInfo2.GetValue(_enemy) && !masterUnkillable) { Vector3 val6 = (Vector3)fieldInfo10.GetValue(__instance); val3.Hurt(__instance.enemyDamage, ((Vector3)(ref val6)).normalized); } } __result = true; return false; } [HarmonyPatch(typeof(EnemyParent), "SpawnRPC")] [HarmonyPostfix] private static void SpawnRPCPostfix(EnemyParent __instance) { if ((Object)(object)((Component)__instance).gameObject.GetComponent<BerserkerController>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<BerserkerController>(); if (showDebugLogs) { Log.Info("BerserkerController added to enemy " + __instance.enemyName + "!"); } } } [HarmonyPatch(typeof(EnemyParent), "Despawn")] [HarmonyPrefix] public static bool DespawnPrefix(EnemyParent __instance) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) if (!enableBerserker) { return true; } BerserkerController berserkerController = ((Component)__instance).GetComponent<BerserkerController>(); if ((Object)(object)berserkerController == (Object)null) { berserkerController = ((Component)__instance).gameObject.AddComponent<BerserkerController>(); if (showDebugLogs) { Log.Info("BerserkerController added to enemy " + __instance.enemyName + "!"); } } if ((Object)(object)berserkerScript == (Object)null) { return true; } if ((Object)(object)berserkerController == (Object)null) { Log.Warn("BerserkerController not found in enemy " + __instance.enemyName + "!"); return true; } if (!berserkerController.isBerserkerFlag) { if (showDebugLogs) { Log.Info("Enemy " + __instance.enemyName + " is not Berserker!"); } return true; } if (GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient) { return false; } FieldInfo fieldInfo = AccessTools.Field(typeof(EnemyParent), "Enemy"); Enemy val = (Enemy)fieldInfo.GetValue(__instance); if ((Object)(object)val == (Object)null) { Log.Warn("CurrentEnemy is null! Dropping default valuable!"); return true; } val.CurrentState = (EnemyState)11; float num = (float)AccessTools.Field(typeof(EnemyDirector), "despawnedTimeMultiplier").GetValue(EnemyDirector.instance); __instance.DespawnedTimer = Mathf.Max(Random.Range(__instance.DespawnedTimeMin, __instance.DespawnedTimeMax) * num, 1f); if ((bool)AccessTools.Field(typeof(Enemy), "HasRigidbody").GetValue(val)) { EnemyRigidbody val2 = (EnemyRigidbody)AccessTools.Field(typeof(Enemy), "Rigidbody").GetValue(val); AccessTools.Field(typeof(EnemyRigidbody), "grabbed").SetValue(val2, false); AccessTools.Field(typeof(EnemyRigidbody), "grabStrengthTimer").SetValue(val2, 0f); val2.GrabRelease(true, 0.1f); } if (GameManager.Multiplayer()) { ((Component)__instance).GetComponent<PhotonView>().RPC("DespawnRPC", (RpcTarget)0, new object[0]); } else { MethodInfo method = typeof(EnemyParent).GetMethod("DespawnRPC", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { method.Invoke(__instance, new object[0]); } } EnemyHealth component = ((Component)val).GetComponent<EnemyHealth>(); FieldInfo fieldInfo2 = AccessTools.Field(typeof(Enemy), "HasHealth"); if (!(bool)fieldInfo2.GetValue(val) || component.health > 0) { return false; } GameObject val3 = _assetBundle.LoadAsset<GameObject>("Enemy Valuable - Berserker"); Transform val4 = val.CustomValuableSpawnTransform ?? val.CenterTransform; GameObject val5 = ((!SemiFunc.IsMultiplayer()) ? Object.Instantiate<GameObject>(val3, val4.position, Quaternion.identity) : NetworkPrefabs.SpawnNetworkPrefab(NetworkPrefabs.GetNetworkPrefabRef("Enemy Valuable - Berserker"), val4.position, Quaternion.identity, (byte)0, (object[])null)); float orbValueMax = currentBerserkerValuableMax; float orbValueMin = currentBerserkerValuableMin; if (SemiFunc.IsMultiplayer() && SemiFunc.IsNotMasterClient()) { orbValueMax = _orbValueMax; orbValueMin = _orbValueMin; } ScriptableObject obj = _assetBundle.LoadAsset<ScriptableObject>("Value - Berserker"); Value val6 = (Value)(object)((obj is Value) ? obj : null); val6.valueMax = orbValueMax; val6.valueMin = orbValueMin; if (!canBeStunned) { val6.valueMax += 2000f; val6.valueMin += 2000f; if (showDebugLogs) { Log.Info("Added bonus orb value for non-stunnable Berserker!"); } } val5.GetComponent<ValuableObject>().valuePreset = val6; __instance.DespawnedTimer *= 3f; return false; } public static int CalculateHealthScaling(int baseHealth) { return baseHealth + (RunManager.instance.levelsCompleted + 1 - startingLevel) * (SemiFunc.PlayerGetAll().Count * healthScalingFactor); } public static void CalculateOrbValue(int bHealth, out float outMax, out float outMin) { int num = maxHealth; if (enableHealthScaling) { num += (RunManager.instance.levelsCompleted + 1 - startingLevel) * (SemiFunc.PlayerGetAll().Count * healthScalingFactor); } float num2 = Mathf.InverseLerp((float)minHealth, (float)num, (float)bHealth); outMax = Mathf.Lerp(maxOrbValueSubtract, maximumOrbValue, num2); outMin = outMax - Mathf.Lerp(minOrbValueSubtract, minimumOrbValue, num2); } public static int CalculateBerserkerDamage(int baseDamage, bool masterValues) { bool flag = ((!masterValues) ? enableDamageMultiplier : _masterEnableDamageMultiplier); float num = ((!masterValues) ? damageMultiplier : _masterDamageMultiplier); bool flag2 = ((!masterValues) ? enableDamageScaling : _masterEnableDamageScaling); int num2 = ((!masterValues) ? damageScalingFactor : _masterDamageScalingFactor); if (!flag) { return baseDamage; } float num3 = ((!flag) ? ((float)baseDamage) : ((float)baseDamage * num)); if (flag && flag2) { int num4 = RunManager.instance.levelsCompleted + 1 - startingLevel; int count = SemiFunc.PlayerGetAll().Count; num3 += (float)(num4 * count * num2); } return Mathf.Max(1, Mathf.RoundToInt(num3)); } public static int GetScalingBerserkers() { int num = (RunManager.instance.levelsCompleted + 1 - startingLevel) / berserkerScalingLevel; return Mathf.Min(maxBerserkersAllowed + num, maxScalingBerserkers); } public static T GetComponentInChildrenRecursive<T>(Transform obj) where T : Component { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown foreach (Transform item in obj) { Transform val = item; T component = ((Component)val).GetComponent<T>(); if ((Object)(object)component != (Object)null) { return component; } component = GetComponentInChildrenRecursive<T>(val); if ((Object)(object)component != (Object)null) { return component; } } return (T)(object)null; } public static T GetComponentInMainParent<T>(Transform obj) where T : Component { Transform parent = obj.parent; T result = (T)(object)null; while ((Object)(object)parent != (Object)null) { T component = ((Component)parent).GetComponent<T>(); if ((Object)(object)component != (Object)null) { result = component; } parent = parent.parent; } return result; } public static List<string> GetEnemyTypes() { List<string> list = new List<string>(); if (enableAnimal) { list.Add("Animal"); } if (enableApexPredator) { list.Add("Apex Predator"); } if (enableBowtie) { list.Add("Bowtie"); } if (enableChef) { list.Add("Chef"); } if (enableClown) { list.Add("Clown"); } if (enableHeadman) { list.Add("Headman"); } if (enableHuntsman) { list.Add("Huntsman"); } if (enableMentalist) { list.Add("Mentalist"); } if (enableReaper) { list.Add("Reaper"); } if (enableRobe) { list.Add("Robe"); } if (enableRugrat) { list.Add("Rugrat"); } if (enableShadowChild) { list.Add("Shadow Child"); } if (enableSpewer) { list.Add("Spewer"); } if (enableTrudge) { list.Add("Trudge"); } if (enableUpscream) { list.Add("Upscream"); } if (enableBella) { list.Add("Bella"); } if (enableElsa) { list.Add("Elsa"); } if (enableBirthdayBoy) { list.Add("Birthday Boy"); } if (enableTick) { list.Add("Tick"); } if (enableOogly) { list.Add("Oogly"); } if (enableHeartHugger) { list.Add("Heart Hugger"); } if (enableHeadgrab) { list.Add("Headgrab"); } if (enableLoom) { list.Add("Loom"); } if (enablePeeper) { list.Add("Peeper"); } if (enableGambit) { list.Add("Gambit"); } if (containModded) { if (enableGusher) { list.Add("Gusher"); } if (enableRoaster) { list.Add("Roaster"); } if (enableDroid) { list.Add("Lost droid"); } if (enableDestroyer) { list.Add("Lost Destroyer"); } if (enableSoldier) { list.Add("Soldier"); } if (enableFreddyFazbear) { list.Add("Freddy Fazbear"); } if (enableBaldi) { list.Add("Baldi"); } if (enableMoon) { list.Add("The Moon"); } if (enableRobot) { list.Add("Robot"); } if (enableRollingGiant) { list.Add("Rolling Giant"); } if (enableZombie) { list.Add("Zombie"); } if (enableDriller) { list.Add("Driller"); } } return list; } } internal class BerserkerManager : MonoBehaviourPunCallbacks { public static BerserkerManager instance; public EnemyParent berserkerChosen; private static Transform berserkerChosenTransform; private static ParticleSystem berserkerParticlesObjPS; private List<int[]> pendingBerserkers = new List<int[]>(); private bool levelReady = false; public string DEBUG_ENEMY_NAME = ""; private static MethodInfo _mi_overrideGrabForceZero = null; private static MethodInfo _mi_anim = null; private static bool _anim_checked = false; private void Awake() { instance = this; } private void Update() { //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected I4, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) if (!ModPatch.enableBerserker || EnemyDirector.instance.enemiesSpawned.Count <= 0) { return; } if (!levelReady && SemiFunc.LevelGenDone()) { levelReady = true; StartPendingBerserkers(); } for (int i = 0; i < EnemyDirector.instance.enemiesSpawned.Count; i++) { Enemy val = null; try { val = GetBerserkerEnemyScript(((Component)EnemyDirector.instance.enemiesSpawned[i]).transform); } catch { continue; } if ((Object)(object)val == (Object)null) { if (ModPatch.showDebugLogs) { Log.Warn("Enemy script is null!"); } continue; } EnemyParent componentInMainParent = ModPatch.GetComponentInMainParent<EnemyParent>(((Component)val).transform); if ((Object)(object)componentInMainParent == (Object)null) { if (ModPatch.showDebugLogs) { Log.Warn("EnemyParent script is null!"); } continue; } try { if (componentInMainParent.enemyName == "Freddy Fazbear") { val = GetBerserkerEnemyScript(((Component)componentInMainParent).transform); if ((Object)(object)val != (Object)null && ((Component)((Component)val).transform.parent).gameObject.activeInHierarchy) { GameObject gameObject = ((Component)((Component)val).transform.parent.GetChild(2).GetChild(3).GetChild(0) .GetChild(3)).gameObject; if ((Object)(object)gameObject != (Object)null && (Object)(object)berserkerParticlesObjPS != (Object)null) { if (gameObject.transform.localPosition.z > 0f) { if (berserkerParticlesObjPS.isPlaying) { berserkerParticlesObjPS.Stop(); } } else if (berserkerParticlesObjPS.isStopped) { berserkerParticlesObjPS.Play(); } } } } } catch (Exception ex) { Log.Warn("Error while processing Freddy Fazbear: " + ex); } try { if (componentInMainParent.enemyName != "Spewer") { continue; } val = GetBerserkerEnemyScript(((Component)componentInMainParent).transform); if ((Object)(object)val == (Object)null || !((Component)((Component)val).transform.parent).gameObject.activeInHierarchy) { continue; } EnemySlowMouth component = ((Component)val).GetComponent<EnemySlowMouth>(); if ((Object)(object)berserkerParticlesObjPS == (Object)null) { continue; } int num = (int)component.currentState; if (num == 9 || num == 10) { if (berserkerParticlesObjPS.isPlaying) { berserkerParticlesObjPS.Stop(); } } else if (berserkerParticlesObjPS.isStopped) { berserkerParticlesObjPS.Play(); } } catch (Exception ex2) { Log.Warn("Error while processing Spewer: " + ex2); } } } public override void OnPlayerEnteredRoom(Player newPlayer) { if (PhotonNetwork.IsMasterClient && SemiFunc.RunIsLevel() && ModPatch.enableBerserker) { Log.Info(newPlayer.NickName + " joined! Sending berserker data..."); ((MonoBehaviour)this).StartCoroutine(DelayedStartBerserker(newPlayer)); } } private IEnumerator DelayedStartBerserker(Player newPlayer) { yield return (object)new WaitUntil((Func<bool>)(() => SemiFunc.LevelGenDone())); foreach (int enemyIndex in ModPatch.enemyIndexes) { ((MonoBehaviourPun)this).photonView.RPC("SyncBerserkerToPlayer", (RpcTarget)1, new object[11] { newPlayer.ActorNumber, ModPatch.berserkerHealth, enemyIndex, ModPatch.canBeStunned, ModPatch.berserkerUnkillable, ModPatch._orbValueMax, ModPatch._orbValueMin, ModPatch.enableDamageMultiplier, ModPatch.damageMultiplier, ModPatch.enableDamageScaling, ModPatch.damageScalingFactor }); } } [PunRPC] public void GetCanBeStunnedFromMaster(bool v) { ModPatch._masterCanBeStunned = v; } [PunRPC] public void GetUnkillableVariableFromMaster(bool v) { ModPatch._masterUnkillable = v; } [PunRPC] public void GetOrbValuableFromMaster(float vMax, float vMin) { ModPatch._orbValueMax = vMax; ModPatch._orbValueMin = vMin; } [PunRPC] public void GetDamageSettingsFromMaster(bool enableMult, float mult, bool enableScale, int scaleFactor) { ModPatch._masterEnableDamageMultiplier = enableMult; ModPatch._masterDamageMultiplier = mult; ModPatch._masterEnableDamageScaling = enableScale; ModPatch._masterDamageScalingFactor = scaleFactor; } [PunRPC] public void SyncBerserkerToPlayer(int actorNumber, int bHealth, int enemyIndex, bool stunnable, bool unkillable, float orbMax, float orbMin, bool enableDamageMult, float damageMult, bool enableDmgScale, int dmgScaleFactor) { if (PhotonNetwork.LocalPlayer.ActorNumber == actorNumber) { ModPatch._masterCanBeStunned = stunnable; ModPatch._masterUnkillable = unkillable; ModPatch._orbValueMax = orbMax; ModPatch._orbValueMin = orbMin; ModPatch._masterEnableDamageMultiplier = enableDamageMult; ModPatch._masterDamageMultiplier = damageMult; ModPatch._masterEnableDamageScaling = enableDmgScale; ModPatch._masterDamageScalingFactor = dmgScaleFactor; pendingBerserkers.Add(new int[2] { bHealth, enemyIndex }); if (levelReady) { StartPendingBerserkers(); } } } private void StartPendingBerserkers() { foreach (int[] pendingBerserker in pendingBerserkers) { StartBerserker(pendingBerserker[0], pendingBerserker[1]); } pendingBerserkers.Clear(); } [PunRPC] public void StartBerserker(int bHealth, int enemyIndex) { berserkerChosen = EnemyDirector.instance.enemiesSpawned[enemyIndex]; if ((Object)(object)berserkerChosen == (Object)null) { if (ModPatch.showDebugLogs) { Log.Warn("Berserker Chosen is null!"); } return; } if ((Object)(object)((Component)berserkerChosen).GetComponent<BerserkerController>() == (Object)null) { ((Component)berserkerChosen).gameObject.AddComponent<BerserkerController>(); } BerserkerController component = ((Component)berserkerChosen).gameObject.GetComponent<BerserkerController>(); if (!component.isBerserkerFlag) { component.isBerserkerFlag = true; } if (ModPatch.showDebugLogs) { Log.Info("Setting up Berserker " + berserkerChosen.enemyName + " properties..."); } else { Log.Info("Setting up Berserker properties..."); } berserkerChosenTransform = ((Component)berserkerChosen).transform; SetBerserkerValues(berserkerChosen, berserkerChosenTransform, bHealth); SetBerserkerGrabForce(berserkerChosenTransform); string enemyName = ((Component)berserkerChosenTransform).GetComponent<EnemyParent>().enemyName; if (enemyName != "Hidden") { SetBerserkerGlow(berserkerChosenTransform); SetBerserkerSmoke(berserkerChosenTransform); } else { SetUpHidden(berserkerChosenTransform); } SetBerserkerDamage(berserkerChosenTransform); if (ModPatch.enableGrabImmunity) { SetBerserkerGrabImmunity(berserkerChosenTransform); } Log.Info("Berserker configured!"); } private static void SetBerserkerValues(EnemyParent enemyParent, Transform enemy, int masterHealth) { bool flag = SemiFunc.IsMultiplayer() && SemiFunc.IsNotMasterClient(); int num = ((!flag) ? ModPatch.berserkerHealth : masterHealth); bool flag2 = ((!flag) ? ModPatch.berserkerUnkillable : ModPatch._masterUnkillable); bool flag3 = ((!flag) ? ModPatch.canBeStunned : ModPatch._masterCanBeStunned); EnemyHealth berserkerHealthScript = GetBerserkerHealthScript(enemy); if ((Object)(object)berserkerHealthScript != (Object)null) { AccessTools.Field(typeof(EnemyHealth), "healthCurrent").SetValue(berserkerHealthScript, num); berserkerHealthScript.health = num; if (flag2) { berserkerHealthScript.impactHurt = false; berserkerHealthScript.objectHurt = false; berserkerHealthScript.objectHurtStun = false; } } if (ModPatch.showDebugLogs && flag3) { Log.Info("Berserker can be stunned!"); } Enemy berserkerEnemyScript = GetBerserkerEnemyScript(enemy); if ((Object)(object)berserkerEnemyScript != (Object)null && !flag3) { AccessTools.Field(typeof(Enemy), "HasStateStunned").SetValue(berserkerEnemyScript, false); if (ModPatch.showDebugLogs) { Log.Info("Berserker " + enemyParent.enemyName + " - Stunned state removed!"); } } EnemyRigidbody berserkerRigidbodyScript = GetBerserkerRigidbodyScript(enemy); if ((Object)(object)berserkerRigidbodyScript != (Object)null && !flag3) { berserkerRigidbodyScript.grabStun = false; berserkerRigidbodyScript.stunFromFall = false; if (ModPatch.showDebugLogs) { Log.Info($"Berserker {enemyParent.enemyName} - Grab Stun: {berserkerRigidbodyScript.grabStun}"); } Log.Info($"Berserker {enemyParent.enemyName} - Stun From Fall: {berserkerRigidbodyScript.stunFromFall}"); } } private static void SetBerserkerDamage(Transform enemy) { bool flag = SemiFunc.IsMultiplayer() && SemiFunc.IsNotMasterClient(); if (!((!flag) ? ModPatch.enableDamageMultiplier : ModPatch._masterEnableDamageMultiplier)) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(HurtCollider), "playerDamage"); if (fieldInfo == null) { Log.Warn("playerDamage field not found on HurtCollider - damage scaling skipped."); return; } HurtCollider[] componentsInChildren = ((Component)enemy).GetComponentsInChildren<HurtCollider>(true); HurtCollider[] array = componentsInChildren; foreach (HurtCollider val in array) { int num = (int)fieldInfo.GetValue(val); int num2 = ModPatch.CalculateBerserkerDamage(num, flag); fieldInfo.SetValue(val, num2); if (ModPatch.showDebugLogs) { Log.Info($"HurtCollider on {((Object)val).name}: playerDamage {num} -> {num2}"); } } } private static void SetBerserkerGrabImmunity(Transform enemy) { if (_mi_overrideGrabForceZero == null) { _mi_overrideGrabForceZero = typeof(PhysGrabObject).GetMethod("OverrideGrabForceZero", BindingFlags.Instance | BindingFlags.Public); } if (_mi_overrideGrabForceZero == null) { Log.Warn("OverrideGrabForceZero method not found - grab immunity skipped."); return; } object[] parameters = new object[1] { 99999f }; PhysGrabObject[] componentsInChildren = ((Component)enemy).GetComponentsInChildren<PhysGrabObject>(true); PhysGrabObject[] array = componentsInChildren; foreach (PhysGrabObject val in array) { try { _mi_overrideGrabForceZero.Invoke(val, parameters); } catch { } if (ModPatch.showDebugLogs) { Log.Info("Grab immunity set on " + ((Object)val).name); } } PhysGrabObject component = ((Component)enemy).GetComponent<PhysGrabObject>(); if (!((Object)(object)component != (Object)null)) { return; } try { _mi_overrideGrabForceZero.Invoke(component, parameters); } catch { } } private static void EnsureMethodCache() { if (!_anim_checked) { _anim_checked = true; _mi_anim = typeof(Enemy).GetMethod("OverrideAnimationSpeed", BindingFlags.Instance | BindingFlags.Public); } } private static void SetBerserkerGlow(Transform enemy) { Renderer[] componentsInChildren = ((Component)enemy).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] materials = val.materials; foreach (Material val2 in materials) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.shader == (Object)null) { continue; } switch (((Object)val2.shader).name) { case "Hurtable/Hurtable": case "Hurtable/Hurtable Alpha Clip": case "Patcher/Hurtable/Hurtable": case "Patcher/Hurtable/Hurtable Alpha Clip": case "Ortong/Hurtable": case "Orton/Hurtable/Hurtable Freddy": case "Orton/Hurtable Alpha Clip": ApplyFresnel(val2); break; case "Standard": { Texture texture = val2.GetTexture("_MainTex"); Shader shader = ((!Application.isEditor) ? Shader.Find("Hurtable/Hurtable") : Shader.Find("Patcher/Hurtable/Hurtable")); val2.shader = shader; if (val2.HasProperty("_AlbedoTexture")) { val2.SetTexture("_AlbedoTexture", texture); } ApplyFresnel(val2); break; } } } } } private static void ApplyFresnel(Material mat) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) mat.SetFloat("_FresnelAmount", 1f); mat.SetFloat("_FresnelScale", 1f); mat.SetFloat("_FresnelPower", 5f); mat.SetFloat("_FresnelBias", 0f); mat.SetColor("_FresnelColor", Color.red); mat.SetFloat("_FresnelEmission", 1f); } private static void SetBerserkerGrabForce(Transform enemy) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown GrabForce val = ScriptableObject.CreateInstance<GrabForce>(); val.amount = 1E+10f; ((Object)val).name = "Grab Force - Berserker"; foreach (Transform item in enemy) { Transform berserkerGrabForce = item; EnemyRigidbody component = ((Component)enemy).gameObject.GetComponent<EnemyRigidbody>(); if ((Object)(object)component != (Object)null && component.grabForceNeeded != val) { component.grabForceNeeded = val; } SetBerserkerGrabForce(berserkerGrabForce); } } private static Transform GetBerserkerParticleParent(Transform enemy) { Animator componentInChildrenRecursive = ModPatch.GetComponentInChildrenRecursive<Animator>(enemy); return (!((Object)(object)componentInChildrenRecursive != (Object)null)) ? null : ((Component)componentInChildrenRecursive).transform; } private static void SetBerserkerSmoke(Transform enemy) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) Transform berserkerParticleParent = GetBerserkerParticleParent(enemy); GameObject val = ModPatch._assetBundle.LoadAsset<GameObject>("BerserkerAura"); GameObject val2 = Object.Instantiate<GameObject>(val); berserkerParticlesObjPS = val2.GetComponent<ParticleSystem>(); if ((Object)(object)berserkerParticleParent != (Object)null) { val2.transform.SetParent(berserkerParticleParent, false); } string enemyName = ((Component)enemy).GetComponent<EnemyParent>().enemyName; Vector3 zero = Vector3.zero; switch (enemyName) { case "Robe": case "Reaper": case "Clown": case "Huntsman": case "Soldier": case "Soldier Ghost": case "Lost droid": case "Lost Destroyer": case "Zombie": case "Bella": case "Birthday Boy": case "Headgrab": case "Peeper": case "Gambit": case "Elsa": ((Vector3)(ref zero))..ctor(0f, 1f, 0f); break; case "Trudge": case "Gusher": case "Roaster": case "Freddy Fazbear": case "Shadow Child": case "Rolling Giant": case "Robot": case "Driller": case "Loom": case "Oogly": case "Heart Hugger": ((Vector3)(ref zero))..ctor(0f, 1.5f, 0f); break; } val2.transform.localPosition = zero; val2.transform.localRotation = Quaternion.identity; } private static Enemy GetBerserkerEnemyScript(Transform enemy) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown foreach (Transform item in enemy) { Transform val = item; if (((Object)val).name == "Controller") { Enemy component = ((Component)val).GetComponent<Enemy>(); if ((Object)(object)component != (Object)null) { return component; } } Enemy berserkerEnemyScript = GetBerserkerEnemyScript(val); if ((Object)(object)berserkerEnemyScript != (Object)null) { return berserkerEnemyScript; } } return null; } private static EnemyRigidbody GetBerserkerRigidbodyScript(Transform enemy) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown foreach (Transform item in enemy) { Transform val = item; if (((Object)val).name == "Rigidbody") { EnemyRigidbody component = ((Component)val).GetComponent<EnemyRigidbody>(); if ((Object)(object)component != (Object)null) { return component; } } EnemyRigidbody berserkerRigidbodyScript = GetBerserkerRigidbodyScript(val); if ((Object)(object)berserkerRigidbodyScript != (Object)null) { return berserkerRigidbodyScript; } } return null; } private static EnemyHealth GetBerserkerHealthScript(Transform enemy) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown foreach (Transform item in enemy) { Transform val = item; if (((Object)val).name == "Controller") { EnemyHealth component = ((Component)val).GetComponent<EnemyHealth>(); if ((Object)(object)component != (Object)null) { return component; } } EnemyHealth berserkerHealthScript = GetBerserkerHealthScript(val); if ((Object)(object)berserkerHealthScript != (Object)null) { return berserkerHealthScript; } } return null; } private static void SetUpHidden(Transform enemy) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) GameObject val = ModPatch._assetBundle.LoadAsset<GameObject>("Berserker Hidden Breath"); GameObject val2 = ModPatch._assetBundle.LoadAsset<GameObject>("Berserker Hidden Breath Constant"); GameObject val3 = ModPatch._assetBundle.LoadAsset<GameObject>("Berserker Hidden Breath Fast"); GameObject val4 = ModPatch._assetBundle.LoadAsset<GameObject>("Berserker Hidden Foot Shape Left"); GameObject val5 = ModPatch._assetBundle.LoadAsset<GameObject>("Berserker Hidden Foot Shape Right"); for (int i = 0; i < 5; i++) { ((Component)enemy.GetChild(0).GetChild(i)).gameObject.SetActive(false); } Transform child = enemy.GetChild(1).GetChild(1).GetChild(6) .GetChild(0); ConstraintSource val6 = default(ConstraintSource); ((ConstraintSource)(ref val6)).sourceTransform = child; ((ConstraintSource)(ref val6)).weight = 1f; ConstraintSource val7 = val6; Vector3 translationAtRest = default(Vector3); ((Vector3)(ref translationAtRest))..ctor(0f, 1.826f, -2.702927f); GameObject val8 = Object.Instantiate<GameObject>(val, enemy.GetChild(0).GetChild(0).position, enemy.GetChild(0).GetChild(0).rotation, enemy.GetChild(0)); val8.transform.SetSiblingIndex(0); GameObject val9 = Object.Instantiate<GameObject>(val3, enemy.GetChild(0).GetChild(1).position, enemy.GetChild(0).GetChild(1).rotation, enemy.GetChild(0)); val9.transform.SetSiblingIndex(1); GameObject val10 = Object.Instantiate<GameObject>(val2, enemy.GetChild(0).GetChild(2).position, enemy.GetChild(0).GetChild(2).rotation, enemy.GetChild(0)); val10.transform.SetSiblingIndex(2); GameObject val11 = Object.Instantiate<GameObject>(val5, enemy.GetChild(0).GetChild(3).position, enemy.GetChild(0).GetChild(3).rotation, enemy.GetChild(0)); val11.transform.SetSiblingIndex(3); GameObject val12 = Object.Instantiate<GameObject>(val4, enemy.GetChild(0).GetChild(4).position, enemy.GetChild(0).GetChild(4).rotation, enemy.GetChild(0)); val12.transform.SetSiblingIndex(4); ParentConstraint component = val8.GetComponent<ParentConstraint>(); component.SetSource(0, val7); component.translationAtRest = translationAtRest; ParentConstraint component2 = val9.GetComponent<ParentConstraint>(); component2.SetSource(0, val7); component2.translationAtRest = translationAtRest; ParentConstraint component3 = val10.GetComponent<ParentConstraint>(); component3.SetSource(0, val7); component3.translationAtRest = translationAtRest; EnemyHiddenAnim component4 = ((Component)enemy.GetChild(1).GetChild(1).GetChild(6)).GetComponent<EnemyHiddenAnim>(); component4.particleBreath = val8.GetComponent<ParticleSystem>(); component4.particleBreathFast = val9.GetComponent<ParticleSystem>(); component4.particleBreathConstant = val10.GetComponent<ParticleSystem>(); component4.particleFootstepShapeLeft = val12.GetComponent<ParticleSystem>(); component4.particleFootstepShapeRight = val11.GetComponent<ParticleSystem>(); } } public class BerserkerController : MonoBehaviourPun { public bool isBerserkerFlag = false; } namespace BerserkerEnemies; [BepInPlugin("Aolion.BerserkerEnemies_Reborn", "Berserker Enemies Reborn", "1.6.0")] public class ModBase : BaseUnityPlugin { private Harmony _harmony = new Harmony("Aolion.BerserkerEnemies_Reborn"); public static ConfigEntry<bool> config_EnableBerserker; public static ConfigEntry<bool> config_showDebugLogs; public static ConfigEntry<bool> config_BerserkerUnkillable; public static ConfigEntry<bool> config_CanBeStunned; public static ConfigEntry<int> config_BerserkerHealth; public static ConfigEntry<bool> config_EnableHealthScaling; public static ConfigEntry<int> config_HealthScalingFactor; public static ConfigEntry<bool> config_EnableDamageMultiplier; public static ConfigEntry<float> config_DamageMultiplier; public static ConfigEntry<bool> config_EnableDamageScaling; public static ConfigEntry<int> config_DamageScalingFactor; public static ConfigEntry<int> config_MaxBerserkers; public static ConfigEntry<int> config_StartingLevel; public static ConfigEntry<float> config_berserkerSpawnChance; public static ConfigEntry<float> config_berserkerSpawnChancePerLevel; public static ConfigEntry<bool> config_EnableBerserkerScaling; public static ConfigEntry<bool> config_ForceSpawnWhenScaling; public static ConfigEntry<int> config_BerserkerScalingLevel; public static ConfigEntry<int> config_MaxScalingBerserkers; public static ConfigEntry<bool> config_EnableGrabImmunity; public static ConfigEntry<bool> config_enableAnimal; public static ConfigEntry<bool> config_enableApexPredator; public static ConfigEntry<bool> config_enableChef; public static ConfigEntry<bool> config_enableClown; public static ConfigEntry<bool> config_enableBowtie; public static ConfigEntry<bool> config_enableMentalist; public static ConfigEntry<bool> config_enableHeadman; public static ConfigEntry<bool> config_enableHuntsman; public static ConfigEntry<bool> config_enableReaper; public static ConfigEntry<bool> config_enableRobe; public static ConfigEntry<bool> config_enableRugrat; public static ConfigEntry<bool> config_enableShadowChild; public static ConfigEntry<bool> config_enableSpewer; public static ConfigEntry<bool> config_enableTrudge; public static ConfigEntry<bool> config_enableUpscream; public static ConfigEntry<bool> config_enableBella; public static ConfigEntry<bool> config_enableElsa; public static ConfigEntry<bool> config_enableBirthdayBoy; public static ConfigEntry<bool> config_enableTick; public static ConfigEntry<bool> config_enableOogly; public static ConfigEntry<bool> config_enableHeartHugger; public static ConfigEntry<bool> config_enableHeadgrab; public static ConfigEntry<bool> config_enableLoom; public static ConfigEntry<bool> config_enablePeeper; public static ConfigEntry<bool> config_enableGambit; public static ConfigEntry<bool> config_enableDestroyer; public static ConfigEntry<bool> config_enableDroid; public static ConfigEntry<bool> config_enableGusher; public static ConfigEntry<bool> config_enableRoaster; public static ConfigEntry<bool> config_enableSoldier; public static ConfigEntry<bool> config_enableFreddyFazbear; public static ConfigEntry<bool> config_enableBaldi; public static ConfigEntry<bool> config_enableZeldaMoon; public static ConfigEntry<bool> config_enableRetermninator; public static ConfigEntry<bool> config_enableRollinGiant; public static ConfigEntry<bool> config_enableMCZombie; public static ConfigEntry<bool> config_enableDrillerKiller; public void Awake() { Log.Init(((BaseUnityPlugin)this).Logger); Log.Info("BerserkerEnemies Reborn loaded!"); _harmony.PatchAll(typeof(ModBase)); _harmony.PatchAll(typeof(ModPatch)); ConfigFile(); SetUpBundle(); } public void SetUpBundle() { string directoryName = Path.GetDirectoryName(typeof(ModBase).Assembly.Location); string text = Path.Combine(directoryName, "berserker_enemies"); if (!File.Exists(text)) { Log.Error("AssetBundle not found: " + text); return; } AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { Log.Error("Failed to load AssetBundle from: " + text); return; } ModPatch._assetBundle = val; GameObject val2 = val.LoadAsset<GameObject>("Enemy Valuable - Berserker"); NetworkPrefabs.RegisterNetworkPrefab(((Object)val2).name, val2); Log.Info("AssetBundle loaded successfully!"); } public void ConfigFile() { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Expected O, but got Unknown //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Expected O, but got Unknown //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Expected O, but got Unknown //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Expected O, but got Unknown //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Expected O, but got Unknown //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Expected O, but got Unknown config_EnableBerserker = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable the Berserker enemy."); ModPatch.enableBerserker = config_EnableBerserker.Value; config_showDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Debug Logs", false, "Enable or disable debug logs."); ModPatch.showDebugLogs = config_showDebugLogs.Value; config_BerserkerUnkillable = ((BaseUnityPlugin)this).Config.Bind<bool>("Berserkers Settings", "Unkillable", false, "If enabled, the Berserker cannot be killed."); ModPatch.berserkerUnkillable = config_BerserkerUnkillable.Value; config_CanBeStunned = ((BaseUnityPlugin)this).Config.Bind<bool>("Berserkers Settings", "Stunnable", false, "If enabled, the Berserker can be stunned."); ModPatch.canBeStunned = config_CanBeStunned.Value; config_BerserkerHealth = ((BaseUnityPlugin)this).Config.Bind<int>("Health Settings", "Health", 2000, new ConfigDescription("Base health of the Berserker.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(ModPatch.minHealth, ModPatch.maxHealth), Array.Empty<object>())); ModPatch.berserkerHealth = config_BerserkerHealth.Value; config_EnableHealthScaling = ((BaseUnityPlugin)this).Config.Bind<bool>("Health Settings", "Scaling", true, "Scale health based on level and player count."); ModPatch.enableHealthScaling = config_EnableHealthScaling.Value; config_HealthScalingFactor = ((BaseUnityPlugin)this).Config.Bind<int>("Health Settings", "Scale Factor", 10, "Health bonus per (level x players)."); ModPatch.healthScalingFactor = config_HealthScalingFactor.Value; config_EnableGrabImmunity = ((BaseUnityPlugin)this).Config.Bind<bool>("Grab Immunity", "Enable Grab Immunity", true, "When true, the Berserker cannot be lifted or grabbed regardless of player strength."); ModPatch.enableGrabImmunity = config_EnableGrabImmunity.Value; config_EnableDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<bool>("Damage Settings", "Enable Damage Multiplier", true, "Master switch for damage modification. Damage Scaling also requires this to be enabled."); ModPatch.enableDamageMultiplier = config_EnableDamageMultiplier.Value; config_DamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Damage Settings", "Damage Multiplier", 1.5f, new ConfigDescription("Base multiplier applied to each HurtCollider's playerDamage. 1.5 = 50% more damage than normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); ModPatch.damageMultiplier = config_DamageMultiplier.Value; config_EnableDamageScaling = ((BaseUnityPlugin)this).Config.Bind<bool>("Damage Settings", "Enable Damage Scaling", false, "When true, adds an extra flat bonus on top of the multiplied value: bonus = levelsAboveStart x players x Damage Scaling Factor. Requires Enable Damage Multiplier to be on."); ModPatch.enableDamageScaling = config_EnableDamageScaling.Value; config_DamageScalingFactor = ((BaseUnityPlugin)this).Config.Bind<int>("Damage Settings", "Damage Scaling Factor", 10, "Per-(level x player) flat damage bonus added after the multiplier when Damage Scaling is enabled."); ModPatch.damageScalingFactor = config_DamageScalingFactor.Value; config_MaxBerserkers = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn Settings", "Max Berserkers", 1, new ConfigDescription("Max Berserkers at once.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>())); ModPatch.maxBerserkersAllowed = config_MaxBerserkers.Value; config_StartingLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn Settings", "Starting Level", 9, new ConfigDescription("Min level required for spawn.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); ModPatch.startingLevel = config_StartingLevel.Value; config_berserkerSpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Settings", "Chance", 10f, new ConfigDescription("Base spawn chance %.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); ModPatch.berserkerSpawnChance = config_berserkerSpawnChance.Value; config_berserkerSpawnChancePerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn Settings", "Extra Chance Per Level", 5f, new ConfigDescription("Extra spawn chance % per level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>())); ModPatch.berserkerSpawnChancePerLevel = config_berserkerSpawnChancePerLevel.Value; config_EnableBerserkerScaling = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn Settings", "Scaling", false, "Enable dynamic Berserker limit increase based on level."); ModPatch.enableBerserkerScaling = config_EnableBerserkerScaling.Value; config_ForceSpawnWhenScaling = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn Settings", "Bypass Spawn Chance", false, "Always spawn when scaling is enabled, ignoring chance."); ModPatch.forceSpawnWhenScaling = config_ForceSpawnWhenScaling.Value; config_BerserkerScalingLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn Settings", "Scaling Step", 10, new ConfigDescription("Levels per extra Berserker allowed.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 20), Array.Empty<object>())); ModPatch.berserkerScalingLevel = config_BerserkerScalingLevel.Value; config_MaxScalingBerserkers = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn Settings", "Max Scaled Berserkers", 3, new ConfigDescription("Max Berserkers when scaling enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); ModPatch.maxScalingBerserkers = config_MaxScalingBerserkers.Value; config_enableAnimal = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Animal", true, ""); ModPatch.enableAnimal = config_enableAnimal.Value; config_enableApexPredator = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Apex Predator", true, ""); ModPatch.enableApexPredator = config_enableApexPredator.Value; config_enableBowtie = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Bowtie", true, ""); ModPatch.enableBowtie = config_enableBowtie.Value; config_enableChef = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Chef", true, ""); ModPatch.enableChef = config_enableChef.Value; config_enableClown = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Clown", true, ""); ModPatch.enableClown = config_enableClown.Value; config_enableHeadman = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Headman", true, ""); ModPatch.enableHeadman = config_enableHeadman.Value; config_enableHuntsman = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Huntsman", true, ""); ModPatch.enableHuntsman = config_enableHuntsman.Value; config_enableMentalist = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Mentalist", true, ""); ModPatch.enableMentalist = config_enableMentalist.Value; config_enableReaper = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Reaper", true, ""); ModPatch.enableReaper = config_enableReaper.Value; config_enableRobe = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Robe", true, ""); ModPatch.enableRobe = config_enableRobe.Value; config_enableRugrat = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Rugrat", true, ""); ModPatch.enableRugrat = config_enableRugrat.Value; config_enableShadowChild = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Shadow Child", true, ""); ModPatch.enableShadowChild = config_enableShadowChild.Value; config_enableSpewer = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Spewer", true, ""); ModPatch.enableSpewer = config_enableSpewer.Value; config_enableTrudge = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Trudge", true, ""); ModPatch.enableTrudge = config_enableTrudge.Value; config_enableUpscream = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "Upscream", true, ""); ModPatch.enableUpscream = config_enableUpscream.Value; config_enableBella = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Bella", true, ""); ModPatch.enableBella = config_enableBella.Value; config_enableElsa = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Elsa", true, ""); ModPatch.enableElsa = config_enableElsa.Value; config_enableBirthdayBoy = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Birthday Boy", true, ""); ModPatch.enableBirthdayBoy = config_enableBirthdayBoy.Value; config_enableTick = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Tick", true, ""); ModPatch.enableTick = config_enableTick.Value; config_enableOogly = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Oogly", true, ""); ModPatch.enableOogly = config_enableOogly.Value; config_enableHeartHugger = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Heart Hugger", true, ""); ModPatch.enableHeartHugger = config_enableHeartHugger.Value; config_enableHeadgrab = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Headgrab", true, ""); ModPatch.enableHeadgrab = config_enableHeadgrab.Value; config_enableLoom = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Loom", true, ""); ModPatch.enableLoom = config_enableLoom.Value; config_enablePeeper = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Peeper", true, ""); ModPatch.enablePeeper = config_enablePeeper.Value; config_enableGambit = ((BaseUnityPlugin)this).Config.Bind<bool>("Monster Update Enemies", "Gambit", true, ""); ModPatch.enableGambit = config_enableGambit.Value; List<string> list = ListPluginFiles(); if (list.Contains("WesleysEnemies.dll")) { ModPatch.containModded = true; config_enableDestroyer = ((BaseUnityPlugin)this).Config.Bind<bool>("Wesleys Enemies", "Destroyer", true, ""); ModPatch.enableDestroyer = config_enableDestroyer.Value; config_enableDroid = ((BaseUnityPlugin)this).Config.Bind<bool>("Wesleys Enemies", "Droid", true, ""); ModPatch.enableDroid = config_enableDroid.Value; config_enableGusher = ((BaseUnityPlugin)this).Config.Bind<bool>("Wesleys Enemies", "Gusher", true, ""); ModPatch.enableGusher = config_enableGusher.Value; config_enableRoaster = ((BaseUnityPlugin)this).Config.Bind<bool>("Wesleys Enemies", "Roaster", true, ""); ModPatch.enableRoaster = config_enableRoaster.Value; config_enableSoldier = ((BaseUnityPlugin)this).Config.Bind<bool>("Wesleys Enemies", "The Soldier", true, ""); ModPatch.enableSoldier = config_enableSoldier.Value; } if (list.Contains("FreddyEnemy.dll")) { ModPatch.containModded = true; config_enableFreddyFazbear = ((BaseUnityPlugin)this).Config.Bind<bool>("Freddy Enemy", "Freddy Fazbear", true, ""); ModPatch.enableFreddyFazbear = config_enableFreddyFazbear.Value; } if (list.Contains("BaldiEnemy.dll")) { ModPatch.containModded = true; config_enableBaldi = ((BaseUnityPlugin)this).Config.Bind<bool>("Baldi Enemy", "Baldi", true, ""); ModPatch.enableBaldi = config_enableBaldi.Value; } if (list.Contains("Zelda_Moon_Mod.repobundle")) { ModPatch.containModded = true; config_enableZeldaMoon = ((BaseUnityPlugin)this).Config.Bind<bool>("Zelda Moon Mod", "The Moon", true, ""); ModPatch.enableMoon = config_enableZeldaMoon.Value; } if (list.Contains("RETEMINATOR.repobundle")) { ModPatch.containModded = true; config_enableRetermninator = ((BaseUnityPlugin)this).Config.Bind<bool>("RETERMINATOR", "Robot", true, ""); ModPatch.enableRobot = config_enableRetermninator.Value; } if (list.Contains("Rolling_Giant_Enemy.repobundle")) { ModPatch.containModded = true; config_enableRollinGiant = ((BaseUnityPlugin)this).Config.Bind<bool>("Rolling Giant Enemy", "Rolling Giant", true, ""); ModPatch.enableRollingGiant = config_enableRollinGiant.Value; } if (list.Contains("MCZombieMod.dll")) { ModPatch.containModded = true; config_enableMCZombie = ((BaseUnityPlugin)this).Config.Bind<bool>("Minecraft Zombie Mod", "Zombie", true, ""); ModPatch.enableZombie = config_enableMCZombie.Value; } if (list.Contains("DrillerKiller.dll")) { ModPatch.containModded = true; config_enableDrillerKiller = ((BaseUnityPlugin)this).Config.Bind<bool>("Driller Killer", "Driller Killer", true, ""); ModPatch.enableDriller = config_enableDrillerKiller.Value; } } public static List<string> ListPluginFiles() { if (config_showDebugLogs != null && config_showDebugLogs.Value) { Log.Info("Checking mods..."); } List<string> list = new List<string>(); string pluginPath = Paths.PluginPath; if (!Directory.Exists(pluginPath)) { Log.Error("Folder " + pluginPath + " not found!"); return list; } foreach (string item in Directory.GetFiles(pluginPath, "*.dll", SearchOption.AllDirectories).Concat(Directory.GetFiles(pluginPath, "*.repobundle", SearchOption.AllDirectories))) { string fileName = Path.GetFileName(item); if (config_showDebugLogs != null && config_showDebugLogs.Value) { Log.Info("Mod found: " + fileName); } list.Add(fileName); } return list; } } public static class Log { public static ManualLogSource Source; public static void Init(ManualLogSource logger) { Source = logger; } public static void Info(object msg) { if (Source != null) { Source.LogInfo(msg); } } public static void Warn(object msg) { if (Source != null) { Source.LogWarning(msg); } } public static void Error(object msg) { if (Source != null) { Source.LogError(msg); } } }