Decompiled source of Epicurean v1.3.0

Epicurean.dll

Decompiled 4 months ago
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using HarmonyLib;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppScheduleOne;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Law;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Handover;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Utils;
using QualityMod;
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(global::QualityMod.QualityMod), "Epicurean", "1.3.0", "Ryocery", null)]
[assembly: MelonColor(255, 255, 60, 255)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("QualityMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("QualityMod")]
[assembly: AssemblyTitle("QualityMod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace QualityMod;

public static class BuildInfo
{
	public const string Name = "Epicurean";

	public const string Description = "Adds percentage bonuses per quality tier above customer standards for payment, addiction, and affinity";

	public const string Author = "Ryocery";

	public const string Company = null;

	public const string Version = "1.3.0";

	public const string DownloadLink = null;
}
public class QualityMod : MelonMod
{
	[HarmonyPatch(typeof(Customer), "ProcessHandover")]
	public static class Customer_ProcessHandover_Patch
	{
		public static bool Prefix(Customer __instance, EHandoverOutcome outcome, Contract contract, List<ItemInstance> items, bool handoverByPlayer, bool giveBonuses)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Expected O, but got Unknown
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Expected O, but got Unknown
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Invalid comparison between Unknown and I4
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			if (!handoverByPlayer && !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));
			float num4 = 1f;
			float qualityScalar = CustomerData.GetQualityScalar(StandardsMethod.GetCorrespondingQuality(__instance.customerData.Standards));
			Enumerator<ItemInstance> enumerator = items.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemInstance current = enumerator.Current;
				ProductItemInstance val2 = ((Il2CppObjectBase)current).TryCast<ProductItemInstance>();
				if (val2 != null)
				{
					float qualityScalar2 = CustomerData.GetQualityScalar(((QualityItemInstance)val2).Quality);
					if (qualityScalar2 < num4)
					{
						num4 = qualityScalar2;
					}
				}
				else
				{
					MelonLogger.Msg("Found null product item! Please report this bug.");
				}
			}
			float num5 = num4 - qualityScalar;
			int num6 = 0;
			if (num5 > 0f)
			{
				num6 = Mathf.RoundToInt(num5 / 0.25f);
			}
			float num7 = 1f;
			if (num6 > 0)
			{
				num7 = 1f + (float)num6 * addictionBonusPercent / 100f;
			}
			__instance.ChangeAddiction(num / 5f * num7);
			float relationDelta = __instance.NPC.RelationData.RelationDelta;
			float relationshipChange = CustomerSatisfaction.GetRelationshipChange(num3);
			float num8 = relationshipChange * 0.2f * Mathf.Lerp(0.75f, 1.5f, num);
			float num9 = 1f;
			if (num6 > 0)
			{
				num9 = 1f + (float)num6 * affinityBonusPercent / 100f;
			}
			float num10 = num8 * num9;
			__instance.AdjustAffinity(val, num10);
			float num11 = relationshipChange;
			if (num6 > 0 && affinityBonusPercent > 0f)
			{
				num11 = relationshipChange * num9;
			}
			__instance.NPC.RelationData.ChangeRelationship(num11, true);
			List<BonusPayment> val3 = new List<BonusPayment>();
			if (NetworkSingleton<CurfewManager>.Instance.IsCurrentlyActive && giveBonuses)
			{
				val3.Add(new BonusPayment("Curfew Bonus", contract.Payment * 0.2f));
			}
			if (num2 > contract.ProductList.GetTotalQuantity() && giveBonuses)
			{
				val3.Add(new BonusPayment("Generosity Bonus", 10f * (float)(num2 - contract.ProductList.GetTotalQuantity())));
			}
			GameDateTime acceptTime = contract.AcceptTime;
			GameDateTime val4 = default(GameDateTime);
			((GameDateTime)(ref val4))..ctor(acceptTime.elapsedDays, TimeManager.AddMinutesTo24HourTime(contract.DeliveryWindow.WindowStartTime, 60));
			if (NetworkSingleton<TimeManager>.Instance.IsCurrentDateWithinRange(acceptTime, val4) && giveBonuses)
			{
				val3.Add(new BonusPayment("Quick Delivery Bonus", contract.Payment * 0.1f));
			}
			MelonLogger.Msg($"Contract payment: ${contract.Payment:F2}, Items quantity: {contract.ProductList.GetTotalQuantity()}");
			if (num5 > 0f)
			{
				float num12 = (float)num6 * qualityBonusPercent / 100f;
				float num13 = contract.Payment * num12;
				val3.Add(new BonusPayment("Quality Bonus", num13));
				MelonLogger.Msg($"Tiers above standard: {num6} ({(float)num6 * qualityBonusPercent}% bonus), Bonus: ${num13:F2}");
			}
			float num14 = 0f;
			Enumerator<BonusPayment> enumerator2 = val3.GetEnumerator();
			while (enumerator2.MoveNext())
			{
				BonusPayment current2 = enumerator2.Current;
				Console.Log(Object.op_Implicit($"Bonus: {current2.Title} Amount: {current2.Amount}"), (Object)null);
				num14 += current2.Amount;
			}
			if (handoverByPlayer)
			{
				Singleton<HandoverScreen>.Instance.ClearCustomerSlots(false);
			}
			if (handoverByPlayer)
			{
				contract.SubmitPayment(num14);
			}
			if ((int)outcome == 1 && handoverByPlayer)
			{
				Singleton<DealCompletionPopup>.Instance.PlayPopup(__instance, num3, relationDelta, contract.Payment, val3);
			}
			__instance.TimeSinceLastDealCompleted = 0;
			__instance.NPC.SendAnimationTrigger("GrabItem");
			NetworkObject val5 = null;
			if ((Object)(object)contract.Dealer != (Object)null)
			{
				val5 = ((NetworkBehaviour)contract.Dealer).NetworkObject;
			}
			Console.Log(Object.op_Implicit($"Base payment: {contract.Payment} Total Bonus: {num14} Satisfaction: {num3} Dealer: {((val5 != null) ? ((Object)val5).name : null)}"), (Object)null);
			float num15 = Mathf.Clamp(contract.Payment + num14, 0f, float.MaxValue);
			__instance.ProcessHandoverServerSide(outcome, items, handoverByPlayer, num15, contract.ProductList, num3, val5);
			return false;
		}
	}

	private static string configPath = Path.Combine(MelonEnvironment.UserDataDirectory, "Epicurean.cfg");

	private static float qualityBonusPercent = 10f;

	private static float addictionBonusPercent = 20f;

	private static float affinityBonusPercent = 15f;

	private static bool affectsDealers = true;

	public override void OnInitializeMelon()
	{
		MelonLogger.Msg("Epicurean v1.3.0 loaded! :3");
		LoadConfig();
	}

	private void LoadConfig()
	{
		if (File.Exists(configPath))
		{
			string[] array = File.ReadAllLines(configPath);
			foreach (string text in array)
			{
				bool result4;
				if (text.StartsWith("BonusPercentage="))
				{
					if (float.TryParse(text.Split('=')[1].Trim(), out var result))
					{
						qualityBonusPercent = result;
					}
				}
				else if (text.StartsWith("AddictionBonusPercentage="))
				{
					if (float.TryParse(text.Split('=')[1].Trim(), out var result2))
					{
						addictionBonusPercent = result2;
					}
				}
				else if (text.StartsWith("AffinityBonusPercentage="))
				{
					if (float.TryParse(text.Split('=')[1].Trim(), out var result3))
					{
						affinityBonusPercent = result3;
					}
				}
				else if (text.StartsWith("AffectsDealers=") && bool.TryParse(text.Split('=')[1].Trim(), out result4))
				{
					affectsDealers = result4;
				}
			}
		}
		else
		{
			SaveConfig();
		}
		MelonLogger.Msg("Config loaded.");
	}

	private static void SaveConfig()
	{
		File.WriteAllText(configPath, $"BonusPercentage={qualityBonusPercent}\nAddictionBonusPercentage={addictionBonusPercent}\nAffinityBonusPercentage={affinityBonusPercent}\nAffectsDealers={affectsDealers}");
		MelonLogger.Msg("Config file created.");
	}
}