Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of RecommendedPriceMono v1.1.2
Mods/RecommendedPrice.Mono.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; 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 RecommendedPrice; using ScheduleOne.Core.Items.Framework; using ScheduleOne.DevUtilities; using ScheduleOne.Product; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Mod), "Recommended Price", "1.1.2", "Foxcapades", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RecommendedPrice")] [assembly: AssemblyConfiguration("Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9f29c78855c6d2f08159db0ee3cacc20b8bac4da")] [assembly: AssemblyProduct("RecommendedPrice")] [assembly: AssemblyTitle("RecommendedPrice")] [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; } } } } namespace RecommendedPrice { [HarmonyPatch] public class Mod : FxMod { public const string MOD_NAME = "Recommended Price"; private static MelonPreferences_Category? preferences; private static MelonPreferences_Entry<float>? weedModifier; private static MelonPreferences_Entry<float>? cokeModifier; private static MelonPreferences_Entry<float>? methModifier; private static MelonPreferences_Entry<float>? shrmModifier; private static Action<ProductDefinition>? onProductAction; private static readonly Dictionary<string, float> originalProductPrices = new Dictionary<string, float>(12); public override void OnInitializeMelon() { preferences = MelonPreferences.CreateCategory("Recommended Price", "Recommended Price"); weedModifier = preferences.CreateEntry<float>("weedModifier", 1f, "Weed Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)weedModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); cokeModifier = preferences.CreateEntry<float>("cocaineModifier", 1f, "Cocaine Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)cokeModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); methModifier = preferences.CreateEntry<float>("methModifier", 1f, "Meth Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)methModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); shrmModifier = preferences.CreateEntry<float>("shoomModifier", 1f, "Shroom Price Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<float, float>>)(object)shrmModifier.OnEntryValueChanged).Subscribe((LemonAction<float, float>)onPrefChange, 0, false); } private void onPrefChange(float o, float n) { if (!Mathf.Approximately(o, n)) { applyInMainOnly(); } } [HarmonyPrefix] [HarmonyPatch(typeof(ProductManager), "OnStartServer")] private static void PreStartServer(ProductManager __instance) { onProductAction = onProduct; __instance.onProductDiscovered = (Action<ProductDefinition>)Delegate.Combine(__instance.onProductDiscovered, onProductAction); __instance.onNewProductCreated = (Action<ProductDefinition>)Delegate.Combine(__instance.onNewProductCreated, onProductAction); } [HarmonyPostfix] [HarmonyPatch(typeof(ProductManager), "Clean")] private static void PostClean(ProductManager __instance) { unapplyModifiers(__instance); if (onProductAction != null) { __instance.onProductDiscovered = (Action<ProductDefinition>)Delegate.Remove(__instance.onProductDiscovered, onProductAction); __instance.onNewProductCreated = (Action<ProductDefinition>)Delegate.Remove(__instance.onNewProductCreated, onProductAction); onProductAction = null; } } private static void applyInMainOnly() { if (!FxMod.Instance.InMainScene) { return; } Instance loggerInstance = ((MelonBase)Melon<Mod>.Instance).LoggerInstance; ProductManager val = NetworkSingleton<ProductManager>.Instance; loggerInstance.Msg("attempting to apply recommended price modifiers"); Dictionary<ProductDefinition, float> productPrices = getProductPrices(); if (productPrices == null) { loggerInstance.Error("failed to get product prices, cannot modify price values"); return; } foreach (ProductDefinition allProduct in val.AllProducts) { apply(productPrices, allProduct); } } private static void onProduct(ProductDefinition product) { apply(getProductPrices(), product); } private static void apply(Dictionary<ProductDefinition, float>? prices, ProductDefinition product) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) float marketValue = product.MarketValue; originalProductPrices.TryAdd(((BaseItemDefinition)product).ID, product.MarketValue); product.MarketValue = safeMultiply(originalProductPrices[((BaseItemDefinition)product).ID], product.DrugType); if (prices != null && prices.TryGetValue(product, out var value) && (value == 0f || Mathf.Approximately(value, product.BasePrice) || Mathf.Approximately(value, marketValue))) { prices[product] = product.MarketValue; } } private static void unapplyModifiers(ProductManager manager) { Dictionary<ProductDefinition, float> productPrices = getProductPrices(); Instance loggerInstance = ((MelonBase)Melon<Mod>.Instance).LoggerInstance; loggerInstance.Msg("attempting to revert recommended price modifiers"); if (productPrices == null) { loggerInstance.Error("failed to get product prices, cannot revert price values"); return; } foreach (ProductDefinition allProduct in manager.AllProducts) { if (!originalProductPrices.ContainsKey(((BaseItemDefinition)allProduct).ID)) { loggerInstance.Warning("unrecognized product id {0}", new object[1] { ((BaseItemDefinition)allProduct).ID }); } else if (!productPrices.ContainsKey(allProduct)) { loggerInstance.Warning("product id {0} not found in product price index", new object[1] { ((BaseItemDefinition)allProduct).ID }); } else { productPrices[allProduct] = originalProductPrices[((BaseItemDefinition)allProduct).ID]; } } } private static float safeMultiply(float price, EDrugType type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown if (1 == 0) { } float num = (int)type switch { 0 => weedModifier.Value, 1 => methModifier.Value, 2 => cokeModifier.Value, 4 => shrmModifier.Value, _ => 1f, }; if (1 == 0) { } float num2 = num; num2 = ((num2 < 0.01f) ? 0.01f : num2); return (float)Math.Round(price * num2, MidpointRounding.AwayFromZero); } private static Dictionary<ProductDefinition, float>? getProductPrices() { PropertyInfo propertyInfo = AccessTools.DeclaredProperty(typeof(ProductManager), "ProductPrices"); if (propertyInfo == null) { return null; } return (Dictionary<ProductDefinition, float>)propertyInfo.GetValue(NetworkSingleton<ProductManager>.Instance); } } }