Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Lithium v1.0.5
mods/Lithium.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using HarmonyLib; using Il2CppFishNet; using Il2CppFishNet.Object; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Dialogue; using Il2CppScheduleOne.Economy; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.Equipping; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.Growing; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Law; using Il2CppScheduleOne.Levelling; using Il2CppScheduleOne.Messaging; using Il2CppScheduleOne.Money; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Behaviour; using Il2CppScheduleOne.NPCs.CharacterClasses; using Il2CppScheduleOne.ObjectScripts; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Properties; using Il2CppScheduleOne.Property; using Il2CppScheduleOne.Quests; using Il2CppScheduleOne.UI; using Il2CppScheduleOne.UI.Handover; using Il2CppScheduleOne.UI.Items; using Il2CppScheduleOne.UI.Phone; using Il2CppScheduleOne.UI.Phone.Delivery; using Il2CppScheduleOne.UI.Shop; using Il2CppScheduleOne.UI.Stations; using Il2CppScheduleOne.UI.Stations.Drying_rack; using Il2CppScheduleOne.Variables; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using Lithium; using Lithium.Helper; using Lithium.Modules; using Lithium.Modules.ChemistryStation; using Lithium.Modules.Customers; using Lithium.Modules.Customers.Architecture; using Lithium.Modules.Customers.Behaviours; using Lithium.Modules.Customers.BonusPayments; using Lithium.Modules.DryingRacks; using Lithium.Modules.EffectCombos; using Lithium.Modules.EffectCombos.BonusPayments; using Lithium.Modules.LabOven; using Lithium.Modules.MixingStations; using Lithium.Modules.PlantGrowth; using Lithium.Modules.PlantGrowth.Behaviours; using Lithium.Modules.PropertyPrices; using Lithium.Modules.Shops; using Lithium.Modules.StackSizes; using Lithium.Modules.Storyline; using Lithium.Modules.TrashGrabber; using Lithium.Modules.WateringCans; using Lithium.Util; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Converters; 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(Core), "Lithium", "1.0.0", "DerTomDer & YukiSora", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Lithium")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+7dd150e58cb6b8e41bdfda499897bee8c6506e7a")] [assembly: AssemblyProduct("Lithium")] [assembly: AssemblyTitle("Lithium")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Lithium { public class Core : MelonMod { public static readonly List<ModuleBase> Modules = new List<ModuleBase>(13) { new ModPropertyPrices(), new ModPlants(), new ModDryingRacks(), new ModCustomers(), new ModStackSizes(), new ModLabOven(), new ModTrashGrabber(), new ModMixingStations(), new ModStoryline(), new ModShops(), new ModChemistryStation(), new ModWateringCan(), new ModEffectCombos() }; private bool _isFirstStart = true; public static Instance Logger { get; set; } public static T Get<T>() where T : ModuleBase { return Modules.OfType<T>().FirstOrDefault(); } public override void OnInitializeMelon() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown Logger = ((MelonBase)this).LoggerInstance; foreach (ModuleBase module in Modules) { ((MelonBase)this).LoggerInstance.Msg("Loading " + module.GetType().Name); module.Load(); } Harmony val = new Harmony("com.lithium"); val.PatchAll(); ((MelonBase)this).LoggerInstance.Msg("Lithium initialized"); } public override void OnSceneWasInitialized(int buildIndex, string sceneName) { if (sceneName == "Main") { foreach (ModuleBase module in Modules) { ((MelonBase)this).LoggerInstance.Msg("Loading " + module.GetType().Name); module.Apply(); } _isFirstStart = false; } else if (sceneName.Equals("Menu", StringComparison.OrdinalIgnoreCase) && !_isFirstStart) { _isFirstStart = true; } } public override void OnUpdate() { ((MelonBase)this).OnUpdate(); if (Input.GetKeyDown((KeyCode)286)) { Customer val = Customer.UnlockedCustomers.ToList<Customer>()[0]; } } } } namespace Lithium.Util { public static class DeliveryUtils { public static void ApplyDeliveryOverrides() { Dictionary<string, DeliveryShop> dictionary = (from s in ((IEnumerable<DeliveryShop>)Object.FindObjectsOfType<DeliveryShop>(true)).ToList() where (Object)(object)s != (Object)null && (Object)(object)s.MatchingShop != (Object)null select s).ToDictionary((DeliveryShop s) => s.MatchingShop.ShopName, (DeliveryShop s) => s); ModShopsConfiguration configuration = Core.Get<ModShops>().Configuration; foreach (KeyValuePair<string, DeliverySettings> delivery in configuration.Deliveries) { if (!dictionary.TryGetValue(delivery.Key, out var value)) { continue; } switch (delivery.Value.Availability) { case DeliveryAvailabilitySettings.Unchanged: switch (value.MatchingShop.ShopName) { case "Albert Hoover": { Albert val3 = Object.FindObjectOfType<Albert>(); value.IsAvailable = ((NPC)val3).RelationData.RelationDelta > Supplier.DELIVERY_RELATIONSHIP_REQUIREMENT; break; } case "Shirley Watts": { Shirley val2 = Object.FindObjectOfType<Shirley>(); value.IsAvailable = ((NPC)val2).RelationData.RelationDelta > Supplier.DELIVERY_RELATIONSHIP_REQUIREMENT; break; } case "Salvador Moreno": { Salvador val = Object.FindObjectOfType<Salvador>(); value.IsAvailable = ((NPC)val).RelationData.RelationDelta > Supplier.DELIVERY_RELATIONSHIP_REQUIREMENT; break; } default: value.IsAvailable = value.IsAvailable; break; } continue; case DeliveryAvailabilitySettings.Never: value.IsAvailable = false; break; case DeliveryAvailabilitySettings.Always: value.IsAvailable = true; break; case DeliveryAvailabilitySettings.AfterReachingXP: value.IsAvailable = NetworkSingleton<LevelManager>.Instance.TotalXP >= delivery.Value.XPRequirement; break; default: throw new ArgumentOutOfRangeException(); } value.DeliveryFee = delivery.Value.DeliveryFee; value.DeliveryFeeLabel.text = $"${value.DeliveryFee}"; ((Component)value).gameObject.SetActive(value.IsAvailable); } } } public static class SuccessChanceCalculator { public static float CalculateSuccess(EDrugType drugType, EQuality quality, float qualityLevelModifier, ECustomerStandard standard, string[] desires, string[] effects, CustomerAffinityData affinities, bool includeDrugPreference, float baseAcceptance) { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected I4, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) float num2; if (desires.Length != 0) { int num = 0; foreach (string item in desires.Where((string d) => !string.IsNullOrEmpty(d))) { num += (effects.Contains(item) ? 1 : 0); } num2 = (float)num / (float)desires.Length; Core.Logger.Msg($"Sample offering: Covered {num} desires. Base acceptance {num2 * 100f:F1}%"); } else { Core.Logger.Msg("Sample offering: No desired. Base acceptance 100%"); num2 = 1f; } int num3 = quality - standard; Core.Logger.Msg($"Sample offering: Quality difference {num3} levels"); num2 += qualityLevelModifier * (float)num3; Core.Logger.Msg($"Adjusted acceptance: {num2 * 100f:F1}%"); if (includeDrugPreference) { Enumerator<ProductTypeAffinity> enumerator2 = affinities.ProductAffinities.GetEnumerator(); while (enumerator2.MoveNext()) { ProductTypeAffinity current2 = enumerator2.Current; if (current2.DrugType == drugType) { Core.Logger.Msg($"Sample offering: Product affinity modifier: {current2.Affinity * 100f:F1}%"); num2 *= current2.Affinity; break; } } } num2 += baseAcceptance; Core.Logger.Msg($"Sample offering: Final acceptance is {Mathf.Clamp01(num2):F1}%"); return Mathf.Clamp01(num2); } } public class WeightedNormalizer { private readonly List<float> _weights = new List<float>(); private readonly List<float> _values = new List<float>(); private readonly List<float> _cdf = new List<float>(); private bool _isInitialized; public void Add(float weight, float value) { if (weight < 0f) { throw new ArgumentOutOfRangeException("weight", "Weight must be non-negative."); } _weights.Add(weight); _values.Add(value); _isInitialized = false; } private void Initialize() { _cdf.Clear(); float num = _weights.Sum(); if (num == 0f) { _cdf.Clear(); _cdf.Add(1f); _isInitialized = true; return; } float num2 = 0f; foreach (float weight in _weights) { num2 += weight / num; _cdf.Add(num2); } _isInitialized = true; } public float Evaluate(float n) { if (!_isInitialized) { Initialize(); } if (_values.Count == 0) { throw new InvalidOperationException("No values added to normalize."); } float num = n; float num2 = num; if (!(num2 <= 0f)) { if (num2 >= 1f) { List<float> values = _values; return values[values.Count - 1]; } int num3 = _cdf.FindIndex((float x) => x > n); switch (num3) { case -1: { List<float> values2 = _values; return values2[values2.Count - 1]; } case 0: return _values[0]; default: { int index = num3 - 1; float num4 = _cdf[index]; float num5 = _cdf[num3]; float num6 = (n - num4) / (num5 - num4); float num7 = _values[index]; float num8 = _values[num3]; return num7 + (num8 - num7) * num6; } } } return _values[0]; } } public class PickerEmptyException : Exception { } public class WeightedPicker<T> { private readonly Random _random; private bool _hasChanged; private readonly Dictionary<T, float> _dictionary = new Dictionary<T, float>(); private double _totalWeight; public int Count => _dictionary.Count; public float this[T key] { get { return _dictionary[key]; } set { _dictionary[key] = value; _hasChanged = true; } } public WeightedPicker(Random random) { _random = random; } public WeightedPicker() : this(new Random(Guid.NewGuid().GetHashCode())) { } public T Pick() { if (_hasChanged) { Rebuild(); } float value = (float)_random.Next((int)(_totalWeight * 100.0)) / 100f; return PickManually(value); } public T PickManually(float value) { if (_hasChanged) { Rebuild(); } value = Math.Min((float)_totalWeight, Math.Max(0f, value)); float num = 0f; KeyValuePair<T, float>? keyValuePair = null; foreach (KeyValuePair<T, float> item in _dictionary) { if (num > value) { break; } keyValuePair = item; num += item.Value; } if (!keyValuePair.HasValue) { throw new PickerEmptyException(); } return keyValuePair.Value.Key; } private void Rebuild() { _totalWeight = _dictionary.Values.Sum(); _hasChanged = false; } public void Add(T value, float weight) { _dictionary.Add(value, weight); _hasChanged = true; } public void AddRange(IEnumerable<KeyValuePair<T, float>> entries) { foreach (KeyValuePair<T, float> entry in entries) { _dictionary.Add(entry.Key, entry.Value); } _hasChanged = true; } public bool Remove(T key) { _hasChanged = true; return _dictionary.Remove(key); } public void Clear() { _dictionary.Clear(); _hasChanged = true; } } } namespace Lithium.Modules { public abstract class ModuleBase { public abstract void Load(); public abstract void Apply(); } public abstract class ModuleBase<TConfiguration> : ModuleBase where TConfiguration : ModuleConfiguration { public TConfiguration Configuration { get; private set; } protected virtual void OnBeforeConfigurationLoaded() { } public override void Load() { Configuration = Activator.CreateInstance<TConfiguration>(); OnBeforeConfigurationLoaded(); Configuration.LoadConfiguration(); } } public abstract class ModuleConfiguration { private static readonly string ConfigFolder = Path.Combine(MelonEnvironment.UserDataDirectory, "Lithium"); [JsonProperty(Order = -500)] public bool Enabled; [JsonIgnore] public abstract string Name { get; } public string GetConfigFile() { return Path.Combine(ConfigFolder, Name + ".json"); } public void SaveConfiguration() { if (!Directory.Exists(ConfigFolder)) { Directory.CreateDirectory(ConfigFolder); } string configFile = GetConfigFile(); string contents = JsonConvert.SerializeObject((object)this, (Formatting)1); File.WriteAllText(configFile, contents); } public void LoadConfiguration() { string configFile = GetConfigFile(); if (File.Exists(configFile)) { string text = File.ReadAllText(configFile); JsonConvert.PopulateObject(text, (object)this); } else { SaveConfiguration(); } } } } namespace Lithium.Modules.MixingStations { public class ModMixingStationsConfiguration : ModuleConfiguration { public override string Name => "MixingStation"; public int InputCapacity { get; set; } = 20; public int MixStepsPerSecond { get; set; } = 1; } public class ModMixingStations : ModuleBase<ModMixingStationsConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.MixingStations.Patches { [HarmonyPatch(typeof(MixingStation), "Start")] public class MixingStationCapacityPatch { [HarmonyPostfix] public static void MixingStationCapacity(MixingStation __instance) { ModMixingStationsConfiguration configuration = Core.Get<ModMixingStations>().Configuration; if (configuration.Enabled) { __instance.MaxMixQuantity = configuration.InputCapacity; } } } [HarmonyPatch(typeof(MixingStation), "MinPass")] internal class MixingStationSpeedPatch { [HarmonyPrefix] public static bool MixingStationSpeed(MixingStation __instance) { ModMixingStationsConfiguration configuration = Core.Get<ModMixingStations>().Configuration; if (!configuration.Enabled) { return true; } if (__instance.CurrentMixOperation != null || __instance.OutputSlot.Quantity > 0) { int num = 0; if (__instance.CurrentMixOperation != null) { int currentMixTime = __instance.CurrentMixTime; int currentMixTime2 = __instance.CurrentMixTime; __instance.CurrentMixTime = currentMixTime2 + configuration.MixStepsPerSecond; num = __instance.GetMixTimeForCurrentOperation(); if (__instance.CurrentMixTime >= num && currentMixTime < num && InstanceFinder.IsServer) { NetworkSingleton<VariableDatabase>.Instance.SetVariableValue("Mixing_Operations_Completed", (NetworkSingleton<VariableDatabase>.Instance.GetValue<float>("Mixing_Operations_Completed") + 1f).ToString(), true); __instance.MixingDone_Networked(); } } if ((Object)(object)__instance.Clock != (Object)null) { __instance.Clock.SetScreenLit(true); __instance.Clock.DisplayMinutes(Mathf.Max(num - __instance.CurrentMixTime, 0)); } if ((Object)(object)__instance.Light != (Object)null) { if (__instance.IsMixingDone) { __instance.Light.isOn = NetworkSingleton<TimeManager>.Instance.DailyMinTotal % 2 == 0; return false; } __instance.Light.isOn = true; return false; } } else { if ((Object)(object)__instance.Clock != (Object)null) { __instance.Clock.SetScreenLit(false); __instance.Clock.DisplayText(string.Empty); } if ((Object)(object)__instance.Light != (Object)null && __instance.IsMixingDone) { __instance.Light.isOn = false; } } return false; } } } namespace Lithium.Modules.TrashGrabber { public class ModTrashGrabberConfiguration : ModuleConfiguration { public override string Name => "TrashGrabber"; public int CustomCapacity { get; set; } = 20; } public class ModTrashGrabber : ModuleBase<ModTrashGrabberConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.TrashGrabber.Patches { [HarmonyPatch(typeof(Equippable_TrashGrabber), "GetCapacity")] public static class EquippableTrashGrabberGetCapacityPatch { [HarmonyPostfix] public static void Postfix(ref int __result, Equippable_TrashGrabber __instance) { ModTrashGrabberConfiguration configuration = Core.Get<ModTrashGrabber>().Configuration; if (configuration.Enabled) { __result = configuration.CustomCapacity - __instance.trashGrabberInstance.GetTotalSize(); } } } } namespace Lithium.Modules.StackSizes { public class ModStackSizesConfiguration : ModuleConfiguration { public override string Name => "StackSizes"; public Dictionary<EItemCategory, int> CategorySizes { get; set; } = new Dictionary<EItemCategory, int> { { (EItemCategory)0, 20 }, { (EItemCategory)1, 20 }, { (EItemCategory)2, 20 }, { (EItemCategory)3, 10 }, { (EItemCategory)4, 10 }, { (EItemCategory)5, 10 }, { (EItemCategory)6, 1000 }, { (EItemCategory)7, 20 }, { (EItemCategory)8, 20 }, { (EItemCategory)9, 20 }, { (EItemCategory)10, 10 }, { (EItemCategory)11, 10 }, { (EItemCategory)12, 10 } }; public Dictionary<string, int> ItemOverrides { get; set; } = new Dictionary<string, int>(); public List<string> IgnoredItems { get; set; } = new List<string>(); } public class ModStackSizes : ModuleBase<ModStackSizesConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } public static class ItemRegistry { public static List<ItemDefinition> AllItemDefinitions = new List<ItemDefinition>(); public static void UpdateEntireRegistry() { foreach (ItemDefinition allItemDefinition in AllItemDefinitions) { UpdateItemDefinition(allItemDefinition); } } public static void UpdateItemDefinition(ItemDefinition itemDefinition) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) ModStackSizesConfiguration configuration = Core.Get<ModStackSizes>().Configuration; if (configuration.Enabled && !configuration.IgnoredItems.Contains(itemDefinition.ID)) { if (configuration.ItemOverrides.TryGetValue(itemDefinition.ID, out var value)) { itemDefinition.StackLimit = value; return; } if (configuration.CategorySizes.TryGetValue(itemDefinition.Category, out value)) { itemDefinition.StackLimit = value; return; } MelonLogger.Warning($"Found item for category {itemDefinition.Category}, but no category value"); } } } } namespace Lithium.Modules.StackSizes.Patches { [HarmonyPatch(typeof(ItemUIManager), "UpdateCashDragAmount")] [HarmonyPatch(typeof(ItemUIManager), "StartDragCash")] [HarmonyPatch(typeof(ItemUIManager), "EndCashDrag")] public class CashDragPatch { [CompilerGenerated] private sealed class <TranspilerPatch>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private IEnumerator<CodeInstruction> <>s__1; private CodeInstruction <instruction>5__2; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TranspilerPatch>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } <>s__1 = null; <instruction>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>s__1 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; goto IL_00ea; case 2: { <>1__state = -3; goto IL_00ea; } IL_00ea: <instruction>5__2 = null; break; } if (<>s__1.MoveNext()) { <instruction>5__2 = <>s__1.Current; if (<instruction>5__2.opcode == OpCodes.Ldc_R4 && (float)<instruction>5__2.operand == 1000f) { <>2__current = new CodeInstruction(OpCodes.Ldc_R4, (object)5000f); <>1__state = 1; return true; } <>2__current = <instruction>5__2; <>1__state = 2; return true; } <>m__Finally1(); <>s__1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__1 != null) { <>s__1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <TranspilerPatch>d__0 <TranspilerPatch>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <TranspilerPatch>d__ = this; } else { <TranspilerPatch>d__ = new <TranspilerPatch>d__0(0); } <TranspilerPatch>d__.instructions = <>3__instructions; return <TranspilerPatch>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<TranspilerPatch>d__0))] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> TranspilerPatch(IEnumerable<CodeInstruction> instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TranspilerPatch>d__0(-2) { <>3__instructions = instructions }; } } [HarmonyPatch(typeof(Registry), "AddToRegistry")] public class RegistryAddToRegistryPatch { [HarmonyPostfix] public static void RegistryAddToRegistry(Registry __instance, ItemDefinition item) { CollectionExtensions.AddItem<ItemDefinition>((IEnumerable<ItemDefinition>)ItemRegistry.AllItemDefinitions, item); ItemRegistry.UpdateItemDefinition(item); } } [HarmonyPatch(typeof(Registry), "Start")] public class RegistryStartPatch { [HarmonyPostfix] public static void RegistryStart(Registry __instance) { ModStackSizesConfiguration configuration = Core.Get<ModStackSizes>().Configuration; if (configuration.Enabled) { List<ItemRegister> list = new List<ItemRegister>(); Enumerator<ItemRegister> enumerator = __instance.ItemRegistry.GetEnumerator(); while (enumerator.MoveNext()) { ItemRegister current = enumerator.Current; list.Add(current); } ItemRegistry.AllItemDefinitions = list.Select((ItemRegister itemRegister) => itemRegister.Definition).ToList(); ItemRegistry.UpdateEntireRegistry(); } } } } namespace Lithium.Modules.PlantGrowth { public class WeightedFloat { public float Weight; public float Value; [JsonConstructor] public WeightedFloat(float weight, float value) { Weight = weight; Value = value; } } public class ModPlantsConfiguration : ModuleConfiguration { public float GrowthModifier = 1f; public float WaterDrainModifier = 1f; public static readonly List<WeightedFloat> RandomYieldsPerBudModifierDefaults = new List<WeightedFloat>(3) { new WeightedFloat(7f, 1f), new WeightedFloat(2f, 2f), new WeightedFloat(1f, 3f) }; public static readonly List<WeightedFloat> RandomYieldModifiersDefaults = new List<WeightedFloat>(4) { new WeightedFloat(7.5f, 1f), new WeightedFloat(1f, 0.25f), new WeightedFloat(1f, 1.5f), new WeightedFloat(0.5f, 3f) }; public static readonly List<WeightedFloat> RandomQualityModifiersDefaults = new List<WeightedFloat>(5) { new WeightedFloat(0f, -0.5f), new WeightedFloat(0.5f, 0f), new WeightedFloat(0.75f, 0f), new WeightedFloat(0.2f, 0.4f), new WeightedFloat(0.01f, 0.5f) }; public List<WeightedFloat> RandomYieldsPerBudModifier = RandomYieldsPerBudModifierDefaults; public List<WeightedFloat> RandomYieldModifiers = RandomYieldModifiersDefaults; public List<WeightedFloat> RandomQualityModifiers = RandomQualityModifiersDefaults; [JsonIgnore] public WeightedPicker<float> RandomYieldPerBudPicker; [JsonIgnore] public WeightedNormalizer RandomYieldModifierPicker; [JsonIgnore] public WeightedNormalizer RandomYieldQualityPicker; public override string Name => "Plants"; } public class ModPlants : ModuleBase<ModPlantsConfiguration> { public ModPlants() { ClassInjector.RegisterTypeInIl2Cpp<PlantModified>(); ClassInjector.RegisterTypeInIl2Cpp<PlantBaseQuality>(); ClassInjector.RegisterTypeInIl2Cpp<PotBaseValues>(); } protected override void OnBeforeConfigurationLoaded() { base.OnBeforeConfigurationLoaded(); base.Configuration.RandomYieldsPerBudModifier.Clear(); base.Configuration.RandomYieldModifiers.Clear(); base.Configuration.RandomQualityModifiers.Clear(); } public override void Load() { base.Load(); base.Configuration.RandomYieldPerBudPicker = new WeightedPicker<float>(); base.Configuration.RandomYieldPerBudPicker.AddRange((base.Configuration.RandomYieldPerBudPicker.Count == 0) ? ModPlantsConfiguration.RandomYieldsPerBudModifierDefaults.Select((WeightedFloat p) => new KeyValuePair<float, float>(p.Value, p.Weight)) : base.Configuration.RandomYieldsPerBudModifier.Select((WeightedFloat p) => new KeyValuePair<float, float>(p.Value, p.Weight))); base.Configuration.RandomYieldModifierPicker = new WeightedNormalizer(); foreach (WeightedFloat randomYieldModifier in base.Configuration.RandomYieldModifiers) { base.Configuration.RandomYieldModifierPicker.Add(randomYieldModifier.Weight, randomYieldModifier.Value); } if (base.Configuration.RandomYieldModifiers.Count == 0 || base.Configuration.RandomYieldModifiers.Sum((WeightedFloat e) => e.Weight) <= 0f) { foreach (WeightedFloat randomYieldModifiersDefault in ModPlantsConfiguration.RandomYieldModifiersDefaults) { base.Configuration.RandomYieldModifiers.Add(randomYieldModifiersDefault); } } base.Configuration.RandomYieldQualityPicker = new WeightedNormalizer(); foreach (WeightedFloat randomQualityModifier in base.Configuration.RandomQualityModifiers) { base.Configuration.RandomYieldQualityPicker.Add(randomQualityModifier.Weight, randomQualityModifier.Value); } if (base.Configuration.RandomQualityModifiers.Count != 0 && !(base.Configuration.RandomQualityModifiers.Sum((WeightedFloat e) => e.Weight) <= 0f)) { return; } foreach (WeightedFloat randomQualityModifiersDefault in ModPlantsConfiguration.RandomQualityModifiersDefaults) { base.Configuration.RandomYieldQualityPicker.Add(randomQualityModifiersDefault.Weight, randomQualityModifiersDefault.Value); } } public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.PlantGrowth.Patches { [HarmonyPatch(typeof(PotActionBehaviour), "CompleteAction")] public class PotActionBehaviorPatch { public static void Postfix(PotActionBehaviour __instance) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 ModPlantsConfiguration configuration = Core.Get<ModPlants>().Configuration; if (configuration.Enabled && (int)__instance.CurrentActionType == 5 && !((Object)(object)__instance.botanist == (Object)null) && !((Object)(object)((NPC)__instance.botanist).Inventory == (Object)null)) { ItemInstance itemToRetrieveTemplate = ((Employee)__instance.botanist).MoveItemBehaviour.itemToRetrieveTemplate; if (itemToRetrieveTemplate != null) { itemToRetrieveTemplate.Quantity = (int)Math.Min((float)itemToRetrieveTemplate.Quantity * configuration.RandomYieldPerBudPicker.Pick(), itemToRetrieveTemplate.StackLimit); } } } } [HarmonyPatch(typeof(Plant), "GrowthDone")] public class PlantGrowthDonePatch { [HarmonyPrefix] public static void Prefix(Plant __instance) { ModPlantsConfiguration configuration = Core.Get<ModPlants>().Configuration; if (configuration.Enabled && !((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponent<PlantModified>() != (Object)null)) { PlantModified plantModified = ((Component)__instance).gameObject.AddComponent<PlantModified>(); plantModified.OriginalYieldLevel = __instance.YieldLevel; Plant val = ((Component)__instance).GetComponentInParent<Plant>(); if ((Object)(object)val == (Object)null) { val = ((Component)__instance).GetComponent<Plant>(); } if ((Object)(object)val != (Object)null) { plantModified.QualityLevel = val.QualityLevel; } __instance.YieldLevel *= configuration.RandomYieldModifierPicker.Evaluate(Random.value); } } } [HarmonyPatch(typeof(PlantHarvestable), "Harvest")] public class PlantHarvestablePatch { private static readonly Dictionary<object, bool> SkipFlags = new Dictionary<object, bool>(); private static readonly Dictionary<object, bool> GenerateFlags = new Dictionary<object, bool>(); [HarmonyPrefix] public static bool Prefix(PlantHarvestable __instance) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown ModPlantsConfiguration configuration = Core.Get<ModPlants>().Configuration; if (!configuration.Enabled) { return true; } Plant componentInParent = ((Component)__instance).GetComponentInParent<Plant>(); PlantBaseQuality plantBaseQuality = default(PlantBaseQuality); if (!((Component)componentInParent).TryGetComponent<PlantBaseQuality>(ref plantBaseQuality)) { PlantBaseQuality plantBaseQuality2 = ((Component)componentInParent).gameObject.AddComponent<PlantBaseQuality>(); plantBaseQuality2.Quality = componentInParent.QualityLevel; plantBaseQuality2.NeedsNotification = true; } if (!GenerateFlags.ContainsKey(__instance)) { componentInParent.QualityLevel += configuration.RandomYieldQualityPicker.Evaluate(Random.value); __instance.ProductQuantity = (int)configuration.RandomYieldPerBudPicker.Pick(); GenerateFlags[__instance] = true; } QualityItemInstance val = new QualityItemInstance((ItemDefinition)(object)__instance.Product, __instance.ProductQuantity, ItemQuality.GetQuality(componentInParent.QualityLevel)); if (!PlayerSingleton<PlayerInventory>.Instance.CanItemFitInInventory((ItemInstance)(object)val, 1)) { SkipFlags[__instance] = true; return false; } SkipFlags.Remove(__instance); return true; } [HarmonyPostfix] public static void Postfix(PlantHarvestable __instance) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) ModPlantsConfiguration configuration = Core.Get<ModPlants>().Configuration; if (configuration.Enabled && !SkipFlags.ContainsKey(__instance) && GenerateFlags.Remove(__instance)) { Plant componentInParent = ((Component)__instance).GetComponentInParent<Plant>(); PlantBaseQuality plantBaseQuality = default(PlantBaseQuality); if (((Component)componentInParent).TryGetComponent<PlantBaseQuality>(ref plantBaseQuality) && plantBaseQuality.NeedsNotification) { EQuality quality = ItemQuality.GetQuality(componentInParent.QualityLevel); Singleton<NotificationsManager>.Instance.SendNotification($"{__instance.ProductQuantity}x {((ItemDefinition)componentInParent.SeedDefinition).Name}", $"{quality:G} quality", ((ItemDefinition)componentInParent.SeedDefinition).Icon, 2f, false); componentInParent.QualityLevel = plantBaseQuality.Quality; plantBaseQuality.NeedsNotification = false; Object.Destroy((Object)(object)plantBaseQuality); } } } } [HarmonyPatch(typeof(Pot), "GetAdditiveGrowthMultiplier")] public class PotPatch { [HarmonyPostfix] public static void Postfix(ref float __result) { if (Core.Get<ModPlants>().Configuration.Enabled) { float growthModifier = Core.Get<ModPlants>().Configuration.GrowthModifier; if (growthModifier <= 0.001f) { MelonLogger.Error("Invalid Growth Modifier. Skipping patch"); } else { __result *= Mathf.Max(0.001f, growthModifier); } } } } [HarmonyPatch(typeof(Pot), "Start")] public class PotStartPatch { [HarmonyPostfix] public static void Postfix(Pot __instance) { if (Core.Get<ModPlants>().Configuration.Enabled) { ((Component)__instance).gameObject.AddComponent<PotBaseValues>().Init(__instance); } } } [HarmonyPatch(typeof(Pot), "OnMinPass")] public class PotMinPassPatch { [HarmonyPrefix] public static void Prefix(Pot __instance) { if (Core.Get<ModPlants>().Configuration.Enabled && !((Object)(object)__instance == (Object)null)) { PotBaseValues component = ((Component)__instance).gameObject.GetComponent<PotBaseValues>(); if (!((Object)(object)component == (Object)null)) { float baseWaterDrainPerHour = component.BaseWaterDrainPerHour; __instance.WaterDrainPerHour = baseWaterDrainPerHour * Core.Get<ModPlants>().Configuration.WaterDrainModifier; } } } } } namespace Lithium.Modules.PlantGrowth.Behaviours { public class PlantBaseQuality : MonoBehaviour { public float Quality; public bool NeedsNotification; } public class PlantModified : MonoBehaviour { public float OriginalYieldLevel; public float QualityLevel; } public class PotBaseValues : MonoBehaviour { public float BaseWaterDrainPerHour; public void Init(Pot pot) { BaseWaterDrainPerHour = pot.WaterDrainPerHour; } } } namespace Lithium.Modules.Storyline { public class ModStorylineConfiguration : ModuleConfiguration { public override string Name => "Storyline"; public bool PreventRVExplosion { get; set; } = true; } public class ModStoryline : ModuleBase<ModStorylineConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.Storyline.Patches { [HarmonyPatch(typeof(RV), "SetExploded", new Type[] { })] public class RVSetExplodedPatch { [HarmonyPrefix] public static bool DisableRVExplosion(RV __instance) { ModStorylineConfiguration configuration = Core.Get<ModStoryline>().Configuration; if (!configuration.Enabled || !configuration.PreventRVExplosion) { return true; } GameObject childGameObject = GetChildGameObject(((Component)__instance).gameObject, "Destroyed RV"); if ((Object)(object)childGameObject != (Object)null) { childGameObject.SetActive(true); GameObject childGameObject2 = GetChildGameObject(childGameObject, "CartelNote"); if ((Object)(object)childGameObject2 != (Object)null) { childGameObject2.SetActive(true); } GameObject childGameObject3 = GetChildGameObject(childGameObject, "destroyed rv"); if ((Object)(object)childGameObject3 != (Object)null) { childGameObject3.SetActive(false); } } else { MelonLogger.Msg("Destroyed RV not found"); } return false; } private static GameObject GetChildGameObject(GameObject obj, string childName) { Transform val = obj.transform.Find(childName); return ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null; } } [HarmonyPatch(typeof(Quest_WelcomeToHylandPoint), "Explode")] public class QuestWelcomeToHylandPointPatch { [HarmonyPrefix] public static bool DisableRVExplosion(Quest_WelcomeToHylandPoint __instance) { ModStorylineConfiguration configuration = Core.Get<ModStoryline>().Configuration; if (!configuration.Enabled || !configuration.PreventRVExplosion) { return true; } return false; } } } namespace Lithium.Modules.Shops { public class SupplierListingOverride { public Dictionary<string, float> PriceOverrides { get; set; } = new Dictionary<string, float>(); } public class ItemListingOverride { public float Price { get; set; } [JsonConverter(typeof(StringEnumConverter))] public ERestockRate RestockRate { get; set; } = (ERestockRate)0; public int Stock { get; set; } = -1; } public class ShopListingSettings { [JsonProperty(Order = 6)] public Dictionary<string, ItemListingOverride> ItemOverrides = new Dictionary<string, ItemListingOverride>(); [JsonProperty(Order = 1)] public bool Override { get; set; } = false; [JsonProperty(Order = 2)] public int DefaultStock { get; set; } = -1; [JsonConverter(typeof(StringEnumConverter))] [JsonProperty(Order = 3)] public EPaymentType PaymentType { get; set; } } public enum DeliveryAvailabilitySettings { Unchanged, Never, Always, AfterReachingXP } public class DeliverySettings { [JsonConverter(typeof(StringEnumConverter))] public DeliveryAvailabilitySettings Availability { get; set; } = DeliveryAvailabilitySettings.Unchanged; public float DeliveryFee { get; set; } = 200f; public int XPRequirement { get; set; } = 0; } public class ModShopsConfiguration : ModuleConfiguration { public ShopListingSettings ThriftyThreads; public ShopListingSettings CokeSupplier; public ShopListingSettings MethSupplier; public ShopListingSettings WeedSupplier; public ShopListingSettings Boutique; public ShopListingSettings DarkMarket; public ShopListingSettings GasStation; public ShopListingSettings CentralGasStation; public ShopListingSettings DansHardware; public ShopListingSettings HandyHanks; public SupplierListingOverride Albert; public SupplierListingOverride Shirley; public SupplierListingOverride Salvador; public override string Name => "Shops"; public Dictionary<string, DeliverySettings> Deliveries { get; set; } } public class ModShops : ModuleBase<ModShopsConfiguration> { public override void Apply() { } } } namespace Lithium.Modules.Shops.Patches { [HarmonyPatch(typeof(ShopInterface), "SetIsOpen")] public class ForceUpdateShopPrices { [HarmonyPostfix] public static void ShopInterfaceSetIsOpen(ShopInterface __instance, bool isOpen) { Enumerator<ListingUI> enumerator = __instance.listingUI.GetEnumerator(); while (enumerator.MoveNext()) { ListingUI current = enumerator.Current; current.UpdateLockStatus(); current.Update(); current.UpdatePrice(); current.UpdateStock(); current.UpdateButtons(); } } } [HarmonyPatch(typeof(Player), "NetworkInitialize__Late")] public class SupplierStartPatch { [HarmonyPrefix] public static void PatchPrices() { ModShopsConfiguration configuration = Core.Get<ModShops>().Configuration; if (configuration.Enabled) { ApplyShopOverrides(); configuration.SaveConfiguration(); } } private static void ApplySupplierOverrides() { ModShopsConfiguration configuration2 = Core.Get<ModShops>().Configuration; Albert supplier2 = Object.FindObjectOfType<Albert>(); AssertSupplierConfigEntryExists(ref configuration2.Albert, (Supplier)(object)supplier2); ApplySupplierConfigValues(configuration2.Albert, (Supplier)(object)supplier2); Shirley supplier3 = Object.FindObjectOfType<Shirley>(); AssertSupplierConfigEntryExists(ref configuration2.Shirley, (Supplier)(object)supplier3); ApplySupplierConfigValues(configuration2.Shirley, (Supplier)(object)supplier3); Salvador supplier4 = Object.FindObjectOfType<Salvador>(); AssertSupplierConfigEntryExists(ref configuration2.Salvador, (Supplier)(object)supplier4); ApplySupplierConfigValues(configuration2.Salvador, (Supplier)(object)supplier4); static void ApplySupplierConfigValues(SupplierListingOverride configuration, Supplier supplier) { foreach (Listing item in (Il2CppArrayBase<Listing>)(object)supplier.OnlineShopItems) { if (configuration.PriceOverrides.TryGetValue(((ItemDefinition)item.Item).ID, out var value)) { item.Item.BasePurchasePrice = value; } } } static void AssertSupplierConfigEntryExists(ref SupplierListingOverride configuration, Supplier supplier) { if (configuration == null) { configuration = new SupplierListingOverride { PriceOverrides = ((IEnumerable<Listing>)supplier.OnlineShopItems).ToDictionary((Listing listing) => ((ItemDefinition)listing.Item).ID, (Listing listing) => listing.Price) }; } } } private static void ApplyShopOverrides() { List<ShopInterface> list = ((IEnumerable<ShopInterface>)Object.FindObjectsOfType<ShopInterface>()).ToList(); ModShopsConfiguration configuration = Core.Get<ModShops>().Configuration; foreach (ShopInterface item in list) { if ((Object)(object)item == (Object)null) { continue; } List<ShopListing> list2 = item.Listings.ToList<ShopListing>(); if (list2 == null) { continue; } switch (item.ShopCode) { case "thrifty_threads": AssertConfigurationEntries(ref configuration.ThriftyThreads, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.ThriftyThreads); } break; case "coke_shop": AssertConfigurationEntries(ref configuration.CokeSupplier, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.CokeSupplier); } break; case "meth_shop": AssertConfigurationEntries(ref configuration.MethSupplier, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.MethSupplier); } break; case "weed_shop": AssertConfigurationEntries(ref configuration.WeedSupplier, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.WeedSupplier); } break; case "boutique": AssertConfigurationEntries(ref configuration.Boutique, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.Boutique); } break; case "dark_market_shop": AssertConfigurationEntries(ref configuration.DarkMarket, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.DarkMarket); } break; case "gas_mart_west": AssertConfigurationEntries(ref configuration.GasStation, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.GasStation); } break; case "gas_mart_central": AssertConfigurationEntries(ref configuration.CentralGasStation, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.CentralGasStation); } break; case "dans_hardware": AssertConfigurationEntries(ref configuration.DansHardware, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.DansHardware); } break; case "handy_hanks": AssertConfigurationEntries(ref configuration.HandyHanks, item, list2); if (configuration.Enabled) { ApplyShopSettings(list2, item, configuration.HandyHanks); } break; } } } private static void AssertConfigurationEntries(ref ShopListingSettings configSetting, ShopInterface shopInterface, List<ShopListing> listings) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (configSetting == null) { configSetting = new ShopListingSettings { Override = false, DefaultStock = -1, PaymentType = shopInterface.PaymentType, ItemOverrides = listings.ToDictionary((ShopListing listing) => ((ItemDefinition)listing.Item).ID, (ShopListing listing) => new ItemListingOverride { Price = listing.Price, Stock = (listing.LimitedStock ? listing.DefaultStock : (-1)), RestockRate = listing.RestockRate }) }; } shopInterface.RefreshShownItems(); shopInterface.RefreshUnlockStatus(); } private static void ApplyShopSettings(List<ShopListing> listings, ShopInterface shopInterface, ShopListingSettings shopSettings) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if (!shopSettings.Override) { return; } shopInterface.PaymentType = shopSettings.PaymentType; foreach (ShopListing listing in listings) { if (shopSettings.ItemOverrides.TryGetValue(((ItemDefinition)listing.Item).ID, out var value)) { listing.LimitedStock = value.Stock >= 0; listing.DefaultStock = ((value.Stock >= 0) ? value.Stock : shopSettings.DefaultStock); listing.CurrentStock = listing.DefaultStock; listing.OverridePrice = true; listing.OverriddenPrice = value.Price; listing.RestockRate = value.RestockRate; } } } } } namespace Lithium.Modules.LabOven { public class ModLabOvenConfiguration : ModuleConfiguration { public float Speed = 1f; public override string Name => "LabOven"; } public class ModLabOven : ModuleBase<ModLabOvenConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.LabOven.Patches { [HarmonyPatch(typeof(OvenCookOperation), "IsReady")] public class OvenCookOperationIsReadyPatch { [HarmonyPostfix] public static void Postfix(OvenCookOperation __instance, ref bool __result) { ModLabOvenConfiguration configuration = Core.Get<ModLabOven>().Configuration; if (configuration.Enabled) { __result = __instance.CookProgress >= __instance.GetCookDuration(); } } } [HarmonyPatch(typeof(OvenCookOperation), "GetCookDuration")] public class OvenCookOperationGetCookDurationPatch { [HarmonyPostfix] public static void Postfix(ref int __result) { ModLabOvenConfiguration configuration = Core.Get<ModLabOven>().Configuration; if (configuration.Enabled) { float speed = Core.Get<ModLabOven>().Configuration.Speed; __result = Mathf.FloorToInt((float)__result / speed); } } } } namespace Lithium.Modules.DryingRacks { public class ModDryingRacksConfiguration : ModuleConfiguration { public Dictionary<string, int> PerQualityDryTimes = new Dictionary<string, int> { { "Trash", 720 }, { "Poor", 720 }, { "Standard", 720 }, { "Premium", 720 }, { "Heavenly", 720 } }; public override string Name => "DryingRacks"; public int Capacity { get; set; } = 20; } public class ModDryingRacks : ModuleBase<ModDryingRacksConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.DryingRacks.Patches { [HarmonyPatch(typeof(DryingRack), "MinPass")] public class DryingRackPatch { [HarmonyPrefix] private static bool Prefix(DryingRack __instance) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 if (!Core.Get<ModDryingRacks>().Configuration.Enabled) { return true; } foreach (DryingOperation item in __instance.DryingOperations.ToArray()) { int time = item.Time; item.Time = time + 1; Dictionary<string, int> perQualityDryTimes = Core.Get<ModDryingRacks>().Configuration.PerQualityDryTimes; EQuality quality = item.GetQuality(); string key = ((object)(EQuality)(ref quality)).ToString(); int valueOrDefault = perQualityDryTimes.GetValueOrDefault(key, 720); if (item.Time < valueOrDefault) { continue; } if ((int)item.StartQuality >= 3) { if (InstanceFinder.IsServer && __instance.GetOutputCapacityForOperation(item, (EQuality)4) >= item.Quantity) { __instance.TryEndOperation(__instance.DryingOperations.IndexOf(item), false, (EQuality)4, Random.Range(int.MinValue, int.MaxValue)); } } else { item.IncreaseQuality(); } } return false; } } [HarmonyPatch(typeof(DryingOperationUI), "UpdatePosition")] public class DryingOperationUIPatch { [HarmonyPrefix] private static bool Prefix(DryingOperationUI __instance) { //IL_0037: 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_00fd: Unknown result type (might be due to invalid IL or missing references) if (!Core.Get<ModDryingRacks>().Configuration.Enabled) { return true; } Dictionary<string, int> perQualityDryTimes = Core.Get<ModDryingRacks>().Configuration.PerQualityDryTimes; EQuality startQuality = __instance.AssignedOperation.StartQuality; string key = ((object)(EQuality)(ref startQuality)).ToString(); int valueOrDefault = perQualityDryTimes.GetValueOrDefault(key, 720); DryingOperation assignedOperation = __instance.AssignedOperation; float num = Mathf.Clamp01((float)assignedOperation.Time / (float)valueOrDefault); int num2 = Mathf.Clamp(valueOrDefault - assignedOperation.Time, 0, valueOrDefault); int value = num2 / 60; int value2 = num2 % 60; __instance.Tooltip.text = $"{value}h {value2}m until next tier"; float num3 = -62.5f; float num4 = 0f - num3; __instance.Rect.anchoredPosition = new Vector2(Mathf.Lerp(num3, num4, num), 0f); return false; } } [HarmonyPatch(typeof(DryingOperation), "GetQuality")] public class DryingOperationPatch { [HarmonyPrefix] private static bool Prefix(DryingOperation __instance, ref EQuality __result) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected I4, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected I4, but got Unknown if (!Core.Get<ModDryingRacks>().Configuration.Enabled) { return true; } Dictionary<string, int> perQualityDryTimes = Core.Get<ModDryingRacks>().Configuration.PerQualityDryTimes; EQuality startQuality = __instance.StartQuality; string key = ((object)(EQuality)(ref startQuality)).ToString(); if (__instance.Time >= perQualityDryTimes.GetValueOrDefault(key, 720)) { __result = (EQuality)(__instance.StartQuality + 1); } else { __result = (EQuality)(int)__instance.StartQuality; } return false; } } [HarmonyPatch(typeof(DryingRackCanvas), "SetIsOpen")] public class DryingRackCapacityPatch { [HarmonyPostfix] public static void DryingRackCapacity(DryingRackCanvas __instance, DryingRack rack, bool open) { ModDryingRacksConfiguration configuration = Core.Get<ModDryingRacks>().Configuration; if (configuration.Enabled && rack != null) { rack.ItemCapacity = configuration.Capacity; } } } } namespace Lithium.Modules.WateringCans { public class ModWateringCanConfiguration : ModuleConfiguration { public float DrainModifier = 1f; public override string Name => "WateringCan"; } public class ModWateringCan : ModuleBase<ModWateringCanConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.WateringCans.Patches { [HarmonyPatch(typeof(FunctionalWateringCan), "PourAmount")] public static class FunctionalWateringCanPourAmountPatch { [HarmonyPrefix] public static void Prefix(ref float amount) { ModWateringCanConfiguration configuration = Core.Get<ModWateringCan>().Configuration; if (configuration.Enabled) { amount *= configuration.DrainModifier; } } } } namespace Lithium.Modules.PropertyPrices { public class ModPropertyPricesConfiguration : ModuleConfiguration { public override string Name => "Property Prices"; public Dictionary<string, int> PropertyPrices { get; set; } = new Dictionary<string, int> { { "RV", 0 }, { "Motel Room", 75 }, { "Sweatshop", 800 }, { "Storage Unit", 5000 }, { "Bungalow", 6000 }, { "Barn", 25000 }, { "Docks Warehouse", 50000 }, { "Laundromat", 4000 }, { "Post Office", 10000 }, { "Car Wash", 20000 }, { "Taco Ticklers", 50000 }, { "Manor", 100000 } }; } public class ModPropertyPrices : ModuleBase<ModPropertyPricesConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.PropertyPrices.Patches { [HarmonyPatch(typeof(Player), "NetworkInitialize___Early")] public class ForcePropertyPrices { [HarmonyPrefix] public static void PatchPrices() { ModPropertyPricesConfiguration configuration = Core.Get<ModPropertyPrices>().Configuration; if (configuration.Enabled) { ChangePropertyPrices(configuration); UpdateMissMingDialog(configuration); configuration.SaveConfiguration(); } } private static void ChangePropertyPrices(ModPropertyPricesConfiguration configuration) { Property[] array = Il2CppArrayBase<Property>.op_Implicit(Object.FindObjectsOfType<Property>()); Property[] array2 = array; foreach (Property val in array2) { if (!configuration.PropertyPrices.TryGetValue(val.PropertyName, out var value)) { MelonLogger.Warning("Property " + val.PropertyName + " not found in configuration. Skipping."); continue; } val.Price = value; if ((Object)(object)val.ForSaleSign != (Object)null) { ((TMP_Text)((Component)val.ForSaleSign.transform.Find("Price")).GetComponent<TextMeshPro>()).text = MoneyManager.FormatAmount((float)value, false, false); } if ((Object)(object)val.ListingPoster != (Object)null) { ((TMP_Text)((Component)val.ListingPoster.Find("Price")).GetComponent<TextMeshPro>()).text = MoneyManager.FormatAmount((float)value, false, false); } } } private static void UpdateMissMingDialog(ModPropertyPricesConfiguration configuration) { DialogueController_Ming[] array = Il2CppArrayBase<DialogueController_Ming>.op_Implicit(Object.FindObjectsOfType<DialogueController_Ming>()); DialogueController_Ming[] array2 = array; foreach (DialogueController_Ming val in array2) { DialogueController_Ming val2 = val; Transform parent = ((Component)val).gameObject.transform.parent; string text = ((parent != null) ? ((Object)parent).name : null); if (1 == 0) { } float price = ((text == "Ming") ? ((float)configuration.PropertyPrices["Sweatshop"]) : ((!(text == "Donna")) ? val.Price : ((float)configuration.PropertyPrices["Motel Room"]))); if (1 == 0) { } val2.Price = price; } } } } namespace Lithium.Modules.Employees { public class BotanistsConfiguration { public int MaxAssignedPots = 8; public float WalkSpeed = 1.2f; public int DailyWage = 200; public float SoilPourTime = 10f; public float WaterPourTime = 10f; public float AdditivePourTime = 10f; public float SeedSowTime = 15f; public float HarvestTime = 15f; } public class ChemistConfiguration { public int MaxStations = 6; public int DailyWage = 300; public float WalkSpeed = 1.2f; } public class PackagerConfiguration { public int MaxStations = 3; public int MaxRoutes = 10; public float PackagingSpeedMultiplier = 2f; public int DailyWage = 200; public float WalkSpeed = 1.2f; } public class CleanerConfiguration { public int MaxBins = 3; public int DailyWage = 100; public float WalkSpeed = 1.2f; } public class ModEmployeesConfiguration : ModuleConfiguration { public BotanistsConfiguration Botanists = new BotanistsConfiguration(); public ChemistConfiguration Chemists = new ChemistConfiguration(); public PackagerConfiguration Packagers = new PackagerConfiguration(); public CleanerConfiguration Cleaners = new CleanerConfiguration(); public override string Name => "Employees"; } public class ModEmployees : ModuleBase<ModEmployeesConfiguration> { public static readonly HashSet<Employee> ConfiguredEmployees = new HashSet<Employee>(); public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.EffectCombos { public class EffectCombo { public string Name { get; set; } public int FixedBonus { get; set; } = 0; public float PercentageBonus { get; set; } = 0f; public string[] Effects { get; set; } = Array.Empty<string>(); } public class ModEffectCombosConfiguration : ModuleConfiguration { public override string Name => "EffectCombos"; public bool AffectsDealers { get; set; } = true; public EffectCombo[] Combos { get; set; } = Array.Empty<EffectCombo>(); } public class ModEffectCombos : ModuleBase<ModEffectCombosConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { Core.Get<ModCustomers>().RegisterBonusPaymentHandler(new EffectComboBonus()); } } } } namespace Lithium.Modules.EffectCombos.BonusPayments { public class EffectComboBonus : IBonusPaymentHandler { public bool BonusPaymentHandler(Customer customer, Contract contract, List<ItemInstance> items, out List<BonusPayment> boni) { //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown boni = new List<BonusPayment>(); ModEffectCombosConfiguration configuration = Core.Get<ModEffectCombos>().Configuration; if (!configuration.Enabled) { return false; } if (!configuration.AffectsDealers && (Object)(object)contract.Dealer != (Object)null) { return false; } int num = items.ToList().Sum((ItemInstance i) => (i != null) ? i.Quantity : 0); foreach (ItemInstance item in items) { if (item == null) { continue; } ProductDefinition val = ((IEnumerable<ProductDefinition>)ProductManager.DiscoveredProducts.ToList<ProductDefinition>()).SingleOrDefault((Func<ProductDefinition, bool>)((ProductDefinition p) => ((ItemDefinition)p).ID.Equals(item.ID))); if ((Object)(object)val == (Object)null) { continue; } string[] second = (from p in ((PropertyItemDefinition)val).Properties.ToList<Property>() select p.Name.ToLowerInvariant()).ToArray(); EffectCombo[] combos = configuration.Combos; foreach (EffectCombo effectCombo in combos) { if (effectCombo.Effects.Select((string s) => s.ToLowerInvariant()).Intersect(second).Count() == effectCombo.Effects.Length) { float num2 = effectCombo.FixedBonus * item.Quantity; float num3 = (float)item.Quantity / (float)num; float num4 = contract.Payment * (effectCombo.PercentageBonus / 100f) * num3; float num5 = num2 + num4; boni.Add(new BonusPayment("\"" + effectCombo.Name + "\" Combo Bonus", num5)); } } } return boni.Any(); } } } namespace Lithium.Modules.Customers { public class EffectMatchBonus { public float PercentageBonusMin { get; set; } = 0f; public float PercentageBonusMax { get; set; } = 0f; public int FixedBonusMin { get; set; } = 0; public int FixedBonusMax { get; set; } = 0; } public class EffectBonus { public bool Enabled { get; set; } public bool AffectsDealers { get; set; } = true; public EffectMatchBonus OneCoveredEffect { get; set; } = new EffectMatchBonus(); public EffectMatchBonus TwoCoveredEffects { get; set; } = new EffectMatchBonus(); public EffectMatchBonus ThreeCoveredEffects { get; set; } = new EffectMatchBonus(); } public class QualityBonus { public bool Enabled { get; set; } public bool AffectsDealers { get; set; } = true; public float BonusPercentage { get; set; } } public class SampleOffering { public bool Enabled { get; set; } public float QualityLevelModifier { get; set; } = 0.2f; public bool IncludeDrugPreference { get; set; } = true; public float BaseAcceptance { get; set; } = 0f; } public class Contracts { public bool Enabled { get; set; } public int XPRequired { get; set; } = 1400; public bool SendNotification { get; set; } = true; public bool SendNotificationForDealers { get; set; } = true; public int NotificationCooldownInMinutes { get; set; } = 5; public string[] MessageTemplates { get; set; } = new string[4] { "Hey, I wanted to get fresh stuff, but you don't offer good stuff. I prefer ##DESIRES##", "I was looking for something ##DESIRES##, but you don't have any. Please improve your offering.", "Yo you still haven't got anything ##DESIRES##? Dang!", "##DESIRES## ... come on, can't be that hard to find, right?" }; public string[] DealerTemplates { get; set; } = new string[4] { "Hey, I wanted to get fresh stuff, but ##DEALER## doesn't offer good stuff. I prefer ##DESIRES##", "I was looking for something ##DESIRES##, but ##DEALER## doesn't have any. Could you help him out?", "Yo ##DEALER## still hasn't got anything ##DESIRES##? Dang!", "##DESIRES## ... come on, can't be that hard for ##DEALER## to find, right?" }; } public class ModCustomersConfiguration : ModuleConfiguration { public override string Name => "Customers"; public SampleOffering SampleOffering { get; set; } = new SampleOffering(); public Contracts Contracts { get; set; } = new Contracts(); public QualityBonus QualityBonus { get; set; } = new QualityBonus(); public EffectBonus EffectBonus { get; set; } = new EffectBonus(); } public class ModCustomers : ModuleBase<ModCustomersConfiguration> { internal readonly List<IBonusPaymentHandler> BonusPaymentHandlers = new List<IBonusPaymentHandler>(); public ModCustomers() { ClassInjector.RegisterTypeInIl2Cpp<CustomerNotificationState>(); RegisterBonusPaymentHandler(new EffectCoverageBonus()); RegisterBonusPaymentHandler(new Lithium.Modules.Customers.BonusPayments.QualityBonus()); } public override void Apply() { if (base.Configuration.Enabled) { } } public void RegisterBonusPaymentHandler(IBonusPaymentHandler handler) { if (BonusPaymentHandlers.All((IBonusPaymentHandler h) => h.GetType() != handler.GetType())) { BonusPaymentHandlers.Add(handler); } } } } namespace Lithium.Modules.Customers.Patches { [HarmonyPatch(typeof(Customer), "TryGenerateContract")] public class CustomerContractGenerationPatch { [HarmonyPostfix] public static void Postfix(ref ContractInfo __result, Customer __instance, Dealer dealer) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) ModCustomersConfiguration configuration = Core.Get<ModCustomers>().Configuration; if (!configuration.Enabled || !configuration.Contracts.Enabled || __result == null || NetworkSingleton<LevelManager>.Instance.TotalXP < configuration.Contracts.XPRequired) { return; } List<string> desires = (from p in __instance.CustomerData.PreferredProperties.ToList<Property>() select p.Name).ToList(); Entry val = __result.Products.entries.ToList<Entry>()[0]; EQuality quality = val.Quality; int quantity = val.Quantity; if (desires.Count == 0) { return; } if ((Object)(object)__instance.AssignedDealer != (Object)null) { if (__instance.DealerHasSuitableProduct(out var dealerItems)) { List<ProductDefinition> list = dealerItems.Select((ItemInstance d) => ProductManager.DiscoveredProducts.ToList<ProductDefinition>().Single((ProductDefinition p) => ((ItemDefinition)p).ID.Equals(d.ID))).Distinct().ToList(); if (list.Count == 0) { NotifyDealerNotSuitable(__instance); __result = null; return; } Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (ProductDefinition product in list) { if (!((Object)(object)product == (Object)null)) { int num = dealerItems.Where((ItemInstance i) => i.ID == ((ItemDefinition)product).ID).Sum((ItemInstance i) => i.Quantity); if (num > 0) { dictionary[((ItemDefinition)product).ID] = num; } } } WeightedPicker<string> weightedPicker = new WeightedPicker<string>(); foreach (KeyValuePair<string, int> entry in dictionary) { weightedPicker.Add(entry.Key, ProductHelper.GetMatchCount(((PropertyItemDefinition)list.First((ProductDefinition p) => ((ItemDefinition)p).ID.Equals(entry.Key))).Properties.ToList<Property>(), desires)); } string text = weightedPicker.Pick(); quantity = dictionary[text]; RewireOrderedProduct(__result, text, quality, Mathf.Clamp(quantity, 1, quantity)); } else { NotifyDealerNotSuitable(__instance); __result = null; } } else { List<ProductDefinition> list2 = (from p in ProductManager.ListedProducts.ToList<ProductDefinition>() where ProductHelper.ProductMatchesDesires(p, desires) select p into x orderby Random.value select x).ToList(); if (list2.Count == 0) { NotifyPlayerProductsNotSuitable(__instance); __result = null; } else { RewireOrderedProduct(__result, ((ItemDefinition)list2[0]).ID, quality, quantity); } } } private static void RewireOrderedProduct(ContractInfo __result, string id, EQuality quality, int maxAvailableQuantity) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0042: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown int num = __result.Products.entries.ToList<Entry>().Sum((Entry e) => e.Quantity); ProductList val = new ProductList(); val.entries.Add(new Entry { ProductID = id, Quality = quality, Quantity = Mathf.Min(maxAvailableQuantity, num) }); __result.Products = val; } private static void NotifyPlayerProductsNotSuitable(Customer __instance) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown ModCustomersConfiguration configuration = Core.Get<ModCustomers>().Configuration; if (!configuration.Contracts.SendNotification) { return; } CustomerNotificationState customerNotificationState = default(CustomerNotificationState); if (((Component)__instance).TryGetComponent<CustomerNotificationState>(ref customerNotificationState)) { if (NetworkSingleton<TimeManager>.Instance.Playtime - customerNotificationState.LastNotification < (float)(60 * configuration.Contracts.NotificationCooldownInMinutes)) { return; } } else { customerNotificationState = ((Component)__instance).gameObject.AddComponent<CustomerNotificationState>(); customerNotificationState.LastNotification = NetworkSingleton<TimeManager>.Instance.Playtime; } string text = configuration.Contracts.MessageTemplates.OrderBy((string x) => Random.value).FirstOrDefault().Replace("##DESIRES##", ProductHelper.FormatDesires(__instance.CustomerData)); NetworkSingleton<MessagingManager>.Instance.ReceiveMessage(new Message(text, (ESenderType)1, false, -1), true, __instance.NPC.ID); customerNotificationState.LastNotification = NetworkSingleton<TimeManager>.Instance.Playtime; } private static void NotifyDealerNotSuitable(Customer __instance) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown ModCustomersConfiguration configuration = Core.Get<ModCustomers>().Configuration; if (!configuration.Contracts.SendNotificationForDealers) { return; } CustomerNotificationState customerNotificationState = default(CustomerNotificationState); if (((Component)__instance).TryGetComponent<CustomerNotificationState>(ref customerNotificationState)) { if (NetworkSingleton<TimeManager>.Instance.Playtime - customerNotificationState.LastNotification < (float)(60 * configuration.Contracts.NotificationCooldownInMinutes)) { return; } } else { customerNotificationState = ((Component)__instance).gameObject.AddComponent<CustomerNotificationState>(); customerNotificationState.LastNotification = NetworkSingleton<TimeManager>.Instance.Playtime; } string text = configuration.Contracts.DealerTemplates.OrderBy((string x) => Random.value).FirstOrDefault().Replace("##DEALER##", ((NPC)__instance.AssignedDealer).FirstName) .Replace("##DESIRES##", ProductHelper.FormatDesires(__instance.CustomerData)); NetworkSingleton<MessagingManager>.Instance.ReceiveMessage(new Message(text, (ESenderType)1, false, -1), true, __instance.NPC.ID); customerNotificationState.LastNotification = NetworkSingleton<TimeManager>.Instance.Playtime; } } [HarmonyPatch(typeof(Customer), "ProcessHandover")] public static class CustomerProcessHandoverPatch { public static bool Prefix(Customer __instance, EHandoverOutcome outcome, Contract contract, List<ItemInstance> items, bool handoverByPlayer, bool giveBonuses) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Invalid comparison between Unknown and I4 //IL_03ee: Unknown result type (might be due to invalid IL or missing references) ModCustomersConfiguration configuration = Core.Get<ModCustomers>().Configuration; if (!configuration.Enabled || !configuration.EffectBonus.Enabled) { return true; } if (!handoverByPlayer && !configuration.EffectBonus.AffectsDealers) { return true; } float num = default(float); EDrugType val = default(EDrugType); int num2 = default(int); float num3 = Mathf.Clamp01(__instance.EvaluateDelivery(contract, items, ref num, ref val, ref num2)); __instance.ChangeAddiction(num3 / 5f); float relationDelta = __instance.NPC.RelationData.RelationDelta; float relationshipChange = CustomerSatisfaction.GetRelationshipChange(num3); float num4 = relationshipChange * 0.2f * Mathf.Lerp(0.75f, 1.5f, num); __instance.AdjustAffinity(val, num4); __instance.NPC.RelationData.ChangeRelationship(relationshipChange, true); List<BonusPayment> list = new List<BonusPayment>(); if (NetworkSingleton<CurfewManager>.Instance.IsCurrentlyActive) { list.Add(new BonusPayment("Curfew Bonus", contract.Payment * 0.2f)); } if (num2 > contract.ProductList.GetTotalQuantity()) { list.Add(new BonusPayment("Generosity Bonus", 10f * (float)(num2 - contract.ProductList.GetTotalQuantity()))); } GameDateTime acceptTime = contract.AcceptTime; GameDateTime val2 = default(GameDateTime); ((GameDateTime)(ref val2))..ctor(acceptTime.elapsedDays, TimeManager.AddMinutesTo24HourTime(contract.DeliveryWindow.WindowStartTime, 60)); if (NetworkSingleton<TimeManager>.Instance.IsCurrentDateWithinRange(acceptTime, val2)) { list.Add(new BonusPayment("Quick Delivery Bonus", contract.Payment * 0.1f)); } List<ItemInstance> items2 = items.ToList<ItemInstance>(); foreach (IBonusPaymentHandler bonusPaymentHandler in Core.Get<ModCustomers>().BonusPaymentHandlers) { if (bonusPaymentHandler.BonusPaymentHandler(__instance, contract, items2, out var boni) && boni.Sum((BonusPayment b) => b.Amount) > 0f) { list.AddRange(boni); } } float num5 = 0f; foreach (BonusPayment item in list) { MelonLogger.Msg($"Bonus: {item.Title} Amount: {item.Amount}"); num5 += item.Amount; } if (handoverByPlayer) { Singleton<HandoverScreen>.Instance.ClearCustomerSlots(false); contract.SubmitPayment(num5); } if ((int)outcome == 1 && handoverByPlayer) { Singleton<DealCompletionPopup>.Instance.PlayPopup(__instance, num3, relationDelta, contract.Payment, list.ToIL2CPPList()); } __instance.TimeSinceLastDealCompleted = 0; __instance.NPC.SendAnimationTrigger("GrabItem"); NetworkObject val3 = null; if ((Object)(object)contract.Dealer != (Object)null) { val3 = ((NetworkBehaviour)contract.Dealer).NetworkObject; } MelonLogger.Msg($"Base payment: {contract.Payment} Total bonus: {num5} Satisfaction: {num3} Dealer: {((val3 != null) ? ((Object)val3).name : null) ?? "none"}"); float num6 = Mathf.Clamp(contract.Payment + num5, 0f, float.MaxValue); __instance.ProcessHandoverServerSide(outcome, items, handoverByPlayer, num6, contract.ProductList, num3, val3); return false; } } [HarmonyPatch(typeof(Customer), "GetSampleSuccess")] public class CustomerSampleSuccessPatch { [HarmonyPrefix] private static bool Prefix(Customer __instance, List<ItemInstance> items, float price, ref float __result) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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) ModCustomersConfiguration configuration = Core.Get<ModCustomers>().Configuration; if (!configuration.Enabled || !configuration.SampleOffering.Enabled) { return true; } float num = 0f; Enumerator<ItemInstance> enumerator = items.GetEnumerator(); while (enumerator.MoveNext()) { ItemInstance current = enumerator.Current; ProductDefinition val = ((Il2CppObjectBase)current.definition).TryCast<ProductDefinition>(); ProductItemInstance val2 = ((Il2CppObjectBase)current).TryCast<ProductItemInstance>(); string[] array = new string[__instance.CustomerData.PreferredProperties.Count]; int num2 = 0; Enumerator<Property> enumerator2 = __instance.CustomerData.PreferredProperties.GetEnumerator(); while (enumerator2.MoveNext()) { Property current2 = enumerator2.Current; array[0] = current2.Name; num2++; } string[] array2 = new string[((PropertyItemDefinition)val).Properties.Count]; num2 = 0; Enumerator<Property> enumerator3 = ((PropertyItemDefinition)val).Properties.GetEnumerator(); while (enumerator3.MoveNext()) { Property current3 = enumerator3.Current; array2[0] = current3.Name; num2++; } num += SuccessChanceCalculator.CalculateSuccess(val.DrugType, ((QualityItemInstance)val2).Quality, configuration.SampleOffering.QualityLevelModifier, __instance.CustomerData.Standards, array, array2, __instance.CustomerData.DefaultAffinityData, configuration.SampleOffering.IncludeDrugPreference, configuration.SampleOffering.BaseAcceptance); } __result = num / (float)items.Count; return false; } } [HarmonyPatch(typeof(DeliveryApp), "SetOpen")] public class DeliveryAppPatch { [HarmonyPrefix] public static void Prefix(ref bool open, DeliveryApp __instance) { ModShops modShops = Core.Get<ModShops>(); if (modShops == null || !modShops.Configuration.Enabled) { return; } ModShopsConfiguration configuration = Core.Get<ModShops>().Configuration; if (configuration.Deliveries == null) { configuration.Deliveries = PlayerSingleton<DeliveryApp>.Instance.deliveryShops.ToList<DeliveryShop>().ToDictionary((DeliveryShop d) => d.MatchingShop.ShopName, (DeliveryShop d) => new DeliverySettings { Availability = DeliveryAvailabilitySettings.Unchanged, DeliveryFee = d.DeliveryFee, XPRequirement = 0 }); configuration.SaveConfiguration(); } DeliveryUtils.ApplyDeliveryOverrides(); } } } namespace Lithium.Modules.Customers.BonusPayments { public class EffectCoverageBonus : IBonusPaymentHandler { public bool BonusPaymentHandler(Customer customer, Contract contract, List<ItemInstance> items, out List<BonusPayment> boni) { //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Expected O, but got Unknown boni = new List<BonusPayment>(); ModCustomersConfiguration configuration = Core.Get<ModCustomers>().Configuration; if (!configuration.EffectBonus.Enabled) { return false; } if (!configuration.EffectBonus.AffectsDealers && (Object)(object)contract.Dealer != (Object)null) { return false; } List<string> list = (from p in customer.CustomerData.PreferredProperties.ToList<Property>() select p.Name.ToLowerInvariant()).ToList(); if (list.Count == 0 || items == null || items.Count == 0) { return false; } int num = items.ToList().Sum((ItemInstance i) => (i != null) ? i.Quantity : 0); float num2 = 0f; foreach (ItemInstance item in items) { if (item == null) { continue; } ProductDefinition val = ((IEnumerable<ProductDefinition>)ProductManager.DiscoveredProducts.ToList<ProductDefinition>()).SingleOrDefault((Func<ProductDefinition, bool>)((ProductDefinition p) => ((ItemDefinition)p).ID.Equals(item.ID))); if ((Object)(object)val == (Object)null) { continue; } int num3 = (from p in ((PropertyItemDefinition)val).Properties.ToList<Property>() select p.Name.ToLowerInvariant()).Intersect(list).Count(); if (num3 > 0) { if (1 == 0) { } EffectMatchBonus effectMatchBonus = num3 switch { 1 => configuration.EffectBonus.OneCoveredEffect, 2 => configuration.EffectBonus.TwoCoveredEffects, _ => configuration.EffectBonus.ThreeCoveredEffects, }; if (1 == 0) { } EffectMatchBonus effectMatchBonus2 = effectMatchBonus; int num4 = Mathf.Max(1, item.Quantity); int num5 = Mathf.Min(effectMatchBonus2.FixedBonusMin, effectMatchBonus2.FixedBonusMax); int num6 = Mathf.Max(effectMatchBonus2.FixedBonusMin, effectMatchBonus2.FixedBonusMax); float num7 = Mathf.Min(effectMatchBonus2.PercentageBonusMin, effectMatchBonus2.PercentageBonusMax); float num8 = Mathf.Max(effectMatchBonus2.PercentageBonusMin, effectMatchBonus2.PercentageBonusMax); int num9 = ((num6 > num5) ? Random.Range(num5, num6 + 1) : num5); float num10 = ((num8 > num7) ? Random.Range(num7, num8) : num7); float num11 = num9 * num4; float num12 = (float)num4 / (float)num; float num13 = contract.Payment * (num10 / 100f) * num12; float num14 = num11 + num13; num2 += num14; MelonLogger.Msg($"Effect match boni for item {((ItemDefinition)val).Name}: x{num4} (matches: {num3}) Fixed: {num11} Percent: {num13} Total: {num14}"); } } if (num2 <= 0f) { return false; } boni.Add(new BonusPayment("Effect Match Bonus", num2)); return true; } } public class QualityBonus : IBonusPaymentHandler { public bool BonusPaymentHandler(Customer customer, Contract contract, List<ItemInstance> items, out List<BonusPayment> boni) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown boni = new List<BonusPayment>(); ModCustomersConfiguration configuration = Core.Get<ModCustomers>().Configuration; if (!configuration.QualityBonus.Enabled) { return false; } if (!configuration.QualityBonus.AffectsDealers && (Object)(object)contract.Dealer != (Object)null) { return false; } float qualityScalar = CustomerData.GetQualityScalar(StandardsMethod.GetCorrespondingQuality(customer.customerData.Standards)); float num = 1f; foreach (ItemInstance item in items) { ProductItemInstance val = ((Il2CppObjectBase)item).TryCast<ProductItemInstance>(); if (val != null) { float qualityScalar2 = CustomerData.GetQualityScalar(((QualityItemInstance)val).Quality); if (qualityScalar2 < num) { num = qualityScalar2; } } else { MelonLogger.Msg("Found null product item! Please report this bug."); } } float num2 = num - qualityScalar; if (num2 > 0f) { int num3 = Mathf.RoundToInt(num2 / 0.25f); float num4 = contract.Payment * ((float)num3 * configuration.QualityBonus.BonusPercentage / 100f); boni.Add(new BonusPayment("Quality Bonus", num4)); return true; } return false; } } } namespace Lithium.Modules.Customers.Behaviours { public class CustomerNotificationState : MonoBehaviour { public float LastNotification; } } namespace Lithium.Modules.Customers.Architecture { public interface IBonusPaymentHandler { bool BonusPaymentHandler(Customer customer, Contract contract, List<ItemInstance> items, out List<BonusPayment> boni); } } namespace Lithium.Modules.ChemistryStation { public class ModChemistryStationConfiguration : ModuleConfiguration { public int BonusStepsPerTick = 0; public override string Name => "ChemistryStation"; } public class ModChemistryStation : ModuleBase<ModChemistryStationConfiguration> { public override void Apply() { if (base.Configuration.Enabled) { } } } } namespace Lithium.Modules.ChemistryStation.Patches { [HarmonyPatch(typeof(ChemistryCookOperation), "Progress")] public class ChemistryCookOperationProgressPatch { [HarmonyPrefix] public static void Prefix(ChemistryCookOperation __instance, int mins) { ModChemistryStationConfiguration configuration = Core.Get<ModChemistryStation>().Configuration; if (configuration.Enabled) { __instance.CurrentTime += configuration.BonusStepsPerTick; } } } } namespace Lithium.Helper { public static class CollectionConverter { public static T[] ToArray<T>(this List<T> list) { if (list == null) { return Array.Empty<T>(); } T[] array = new T[list.Count]; int num = 0; Enumerator<T> enumerator = list.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; array[num] = current; num++; } return array; } public static List<T> ToList<T>(this List<T> list) { if (list == null) { return new List<T>(); } List<T> list2 = new List<T>(list.Count); Enumerator<T> enumerator = list.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; list2.Add(current); } return list2; } public static List<T> ToIL2CPPList<T>(this List<T>? list) { List<T> val = new List<T>(list?.Count ?? 0); if (list == null) { return val; } foreach (T item in list) { val.Add(item); } return val; } } public static class ProductHelper { public static bool PlayerHasSuitableProduct(this Customer customer) { List<Property> desires = customer.CustomerData.PreferredProperties.ToList<Property>(); if (desires.Count == 0) { return true; } int num = ProductManager.DiscoveredProducts.ToList<ProductDefinition>().Count((ProductDefinition pd) => GetMatchCount(pd, desires.Select((Property p) => p.Name).ToList()) > 0); return num > 0 || desires.Count <= 0; } public static bool DealerHasSuitableProduct(this Customer customer, out List<ItemInstance> dealerItems) { List<string> list = (from p in customer.CustomerData.PreferredProperties.ToList<Property>() select p.Name).ToList(); if (list.Count == 0) { dealerItems = new List<ItemInstance>(); return true; } dealerItems = (from i in ((NPC)customer.AssignedDealer).Inventory.ItemSlots.ToList<ItemSlot>() where i.ItemInstance != null select i.ItemInstance).ToList(); List<ProductDefinition> source = dealerItems.Select((ItemInstance d) => ProductManager.DiscoveredProducts.ToList<ProductDefinition>().Single((ProductDefinition p) => ((ItemDefinition)p).ID.Equals(d.ID))).Distinct().ToList(); List<string> source2 = (from p in source.Where((ProductDefinition p) => (Object)(object)p != (Object)null).SelectMany((ProductDefinition p) => ((PropertyItemDefinition)p).Properties.ToList<Property>()) select p.Name).Distinct().ToList(); return list.Intersect(source2.Distinct().ToList()).Any(); } public static bool ProductMatchesDesires(ProductDefinition pd, List<string> desires) { return (from p in ((PropertyItemDefinition)pd).Properties.ToList<Property>() select p.Name).Intersect(desires).Any(); } public static string FormatDesires(CustomerData customerData) { return (from p in customerData.PreferredProperties.ToList<Property>() select p.Name).SmartJoin(", ", " or "); } public static int GetMatchCount(ProductDefinition pd, List<string> desires) { return ProductManager.DiscoveredProducts.ToList<ProductDefinition>().Count((ProductDefinition p) => (from p in ((PropertyItemDefinition)p).Properties.ToList<Property>() select p.Name).Intersect(desires).Any()); } public static float GetMatchCount(List<Property> source, List<string> desires) { return source.Count((Property p) => desires.Contains(p.Name)); } } public static class StringExtensions { public static string SmartJoin<T>(this IEnumerable<T> source, string glue, string lastGlue) { T[] array = source.ToArray(); switch (array.Length) { case 0: return string.Empty; case 1: return array[0].ToString(); default: { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(string.Join(glue, array[..^1])); StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(0, 2, stringBuilder2); handler.AppendFormatted(lastGlue); handler.AppendFormatted(array.Last()); stringBuilder2.Append(ref handler); return stringBuilder.ToString(); } } } } }