Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Bigger Mag Capacity v1.0.0
BiggerMagCapacity.dll
Decompiled 4 hours 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 Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne.Equipping; using Il2CppScheduleOne.ItemFramework; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(AmmoCostCapacityMod), "BiggerMagCapacity", "1.0.0", "HontoRon", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("BiggerMagCapacity")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BiggerMagCapacity")] [assembly: AssemblyTitle("BiggerMagCapacity")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] 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; } } } public class AmmoCostCapacityMod : MelonMod { [CompilerGenerated] private sealed class <ApplyAfterDelay>d__18 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyAfterDelay>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; ApplyShopAmmoOnly(); 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 int revolverMultiplier = 1; public static int m1911Multiplier = 1; public const int revolverBaseSize = 6; public const int revolverBasePrice = 10; public const int m1911BaseSize = 7; public const int m1911BasePrice = 20; private static string _configPath = Path.Combine(MelonEnvironment.UserDataDirectory, "BiggerMagCapacity.cfg"); private static bool _appliedThisScene = false; public static int RevolverAmmoAmount => 6 * revolverMultiplier; public static int RevolverAmmoPrice => 10 * revolverMultiplier; public static int M1911AmmoAmount => 7 * m1911Multiplier; public static int M1911AmmoPrice => 20 * m1911Multiplier; public override void OnInitializeMelon() { LoadConfig(); MelonLogger.Msg("BiggerMagCapacity loaded."); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { _appliedThisScene = false; MelonCoroutines.Start(ApplyAfterDelay()); } [IteratorStateMachine(typeof(<ApplyAfterDelay>d__18))] private static IEnumerator ApplyAfterDelay() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ApplyAfterDelay>d__18(0); } private static void ApplyShopAmmoOnly() { if (_appliedThisScene) { return; } _appliedThisScene = true; try { ApplyAmmoItemFromWeapon("Revolver", RevolverAmmoAmount, RevolverAmmoPrice); ApplyAmmoItemFromWeapon("M1911", M1911AmmoAmount, M1911AmmoPrice); MelonLogger.Msg("BiggerMagCapacity: Mod applied."); } catch (Exception ex) { MelonLogger.Error("BiggerMagCapacity ApplyShopAmmoOnly failed: " + ex); } } private static bool ApplyAmmoItemFromWeapon(string weaponNameContains, int newAmount, int newPrice) { Il2CppArrayBase<Equippable_RangedWeapon> val = Resources.FindObjectsOfTypeAll<Equippable_RangedWeapon>(); if (val == null || val.Length == 0) { MelonLogger.Msg("BiggerMagCapacity: no ranged weapons found in Resources."); return false; } Equippable_RangedWeapon val2 = null; for (int i = 0; i < val.Length; i++) { Equippable_RangedWeapon val3 = val[i]; if (!((Object)(object)val3 == (Object)null)) { GameObject gameObject = ((Component)val3).gameObject; if (!((Object)(object)gameObject == (Object)null) && ((Object)gameObject).name != null && ((Object)gameObject).name.IndexOf(weaponNameContains, StringComparison.OrdinalIgnoreCase) >= 0) { val2 = val3; break; } } } if ((Object)(object)val2 == (Object)null) { MelonLogger.Msg("BiggerMagCapacity: could not find weapon containing name: " + weaponNameContains); return false; } StorableItemDefinition magazine = val2.Magazine; if ((Object)(object)magazine == (Object)null) { MelonLogger.Msg("BiggerMagCapacity: weapon found but Magazine item was null for: " + ((Object)((Component)val2).gameObject).name); return false; } magazine.BasePurchasePrice = newPrice; IntegerItemDefinition val4 = ((Il2CppObjectBase)magazine).Cast<IntegerItemDefinition>(); if ((Object)(object)val4 != (Object)null) { val4.DefaultValue = newAmount; MelonLogger.Msg($"BiggerMagCapacity: Updated ammo item for {((Object)((Component)val2).gameObject).name} -> amount={newAmount}, price={newPrice}"); } else { MelonLogger.Msg($"BiggerMagCapacity: Ammo item for {((Object)((Component)val2).gameObject).name} is not IntegerItemDefinition; price set to {newPrice} only."); } return true; } private void LoadConfig() { try { if (!File.Exists(_configPath)) { SaveConfig(); return; } string[] array = File.ReadAllLines(_configPath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (string.IsNullOrEmpty(text) || text.StartsWith("#") || text.StartsWith(";") || (text.StartsWith("[") && text.EndsWith("]"))) { continue; } int num = text.IndexOf('='); if (num > 0) { string text2 = text.Substring(0, num).Trim().ToLowerInvariant(); string text3 = text.Substring(num + 1).Trim(); int num2 = text3.IndexOf('#'); if (num2 >= 0) { text3 = text3.Substring(0, num2).Trim(); } int num3 = text3.IndexOf(';'); if (num3 >= 0) { text3 = text3.Substring(0, num3).Trim(); } if (text3.Length >= 2 && text3.StartsWith("\"") && text3.EndsWith("\"")) { text3 = text3.Substring(1, text3.Length - 2).Trim(); } switch (text2) { case "revolver_multiplier": case "revolvermultiplier": revolverMultiplier = ClampMin1(ParseInt(text3, revolverMultiplier)); break; case "m1911_multiplier": case "m1911multiplier": m1911Multiplier = ClampMin1(ParseInt(text3, m1911Multiplier)); break; } } } MelonLogger.Msg("AmmoCostCapacity config loaded from " + _configPath); MelonLogger.Msg($"Multipliers NOW: Revolver={revolverMultiplier}, M1911={m1911Multiplier}"); } catch (Exception ex) { MelonLogger.Error("AmmoCostCapacity LoadConfig failed: " + ex); } } private void SaveConfig() { try { string contents = "[Bigger Mag Capacity]\n# Revolver default: 6 rounds for $10\nrevolver_multiplier = " + revolverMultiplier + "\n# M1911 default: 7 rounds for $20\nm1911_multiplier = " + m1911Multiplier + "\n"; File.WriteAllText(_configPath, contents); MelonLogger.Msg("BiggerMagCapacity config created at " + _configPath); } catch (Exception ex) { MelonLogger.Error("BiggerMagCapacity SaveConfig failed: " + ex.Message); } } private int ParseInt(string s, int fallback) { try { if (int.TryParse(s, out var result)) { return result; } } catch { } return fallback; } private int ParseRightInt(string line, int fallback) { try { string[] array = line.Split(new char[1] { '=' }, 2); if (array.Length == 2) { return int.Parse(array[1]); } } catch { } return fallback; } private int ClampMin1(int v) { if (v < 1) { return 1; } return v; } }