Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Trash Capacity Multipliers v1.1.0
TrashCanCapacity.Il2Cpp.dll
Decompiled 2 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Fxcpds; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppScheduleOne.Core.Items.Framework; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.ObjectScripts; using Il2CppScheduleOne.ObjectScripts.WateringCan; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Property; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.IO; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using TrashCapacity; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default)] [assembly: MelonInfo(typeof(Mod), "Trash Capacity", "1.1.0", "Foxcapades", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("TrashCanCapacity")] [assembly: AssemblyConfiguration("Il2Cpp")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+7bfea11baa0762b455f6302706021400dc114fac")] [assembly: AssemblyProduct("TrashCanCapacity")] [assembly: AssemblyTitle("TrashCanCapacity")] [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 Fxcpds { public abstract class FxMod : MelonMod { protected const string SCENE_NAME_MAIN = "Main"; private static FxMod? instance; public static FxMod Instance => instance; protected string Scene { get; private set; } = ""; public bool InMainScene { get; private set; } protected virtual string? configPath { get; } public string? ConfigPath => (configPath == null) ? null : Path.Combine(MelonEnvironment.UserDataDirectory, configPath); public override void OnEarlyInitializeMelon() { instance = this; } public override void OnInitializeMelon() { Player.onPlayerSpawned += DelegateSupport.ConvertDelegate<Action<Player>>((Delegate)new Action<Player>(onPlayerSpawned)); } public override void OnSceneWasLoaded(int _, string sceneName) { Scene = sceneName; if (sceneName == "Main") { InMainScene = true; onMainLoaded(); } } public override void OnSceneWasInitialized(int _, string sceneName) { if (sceneName == "Main") { onMainInitialized(); } } public override void OnSceneWasUnloaded(int _, string sceneName) { if (Scene == sceneName) { Scene = ""; } if (sceneName == "Main") { InMainScene = false; onMainUnloaded(); } } public sealed override void OnPreferencesSaved(string filepath) { if (configPath != null && filepath.EndsWith(configPath)) { onModPreferencesSaved(); } } public override void OnPreferencesLoaded(string filepath) { if (configPath != null && filepath.EndsWith(configPath)) { onModPreferencesSaved(); } } protected virtual void onModPreferencesSaved() { } private void onPlayerSpawned(Player player) { if (player.IsLocalPlayer) { onLocalPlayerLoaded(player); } onPlayerLoaded(player); } protected virtual void onPlayerLoaded(Player player) { } protected virtual void onLocalPlayerLoaded(Player player) { } protected virtual void onMainLoaded() { } protected virtual void onMainInitialized() { } protected virtual void onMainUnloaded() { } } public sealed class NumberValidator<T> : ValueValidator where T : IComparable<T> { private readonly T min; private readonly T max; public NumberValidator(T min, T max) { this.min = min; this.max = max; } public override bool IsValid(object value) { T val = (T)value; return val.CompareTo(min) > -1 && val.CompareTo(max) < 1; } public override object EnsureValid(object value) { T val = (T)value; if (val.CompareTo(min) < 0) { return min; } if (val.CompareTo(max) > 0) { return max; } return value; } } } namespace TrashCapacity { public class Mod : FxMod { [HarmonyPatch(typeof(TrashGrabberInstance), "GetTotalSize")] private static class GrabberPatch { private static int Postfix(int result) { return Mathf.FloorToInt((float)result / grabberMultiplier.Value); } } [HarmonyPatch(typeof(TrashContainerItem), "InitializeGridItem")] private static class BinPatch { private static void Prefix(ItemInstance instance, TrashContainerItem __instance) { if (((BaseItemInstance)instance).ID == "trashcan") { if (initialBinCapacity == 0f) { initialBinCapacity = __instance.Container.TrashCapacity; } __instance.Container.TrashCapacity = calcCapacity(); } } } public const string MOD_NAME = "Trash Capacity"; private static MelonPreferences_Entry<float>? binMultiplier; private static MelonPreferences_Entry<float>? grabberMultiplier; private static float initialBinCapacity; public override void OnInitializeMelon() { MelonPreferences_Category val = MelonPreferences.CreateCategory("Trash Capacity"); NumberValidator<float> numberValidator = new NumberValidator<float>(1f, 100f); ((MelonEventBase<LemonAction<float, float>>)(object)(binMultiplier = val.CreateEntry<float>("trashCanCapacityMultiplier", 2f, "Bin Capacity Multiplier", (string)null, false, false, (ValueValidator)(object)numberValidator, "capacityMultiplier")).OnEntryValueChanged).Subscribe((LemonAction<float, float>)onBinPreferencesSaved, 0, false); grabberMultiplier = val.CreateEntry<float>("trashGrabberCapacityMultiplier", 1f, "Grabber Capacity Multiplier", (string)null, false, false, (ValueValidator)(object)numberValidator, (string)null); } private void onBinPreferencesSaved(float o, float n) { if (!Mathf.Approximately(n, o)) { updateBins(); } } private void updateBins() { if (!base.InMainScene || initialBinCapacity == 0f) { return; } Enumerator<Property> enumerator = Property.Properties.GetEnumerator(); while (enumerator.MoveNext()) { Property current = enumerator.Current; Enumerator<TrashContainerItem> enumerator2 = current.GetBuildablesOfType<TrashContainerItem>().GetEnumerator(); while (enumerator2.MoveNext()) { TrashContainerItem current2 = enumerator2.Current; current2.Container.TrashCapacity = calcCapacity(); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int calcCapacity() { return (int)Math.Round((double)(initialBinCapacity * binMultiplier.Value), (MidpointRounding)1); } } }