Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of OscarsInventoryTweaksIl2Cpp v1.2.0
Mods/OscarsInventoryTweaks.Il2Cpp.dll
Decompiled 2 months agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Fxcpds; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.Runtime; using Il2CppScheduleOne; using Il2CppScheduleOne.Core.Items.Framework; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.CharacterClasses; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.UI.Shop; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.IO; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using OscarsInventoryTweaks; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonInfo(typeof(Mod), "Oscar's Inventory Tweaks", "1.2.0", "Foxcapades", null)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("OscarsInventoryTweaks")] [assembly: AssemblyConfiguration("Il2Cpp")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+7d32857f571070ba18933c47e913d0f34ddd7d5d")] [assembly: AssemblyProduct("OscarsInventoryTweaks")] [assembly: AssemblyTitle("OscarsInventoryTweaks")] [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)) { ((MelonBase)this).LoggerInstance.Debug("calling onModPreferencesSaved()"); onModPreferencesSaved(); } } public override void OnPreferencesLoaded(string filepath) { if (configPath != null && filepath.EndsWith(configPath)) { ((MelonBase)this).LoggerInstance.Debug("calling onModPreferencesLoaded()"); onModPreferencesSaved(); } } protected virtual void onModPreferencesSaved() { } protected virtual void onModPreferencesLoaded() { } private void onPlayerSpawned(Player player) { if (player.IsLocalPlayer) { ((MelonBase)this).LoggerInstance.Debug("local player loaded"); 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() { } } internal static class DebugTools { public static void Debug(this Instance logger, string message) { } public static void Debug(this Instance logger, string message, object? a1) { } } public static class Interop { public static T? cast<T>(Il2CppObjectBase? obj) where T : Il2CppObjectBase { return (obj == null) ? default(T) : Il2CppObjectPool.Get<T>(obj.Pointer); } } public static class NPC { public const string Oscar = "oscar_holland"; public const string Dan = "dan_samwell"; public const string Hank = "hank_stevenson"; public static T? Get<T>(string id) where T : NPC { return Interop.cast<T>((Il2CppObjectBase?)(object)NPCManager.GetNPC(id)); } } } namespace OscarsInventoryTweaks { internal readonly struct Category { public static readonly Category Additives = new Category("Additives", "extralonglifesoil"); public static readonly Category Storage = new Category("Storage", "bed"); public static readonly Category Equipment = new Category("Growing", "soilpourer"); public static readonly Category[] allCategories = new Category[3] { Additives, Storage, Equipment }; public readonly string name; public readonly string appearsAfter; private Category(string name, string appearsAfter) { this.name = name; this.appearsAfter = appearsAfter; } public override bool Equals(object? obj) { return obj != null && (obj as Category?)?.name == name; } public override int GetHashCode() { return name.GetHashCode(); } public static bool operator ==(Category a, Category b) { return a.name == b.name; } public static bool operator !=(Category a, Category b) { return a.name != b.name; } } internal readonly struct Item { public static readonly Item Fertilizer = new Item("fertilizer", Category.Additives); public static readonly Item PGR = new Item("pgr", Category.Additives); public static readonly Item SpeedGrow = new Item("speedgrow", Category.Additives); public static readonly Item Locker = new Item("locker", Category.Storage); public static readonly Item SmallStorageCloset = new Item("smallstoragecloset", Category.Storage); public static readonly Item MediumStorageCloset = new Item("mediumstoragecloset", Category.Storage); public static readonly Item LargeStorageCloset = new Item("largestoragecloset", Category.Storage); public static readonly Item HugeStorageCloset = new Item("hugestoragecloset", Category.Storage); public static readonly Item SmallStorageRack = new Item("smallstoragerack", Category.Storage); public static readonly Item MediumStorageRack = new Item("mediumstoragerack", Category.Storage); public static readonly Item LargeStorageRack = new Item("largestoragerack", Category.Storage); public static readonly Item BigSprinkler = new Item("bigsprinkler", Category.Equipment); public static readonly Item AirConditioner = new Item("acunit", Category.Equipment); public static readonly Item[] allItems = new Item[13] { Fertilizer, PGR, SpeedGrow, Locker, BigSprinkler, AirConditioner, SmallStorageCloset, MediumStorageCloset, LargeStorageCloset, HugeStorageCloset, SmallStorageRack, MediumStorageRack, LargeStorageRack }; public readonly string id; public readonly Category category; public static int itemCount => allItems.Length; private Item(string id, Category category) { this.id = id; this.category = category; } } public class Mod : FxMod { public const string MOD_ID = "Oscar's Inventory Tweaks"; private static readonly ShopListing[] targetItemListings = (ShopListing[])(object)new ShopListing[Item.itemCount]; private static Preferences? preferences; protected override string configPath => "OscarsInventoryTweaks.cfg"; public override void OnInitializeMelon() { preferences = new Preferences(base.ConfigPath); base.OnInitializeMelon(); } protected override void onModPreferencesSaved() { if (base.InMainScene) { updateShopListings(); } } protected override void onLocalPlayerLoaded(Player _) { init(); updateShopListings(); } private static void init() { ((MelonBase)FxMod.Instance).LoggerInstance.Debug("initializing"); ShopInterface shopInterface = NPC.Get<Dan>("dan_samwell").ShopInterface; for (int i = 0; i < Item.itemCount; i++) { targetItemListings[i] = shopInterface.GetListing(Item.allItems[i].id); ((MelonBase)FxMod.Instance).LoggerInstance.Debug("grabbed {0} listing from dan", ((BaseItemDefinition)targetItemListings[i].Item).ID); } } private static void moveItem<T>(List<T> items, int from, int to) { T val = items[from]; items.RemoveAt(from); items.Insert(to, val); } private static Dictionary<string, ShopListing?> buildListings() { Dictionary<string, ShopListing> val = new Dictionary<string, ShopListing>(Item.itemCount); (Item, bool)[] items = preferences.getItems(); for (int i = 0; i < items.Length; i++) { var (item, flag) = items[i]; val[item.id] = (flag ? targetItemListings[i] : null); } return val; } private static void pruneDisabledListings(ShopInterface oscar, Dictionary<string, ShopListing?> newListings, List<ListingUI> uiListings, UIPanel listingPanel) { Enumerator<string, ShopListing> enumerator = newListings.GetEnumerator(); string text = default(string); ShopListing val = default(ShopListing); while (enumerator.MoveNext()) { enumerator.Current.Deconstruct(ref text, ref val); string text2 = text; ShopListing val2 = val; if (val2 != null) { continue; } ShopListing listing = oscar.GetListing(text2); if (listing == null) { continue; } ((MelonBase)FxMod.Instance).LoggerInstance.Debug("removing {0} from Oscar's inventory", text2); oscar.Listings.Remove(listing); ListingUI val3 = null; for (int i = 0; i < uiListings.Count; i++) { if (((BaseItemDefinition)uiListings[i].Listing.Item).ID == text2) { val3 = uiListings[i]; uiListings.RemoveAt(i); break; } } if (!((Object)(object)val3 == (Object)null)) { listingPanel.RemoveSelectable(((Component)val3).GetComponent<UISelectable>(), true); Object.Destroy((Object)(object)((Component)val3).gameObject); } } } private static void injectNewListings(ShopInterface oscar, Dictionary<string, ShopListing?> newListings, List<ListingUI> uiListings) { Enumerator<ShopListing> enumerator = oscar.Listings.GetEnumerator(); while (enumerator.MoveNext()) { ShopListing current = enumerator.Current; newListings.Remove(((BaseItemDefinition)current.Item).ID); } ShopListing val = default(ShopListing); for (int num = Item.allItems.Length - 1; num >= 0; num--) { Item item = Item.allItems[num]; if (newListings.TryGetValue(item.id, ref val) && val != null) { oscar.Listings.Add(Utils.copyListing(targetItemListings[num], oscar)); oscar.CreateListingUI(val); int num2 = findInsertPosition(uiListings, item.category.appearsAfter); if (num2 > -1) { moveItem<ListingUI>(uiListings, uiListings.Count - 1, num2); } } } } private static int findInsertPosition(List<ListingUI> list, string target) { for (int i = 0; i < list.Count; i++) { if (((BaseItemDefinition)list[i].Listing.Item).ID == target) { return i + 1; } } return -1; } private static void updateShopListings() { Oscar? obj = NPC.Get<Oscar>("oscar_holland"); ShopInterface val = ((obj != null) ? obj.ShopInterface : null); if ((Object)(object)val == (Object)null) { ((MelonBase)FxMod.Instance).LoggerInstance.Debug("oscar was null"); return; } List<ListingUI> val2 = val.ListingUIItems(); if (val2 == null) { ((MelonBase)FxMod.Instance).LoggerInstance.Debug("uiListings was null"); return; } UIPanel val3 = val.ListingPanel(); if ((Object)(object)val3 == (Object)null) { ((MelonBase)FxMod.Instance).LoggerInstance.Debug("uiPanel was null"); return; } Dictionary<string, ShopListing> newListings = buildListings(); pruneDisabledListings(val, newListings, val2, val3); injectNewListings(val, newListings, val2); } } internal sealed class Preferences { private readonly MelonPreferences_Entry<bool> sellFertilizer; private readonly MelonPreferences_Entry<bool> sellPGR; private readonly MelonPreferences_Entry<bool> sellSpeedGrow; private readonly MelonPreferences_Entry<bool> sellBigSprinkler; private readonly MelonPreferences_Entry<bool> sellLocker; private readonly MelonPreferences_Entry<bool> sellShelves; private readonly MelonPreferences_Entry<bool> sellClosets; private readonly MelonPreferences_Entry<bool> sellAirCon; public bool SellFertilizer => sellFertilizer.Value; public bool SellPgr => sellPGR.Value; public bool SellSpeedGrow => sellSpeedGrow.Value; public bool SellBigSprinkler => sellBigSprinkler.Value; public bool SellLocker => sellLocker.Value; public bool SellShelves => sellShelves.Value; public bool SellClosets => sellClosets.Value; public bool SellAirCon => sellAirCon.Value; public Preferences(string configPath) { MelonPreferences_Category val = MelonPreferences.CreateCategory("Oscar's Inventory Tweaks - Additives", "Growth Additives"); val.SetFilePath(configPath); sellFertilizer = val.CreateEntry<bool>("sellFertilizer", true, "Sell Fertilizer", (string)null, false, false, (ValueValidator)null, (string)null); sellPGR = val.CreateEntry<bool>("sellPGR", true, "Sell PGR", (string)null, false, false, (ValueValidator)null, (string)null); sellSpeedGrow = val.CreateEntry<bool>("sellSpeedGrow", true, "Sell Speed Grow", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Category val2 = MelonPreferences.CreateCategory("Oscar's Inventory Tweaks - Growing", "Equipment"); val2.SetFilePath(configPath); sellBigSprinkler = val2.CreateEntry<bool>("sellBigSprinkler", true, "Sell Big Sprinkler", (string)null, false, false, (ValueValidator)null, (string)null); sellAirCon = val2.CreateEntry<bool>("sellAirConditioner", true, "Sell AC Unit", (string)null, false, false, (ValueValidator)null, (string)null); MelonPreferences_Category val3 = MelonPreferences.CreateCategory("Oscar's Inventory Tweaks - Storage", "Storage"); val3.SetFilePath(configPath); sellLocker = val3.CreateEntry<bool>("sellLocker", true, "Sell Locker", (string)null, false, false, (ValueValidator)null, (string)null); sellShelves = val3.CreateEntry<bool>("sellShelves", true, "Sell Shelves", (string)null, false, false, (ValueValidator)null, (string)null); sellClosets = val3.CreateEntry<bool>("sellClosets", true, "Sell Closets", (string)null, false, false, (ValueValidator)null, (string)null); } } internal static class Utils { public static (Item, bool)[] getItems(this Preferences prefs) { return new(Item, bool)[13] { (Item.Fertilizer, prefs.SellFertilizer), (Item.PGR, prefs.SellPgr), (Item.SpeedGrow, prefs.SellSpeedGrow), (Item.Locker, prefs.SellLocker), (Item.BigSprinkler, prefs.SellBigSprinkler), (Item.AirConditioner, prefs.SellAirCon), (Item.SmallStorageCloset, prefs.SellClosets), (Item.MediumStorageCloset, prefs.SellClosets), (Item.LargeStorageCloset, prefs.SellClosets), (Item.HugeStorageCloset, prefs.SellClosets), (Item.SmallStorageRack, prefs.SellShelves), (Item.MediumStorageRack, prefs.SellShelves), (Item.LargeStorageRack, prefs.SellShelves) }; } public static List<ListingUI>? ListingUIItems(this ShopInterface shop) { return shop.listingUI; } public static UIPanel? ListingPanel(this ShopInterface shop) { return shop.listingPanel; } public static ShopListing copyListing(ShopListing old, ShopInterface shop) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown ShopListing val = new ShopListing { name = old.name, Item = old.Item, LimitedStock = old.LimitedStock, DefaultStock = old.DefaultStock, RestockRate = old.RestockRate, TieStockToNumberVariable = old.TieStockToNumberVariable, StockVariableName = old.StockVariableName, TrackPurchases = old.TrackPurchases, PurchasedQuantityVariableName = old.PurchasedQuantityVariableName, EnforceMinimumGameCreationVersion = old.EnforceMinimumGameCreationVersion, MinimumGameCreationVersion = old.MinimumGameCreationVersion, CanBeDelivered = old.CanBeDelivered, UseIconTint = old.UseIconTint, IconTint = old.IconTint, ConditionalVisibility = old.ConditionalVisibility, ConditionalVisibilityVariableName = old.ConditionalVisibilityVariableName }; val.Initialize(shop); val.SetStock(old.CurrentStock, true); return val; } } }