Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of TrashCapacityMultipliersMono v1.1.1
Mods/TrashCapacityMultipliers.Mono.dll
Decompiled 3 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Fxcpds; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using ScheduleOne.Core.Items.Framework; using ScheduleOne.ItemFramework; using ScheduleOne.ObjectScripts; using ScheduleOne.ObjectScripts.WateringCan; using ScheduleOne.Property; using TrashCapacity; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default)] [assembly: MelonInfo(typeof(Mod), "Trash Capacity", "1.1.1", "Foxcapades", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TrashCapacityMultipliers")] [assembly: AssemblyConfiguration("Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9f29c78855c6d2f08159db0ee3cacc20b8bac4da")] [assembly: AssemblyProduct("TrashCapacityMultipliers")] [assembly: AssemblyTitle("TrashCapacityMultipliers")] [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 { private static FxMod? instance; protected const string SCENE_NAME_MAIN = "Main"; public static FxMod Instance => instance; public static Instance Logger => ((MelonBase)instance).LoggerInstance; protected string Scene { get; private set; } = ""; public bool InMainScene { get; private set; } public override void OnEarlyInitializeMelon() { instance = this; } public override void OnSceneWasLoaded(int _, string sceneName) { Scene = sceneName; if (sceneName == "Main") { InMainScene = true; } } public override void OnSceneWasUnloaded(int _, string sceneName) { if (Scene == sceneName) { Scene = ""; } if (sceneName == "Main") { InMainScene = false; } } } 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) { float num = (float)result / grabberMultiplier.Value; return (num > 0f && num < 1f) ? 1 : Mathf.FloorToInt(num); } } [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; } foreach (Property property in Property.Properties) { foreach (TrashContainerItem item in property.GetBuildablesOfType<TrashContainerItem>()) { item.Container.TrashCapacity = calcCapacity(); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int calcCapacity() { return (int)Math.Round(initialBinCapacity * binMultiplier.Value, MidpointRounding.AwayFromZero); } } }