Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Configurable Drying Rack Mono v1.0.1
Configurable_Drying_Rack_Mono.dll
Decompiled 4 months agousing System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using ExampleMod; using FishNet; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using ScheduleOne.ItemFramework; using ScheduleOne.ObjectScripts; using ScheduleOne.UI.Stations.Drying_rack; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(global::ExampleMod.ExampleMod), "Configurable Drying Rack", "1.0", "Mr. Bones", null)] [assembly: MelonColor] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Configurable_Drying_Rack_Mono")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Configurable_Drying_Rack_Mono")] [assembly: AssemblyTitle("Configurable_Drying_Rack_Mono")] [assembly: AssemblyVersion("1.0.0.0")] namespace ExampleMod; public static class BuildInfo { public const string Name = "Configurable Drying Rack"; public const string Description = ""; public const string Author = "Mr. Bones"; public const string Company = "Mr. Bones Workshop"; public const string Version = "1.0"; public const string DownloadLink = null; } public class ExampleMod : MelonMod { [HarmonyPatch(typeof(DryingRack), "Awake")] private static class DryingRack_Awake_Patch { private static void Postfix(DryingRack __instance) { __instance.ItemCapacity = cfgItemCapacity.Value; } } [HarmonyPatch(typeof(DryingRack), "MinPass")] private static class DryingRack_MinPass_Patch { private static bool Prefix(DryingRack __instance) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 int value = cfgDryMinsPerTier.Value; DryingOperation[] array = __instance.DryingOperations.ToArray(); foreach (DryingOperation val in array) { val.Time++; if (val.Time < value) { continue; } if ((int)val.StartQuality >= 3) { if (InstanceFinder.IsServer && __instance.GetOutputCapacityForOperation(val, (EQuality)4) >= val.Quantity) { __instance.TryEndOperation(__instance.DryingOperations.IndexOf(val), false, (EQuality)4, Random.Range(int.MinValue, int.MaxValue)); } } else { val.IncreaseQuality(); } } return false; } } [HarmonyPatch(typeof(DryingOperation), "GetQuality")] private static class DryingOperation_GetQuality_Patch { private static void Postfix(DryingOperation __instance, ref EQuality __result) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected I4, but got Unknown int num = __instance.Time / cfgDryMinsPerTier.Value; int num2 = Mathf.Clamp(__instance.StartQuality + num, 0, 4); __result = (EQuality)num2; } } [HarmonyPatch(typeof(DryingOperationUI), "UpdatePosition")] private static class DryingOperationUI_UpdatePosition_Patch { private static void Postfix(DryingOperationUI __instance) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (__instance.AssignedOperation == null) { MelonLogger.Warning("DryingOperationUI.UpdatePosition skipped: AssignedOperation is null"); return; } if ((Object)(object)__instance.Tooltip == (Object)null) { MelonLogger.Warning("DryingOperationUI.UpdatePosition skipped: Tooltip is null"); return; } if ((Object)(object)__instance.Rect == (Object)null) { MelonLogger.Warning("DryingOperationUI.UpdatePosition skipped: Rect is null"); return; } int value = cfgDryMinsPerTier.Value; int time = __instance.AssignedOperation.Time; float num = Mathf.Clamp01((float)time / (float)value); int num2 = Mathf.Clamp(value - time, 0, value); int num3 = num2 / 60; int num4 = num2 % 60; __instance.Tooltip.text = $"{num3}h {num4}m until next tier"; float num5 = -62.5f; float num6 = 0f - num5; __instance.Rect.anchoredPosition = new Vector2(Mathf.Lerp(num5, num6, num), 0f); } } private static readonly MelonPreferences_Category cfgCategory; private static readonly MelonPreferences_Entry<int> cfgDryMinsPerTier; private static readonly MelonPreferences_Entry<int> cfgItemCapacity; static ExampleMod() { cfgCategory = MelonPreferences.CreateCategory("ConfigurableDryingRack", "Configurable Drying Rack"); cfgDryMinsPerTier = cfgCategory.CreateEntry<int>("DryMinsPerTier", 720, (string)null, "Minutes required per tier", false, false, (ValueValidator)null, (string)null); cfgItemCapacity = cfgCategory.CreateEntry<int>("ItemCapacity", 20, (string)null, "Slots available on the rack", false, false, (ValueValidator)null, (string)null); cfgCategory.SetFilePath(Path.Combine(MelonEnvironment.UserDataDirectory, "Configurable Drying Rack.cfg")); } public override void OnInitializeMelon() { MelonPreferences.Save(); } }