Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of GeneratorMod v0.3.0
GeneratorMod.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using REPOLib.Modules; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("GeneratorMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0")] [assembly: AssemblyProduct("GeneratorMod")] [assembly: AssemblyTitle("GeneratorMod")] [assembly: AssemblyVersion("0.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GeneratorMod { internal static class ChargingStationAccess { private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly FieldInfo ChargeTotal = typeof(ChargingStation).GetField("chargeTotal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ChargeFloat = typeof(ChargingStation).GetField("chargeFloat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo SegmentCurrent = typeof(ChargingStation).GetField("chargeSegmentCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Segments = typeof(ChargingStation).GetField("chargeSegments", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static ChargingStation cached; private static float nextSearchTime; private static bool loggedLayout; private static bool warnedMissing; public static bool Usable { get { if (ChargeTotal != null) { return ChargeTotal.FieldType == typeof(int); } return false; } } public static ChargingStation Get() { if ((Object)(object)cached != (Object)null) { return cached; } if (Time.unscaledTime < nextSearchTime) { return null; } nextSearchTime = Time.unscaledTime + 1f; cached = Object.FindObjectOfType<ChargingStation>(); if ((Object)(object)cached != (Object)null) { LogLayoutOnce(cached); } return cached; } public static int GetCharge(ChargingStation station) { if (!Usable) { return 0; } return (int)ChargeTotal.GetValue(station); } public static bool AddCharge(ChargingStation station, int percent) { if (!Usable) { if (!warnedMissing) { warnedMissing = true; Plugin.Log.LogError((object)"ChargingStation.chargeTotal (int) not found - the game may have renamed it. Recharge disabled."); } return false; } int num = Mathf.Max(1, Plugin.MaxCharge.Value); int num2 = (int)ChargeTotal.GetValue(station); int num3 = Mathf.Clamp(num2 + percent, 0, num); if (num3 == num2) { return false; } Plugin.Log.LogInfo((object)$"AddCharge called: percent={percent}, before={num2}, max={num}"); if (num3 == num2) { Plugin.Log.LogInfo((object)"AddCharge: no change (clamped or percent is 0)"); return false; } ChargeTotal.SetValue(station, num3); Plugin.Log.LogInfo((object)$"AddCharge set: total={(int)ChargeTotal.GetValue(station)}"); float num4 = (float)num3 / (float)num; if (ChargeFloat != null && ChargeFloat.FieldType == typeof(float)) { ChargeFloat.SetValue(station, num4); } if (SegmentCurrent != null && SegmentCurrent.FieldType == typeof(int) && Segments != null && Segments.FieldType == typeof(int)) { int num5 = (int)Segments.GetValue(station); SegmentCurrent.SetValue(station, Mathf.RoundToInt(num4 * (float)num5)); } return true; } private static void LogLayoutOnce(ChargingStation station) { if (!loggedLayout) { loggedLayout = true; IEnumerable<string> values = from f in typeof(ChargingStation).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where f.Name.StartsWith("charge", StringComparison.OrdinalIgnoreCase) select $"{f.FieldType.Name} {f.Name}={f.GetValue(station)}"; Plugin.Log.LogInfo((object)("ChargingStation found. Charge-related fields: " + string.Join(", ", values))); } } } [HarmonyPatch(typeof(ChargingStation), "Update")] internal static class ChargingStationUpdatePatch { private static void Postfix(ref float ___chargeFloat) { float percentPerSecond = GeneratorTicker.PercentPerSecond; if (!(percentPerSecond <= 0f) && SemiFunc.IsMasterClientOrSingleplayer()) { float num = (float)Mathf.Max(1, Plugin.MaxCharge.Value) / 100f; if (!(___chargeFloat >= num)) { ___chargeFloat = Mathf.Min(num, ___chargeFloat + percentPerSecond * Time.deltaTime / 100f); } } } } internal static class GeneratorItemFactory { internal const string AssetName = "Item Upgrade Player Generator"; internal const string DisplayName = "Generator Upgrade"; private static GameObject prefabRoot; internal static Item CreateItemData() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Item obj = ScriptableObject.CreateInstance<Item>(); ((Object)obj).name = "Item Upgrade Player Generator"; obj.itemName = "Generator Upgrade"; obj.description = "Slowly recharges the truck's energy crystals during levels."; obj.itemType = (itemType)3; obj.emojiIcon = (emojiIcon)11; obj.itemVolume = (itemVolume)6; obj.value = ScriptableObject.CreateInstance<Value>(); obj.minPlayerCount = 1; obj.physicalItem = true; ApplyConfiguredValues(obj); return obj; } internal static void ApplyConfiguredValues(Item item) { if (!((Object)(object)item == (Object)null)) { if ((Object)(object)item.value == (Object)null) { item.value = ScriptableObject.CreateInstance<Value>(); } float num = (float)Plugin.BasePrice.Value / 4f; item.value.valueMin = num; item.value.valueMax = num; int value = Plugin.MaxPurchases.Value; item.maxPurchase = true; item.maxPurchaseAmount = value; item.maxAmount = value; } } internal static IEnumerator RegisterPrefabWhenReady() { Item template = null; int waits = 0; while ((Object)(object)template == (Object)null) { template = FindTemplate(); if ((Object)(object)template != (Object)null) { break; } waits++; if (waits == 120) { Plugin.Log.LogWarning((object)("Still waiting for vanilla upgrade '" + Plugin.TemplateItemName.Value + "'. Upgrade items seen so far: " + ListUpgradeItemNames())); } yield return (object)new WaitForSeconds(0.25f); } Plugin.Log.LogInfo((object)("Using '" + ((Object)template).name + "' as the prefab template.")); CopyTemplateMetadata(template, Plugin.GeneratorItem); prefabRoot = new GameObject("GeneratorMod - Registered Prefabs"); prefabRoot.SetActive(false); Object.DontDestroyOnLoad((Object)(object)prefabRoot); GameObject val = Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)template.prefab).Prefab, prefabRoot.transform, false); ((Object)val).name = "Item Upgrade Player Generator"; ItemAttributes component = val.GetComponent<ItemAttributes>(); ItemUpgrade component2 = val.GetComponent<ItemUpgrade>(); ItemToggle component3 = val.GetComponent<ItemToggle>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null) { Plugin.Log.LogError((object)("Template prefab '" + ((Object)template).name + "' is missing ItemAttributes / ItemUpgrade / ItemToggle. The game may have changed. Aborting.")); Object.Destroy((Object)(object)prefabRoot); prefabRoot = null; yield break; } component.item = Plugin.GeneratorItem; component2.isPlayerUpgrade = true; component2.upgradeEvent = new UnityEvent(); StripVanillaUpgradeComponents(val); GeneratorVisuals.Apply(val); REPOLibItemUpgrade val2 = val.GetComponent<REPOLibItemUpgrade>(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent<REPOLibItemUpgrade>(); } AccessTools.Field(typeof(REPOLibItemUpgrade), "_upgradeId").SetValue(val2, "Generator"); if ((Object)(object)val.GetComponent<GeneratorUpgradeBridge>() == (Object)null) { val.AddComponent<GeneratorUpgradeBridge>(); } if (Items.RegisterItem(component) == null) { Plugin.Log.LogError((object)"REPOLib rejected the Generator item prefab."); } else { Plugin.Log.LogInfo((object)($"Registered '{Plugin.GeneratorItem.itemName}' at ${Plugin.BasePrice.Value:N0}, " + $"{Plugin.ShopChancePercent.Value}% shop chance.")); } } private static Item FindTemplate() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 string value = Plugin.TemplateItemName.Value; Item val = null; foreach (Item allItem in Items.AllItems) { if (!((Object)(object)allItem == (Object)null) && !((Object)(object)allItem == (Object)(object)Plugin.GeneratorItem) && allItem.prefab != null && !((Object)(object)((PrefabRef<GameObject>)(object)allItem.prefab).Prefab == (Object)null)) { if (((Object)allItem).name == value) { return allItem; } if ((Object)(object)val == (Object)null && (int)allItem.itemType == 3 && ((Object)allItem).name.StartsWith("Item Upgrade Player", StringComparison.Ordinal) && (((Object)allItem).name.IndexOf("Energy", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)allItem).name.IndexOf("Stamina", StringComparison.OrdinalIgnoreCase) >= 0)) { val = allItem; } } } return val; } private static string ListUpgradeItemNames() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 List<string> list = new List<string>(); foreach (Item allItem in Items.AllItems) { if ((Object)(object)allItem != (Object)null && (int)allItem.itemType == 3) { list.Add(((Object)allItem).name); } } if (list.Count != 0) { return string.Join(", ", list); } return "(none yet)"; } private static void StripVanillaUpgradeComponents(GameObject prefab) { MonoBehaviour[] components = prefab.GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val in components) { if (!((Object)(object)val == (Object)null)) { string name = ((object)val).GetType().Name; if (name.StartsWith("ItemUpgradePlayer", StringComparison.Ordinal)) { Plugin.Log.LogInfo((object)("Removing vanilla component " + name + " from the copied prefab.")); Object.DestroyImmediate((Object)(object)val); } } } } private static void CopyTemplateMetadata(Item source, Item destination) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) destination.disabled = false; destination.itemType = (itemType)3; destination.emojiIcon = source.emojiIcon; destination.itemVolume = source.itemVolume; destination.itemSecretShopType = source.itemSecretShopType; destination.colorPreset = source.colorPreset; destination.spawnRotationOffset = source.spawnRotationOffset; destination.physicalItem = source.physicalItem; } } internal static class GeneratorLevels { public static int TotalOwned() { PlayerUpgrade generatorUpgrade = Plugin.GeneratorUpgrade; if (generatorUpgrade == null) { return 0; } int num = 0; foreach (int value in generatorUpgrade.PlayerDictionary.Values) { num += Mathf.Max(0, value); } return num; } public static int TotalForPresentPlayers() { PlayerUpgrade generatorUpgrade = Plugin.GeneratorUpgrade; if (generatorUpgrade == null) { return 0; } int num = 0; HashSet<string> hashSet = new HashSet<string>(); foreach (PlayerAvatar item in SemiFunc.PlayerGetAll()) { if (!((Object)(object)item == (Object)null)) { string text = SemiFunc.PlayerGetSteamID(item); if (!string.IsNullOrEmpty(text) && hashSet.Add(text)) { num += Mathf.Max(0, generatorUpgrade.GetLevel(text)); } } } return num; } } internal class GeneratorTicker : MonoBehaviour { internal static float PercentPerSecond; private float levelTimer; private int cachedLevels; private void Update() { if (!SemiFunc.RunIsLevel() || (Plugin.HostOnly.Value && !SemiFunc.IsMasterClientOrSingleplayer())) { PercentPerSecond = 0f; return; } levelTimer -= Time.unscaledDeltaTime; if (levelTimer <= 0f) { levelTimer = 1f; cachedLevels = GeneratorLevels.TotalForPresentPlayers(); } PercentPerSecond = ((cachedLevels <= 0) ? 0f : (Plugin.RatePercentPerMinute.Value * (float)cachedLevels / 60f)); } } internal sealed class GeneratorUpgradeBridge : MonoBehaviour { private static readonly FieldInfo UpgradeIdField = AccessTools.Field(typeof(REPOLibItemUpgrade), "_upgradeId"); private void Awake() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown ItemUpgrade component = ((Component)this).GetComponent<ItemUpgrade>(); REPOLibItemUpgrade component2 = ((Component)this).GetComponent<REPOLibItemUpgrade>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || UpgradeIdField == null) { Plugin.Log.LogError((object)"A spawned Generator box is missing its upgrade components."); return; } UpgradeIdField.SetValue(component2, "Generator"); if (component.upgradeEvent == null) { component.upgradeEvent = new UnityEvent(); } ((UnityEventBase)component.upgradeEvent).RemoveAllListeners(); component.upgradeEvent.AddListener(new UnityAction(component2.Upgrade)); } } internal static class GeneratorVisuals { private const string BoxFile = "generator_box.png"; private const string TargetTextureName = "Upgrade_Energy_Albedo"; private const int TexSize = 512; private static Texture2D boxTexture; internal static void Apply(GameObject prefab) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown int num = 0; Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; bool flag = false; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if ((Object)(object)val2 == (Object)null || !val2.HasProperty("_MainTex")) { continue; } Texture texture = val2.GetTexture("_MainTex"); if ((Object)(object)texture == (Object)null || ((Object)texture).name != "Upgrade_Energy_Albedo") { continue; } if (texture.width != 512 || texture.height != 512) { Plugin.Log.LogWarning((object)$"{((Object)texture).name} is {texture.width}x{texture.height}, expected {512}x{512}. The game may have changed it; keeping the vanilla look."); continue; } if ((Object)(object)boxTexture == (Object)null) { boxTexture = LoadBoxTexture(texture); } if (!((Object)(object)boxTexture == (Object)null)) { Material val3 = new Material(val2) { name = ((Object)val2).name + " (Generator)" }; val3.SetTexture("_MainTex", (Texture)(object)boxTexture); sharedMaterials[j] = val3; flag = true; num++; } } if (flag) { val.sharedMaterials = sharedMaterials; } } Plugin.Log.LogInfo((object)((num > 0) ? string.Format("Retextured {0} material(s) with {1}.", num, "generator_box.png") : "No material using 'Upgrade_Energy_Albedo' was found; keeping the vanilla look.")); } private static Texture2D LoadBoxTexture(Texture like) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "generator_box.png"); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("generator_box.png not found next to the DLL (" + text + "). Keeping the vanilla look.")); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text))) { Plugin.Log.LogWarning((object)"Could not decode generator_box.png."); return null; } if (((Texture)val).width != 512 || ((Texture)val).height != 512) { Plugin.Log.LogWarning((object)string.Format("{0} must be {1}x{2}, but is {3}x{4}.", "generator_box.png", 512, 512, ((Texture)val).width, ((Texture)val).height)); return null; } ((Object)val).name = "GeneratorBoxAlbedo"; ((Texture)val).wrapMode = like.wrapMode; ((Texture)val).filterMode = like.filterMode; ((Texture)val).anisoLevel = like.anisoLevel; ((Object)val).hideFlags = (HideFlags)32; return val; } } [BepInPlugin("KimJongPoon.GeneratorMod", "GeneratorMod", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "KimJongPoon.GeneratorMod"; public const string Name = "GeneratorMod"; public const string Version = "0.3.0"; public const string UpgradeId = "Generator"; public const float ShopValueMultiplier = 4f; internal static ManualLogSource Log; internal static PlayerUpgrade GeneratorUpgrade; internal static Item GeneratorItem; internal static ConfigEntry<int> BasePrice; internal static ConfigEntry<float> ShopChancePercent; internal static ConfigEntry<int> MaxPurchases; internal static ConfigEntry<bool> UseVanillaPriceScaling; internal static ConfigEntry<string> TemplateItemName; internal static ConfigEntry<float> RatePercentPerMinute; internal static ConfigEntry<bool> HostOnly; internal static ConfigEntry<int> MaxCharge; internal static ConfigEntry<bool> DebugLogging; private Harmony harmony; private void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BasePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "BasePrice", 25000, new ConfigDescription("Price of the Generator upgrade box in the shop (25000 = $25k).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1000, 5000000), Array.Empty<object>())); ShopChancePercent = ((BaseUnityPlugin)this).Config.Bind<float>("Shop", "ShopChancePercent", 10f, new ConfigDescription("Chance (in percent) that the Generator is added to the pool of upgrades for any one shop visit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); MaxPurchases = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "MaxPurchases", 1, new ConfigDescription("How many Generator levels the whole team can buy in total. Each level adds another RatePercentPerMinute.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); UseVanillaPriceScaling = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "UseVanillaPriceScaling", false, "If false, the price is always exactly BasePrice. If true, the game's normal upgrade price scaling applies on top."); TemplateItemName = ((BaseUnityPlugin)this).Config.Bind<string>("Shop", "TemplateItemName", "Item Upgrade Player Energy", "Name of the vanilla upgrade item whose prefab (the box) is copied. The stamina upgrade is 'Energy' in the game's code."); RatePercentPerMinute = ((BaseUnityPlugin)this).Config.Bind<float>("Recharge", "RatePercentPerMinute", 3f, new ConfigDescription("Percent of a full truck energy bar restored per minute, per Generator level. Only ticks during active levels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); HostOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Recharge", "HostOnly", false, "If true, only the host (or singleplayer) applies the recharge. Leave false unless clients double-count in multiplayer."); MaxCharge = ((BaseUnityPlugin)this).Config.Bind<int>("Recharge", "MaxCharge", 100, "Value of ChargingStation.chargeTotal that means a full bar. Vanilla is 100."); DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Log every shop roll and every recharge tick."); GeneratorItem = GeneratorItemFactory.CreateItemData(); BasePrice.SettingChanged += delegate { GeneratorItemFactory.ApplyConfiguredValues(GeneratorItem); }; MaxPurchases.SettingChanged += delegate { GeneratorItemFactory.ApplyConfiguredValues(GeneratorItem); }; GeneratorUpgrade = Upgrades.RegisterUpgrade("Generator", GeneratorItem, (Action<PlayerAvatar, int>)null, (Action<PlayerAvatar, int>)null); if (GeneratorUpgrade == null) { Log.LogError((object)"Could not register REPOLib upgrade 'Generator'. GeneratorMod will not continue."); return; } harmony = new Harmony("KimJongPoon.GeneratorMod"); harmony.PatchAll(); GameObject val = new GameObject("GeneratorMod.Ticker") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); ((MonoBehaviour)val.AddComponent<GeneratorTicker>()).StartCoroutine(GeneratorItemFactory.RegisterPrefabWhenReady()); Log.LogInfo((object)"GeneratorMod 0.3.0 loaded. Waiting for the vanilla upgrade prefab to copy."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } [HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")] internal static class ShopRollPatch { [HarmonyPrefix] private static void Prefix() { Item generatorItem = Plugin.GeneratorItem; if (!((Object)(object)generatorItem == (Object)null)) { GeneratorItemFactory.ApplyConfiguredValues(generatorItem); int num = GeneratorLevels.TotalOwned(); bool num2 = num < Plugin.MaxPurchases.Value; float num3 = Random.Range(0f, 100f); bool flag = num2 && num3 < Plugin.ShopChancePercent.Value; generatorItem.minPlayerCount = (flag ? 1 : 99); generatorItem.maxAmountInShop = (flag ? 1 : 0); if (Plugin.DebugLogging.Value) { Plugin.Log.LogInfo((object)$"Shop roll: {num3:0.0} vs {Plugin.ShopChancePercent.Value}% | owned {num}/{Plugin.MaxPurchases.Value} | offered = {flag}"); } } } } [HarmonyPatch(typeof(ShopManager), "UpgradeValueGet")] internal static class UpgradePricePatch { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(Item item, ref float __result) { if ((Object)(object)item == (Object)null || ((Object)item).name != "Item Upgrade Player Generator") { return true; } if (Plugin.UseVanillaPriceScaling.Value) { return true; } __result = Plugin.BasePrice.Value; return false; } } }