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 CatBrainRot v1.0.2
plugins/CatBrainRot/BakaMODs.CatBrainRot.dll
Decompiled 7 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BakaMODs.CatBrainRot.NetcodePatcher; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Extras; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BakaMODs.CatBrainRot")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CatBrainRot")] [assembly: AssemblyTitle("BakaMODs.CatBrainRot")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 CatBrainRot { internal class CatBrainRotAI : EnemyAI { private enum State { Spawning, SearchingForPlayer, ChasingPlayer } [CompilerGenerated] private sealed class <PauseLoopForSpecialAttack>d__18 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CatBrainRotAI <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PauseLoopForSpecialAttack>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown int num = <>1__state; CatBrainRotAI catBrainRotAI = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; ((EnemyAI)catBrainRotAI).creatureVoice.Stop(); if ((Object)(object)catBrainRotAI.instaKillSFX != (Object)null) { ((EnemyAI)catBrainRotAI).creatureVoice.PlayOneShot(catBrainRotAI.instaKillSFX); <>2__current = (object)new WaitForSeconds(catBrainRotAI.instaKillSFX.length); <>1__state = 1; return true; } break; case 1: <>1__state = -1; break; } if (!((EnemyAI)catBrainRotAI).isEnemyDead && ((EnemyAI)catBrainRotAI).currentBehaviourStateIndex == 2) { ((EnemyAI)catBrainRotAI).creatureVoice.Play(); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnAnimationDelay>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CatBrainRotAI <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnAnimationDelay>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; CatBrainRotAI catBrainRotAI = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 1; return true; case 1: <>1__state = -1; if (((NetworkBehaviour)catBrainRotAI).IsOwner) { ((EnemyAI)catBrainRotAI).StartSearch(((Component)catBrainRotAI).transform.position, (AISearchRoutine)null); ((EnemyAI)catBrainRotAI).SwitchToBehaviourClientRpc(1); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public Transform turnCompass; public Transform attackArea; private float timeSinceLastDamage; public float damageRadius = 2.5f; public float damageInterval = 1f; public int damageAmount = 5; [Header("Insta-Kill Attack")] public float instaKillChancePerSecond = 0.05f; public AudioClip instaKillSFX; public AudioClip standardAttackSFX; private const int INSTA_KILL_DAMAGE = 1000; [Conditional("DEBUG")] private void LogIfDebugBuild(string text) { Plugin.Logger.LogInfo((object)text); } public override void Start() { ((EnemyAI)this).Start(); ((EnemyAI)this).SwitchToBehaviourClientRpc(0); ((MonoBehaviour)this).StartCoroutine(SpawnAnimationDelay()); } public override void Update() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).Update(); if (!base.isEnemyDead && ((NetworkBehaviour)this).IsOwner) { Animator creatureAnimator = base.creatureAnimator; Vector3 velocity = base.agent.velocity; creatureAnimator.SetBool("isWalking", ((Vector3)(ref velocity)).magnitude > 0.1f); } } public override void DoAIInterval() { //IL_00f1: 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) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).DoAIInterval(); if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead) { return; } switch (base.currentBehaviourStateIndex) { case 0: base.agent.speed = 0f; break; case 1: base.agent.speed = 2f; if (FoundClosestPlayerInRange(25f, 3f)) { ((EnemyAI)this).StopSearch(base.currentSearch, true); ((EnemyAI)this).SwitchToBehaviourClientRpc(2); StartChasingLoopLocal(); } break; case 2: base.agent.speed = 4f; if (!TargetClosestPlayerInAnyCase() || (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 20f && !((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer).transform.position, 45f, 60, -1f, (Transform)null))) { ((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null); ((EnemyAI)this).SwitchToBehaviourClientRpc(1); StopChasingLoopLocal(); break; } ((EnemyAI)this).SetDestinationToPosition(((Component)base.targetPlayer).transform.position, false); if (((NetworkBehaviour)this).IsServer) { timeSinceLastDamage += base.AIIntervalTime; if (timeSinceLastDamage >= damageInterval) { timeSinceLastDamage = 0f; DamagePlayersInAreaServer(); } if ((Object)(object)base.targetPlayer != (Object)null && Random.value < instaKillChancePerSecond * base.AIIntervalTime) { PerformInstaKillAttackServer(); } } break; } } [IteratorStateMachine(typeof(<SpawnAnimationDelay>d__15))] private IEnumerator SpawnAnimationDelay() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SpawnAnimationDelay>d__15(0) { <>4__this = this }; } private void PerformInstaKillAttackServer() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)base.targetPlayer == (Object)null)) { base.targetPlayer.KillPlayer(Vector3.zero, true, (CauseOfDeath)3, 0, default(Vector3)); InterruptLoopWithOneShotLocal(); } } private void InterruptLoopWithOneShotLocal() { ((MonoBehaviour)this).StartCoroutine(PauseLoopForSpecialAttack()); } [IteratorStateMachine(typeof(<PauseLoopForSpecialAttack>d__18))] private IEnumerator PauseLoopForSpecialAttack() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PauseLoopForSpecialAttack>d__18(0) { <>4__this = this }; } private void PlayStandardAttackSoundLocal() { if ((Object)(object)standardAttackSFX != (Object)null) { base.creatureVoice.PlayOneShot(standardAttackSFX); } } private void StartChasingLoopLocal() { if (!base.creatureVoice.isPlaying) { base.creatureVoice.Play(); } } private void StopChasingLoopLocal() { base.creatureVoice.Stop(); } private void DamagePlayersInAreaServer() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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) bool flag = false; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!val.isPlayerDead && val.isPlayerControlled && Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) < damageRadius) { val.DamagePlayer(damageAmount, true, true, (CauseOfDeath)0, 0, false, default(Vector3)); flag = true; } } if (flag) { PlayStandardAttackSoundLocal(); } } private bool FoundClosestPlayerInRange(float range, float senseRange) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f); if ((Object)(object)base.targetPlayer == (Object)null) { ((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f); range = senseRange; } if ((Object)(object)base.targetPlayer != (Object)null) { return Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range; } return false; } private bool TargetClosestPlayerInAnyCase() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) base.mostOptimalDistance = 2000f; base.targetPlayer = null; for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++) { if (!StartOfRound.Instance.allPlayerScripts[i].isPlayerDead) { base.tempDist = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position); if (base.tempDist < base.mostOptimalDistance) { base.mostOptimalDistance = base.tempDist; base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i]; } } } return (Object)(object)base.targetPlayer != (Object)null; } public override void OnCollideWithPlayer(Collider other) { ((EnemyAI)this).OnCollideWithPlayer(other); } public override void OnCollideWithEnemy(Collider other, EnemyAI collidedEnemy = null) { ((EnemyAI)this).OnCollideWithEnemy(other, collidedEnemy); } public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1) { ((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID); if (!base.isEnemyDead) { base.enemyHP -= force; if (((NetworkBehaviour)this).IsServer && base.enemyHP <= 0 && !base.isEnemyDead) { ((MonoBehaviour)this).StopCoroutine(base.searchCoroutine); KillEnemyEffectsLocal(); ((EnemyAI)this).KillEnemyOnOwnerClient(false); } } } private void KillEnemyEffectsLocal() { base.creatureAnimator.SetTrigger("KillEnemy"); if (base.creatureVoice.isPlaying) { base.creatureVoice.Stop(); } base.creatureVoice.PlayOneShot(base.dieSFX); } protected override void __initializeVariables() { ((EnemyAI)this).__initializeVariables(); } protected internal override string __getTypeName() { return "CatBrainRotAI"; } } public class PentagramTrap : NetworkBehaviour { [CompilerGenerated] private sealed class <SummonAndDestroyRoutine>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PentagramTrap <>4__this; public Vector3 position; public Quaternion rotation; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SummonAndDestroyRoutine>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; PentagramTrap pentagramTrap = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; pentagramTrap.PlayEffectsLocal(); <>2__current = (object)new WaitForSeconds(pentagramTrap.spawnDelay); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)pentagramTrap.enemyToSpawnPrefab != (Object)null) { GameObject val = Object.Instantiate<GameObject>(pentagramTrap.enemyToSpawnPrefab, position, rotation); NetworkObject val2 = default(NetworkObject); if (val.TryGetComponent<NetworkObject>(ref val2)) { val2.Spawn(true); } else { Object.Destroy((Object)(object)val); } } if (((NetworkBehaviour)pentagramTrap).IsServer && ((NetworkBehaviour)pentagramTrap).NetworkObject.IsSpawned) { ((NetworkBehaviour)pentagramTrap).NetworkObject.Despawn(true); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public GameObject enemyToSpawnPrefab; public AudioClip spawnSFX; public AudioSource creatureVoice; public Animator pentagramAnimator; [Header("Trap Settings")] public float spawnDelay = 2f; private bool hasBeenTriggered; [Conditional("DEBUG")] private void LogIfDebugBuild(string text) { Plugin.Logger.LogInfo((object)("[PentagramTrap] " + text)); } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(); if (componentsInChildren != null) { Renderer[] array = componentsInChildren; foreach (Renderer val in array) { val.enabled = true; } } _ = (Object)(object)enemyToSpawnPrefab == (Object)null; } private void OnTriggerEnter(Collider other) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!hasBeenTriggered && ((NetworkBehaviour)this).IsServer && ((Component)other).CompareTag("Player")) { PlayerControllerB component = ((Component)other).GetComponent<PlayerControllerB>(); if ((Object)(object)component != (Object)null) { hasBeenTriggered = true; ((MonoBehaviour)this).StartCoroutine(SummonAndDestroyRoutine(((Component)this).transform.position, ((Component)this).transform.rotation)); } } } [IteratorStateMachine(typeof(<SummonAndDestroyRoutine>d__9))] private IEnumerator SummonAndDestroyRoutine(Vector3 position, Quaternion rotation) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SummonAndDestroyRoutine>d__9(0) { <>4__this = this, position = position, rotation = rotation }; } private void PlayEffectsLocal() { Collider component = ((Component)this).GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { component.enabled = false; } if ((Object)(object)pentagramAnimator != (Object)null) { pentagramAnimator.SetTrigger("startGlow"); } if ((Object)(object)spawnSFX != (Object)null && (Object)(object)creatureVoice != (Object)null) { creatureVoice.PlayOneShot(spawnSFX); } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } protected internal override string __getTypeName() { return "PentagramTrap"; } } [BepInPlugin("BakaMODs.CatBrainRot", "CatBrainRot", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(RoundManager))] internal class PentagramSpawnCounterPatch { private static bool hasLoggedSpawnCount; [HarmonyPatch("Start")] [HarmonyPostfix] private static void ResetLogFlagPatch() { hasLoggedSpawnCount = false; } [HarmonyPatch("SpawnScrapInLevel")] [HarmonyPostfix] private static void CountSpawnedPentagramsPatch() { if (!hasLoggedSpawnCount) { PentagramTrap[] array = Object.FindObjectsOfType<PentagramTrap>(); int num = array.Length; Logger.LogInfo((object)$"A total of {num} pentagrams have spawned in the facility."); hasLoggedSpawnCount = true; } } } internal static ManualLogSource Logger; public static AssetBundle? ModAssets; private readonly Harmony harmony = new Harmony("BakaMODs.CatBrainRot"); private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; InitializeNetworkBehaviours(); string path = "catbrainrotassets"; ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), path)); if ((Object)(object)ModAssets == (Object)null) { Logger.LogError((object)"Failed to load custom assets bundle!"); return; } Logger.LogInfo((object)"Successfully loaded assets bundle."); GameObject val = ModAssets.LoadAsset<GameObject>("catbrainrot 1"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Failed to load 'catbrainrot 1' enemy prefab from bundle!"); return; } Logger.LogInfo((object)"Successfully loaded enemy prefab."); SpawnableMapObjectDef val2 = ModAssets.LoadAsset<SpawnableMapObjectDef>("PentagramTrapMapObject"); if ((Object)(object)val2 == (Object)null) { Logger.LogError((object)"Failed to load 'PentagramTrapMapObject' asset from bundle! Check asset name and ensure it's in the bundle."); return; } Logger.LogInfo((object)"Successfully loaded SpawnableMapObjectDef asset."); if (val2.spawnableMapObject == null) { Logger.LogError((object)"'spawnableMapObject' inside the PentagramTrapMapObjectDef is null!"); return; } if ((Object)(object)val2.spawnableMapObject.prefabToSpawn == (Object)null) { Logger.LogError((object)"'prefabToSpawn' inside the PentagramTrapMapObjectDef is null! Make sure you assigned the prefab in the Unity Editor."); return; } Logger.LogInfo((object)"SpawnableMapObjectDef asset seems valid."); PentagramTrap pentagramTrap = default(PentagramTrap); if (val2.spawnableMapObject.prefabToSpawn.TryGetComponent<PentagramTrap>(ref pentagramTrap)) { pentagramTrap.enemyToSpawnPrefab = val; Logger.LogInfo((object)"Successfully found PentagramTrap script and assigned enemy prefab."); Func<SelectableLevel, AnimationCurve> func = (SelectableLevel level) => new AnimationCurve((Keyframe[])(object)new Keyframe[2] { new Keyframe(0f, 5f), new Keyframe(1f, 5f) }); NetworkPrefabs.RegisterNetworkPrefab(val2.spawnableMapObject.prefabToSpawn); NetworkPrefabs.RegisterNetworkPrefab(val); MapObjects.RegisterMapObject(val2, (LevelTypes)(-1), func); harmony.PatchAll(typeof(PentagramSpawnCounterPatch)); Logger.LogInfo((object)"Plugin BakaMODs.CatBrainRot is loaded!"); } else { Logger.LogError((object)"Could not find PentagramTrap script on the pentagram prefab!"); } } private static void InitializeNetworkBehaviours() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } } public static class PluginInfo { public const string PLUGIN_GUID = "BakaMODs.CatBrainRot"; public const string PLUGIN_NAME = "CatBrainRot"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace CatBrainRot.Configuration { public class PluginConfig { public ConfigEntry<int> EasyMoonSpawnWeight; public ConfigEntry<int> MediumMoonSpawnWeight; public ConfigEntry<int> HardMoonSpawnWeight; public ConfigEntry<int> ModdedMoonSpawnWeight; public PluginConfig(ConfigFile cfg) { EasyMoonSpawnWeight = cfg.Bind<int>("Spawn Weights", "1. Easy Moons (Experimentation, Assurance, Vow)", 20, "The spawn chance weight on easy moons. Lower is more rare."); MediumMoonSpawnWeight = cfg.Bind<int>("Spawn Weights", "2. Medium Moons (Offense, March)", 40, "The spawn chance weight on medium moons. Lower is more rare."); HardMoonSpawnWeight = cfg.Bind<int>("Spawn Weights", "3. Hard Moons (Rend, Dine, Titan)", 80, "The spawn chance weight on hard moons. Lower is more rare."); ModdedMoonSpawnWeight = cfg.Bind<int>("Spawn Weights", "4. Modded Moons", 80, "The default spawn chance weight for modded moons that are not specified manually."); ClearUnusedEntries(cfg); } private void ClearUnusedEntries(ConfigFile cfg) { PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(cfg, null); dictionary.Clear(); cfg.Save(); } } } namespace BakaMODs.CatBrainRot.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }