Decompiled source of ButteRyBalance v0.0.1

ButteRyBalance.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ButteRyBalance.NetcodePatcher;
using ButteRyBalance.Network;
using ButteRyBalance.Overrides;
using ButteRyBalance.Overrides.Enemies;
using ButteRyBalance.Overrides.Moons;
using GameNetcodeStuff;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: AssemblyCompany("ButteRyBalance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Buttery's rebalances")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ButteRyBalance")]
[assembly: AssemblyTitle("ButteRyBalance")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ButteRyBalance
{
	internal class Common
	{
		internal static Dictionary<string, EnemyType> enemies = new Dictionary<string, EnemyType>();

		internal static void Disconnect()
		{
			enemies.Clear();
		}
	}
	internal class Configuration
	{
		private static ConfigFile configFile;

		internal static ConfigEntry<bool> coilheadStunReset;

		internal static ConfigEntry<bool> jesterWalkThrough;

		internal static ConfigEntry<bool> butlerManorChance;

		internal static ConfigEntry<bool> butlerStealthStab;

		internal static ConfigEntry<bool> butlerLongCooldown;

		internal static ConfigEntry<bool> jesterLongCooldown;

		internal static ConfigEntry<bool> butlerKnifePrice;

		internal static ConfigEntry<bool> knifeShortCooldown;

		internal static ConfigEntry<bool> knifeAutoSwing;

		internal static ConfigEntry<bool> maneaterLimitGrowth;

		internal static ConfigEntry<bool> maneaterWideTurns;

		internal static ConfigEntry<bool> maneaterScrapGrowth;

		internal static ConfigEntry<bool> moonsKillSwitch;

		internal static ConfigEntry<bool> dineReduceButlers;

		internal static ConfigEntry<bool> barberDynamicSpawns;

		internal static void Init(ConfigFile cfg)
		{
			configFile = cfg;
			ItemConfig();
			EnemyConfig();
			MoonConfig();
			cfg.SettingChanged += delegate
			{
				BRBNetworker.ConfigUpdated();
			};
			cfg.ConfigReloaded += delegate
			{
				BRBNetworker.ConfigUpdated();
			};
		}

		private static void ItemConfig()
		{
			knifeShortCooldown = configFile.Bind<bool>("Item.KitchenKnife", "Short Cooldown", true, "The knife will deal damage faster.");
			knifeAutoSwing = configFile.Bind<bool>("Item.KitchenKnife", "Auto-Swing", true, "(Client-side) Holding the attack button will automatically swing the knife. When damage is dealt, your swing speed will decrease to avoid wasting hits.");
		}

		private static void EnemyConfig()
		{
			barberDynamicSpawns = configFile.Bind<bool>("Enemy.Barber", "Dynamic Spawn Settings", true, "Barbers will spawn in pairs, up to 8 total, in factories and manors. In mineshafts, they are limited to 1 total.");
			butlerManorChance = configFile.Bind<bool>("Enemy.Butler", "Manor Increased Chance", true, "Butlers have an increased chance to spawn in manor interiors.");
			butlerStealthStab = configFile.Bind<bool>("Enemy.Butler", "Stealth Stab", true, "When triggering a Butler to attack by bumping into it (rare chance), it will no longer \"berserk\", unless the offending player is alone.");
			butlerLongCooldown = configFile.Bind<bool>("Enemy.Butler", "Slow Attacks", true, "Butlers will deal damage slower, as long as they haven't been attacked before. In singleplayer, this setting will also increase their HP from 2 to 3.");
			butlerKnifePrice = configFile.Bind<bool>("Enemy.Butler", "Randomize Knife Price", true, "Restores the kitchen knife's price randomization. On average, it will be significantly more valuable than $35, the vanilla price.");
			coilheadStunReset = configFile.Bind<bool>("Enemy.Coilhead", "Stuns Reset", true, "Coil-heads will begin \"recharging\" when they are stunned by stun grenades, radar boosters, or homemade flashbangs.");
			jesterWalkThrough = configFile.Bind<bool>("Enemy.Jester", "Walk-Through", true, "Lets you walk through Jesters once they begin winding up.");
			jesterLongCooldown = configFile.Bind<bool>("Enemy.Jester", "Long Cooldown", true, "Slightly increase the average time before a Jester winds, in multiplayer.");
			maneaterLimitGrowth = configFile.Bind<bool>("Enemy.Maneater", "Limit Growth", true, "Sharply limits (or completely prevents) the Maneater's ability to transform before it has been encountered by a player.");
			maneaterScrapGrowth = configFile.Bind<bool>("Enemy.Maneater", "Metabolism", true, "Eating scrap will permanently reduce the speed at which a Maneater transforms from crying.");
			maneaterWideTurns = configFile.Bind<bool>("Enemy.Maneater", "Limit Turn Speed", true, "Adult Maneaters will have far worse turning speed when ");
		}

		private static void MoonConfig()
		{
			moonsKillSwitch = configFile.Bind<bool>("Moons", "Kill Switch", false, "If this setting is enabled, all other settings in the \"Moon\" category will be disabled. This is helpful if you want to use an external mod to configure them.");
			dineReduceButlers = configFile.Bind<bool>("Moon.Dine", "Reduce Butler Chance", true, "Reduces the spawn weight of Butlers on Dine. Intended to be combined with the \"Manor Increased Chance\" setting for Butlers.");
		}
	}
	internal static class LobbyCompatibility
	{
		internal static void Init()
		{
			PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.butterybalance", Version.Parse("0.0.1"), (CompatibilityLevel)2, (VersionStrictness)0);
		}
	}
	[BepInPlugin("butterystancakes.lethalcompany.butterybalance", "ButteRyBalance", "0.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.butterybalance";

		internal const string PLUGIN_NAME = "ButteRyBalance";

		internal const string PLUGIN_VERSION = "0.0.1";

		internal static ManualLogSource Logger;

		private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility";

		private void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			NetcodePatch();
			Logger = ((BaseUnityPlugin)this).Logger;
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected");
				LobbyCompatibility.Init();
			}
			Configuration.Init(((BaseUnityPlugin)this).Config);
			new Harmony("butterystancakes.lethalcompany.butterybalance").PatchAll();
			Logger.LogInfo((object)"ButteRyBalance v0.0.1 loaded");
		}

		private void NetcodePatch()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ButteRyBalance";

		public const string PLUGIN_NAME = "ButteRyBalance";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ButteRyBalance.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatches
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void GameNetworkManager_Post_Start()
		{
			BRBNetworker.Init();
		}

		[HarmonyPatch("Disconnect")]
		[HarmonyPostfix]
		public static void GameNetworkManager_Post_Disconnect()
		{
			Common.Disconnect();
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatches
	{
		[HarmonyPatch("AdvanceHourAndSpawnNewBatchOfEnemies")]
		[HarmonyPrefix]
		private static void RoundManager_Pre_AdvanceHourAndSpawnNewBatchOfEnemies(RoundManager __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer)
			{
				OverrideCoordinator.BeforeSpawnWave();
			}
		}

		[HarmonyPatch("RefreshEnemiesList")]
		[HarmonyPostfix]
		private static void RoundManager_Post_RefreshEnemiesList()
		{
			OverrideCoordinator.AfterEnemyRefresh();
		}

		[HarmonyPatch("GenerateNewLevelClientRpc")]
		[HarmonyPrefix]
		private static void RoundManager_Pre_GenerateNewLevelClientRpc()
		{
			OverrideCoordinator.BeforeGeneratingLevel();
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatches
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void StartOfRound_Post_Awake()
		{
			BRBNetworker.Create();
			OverrideCoordinator.Init();
			if (Common.enemies.Count >= 1)
			{
				return;
			}
			SelectableLevel val = Object.FindAnyObjectByType<QuickMenuManager>()?.testAllEnemiesLevel;
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			List<SpawnableEnemyWithRarity>[] array = new List<SpawnableEnemyWithRarity>[3] { val.Enemies, val.OutsideEnemies, val.DaytimeEnemies };
			for (int i = 0; i < array.Length; i++)
			{
				foreach (SpawnableEnemyWithRarity item in array[i])
				{
					if (!Common.enemies.ContainsKey(((Object)item.enemyType).name))
					{
						Common.enemies.Add(((Object)item.enemyType).name, item.enemyType);
					}
				}
			}
		}
	}
}
namespace ButteRyBalance.Patches.Items
{
	[HarmonyPatch(typeof(KnifeItem))]
	internal class KnifePatches
	{
		private static float knifeCooldown = 0.43f;

		private static float timeAtLastSwing;

		private static InputAction activateItem;

		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		[HarmonyPostfix]
		private static void GrabbableObject_Post_Start(GrabbableObject __instance)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)__instance).IsServer && !StartOfRound.Instance.inShipPhase && Configuration.butlerKnifePrice.Value && __instance is KnifeItem)
			{
				BRBNetworker.Instance.SyncKnifePriceClientRpc(NetworkObjectReference.op_Implicit(((Component)__instance).GetComponent<NetworkObject>()), Random.Range(28, 84));
			}
		}

		[HarmonyPatch("EquipItem")]
		[HarmonyPostfix]
		private static void KnifeItem_Post_EquipItem(KnifeItem __instance)
		{
			knifeCooldown = (BRBNetworker.Instance.KnifeShortCooldown.Value ? 0.37f : 0.43f);
		}

		[HarmonyPatch("HitKnife")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> KnifeItem_Trans_HitKnife(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 0.43f)
				{
					list[i].opcode = OpCodes.Ldsfld;
					list[i].operand = AccessTools.Field(typeof(KnifePatches), "knifeCooldown");
					Plugin.Logger.LogDebug((object)"Transpiler (Knife): Dynamic cooldown");
					return list;
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnEnable")]
		[HarmonyPostfix]
		private static void PlayerControllerB_Post_OnEnable()
		{
			activateItem = IngamePlayerSettings.Instance.playerInput.actions.FindAction("ActivateItem", false);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void PlayerControllerB_Post_Update(PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance.currentlyHeldObjectServer != (Object)null) || !(__instance.timeSinceSwitchingSlots >= 0.075f))
			{
				return;
			}
			GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer;
			KnifeItem val = (KnifeItem)(object)((currentlyHeldObjectServer is KnifeItem) ? currentlyHeldObjectServer : null);
			if (val != null && __instance.CanUseItem() && activateItem.IsPressed() && Time.realtimeSinceStartup - timeAtLastSwing > 0.2f && Time.realtimeSinceStartup - val.timeAtLastDamageDealt > knifeCooldown)
			{
				if (Time.realtimeSinceStartup - timeAtLastSwing <= 0.5f)
				{
					ShipBuildModeManager.Instance.CancelBuildMode(true);
					__instance.currentlyHeldObjectServer.UseItemOnClient(true);
					__instance.timeSinceSwitchingSlots = 0f;
				}
				timeAtLastSwing = Time.realtimeSinceStartup + Random.Range(0f, 0.1f);
			}
		}
	}
}
namespace ButteRyBalance.Patches.Enemies
{
	[HarmonyPatch(typeof(ButlerEnemyAI))]
	internal class ButlerPatches
	{
		[HarmonyPatch("OnCollideWithPlayer")]
		[HarmonyPrefix]
		private static bool ButlerEnemyAI_Pre_OnCollideWithPlayer(ButlerEnemyAI __instance, Collider other)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			if (!BRBNetworker.Instance.ButlerStealthStab.Value && !BRBNetworker.Instance.ButlerLongCooldown.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex != 2 && __instance.berserkModeTimer <= 0f)
			{
				if (Time.realtimeSinceStartup - __instance.timeSinceStealthStab < 10f)
				{
					return false;
				}
				__instance.timeSinceStealthStab = Time.realtimeSinceStartup;
				if (Random.Range(0, 100) < 95)
				{
					return false;
				}
			}
			float num = 0.25f;
			if (BRBNetworker.Instance.ButlerLongCooldown.Value && __instance.timeAtLastButlerDamage <= 0f && __instance.berserkModeTimer <= 3f)
			{
				num = 0.35f;
			}
			if (__instance.timeSinceHittingPlayer < num)
			{
				return false;
			}
			PlayerControllerB val = ((EnemyAI)__instance).MeetsStandardPlayerCollisionConditions(other, false, false);
			if ((Object)(object)val != (Object)null)
			{
				__instance.timeSinceHittingPlayer = 0f;
				val.DamagePlayer(10, true, true, (CauseOfDeath)14, 0, false, default(Vector3));
				bool flag = ((EnemyAI)__instance).currentBehaviourStateIndex != 2;
				if (flag && BRBNetworker.Instance.ButlerStealthStab.Value)
				{
					flag = !val.NearOtherPlayers(val, 15f);
					if (flag)
					{
						for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
						{
							if (!((Object)(object)StartOfRound.Instance.allPlayerScripts[i] == (Object)(object)GameNetworkManager.Instance.localPlayerController) && !StartOfRound.Instance.allPlayerScripts[i].isPlayerDead && StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)StartOfRound.Instance.allPlayerScripts[i].gameplayCamera).transform.position, 110f, 60, 2f, (Transform)null))
							{
								flag = false;
								break;
							}
						}
					}
				}
				if (flag)
				{
					__instance.berserkModeTimer = 3f;
				}
				__instance.StabPlayerServerRpc((int)val.playerClientId, flag);
			}
			return false;
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyPostfix]
		private static void ButlerEnemyAI_Post_HitEnemy(ButlerEnemyAI __instance, PlayerControllerB playerWhoHit)
		{
			if (BRBNetworker.Instance.ButlerLongCooldown.Value && (Object)(object)playerWhoHit != (Object)null)
			{
				__instance.timeAtLastButlerDamage = Time.realtimeSinceStartup;
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void ButlerEnemyAI_Post_Start(ButlerEnemyAI __instance)
		{
			if (BRBNetworker.Instance.ButlerLongCooldown.Value)
			{
				((EnemyAI)__instance).enemyHP = Mathf.Max(((EnemyAI)__instance).enemyHP, 3);
			}
		}
	}
	[HarmonyPatch(typeof(SpringManAI))]
	internal class CoilHeadPatches
	{
		[HarmonyPatch(typeof(EnemyAI), "SetEnemyStunned")]
		[HarmonyPrefix]
		private static void EnemyAI_Pre_SetEnemyStunned(EnemyAI __instance, float setToStunTime)
		{
			SpringManAI val = (SpringManAI)(object)((__instance is SpringManAI) ? __instance : null);
			if (val != null && ((NetworkBehaviour)__instance).IsServer && Configuration.coilheadStunReset.Value && val.onCooldownPhase <= 0f && setToStunTime > 0.5f)
			{
				val.onCooldownPhase = setToStunTime * __instance.enemyType.stunTimeMultiplier;
				val.setOnCooldown = true;
				val.inCooldownAnimation = true;
				val.SetCoilheadOnCooldownServerRpc(true);
			}
		}

		[HarmonyPatch("SetCoilheadOnCooldownClientRpc")]
		[HarmonyPostfix]
		private static void SpringManAI_Post_SetCoilheadOnCooldownClientRpc(SpringManAI __instance, bool setTrue)
		{
			if (setTrue)
			{
				__instance.onCooldownPhase = Mathf.Max(__instance.onCooldownPhase, ((EnemyAI)__instance).stunNormalizedTimer * ((EnemyAI)__instance).enemyType.stunTimeMultiplier);
			}
		}
	}
	[HarmonyPatch(typeof(JesterAI))]
	internal class JesterPatches
	{
		[HarmonyPatch(typeof(EnemyAI), "SwitchToBehaviourStateOnLocalClient")]
		[HarmonyPostfix]
		private static void EnemyAI_Post_SwitchToBehaviourStateOnLocalClient(EnemyAI __instance, int stateIndex)
		{
			JesterAI val = (JesterAI)(object)((__instance is JesterAI) ? __instance : null);
			if (val != null && stateIndex == 1 && BRBNetworker.Instance.JesterWalkThrough.Value)
			{
				val.mainCollider.isTrigger = true;
			}
		}

		[HarmonyPatch("SetJesterInitialValues")]
		[HarmonyPostfix]
		private static void JesterAI_PostSetJesterInitialValues(JesterAI __instance)
		{
			if (StartOfRound.Instance.connectedPlayersAmount < 4 && BRBNetworker.Instance.JesterLongCooldown.Value)
			{
				__instance.beginCrankingTimer = Mathf.Max(__instance.beginCrankingTimer, Random.Range(12f, 28f));
			}
		}
	}
	[HarmonyPatch(typeof(CaveDwellerAI))]
	internal class ManeaterPatches
	{
		private static bool playersHaveEnteredBuilding;

		private static float GROWTH_SPEED_MULTIPLIER = 0.045f;

		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void CaveDwellerAI_Pre_HitEnemy(CaveDwellerAI __instance, ref float __state)
		{
			__state = __instance.growthMeter;
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyPostfix]
		private static void CaveDwellerAI_Post_HitEnemy(CaveDwellerAI __instance, float __state, PlayerControllerB playerWhoHit)
		{
			if (((NetworkBehaviour)__instance).IsServer && ((EnemyAI)__instance).currentBehaviourStateIndex == 0 && (Object)(object)playerWhoHit == (Object)null && !__instance.hasPlayerFoundBaby && BRBNetworker.Instance.ManeaterLimitGrowth.Value)
			{
				__instance.growthMeter = __state;
			}
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPrefix]
		private static void CaveDwellerAI_Pre_KillEnemy(CaveDwellerAI __instance, ref float __state)
		{
			__state = __instance.growthMeter;
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void CaveDwellerAI_Post_KillEnemy(CaveDwellerAI __instance, float __state)
		{
			if (((NetworkBehaviour)__instance).IsServer && ((EnemyAI)__instance).currentBehaviourStateIndex == 0 && !__instance.hasPlayerFoundBaby && BRBNetworker.Instance.ManeaterLimitGrowth.Value)
			{
				__instance.growthMeter = __state;
			}
		}

		[HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayerClientRpc")]
		[HarmonyPostfix]
		private static void EntranceTeleport_Post_TeleportPlayerClientRpc()
		{
			playersHaveEnteredBuilding = true;
		}

		[HarmonyPatch(typeof(StartOfRound), "EndOfGameClientRpc")]
		[HarmonyPostfix]
		private static void StartOfRound_Post_EndOfGameClientRpc()
		{
			playersHaveEnteredBuilding = false;
		}

		[HarmonyPatch("SetCryingLocalClient")]
		[HarmonyPrefix]
		private static void CaveDwellerAI_Pre_SetCryingLocalClient(CaveDwellerAI __instance, ref bool setCrying)
		{
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && !playersHaveEnteredBuilding && BRBNetworker.Instance.ManeaterLimitGrowth.Value)
			{
				setCrying = false;
			}
		}

		[HarmonyPatch("IncreaseBabyGrowthMeter")]
		[HarmonyPrefix]
		private static void CaveDwellerAI_Pre_IncreaseBabyGrowthMeter(CaveDwellerAI __instance, ref float __state)
		{
			__state = __instance.growthMeter;
		}

		[HarmonyPatch("IncreaseBabyGrowthMeter")]
		[HarmonyPostfix]
		private static void CaveDwellerAI_Post_IncreaseBabyGrowthMeter(CaveDwellerAI __instance, float __state)
		{
			if (BRBNetworker.Instance.ManeaterLimitGrowth.Value)
			{
				if (!playersHaveEnteredBuilding)
				{
					__instance.growthMeter = 0f;
				}
				else if ((Object)(object)((GrabbableObject)(__instance.propScript?)).playerHeldBy != (Object)null && __instance.rockingBaby < 2 && !__instance.stopCryingWhenReleased)
				{
					__instance.growthMeter = __state + (__instance.growthMeter - __state) / 1.3f;
				}
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void CaveDwellerAI_Post_Start(CaveDwellerAI __instance)
		{
			GROWTH_SPEED_MULTIPLIER = __instance.growthSpeedMultiplier;
		}

		[HarmonyPatch("StopObserving")]
		[HarmonyPostfix]
		private static void CaveDwellerAI_Post_StopObserving(CaveDwellerAI __instance, bool eatScrap)
		{
			if (eatScrap && Configuration.maneaterScrapGrowth.Value)
			{
				if (__instance.scrapEaten == 1)
				{
					__instance.growthSpeedMultiplier = GROWTH_SPEED_MULTIPLIER * 0.75f;
				}
				else
				{
					__instance.growthSpeedMultiplier = GROWTH_SPEED_MULTIPLIER * 0.5f;
				}
			}
		}

		[HarmonyPatch("DoNonBabyUpdateLogic")]
		[HarmonyPostfix]
		private static void CaveDwellerAI_Post_DoNonBabyUpdateLogic(CaveDwellerAI __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && BRBNetworker.Instance.ManeaterWideTurns.Value)
			{
				if (__instance.leaping && !((EnemyAI)__instance).isOutside)
				{
					((EnemyAI)__instance).agent.angularSpeed = 320f;
					((EnemyAI)__instance).agent.acceleration = 75f;
				}
				else
				{
					((EnemyAI)__instance).agent.angularSpeed = 700f;
					((EnemyAI)__instance).agent.acceleration = 425f;
				}
			}
		}
	}
}
namespace ButteRyBalance.Overrides
{
	internal class OverrideCoordinator
	{
		private static bool initialized;

		private static Action enemyRefreshOverrides;

		private static Action spawnWaveOverrides;

		private static Action leverPulledOverrides;

		internal static void Init()
		{
			if (!initialized)
			{
				initialized = true;
				enemyRefreshOverrides = (Action)Delegate.Combine(enemyRefreshOverrides, new Action(BarberOverrides.Overrides_AfterEnemyRefresh));
				spawnWaveOverrides = (Action)Delegate.Combine(spawnWaveOverrides, new Action(ButlerOverrides.Overrides_BeforeSpawnWave));
				spawnWaveOverrides = (Action)Delegate.Combine(spawnWaveOverrides, new Action(DineOverrides.Overrides_BeforeSpawnWave));
			}
		}

		internal static void AfterEnemyRefresh()
		{
			enemyRefreshOverrides?.Invoke();
		}

		internal static void BeforeSpawnWave()
		{
			spawnWaveOverrides?.Invoke();
		}

		internal static void BeforeGeneratingLevel()
		{
			leverPulledOverrides?.Invoke();
		}
	}
}
namespace ButteRyBalance.Overrides.Moons
{
	internal class DineOverrides
	{
		private static int rollbackButler = -1;

		internal static void Overrides_BeforeSpawnWave()
		{
			if (((Object)RoundManager.Instance.currentLevel).name != "DineLevel" || (!Configuration.dineReduceButlers.Value && rollbackButler < 0))
			{
				return;
			}
			if (Common.enemies.TryGetValue("Butler", out var butler))
			{
				int num = -1;
				if (Configuration.dineReduceButlers.Value && !BRBNetworker.Instance.MoonsKillSwitch.Value)
				{
					num = 15;
				}
				else if (rollbackButler >= 0)
				{
					num = rollbackButler;
				}
				if (num < 0)
				{
					return;
				}
				SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)RoundManager.Instance.currentLevel.Enemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity enemy) => (Object)(object)enemy.enemyType == (Object)(object)butler));
				if (val != null)
				{
					if (num == rollbackButler)
					{
						rollbackButler = -1;
					}
					else
					{
						rollbackButler = val.rarity;
					}
					if (val.rarity != num)
					{
						Plugin.Logger.LogDebug((object)$"Dine: Butler weight -> {num}");
					}
					val.rarity = num;
				}
			}
			else
			{
				Plugin.Logger.LogWarning((object)"Failed to reference Butler enemy type. This should never happen");
			}
		}
	}
}
namespace ButteRyBalance.Overrides.Enemies
{
	internal class BarberOverrides
	{
		private static int rollbackGroup = -1;

		private static int rollbackCount = -1;

		internal static void Overrides_AfterEnemyRefresh()
		{
			if (!((NetworkBehaviour)RoundManager.Instance).IsServer || (!Configuration.barberDynamicSpawns.Value && rollbackGroup < 0 && rollbackCount < 0))
			{
				return;
			}
			if (Common.enemies.TryGetValue("ClaySurgeon", out var value))
			{
				if (Configuration.barberDynamicSpawns.Value)
				{
					if (rollbackCount < 0)
					{
						rollbackCount = value.MaxCount;
					}
					if (rollbackGroup < 0)
					{
						rollbackGroup = value.spawnInGroupsOf;
					}
					if (RoundManager.Instance.currentDungeonType == 4)
					{
						value.MaxCount = 1;
						value.spawnInGroupsOf = 1;
						Plugin.Logger.LogDebug((object)"Barber - Dynamic Spawn Settings: 1/1 (Mineshaft)");
					}
					else
					{
						value.MaxCount = 8;
						value.spawnInGroupsOf = 2;
						Plugin.Logger.LogDebug((object)$"Barber - Dynamic Spawn Settings: 2/8 (Interior ID: {RoundManager.Instance.currentDungeonType})");
					}
				}
				else
				{
					if (rollbackCount >= 0)
					{
						value.MaxCount = rollbackCount;
						rollbackCount = -1;
						Plugin.Logger.LogDebug((object)"Rolled back Barber max count");
					}
					if (rollbackGroup >= 0)
					{
						value.spawnInGroupsOf = rollbackGroup;
						rollbackGroup = -1;
						Plugin.Logger.LogDebug((object)"Rolled back Barber group");
					}
				}
			}
			else
			{
				Plugin.Logger.LogWarning((object)"Failed to reference Barber enemy type. This should never happen");
			}
		}
	}
	internal class ButlerOverrides
	{
		private static int rollbackManor = -1;

		internal static void Overrides_BeforeSpawnWave()
		{
			if (!Configuration.butlerManorChance.Value && rollbackManor < 0)
			{
				return;
			}
			if (Common.enemies.TryGetValue("Butler", out var value))
			{
				if (Configuration.butlerManorChance.Value)
				{
					if (value.increasedChanceInterior != 1)
					{
						rollbackManor = value.increasedChanceInterior;
						value.increasedChanceInterior = 1;
						Plugin.Logger.LogDebug((object)"Butler: Increased chance in manors");
					}
				}
				else if (rollbackManor >= 0)
				{
					value.increasedChanceInterior = rollbackManor;
					rollbackManor = -1;
					Plugin.Logger.LogDebug((object)$"Butler: Increased chance in interior ID {value.increasedChanceInterior} (-1 is none)");
				}
			}
			else
			{
				Plugin.Logger.LogWarning((object)"Failed to reference Butler enemy type. This should never happen");
			}
		}
	}
}
namespace ButteRyBalance.Network
{
	internal class BRBNetworker : NetworkBehaviour
	{
		internal static GameObject prefab;

		internal static BRBNetworker Instance { get; private set; }

		internal NetworkVariable<bool> JesterWalkThrough { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal NetworkVariable<bool> JesterLongCooldown { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal NetworkVariable<bool> ButlerStealthStab { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal NetworkVariable<bool> ButlerLongCooldown { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal NetworkVariable<bool> KnifeShortCooldown { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal NetworkVariable<bool> ManeaterLimitGrowth { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal NetworkVariable<bool> ManeaterWideTurns { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal NetworkVariable<bool> MoonsKillSwitch { get; private set; } = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);


		internal static void Init()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if ((Object)(object)prefab != (Object)null)
			{
				Plugin.Logger.LogDebug((object)"Skipped network handler registration, because it has already been initialized");
				return;
			}
			try
			{
				prefab = new GameObject("BRBNetworker")
				{
					hideFlags = (HideFlags)61
				};
				NetworkObject obj = prefab.AddComponent<NetworkObject>();
				byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + ((Object)prefab).name));
				obj.GlobalObjectIdHash = BitConverter.ToUInt32(value, 0);
				prefab.AddComponent<BRBNetworker>();
				NetworkManager.Singleton.AddNetworkPrefab(prefab);
				Plugin.Logger.LogDebug((object)"Successfully registered network handler. This is good news!");
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Encountered some fatal error while registering network handler. The mod will not function like this!\n{arg}");
			}
		}

		internal static void Create()
		{
			try
			{
				if (NetworkManager.Singleton.IsServer && (Object)(object)prefab != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab).GetComponent<NetworkObject>().Spawn(false);
				}
			}
			catch
			{
				Plugin.Logger.LogError((object)"Encountered some fatal error while spawning network handler. It is likely that registration failed earlier on start-up, please consult your logs.");
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			if ((Object)(object)Instance != (Object)(object)this)
			{
				NetworkObject val = default(NetworkObject);
				if (((Component)Instance).TryGetComponent<NetworkObject>(ref val) && !val.IsSpawned && (Object)(object)Instance != (Object)(object)prefab)
				{
					Object.Destroy((Object)(object)Instance);
				}
				Plugin.Logger.LogWarning((object)"There are 2 BRBNetworkers instantiated, and the wrong one was assigned as Instance. This shouldn't happen, but is recoverable");
				Instance = this;
			}
			Plugin.Logger.LogDebug((object)"Successfully spawned network handler.");
		}

		private void Start()
		{
			UpdateConfig();
		}

		internal static void ConfigUpdated()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.UpdateConfig();
			}
		}

		private void UpdateConfig()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				JesterWalkThrough.Value = Configuration.jesterWalkThrough.Value;
				JesterLongCooldown.Value = Configuration.jesterLongCooldown.Value;
				ButlerStealthStab.Value = Configuration.butlerStealthStab.Value;
				ButlerLongCooldown.Value = Configuration.butlerLongCooldown.Value;
				KnifeShortCooldown.Value = Configuration.knifeShortCooldown.Value;
				ManeaterLimitGrowth.Value = Configuration.maneaterLimitGrowth.Value;
				ManeaterWideTurns.Value = Configuration.maneaterWideTurns.Value;
				MoonsKillSwitch.Value = Configuration.moonsKillSwitch.Value;
			}
		}

		[ClientRpc]
		internal void SyncKnifePriceClientRpc(NetworkObjectReference knife, int value)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4087302323u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref knife, default(ForNetworkSerializable));
				BytePacker.WriteValueBitPacked(val2, value);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4087302323u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				NetworkObject val3 = default(NetworkObject);
				if (((NetworkObjectReference)(ref knife)).TryGet(ref val3, (NetworkManager)null))
				{
					((Component)val3).GetComponent<GrabbableObject>().SetScrapValue(value);
				}
				else
				{
					Plugin.Logger.LogError((object)"Failed to sync knife price from server");
				}
			}
		}

		protected override void __initializeVariables()
		{
			if (JesterWalkThrough == null)
			{
				throw new Exception("BRBNetworker.<JesterWalkThrough>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)JesterWalkThrough).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)JesterWalkThrough, "JesterWalkThrough");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)JesterWalkThrough);
			if (JesterLongCooldown == null)
			{
				throw new Exception("BRBNetworker.<JesterLongCooldown>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)JesterLongCooldown).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)JesterLongCooldown, "JesterLongCooldown");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)JesterLongCooldown);
			if (ButlerStealthStab == null)
			{
				throw new Exception("BRBNetworker.<ButlerStealthStab>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ButlerStealthStab).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ButlerStealthStab, "ButlerStealthStab");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ButlerStealthStab);
			if (ButlerLongCooldown == null)
			{
				throw new Exception("BRBNetworker.<ButlerLongCooldown>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ButlerLongCooldown).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ButlerLongCooldown, "ButlerLongCooldown");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ButlerLongCooldown);
			if (KnifeShortCooldown == null)
			{
				throw new Exception("BRBNetworker.<KnifeShortCooldown>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)KnifeShortCooldown).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)KnifeShortCooldown, "KnifeShortCooldown");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)KnifeShortCooldown);
			if (ManeaterLimitGrowth == null)
			{
				throw new Exception("BRBNetworker.<ManeaterLimitGrowth>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ManeaterLimitGrowth).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ManeaterLimitGrowth, "ManeaterLimitGrowth");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ManeaterLimitGrowth);
			if (ManeaterWideTurns == null)
			{
				throw new Exception("BRBNetworker.<ManeaterWideTurns>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ManeaterWideTurns).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ManeaterWideTurns, "ManeaterWideTurns");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ManeaterWideTurns);
			if (MoonsKillSwitch == null)
			{
				throw new Exception("BRBNetworker.<MoonsKillSwitch>k__BackingField cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)MoonsKillSwitch).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)MoonsKillSwitch, "MoonsKillSwitch");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)MoonsKillSwitch);
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_BRBNetworker()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(4087302323u, new RpcReceiveHandler(__rpc_handler_4087302323));
		}

		private static void __rpc_handler_4087302323(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkObjectReference knife = default(NetworkObjectReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref knife, default(ForNetworkSerializable));
				int value = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref value);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((BRBNetworker)(object)target).SyncKnifePriceClientRpc(knife, value);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "BRBNetworker";
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace ButteRyBalance.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}