Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of DealsGoneWrong v1.1.0
DealsGoneWrong_IL2CPP.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using DealsGoneWrong; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne.AvatarFramework.Equipping; using Il2CppScheduleOne.Combat; using Il2CppScheduleOne.Economy; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Behaviour; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Quests; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(global::DealsGoneWrong.DealsGoneWrong), "DealsGoneWrong", "1.0", "Jumble", null)] [assembly: MelonColor] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("DealsGoneWrong_IL2CPP")] [assembly: AssemblyConfiguration("Debug_IL2CPP")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DealsGoneWrong_IL2CPP")] [assembly: AssemblyTitle("DealsGoneWrong_IL2CPP")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace DealsGoneWrong { public static class BuildInfo { public const string Name = "DealsGoneWrong"; public const string Description = "Makes addicted customers potentially attack you after doing a deal."; public const string Author = "Jumble"; public const string Company = null; public const string Version = "1.0"; public const string DownloadLink = null; } public static class Config { private static MelonPreferences_Category configCategory; private static MelonPreferences_Entry<float> baseChanceMultiplier; private static MelonPreferences_Entry<float> minRandomBonus; private static MelonPreferences_Entry<float> maxRandomBonus; private static MelonPreferences_Entry<int> brokenBottleChance; private static MelonPreferences_Entry<int> knifeChance; private static MelonPreferences_Entry<bool> dealersAdded; private static MelonPreferences_Entry<float> giveUpRange; private static MelonPreferences_Entry<float> giveUpTime; public static float BaseChanceMultiplier => baseChanceMultiplier?.Value ?? 35f; public static float MinRandomBonus => minRandomBonus?.Value ?? 1f; public static float MaxRandomBonus => maxRandomBonus?.Value ?? 5f; public static int BrokenBottleChance => brokenBottleChance?.Value ?? 30; public static int KnifeChance => knifeChance?.Value ?? 20; public static bool DealersAdded => dealersAdded?.Value ?? false; public static float GiveUpRange => giveUpRange?.Value ?? 20f; public static float GiveUpTime => giveUpTime?.Value ?? 30f; public static void Load() { configCategory = MelonPreferences.CreateCategory("DealsGoneWrong", "Deals Gone Wrong Settings"); baseChanceMultiplier = configCategory.CreateEntry<float>("BaseChanceMultiplier", 35f, "Chance scaling based on addiction", "Multiplied by NPC addiction to calculate attack chance.", false, false, (ValueValidator)null, (string)null); minRandomBonus = configCategory.CreateEntry<float>("MinRandomBonus", 1f, "Minimum random bonus to attack chance", "Lower bound of the random value added to base chance.", false, false, (ValueValidator)null, (string)null); maxRandomBonus = configCategory.CreateEntry<float>("MaxRandomBonus", 5f, "Maximum random bonus to attack chance", "Upper bound of the random value added to base chance.", false, false, (ValueValidator)null, (string)null); brokenBottleChance = configCategory.CreateEntry<int>("BrokenBottleChance", 30, "Broken Bottle selection chance", "The higher the value, the more likely this weapon is selected.", false, false, (ValueValidator)null, (string)null); knifeChance = configCategory.CreateEntry<int>("KnifeChance", 20, "Knife selection chance", "The higher the value, the more likely this weapon is selected.", false, false, (ValueValidator)null, (string)null); dealersAdded = configCategory.CreateEntry<bool>("DealersAdded", false, "Dealer-Triggered Attacks", "Lets customers also have a chance to target you after doing a deal with one of your dealers.", false, false, (ValueValidator)null, (string)null); giveUpRange = configCategory.CreateEntry<float>("GiveUpRange", 20f, "Give Up Range", "The range at which the NPC will give up on attacking.", false, false, (ValueValidator)null, (string)null); giveUpTime = configCategory.CreateEntry<float>("GiveUpTime", 30f, "Give Up Time", "The time after which the NPC will give up on attacking.", false, false, (ValueValidator)null, (string)null); } } public class DealsGoneWrong : MelonMod { [HarmonyPatch(typeof(Customer), "CurrentContractEnded")] public static class Patch_CurrentContractEnded { [CompilerGenerated] private sealed class <HandleAggressionCoroutine>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Customer __instance; private NPC <customer>5__1; private NPCBehaviour <npcBehavior>5__2; private float <addiction>5__3; private float <baseChance>5__4; private float <randomBonus>5__5; private float <finalChance>5__6; private float <rng>5__7; private CombatBehaviour <combatBehavior>5__8; private string <weaponName>5__9; private GameObject <weaponGO>5__10; private AvatarWeapon <weaponComp>5__11; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HandleAggressionCoroutine>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <customer>5__1 = null; <npcBehavior>5__2 = null; <combatBehavior>5__8 = null; <weaponName>5__9 = null; <weaponGO>5__10 = null; <weaponComp>5__11 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <weaponComp>5__11 = <weaponGO>5__10.GetComponent<AvatarWeapon>(); if ((Object)(object)<weaponComp>5__11 != (Object)null) { <combatBehavior>5__8.DefaultWeapon = <weaponComp>5__11; } <weaponComp>5__11 = null; } else { <>1__state = -1; <customer>5__1 = __instance.NPC; NPC obj = <customer>5__1; <npcBehavior>5__2 = ((obj != null) ? obj.behaviour : null); <addiction>5__3 = __instance.CurrentAddiction; <baseChance>5__4 = <addiction>5__3 * Config.BaseChanceMultiplier; <randomBonus>5__5 = Random.Range(Config.MinRandomBonus, Config.MaxRandomBonus); <finalChance>5__6 = Mathf.Clamp(<baseChance>5__4 + <randomBonus>5__5, 0f, 100f); <rng>5__7 = Random.Range(0f, 100f); MelonLogger.Msg($"Addiction: {<addiction>5__3:F2}, Chance: {<finalChance>5__6:F2}%, RNG: {<rng>5__7:F2}"); if (<rng>5__7 > <finalChance>5__6 || (Object)(object)<npcBehavior>5__2 == (Object)null) { if ((Object)(object)<npcBehavior>5__2 == (Object)null) { MelonLogger.Warning("NPCBehavior not found."); } return false; } <customer>5__1.Aggression = 1f; <combatBehavior>5__8 = <npcBehavior>5__2.CombatBehaviour; if (!((Object)(object)<combatBehavior>5__8.DefaultWeapon == (Object)null)) { goto IL_01fc; } <weaponName>5__9 = GetRandomWeapon(); if (<weaponName>5__9 != null && CachedWeapons.TryGetValue(<weaponName>5__9, out <weaponGO>5__10)) { <>2__current = null; <>1__state = 1; return true; } } <weaponName>5__9 = null; <weaponGO>5__10 = null; goto IL_01fc; IL_01fc: ((Behaviour)<combatBehavior>5__8).Enable(); if (Config.DealersAdded) { <combatBehavior>5__8.GiveUpRange = Config.GiveUpRange; <combatBehavior>5__8.GiveUpTime = Config.GiveUpTime; } <combatBehavior>5__8.TargetPlayer = Player.Local; <combatBehavior>5__8.StartCombat(); 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 static void Postfix(EQuestState outcome, Customer __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)outcome == 2 && (Config.DealersAdded || !((Object)(object)((__instance != null) ? __instance.AssignedDealer : null) != (Object)null))) { MelonCoroutines.Start(HandleAggressionCoroutine(__instance)); } } [IteratorStateMachine(typeof(<HandleAggressionCoroutine>d__1))] private static IEnumerator HandleAggressionCoroutine(Customer __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <HandleAggressionCoroutine>d__1(0) { __instance = __instance }; } } private static readonly Dictionary<string, int> Weapons = new Dictionary<string, int> { { "BrokenBottle", Config.BrokenBottleChance }, { "Knife", Config.KnifeChance } }; private static readonly Dictionary<string, GameObject> CachedWeapons = new Dictionary<string, GameObject>(); public override void OnInitializeMelon() { Config.Load(); CacheWeapons(); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (CachedWeapons.Count != Weapons.Count) { CacheWeapons(); } } private static void CacheWeapons() { Il2CppArrayBase<GameObject> source = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (string weaponName in Weapons.Keys) { GameObject val = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject obj) => ((Object)obj).name == weaponName && (Object)(object)obj.transform.parent == (Object)null)); if ((Object)(object)val != (Object)null) { CachedWeapons[weaponName] = val; MelonLogger.Msg("Cached weapon: " + weaponName); } else { MelonLogger.Warning("Weapon '" + weaponName + "' not found for caching."); } } } private static string? GetRandomWeapon() { float num = Random.Range(0f, 100f); float num2 = 0f; foreach (KeyValuePair<string, int> weapon in Weapons) { num2 += (float)weapon.Value; if (num <= num2) { return weapon.Key; } } return null; } } }
DealsGoneWrong_Mono.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using DealsGoneWrong; using FishNet.Object; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using ScheduleOne.AvatarFramework.Equipping; using ScheduleOne.Combat; using ScheduleOne.Economy; using ScheduleOne.NPCs; using ScheduleOne.NPCs.Behaviour; using ScheduleOne.PlayerScripts; using ScheduleOne.Quests; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(global::DealsGoneWrong.DealsGoneWrong), "DealsGoneWrong", "1.0", "Jumble", null)] [assembly: MelonColor] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("DealsGoneWrong_Mono")] [assembly: AssemblyConfiguration("Debug_Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DealsGoneWrong_Mono")] [assembly: AssemblyTitle("DealsGoneWrong_Mono")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace DealsGoneWrong { public static class BuildInfo { public const string Name = "DealsGoneWrong"; public const string Description = "Makes addicted customers potentially attack you after doing a deal."; public const string Author = "Jumble"; public const string Company = null; public const string Version = "1.0"; public const string DownloadLink = null; } public static class Config { private static MelonPreferences_Category configCategory; private static MelonPreferences_Entry<float> baseChanceMultiplier; private static MelonPreferences_Entry<float> minRandomBonus; private static MelonPreferences_Entry<float> maxRandomBonus; private static MelonPreferences_Entry<int> brokenBottleChance; private static MelonPreferences_Entry<int> knifeChance; private static MelonPreferences_Entry<bool> dealersAdded; private static MelonPreferences_Entry<float> giveUpRange; private static MelonPreferences_Entry<float> giveUpTime; public static float BaseChanceMultiplier => baseChanceMultiplier?.Value ?? 35f; public static float MinRandomBonus => minRandomBonus?.Value ?? 1f; public static float MaxRandomBonus => maxRandomBonus?.Value ?? 5f; public static int BrokenBottleChance => brokenBottleChance?.Value ?? 30; public static int KnifeChance => knifeChance?.Value ?? 20; public static bool DealersAdded => dealersAdded?.Value ?? false; public static float GiveUpRange => giveUpRange?.Value ?? 20f; public static float GiveUpTime => giveUpTime?.Value ?? 30f; public static void Load() { configCategory = MelonPreferences.CreateCategory("DealsGoneWrong", "Deals Gone Wrong Settings"); baseChanceMultiplier = configCategory.CreateEntry<float>("BaseChanceMultiplier", 35f, "Chance scaling based on addiction", "Multiplied by NPC addiction to calculate attack chance.", false, false, (ValueValidator)null, (string)null); minRandomBonus = configCategory.CreateEntry<float>("MinRandomBonus", 1f, "Minimum random bonus to attack chance", "Lower bound of the random value added to base chance.", false, false, (ValueValidator)null, (string)null); maxRandomBonus = configCategory.CreateEntry<float>("MaxRandomBonus", 5f, "Maximum random bonus to attack chance", "Upper bound of the random value added to base chance.", false, false, (ValueValidator)null, (string)null); brokenBottleChance = configCategory.CreateEntry<int>("BrokenBottleChance", 30, "Broken Bottle selection chance", "The higher the value, the more likely this weapon is selected.", false, false, (ValueValidator)null, (string)null); knifeChance = configCategory.CreateEntry<int>("KnifeChance", 20, "Knife selection chance", "The higher the value, the more likely this weapon is selected.", false, false, (ValueValidator)null, (string)null); dealersAdded = configCategory.CreateEntry<bool>("DealersAdded", false, "Dealer-Triggered Attacks", "Lets customers also have a chance to target you after doing a deal with one of your dealers.", false, false, (ValueValidator)null, (string)null); giveUpRange = configCategory.CreateEntry<float>("GiveUpRange", 20f, "Give Up Range", "The range at which the NPC will give up on attacking.", false, false, (ValueValidator)null, (string)null); giveUpTime = configCategory.CreateEntry<float>("GiveUpTime", 30f, "Give Up Time", "The time after which the NPC will give up on attacking.", false, false, (ValueValidator)null, (string)null); } } public class DealsGoneWrong : MelonMod { [HarmonyPatch(typeof(Customer), "CurrentContractEnded")] public static class Patch_CurrentContractEnded { [CompilerGenerated] private sealed class <HandleAggressionCoroutine>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Customer __instance; private NPC <customer>5__1; private NPCBehaviour <npcBehavior>5__2; private float <addiction>5__3; private float <baseChance>5__4; private float <randomBonus>5__5; private float <finalChance>5__6; private float <rng>5__7; private CombatBehaviour <combatBehavior>5__8; private MethodInfo <startCombatMethod>5__9; private string <weaponName>5__10; private GameObject <weaponGO>5__11; private AvatarWeapon <weaponComp>5__12; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HandleAggressionCoroutine>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <customer>5__1 = null; <npcBehavior>5__2 = null; <combatBehavior>5__8 = null; <startCombatMethod>5__9 = null; <weaponName>5__10 = null; <weaponGO>5__11 = null; <weaponComp>5__12 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; <weaponComp>5__12 = <weaponGO>5__11.GetComponent<AvatarWeapon>(); if ((Object)(object)<weaponComp>5__12 != (Object)null) { <combatBehavior>5__8.DefaultWeapon = <weaponComp>5__12; } <weaponComp>5__12 = null; } else { <>1__state = -1; <customer>5__1 = __instance.NPC; <npcBehavior>5__2 = <customer>5__1?.behaviour; <addiction>5__3 = __instance.CurrentAddiction; <baseChance>5__4 = <addiction>5__3 * Config.BaseChanceMultiplier; <randomBonus>5__5 = Random.Range(Config.MinRandomBonus, Config.MaxRandomBonus); <finalChance>5__6 = Mathf.Clamp(<baseChance>5__4 + <randomBonus>5__5, 0f, 100f); <rng>5__7 = Random.Range(0f, 100f); MelonLogger.Msg($"Addiction: {<addiction>5__3:F2}, Chance: {<finalChance>5__6:F2}%, RNG: {<rng>5__7:F2}"); if (<rng>5__7 > <finalChance>5__6 || (Object)(object)<npcBehavior>5__2 == (Object)null) { if ((Object)(object)<npcBehavior>5__2 == (Object)null) { MelonLogger.Warning("NPCBehavior not found."); } return false; } <customer>5__1.Aggression = 1f; <combatBehavior>5__8 = <npcBehavior>5__2.CombatBehaviour; if (!((Object)(object)<combatBehavior>5__8.DefaultWeapon == (Object)null)) { goto IL_01fa; } <weaponName>5__10 = GetRandomWeapon(); if (<weaponName>5__10 != null && CachedWeapons.TryGetValue(<weaponName>5__10, out <weaponGO>5__11)) { <>2__current = null; <>1__state = 1; return true; } } <weaponName>5__10 = null; <weaponGO>5__11 = null; goto IL_01fa; IL_01fa: ((Behaviour)<combatBehavior>5__8).Enable(); if (Config.DealersAdded) { <combatBehavior>5__8.GiveUpRange = Config.GiveUpRange; <combatBehavior>5__8.GiveUpTime = Config.GiveUpTime; } <combatBehavior>5__8.SetTarget(Player.Local.Connection, ((NetworkBehaviour)Player.Local).NetworkObject); <startCombatMethod>5__9 = AccessTools.Method(typeof(CombatBehaviour), "StartCombat", (Type[])null, (Type[])null); <startCombatMethod>5__9?.Invoke(<combatBehavior>5__8, null); 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 static void Postfix(EQuestState outcome, Customer __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)outcome == 2 && (Config.DealersAdded || !((Object)(object)((__instance != null) ? __instance.AssignedDealer : null) != (Object)null))) { MelonCoroutines.Start(HandleAggressionCoroutine(__instance)); } } [IteratorStateMachine(typeof(<HandleAggressionCoroutine>d__1))] private static IEnumerator HandleAggressionCoroutine(Customer __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <HandleAggressionCoroutine>d__1(0) { __instance = __instance }; } } private static readonly Dictionary<string, int> Weapons = new Dictionary<string, int> { { "BrokenBottle", Config.BrokenBottleChance }, { "Knife", Config.KnifeChance } }; private static readonly Dictionary<string, GameObject> CachedWeapons = new Dictionary<string, GameObject>(); public override void OnInitializeMelon() { Config.Load(); CacheWeapons(); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (CachedWeapons.Count != Weapons.Count) { CacheWeapons(); } } private static void CacheWeapons() { GameObject[] source = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (string weaponName in Weapons.Keys) { GameObject val = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject obj) => ((Object)obj).name == weaponName && (Object)(object)obj.transform.parent == (Object)null)); if ((Object)(object)val != (Object)null) { CachedWeapons[weaponName] = val; MelonLogger.Msg("Cached weapon: " + weaponName); } else { MelonLogger.Warning("Weapon '" + weaponName + "' not found for caching."); } } } private static string? GetRandomWeapon() { float num = Random.Range(0f, 100f); float num2 = 0f; foreach (KeyValuePair<string, int> weapon in Weapons) { num2 += (float)weapon.Value; if (num <= num2) { return weapon.Key; } } return null; } } }