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 10 months 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; } } }