Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of EnhanceDealSystems v1.1.3
EnhanceDealSystems.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using EnhanceDealSystems; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.AvatarFramework.Animation; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Dialogue; using Il2CppScheduleOne.Economy; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Messaging; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Quests; using Il2CppScheduleOne.UI.Handover; using Il2CppScheduleOne.UI.Phone; using Il2CppScheduleOne.UI.Phone.Messages; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using ModManagerPhoneApp; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(EntryPoint), "EnhanceDealSystems", "1.0.6", "_peron", null)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("EnhanceDealSystems")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EnhanceDealSystems")] [assembly: AssemblyTitle("EnhanceDealSystems")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace EnhanceDealSystems { public class EntryPoint : MelonMod { [HarmonyPatch(typeof(Player))] [HarmonyPatch("PlayerLoaded")] private class ConfigLoad { [HarmonyPostfix] private static void PostfixPlayerLoaded(Player __instance) { LoadAllCategories(); } } [HarmonyPatch(typeof(Customer))] private class HandoverPostFix { [HarmonyPatch("ProcessHandover")] [HarmonyPostfix] private static void ProcessHandoverPostfix(Customer __instance, EHandoverOutcome outcome, Contract contract, List<ItemInstance> items, bool handoverByPlayer, bool giveBonuses = 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(num / 5f); float relationshipChange = CustomerSatisfaction.GetRelationshipChange(num3); __instance.NPC.RelationData.ChangeRelationship(relationshipChange * (float)(int)((MelonPreferences_Entry)RelationMultiplier).BoxedValue, true); } } [HarmonyPatch(typeof(DialogueController))] private class DialogTest { [HarmonyPatch("Interacted")] [HarmonyPrefix] private static bool PreInteracted(DialogueController __instance) { try { if (!(bool)((MelonPreferences_Entry)SuperAutoHandover).BoxedValue) { return true; } Customer component = ((Component)__instance.npc).gameObject.GetComponent<Customer>(); _ = component.CurrentContract.Payment; if (component.IsAtDealLocation()) { return DoDeal(component); } return true; } catch (Exception) { return true; } } } [HarmonyPatch(typeof(Customer))] private class Handovers { [HarmonyPatch(typeof(Customer), "HandoverChosen")] [HarmonyPrefix] private static bool HandoverChosenPrefix(Customer __instance) { return DoDeal(__instance); } } [HarmonyPatch(typeof(DealWindowSelector))] [HarmonyPatch("SetIsOpen", new Type[] { typeof(bool), typeof(MSGConversation), typeof(Action<EDealWindow>) })] private class InstaClick { [HarmonyPostfix] private static void PostOpenWindow(DealWindowSelector __instance, bool open, MSGConversation conversation, Action<EDealWindow> callback) { if ((bool)((MelonPreferences_Entry)AutoScheduleDeals).BoxedValue) { switch ((int)((MelonPreferences_Entry)DealDayTime).BoxedValue) { case 1: __instance.MorningButton.Clicked(); break; case 2: __instance.AfternoonButton.Clicked(); break; case 3: __instance.NightButton.Clicked(); break; default: __instance.LateNightButton.Clicked(); break; } } } } [HarmonyPatch(typeof(AvatarLookController))] private class AvatarLook { [HarmonyPatch("UpdateShit")] [HarmonyPostfix] private static void AvatarLookController(AvatarLookController __instance) { try { if (__instance.nearestPlayerDist < 4f && (bool)((MelonPreferences_Entry)MagicHandover).BoxedValue) { Customer component = ((Component)__instance.NPC).gameObject.GetComponent<Customer>(); _ = component.CurrentContract.Payment; if (component.IsAtDealLocation() && ((Behaviour)component.CurrentContract).enabled) { DoDeal(component); ((Behaviour)component.CurrentContract).enabled = false; ((Object)component.CurrentContract).Finalize(); } } } catch (Exception) { } } } [HarmonyPatch(typeof(Quest))] private class QuestTest { private static HashSet<int> handledQuests = new HashSet<int>(); [HarmonyPatch("SetIsTracked")] [HarmonyPostfix] private static void SetIsTrackedPrefix(Quest __instance, bool tracked) { if (tracked && !(bool)((MelonPreferences_Entry)AutoTrack).BoxedValue && __instance.title.Contains("Deal for")) { int hashCode = ((Object)__instance).GetHashCode(); if (!handledQuests.Contains(hashCode)) { handledQuests.Add(hashCode); __instance.SetIsTracked(false); } } } } [HarmonyPatch(typeof(MSGConversation))] private class MsgTest { [HarmonyPatch("RefreshPreviewText")] [HarmonyPostfix] public static void RefreshPreviewText(MSGConversation __instance) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if (__instance.currentResponses.Count >= 2 && (int)__instance.bubbles[__instance.bubbles.Count - 1].alignment == 1) { if (__instance.currentResponses[1].label == "COUNTEROFFER" && (bool)((MelonPreferences_Entry)AutoCounterOffer).BoxedValue) { __instance.ResponseChosen(__instance.currentResponses[1], true); } else if (__instance.currentResponses[0].label == "ACCEPT_CONTRACT" && (bool)((MelonPreferences_Entry)AutoScheduleDeals).BoxedValue) { __instance.ResponseChosen(__instance.currentResponses[0], true); } } } } [HarmonyPatch(typeof(CounterofferInterface))] private class CounterofferInterfacePatches { private static void UpdateConfirmButtonText(CounterofferInterface instance) { if (!(bool)((MelonPreferences_Entry)AutoCounterOffer).BoxedValue || !instance.IsOpen) { return; } float num = EvaluateCounterofferPercentage(instance.selectedProduct, instance.quantity, instance.price, ((Component)instance.conversation.sender).GetComponent<Customer>()); if (num < 70f) { instance.conversation.ResponseChosen(instance.conversation.currentResponses[0], true); return; } while (Mathf.RoundToInt(num) == 100) { instance.price += 1f; num = EvaluateCounterofferPercentage(instance.selectedProduct, instance.quantity, instance.price, ((Component)instance.conversation.sender).GetComponent<Customer>()); } instance.price -= 1f; instance.PriceInput.text = instance.price.ToString(); instance.Update(); instance.Send(); instance.IsOpen = false; } [HarmonyPatch("Open")] [HarmonyPostfix] private static void PostOpenPatch(CounterofferInterface __instance) { UpdateConfirmButtonText(__instance); } [HarmonyPatch("ChangePrice")] [HarmonyPostfix] private static void PostPriceChangePatch(CounterofferInterface __instance) { UpdateConfirmButtonText(__instance); } [HarmonyPatch("ChangeQuantity")] [HarmonyPostfix] private static void PostQuantityChangePatch(CounterofferInterface __instance) { UpdateConfirmButtonText(__instance); } } public static MelonPreferences_Category ConfigCategory; public static MelonPreferences_Entry<bool> SuperAutoHandover; public static MelonPreferences_Entry<bool> AutoScheduleDeals; public static MelonPreferences_Entry<bool> AutoCounterOffer; public static MelonPreferences_Entry<int> DealDayTime; public static MelonPreferences_Entry<bool> AutoHandOver; public static MelonPreferences_Entry<bool> AutoTrack; public static MelonPreferences_Entry<bool> MagicHandover; public static MelonPreferences_Entry<int> RelationMultiplier; public static float EvaluateCounterofferPercentage(ProductDefinition product, int quantity, float price, Customer customer) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) float adjustedWeeklySpend = customer.customerData.GetAdjustedWeeklySpend(customer.NPC.RelationData.RelationDelta / 5f); List<EDay> orderDays = customer.customerData.GetOrderDays(customer.CurrentAddiction, customer.NPC.RelationData.RelationDelta / 5f); float num = adjustedWeeklySpend / (float)orderDays.Count; if (price >= num * 3f) { return 0f; } float valueProposition = Customer.GetValueProposition(Registry.GetItem<ProductDefinition>(customer.OfferedContractInfo.Products.entries[0].ProductID), customer.OfferedContractInfo.Payment / (float)customer.OfferedContractInfo.Products.entries[0].Quantity); float productEnjoyment = customer.GetProductEnjoyment(product, StandardsMethod.GetCorrespondingQuality(customer.customerData.Standards)); float num2 = Mathf.InverseLerp(-1f, 1f, productEnjoyment); float valueProposition2 = Customer.GetValueProposition(product, price / (float)quantity); float num3 = Mathf.Pow((float)quantity / (float)customer.OfferedContractInfo.Products.entries[0].Quantity, 0.6f); float num4 = Mathf.Lerp(0f, 2f, num3 * 0.5f); float num5 = Mathf.Lerp(1f, 0f, Mathf.Abs(num4 - 1f)); if (valueProposition2 * num5 > valueProposition) { return 100f; } if (valueProposition2 < 0.12f) { return 0f; } float num6 = productEnjoyment * valueProposition; float num7 = num2 * num5 * valueProposition2; if (num7 > num6) { return 100f; } float num8 = num6 - num7; float num9 = Mathf.Lerp(0f, 1f, num8 / 0.2f); float num10 = Mathf.Max(customer.CurrentAddiction, customer.NPC.RelationData.NormalizedRelationDelta); float num11 = Mathf.Lerp(0f, 0.2f, num10); if (num9 <= num11) { return 100f; } if (num9 - num11 >= 0.9f) { return 0f; } return Mathf.Clamp((0.9f + num11 - num9) / 0.9f, 0f, 1f) * 100f; } public override void OnInitializeMelon() { ConfigCategory = MelonPreferences.CreateCategory("EnhanceDealSystems"); SuperAutoHandover = ConfigCategory.CreateEntry<bool>("SuperAutoHandover", true, "Enable Super Auto Handover", (string)null, false, false, (ValueValidator)null, (string)null); AutoScheduleDeals = ConfigCategory.CreateEntry<bool>("AutoScheduleDeals", true, "Enable Auto Schedule Deals", (string)null, false, false, (ValueValidator)null, (string)null); AutoCounterOffer = ConfigCategory.CreateEntry<bool>("AutoCounterOffer", true, "Enable Auto Counter Offer", (string)null, false, false, (ValueValidator)null, (string)null); DealDayTime = ConfigCategory.CreateEntry<int>("DealDayTime", 4, "Deal Day Time (1=Morning, 2=Evening, 3=Night, 4=Late Night)", (string)null, false, false, (ValueValidator)null, (string)null); AutoHandOver = ConfigCategory.CreateEntry<bool>("AutoHandOver", true, "Enable Auto Hand Over", (string)null, false, false, (ValueValidator)null, (string)null); AutoTrack = ConfigCategory.CreateEntry<bool>("AutoTrack", true, "Enable Auto Track", (string)null, false, false, (ValueValidator)null, (string)null); MagicHandover = ConfigCategory.CreateEntry<bool>("MagicHandover", true, "Enable Magic Handover", (string)null, false, false, (ValueValidator)null, (string)null); RelationMultiplier = ConfigCategory.CreateEntry<int>("SatisfactionMultiplier", 1, "Satisfaction Multiplier (1=Normal, 2=Double, etc)", (string)null, false, false, (ValueValidator)null, (string)null); ConfigCategory.SetFilePath("UserData/EnhanceDealSystems.cfg"); ConfigCategory.SaveToFile(true); try { ModSettingsEvents.OnPreferencesSaved += LoadAllCategories; ((MelonBase)this).LoggerInstance.Msg("Successfully subscribed to Mod Manager save event."); } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning("Could not subscribe to Mod Manager event (Mod Manager may not be installed/compatible): " + ex.Message); } } public static void LoadAllCategories() { foreach (MelonPreferences_Category category in MelonPreferences.Categories) { category.LoadFromFile(true); } } public static bool DoDeal(Customer __instance) { if (!(bool)((MelonPreferences_Entry)AutoHandOver).BoxedValue) { return true; } Contract currentContract = __instance.CurrentContract; object obj; if (currentContract == null) { obj = null; } else { ProductList productList = currentContract.ProductList; obj = ((productList != null) ? productList.entries : null); } if (obj == null || __instance.CurrentContract.ProductList.entries.Count == 0) { return true; } Entry obj2 = __instance.CurrentContract.ProductList.entries[0]; string productID = obj2.ProductID; uint quantity = (uint)obj2.Quantity; if (quantity == 0) { return true; } List<ItemSlot> list = new List<ItemSlot>(); List<ItemSlot> list2 = new List<ItemSlot>(); List<ItemSlot> list3 = new List<ItemSlot>(); foreach (ItemSlot item in (Il2CppArrayBase<ItemSlot>)(object)Player.Local.Inventory) { if (((item != null) ? item.ItemInstance : null) == null || !(item.ItemInstance.ID == productID) || item.Quantity <= 0) { continue; } ItemInstance itemInstance = item.ItemInstance; string text = null; _ = ((MemberInfo)((Object)itemInstance).GetIl2CppType()).Name; WeedInstance val = ((Il2CppObjectBase)itemInstance).TryCast<WeedInstance>(); if (val != null) { text = ((ProductItemInstance)val).PackagingID; } else { MethInstance val2 = ((Il2CppObjectBase)itemInstance).TryCast<MethInstance>(); if (val2 != null) { text = ((ProductItemInstance)val2).PackagingID; } else { CocaineInstance val3 = ((Il2CppObjectBase)itemInstance).TryCast<CocaineInstance>(); if (val3 != null) { text = ((ProductItemInstance)val3).PackagingID; } } } switch (text?.ToLower()) { case "brick": list.Add(item); break; case "jar": list2.Add(item); break; case "baggie": list3.Add(item); break; default: list3.Add(item); break; } } uint num = quantity; List<(ItemSlot, int)> list4 = new List<(ItemSlot, int)>(); foreach (ItemSlot item2 in list) { if (num == 0) { break; } uint num2 = num / 20; if (num2 == 0) { break; } uint quantity2 = (uint)item2.Quantity; uint num3 = Math.Min(num2, quantity2); if (num3 != 0) { list4.Add((item2, (int)num3)); num -= num3 * 20; } } if (num != 0) { foreach (ItemSlot item3 in list2) { if (num == 0) { break; } uint num4 = num / 5; if (num4 == 0) { break; } uint quantity3 = (uint)item3.Quantity; uint num5 = Math.Min(num4, quantity3); if (num5 != 0) { list4.Add((item3, (int)num5)); num -= num5 * 5; } } } if (num != 0) { foreach (ItemSlot item4 in list3) { if (num == 0) { break; } uint val4 = num; uint quantity4 = (uint)item4.Quantity; uint num6 = Math.Min(val4, quantity4); if (num6 != 0) { list4.Add((item4, (int)num6)); num -= num6; } } } if (num == 0) { foreach (var item5 in list4) { item5.Item1.ChangeQuantity(-item5.Item2, false); } List<ItemInstance> val5 = new List<ItemInstance>(); ItemDefinition val6 = Singleton<Registry>.instance._GetItem(productID, true); if ((Object)(object)val6 != (Object)null) { ItemInstance defaultInstance = val6.GetDefaultInstance(1); defaultInstance.Quantity = (int)quantity; val5.Add(defaultInstance); __instance.ProcessHandover((EHandoverOutcome)1, __instance.CurrentContract, val5, true, true); } else { MelonLogger.Error("HandoverChosenPrefix: Failed to get ItemDefinition for " + productID + ". Cannot process handover."); } return false; } MelonLogger.Warning($"HandoverChosenPrefix: Failed to fulfill contract. {num} units still needed after planning. No changes applied to inventory."); return true; } } }