Decompiled source of VargheimCooking v1.0.1

VargheimCooking.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using VargheimProfessions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace VargheimCooking
{
	[BepInPlugin("digi.vargheim.cooking", "VargheimCooking", "1.0.1")]
	[BepInDependency("digi.vargheim.professions", "0.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		internal static class Patches
		{
			private static readonly FieldRef<ItemDrop, bool> s_stacked = AccessTools.FieldRefAccess<ItemDrop, bool>("m_haveAutoStacked");

			[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
			[HarmonyPrefix]
			private static void CraftPre(InventoryGui __instance, Player player)
			{
				s_tag = null;
				try
				{
					Recipe value = Traverse.Create((object)__instance).Field("m_craftRecipe").GetValue<Recipe>();
					if (!((Object)(object)value == (Object)null) && !((Object)(object)value.m_item == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && IsFood(value.m_item.m_itemData.m_shared))
					{
						string text = (Api.HasPerk("Cooking", PreserveLevel.Value) ? "P" : "") + (Api.HasPerk("Cooking", CampLevel.Value) ? "C" : "") + (Api.HasPerk("Cooking", SignatureLevel.Value) ? "S" : "");
						if (text.Length > 0)
						{
							s_tag = text + "|" + player.GetPlayerName();
							s_tagItem = value.m_item.m_itemData.m_shared.m_name;
						}
					}
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
			[HarmonyFinalizer]
			private static void CraftPost()
			{
				s_tag = null;
				s_tagItem = null;
			}

			private static void Incoming(ItemData item, ref ItemData __state)
			{
				__state = s_incoming;
				try
				{
					if (item != null && s_tag != null && item.m_shared != null && item.m_shared.m_name == s_tagItem && IsFood(item.m_shared) && TagOf(item).Length == 0)
					{
						Dictionary<string, string> dictionary = ((item.m_customData != null) ? new Dictionary<string, string>(item.m_customData) : new Dictionary<string, string>());
						dictionary["vp_cook"] = s_tag;
						item.m_customData = dictionary;
					}
				}
				catch
				{
				}
				s_incoming = item;
			}

			[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
			[HarmonyPrefix]
			private static void AddPre(ItemData item, ref ItemData __state)
			{
				Incoming(item, ref __state);
			}

			[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
			[HarmonyFinalizer]
			private static void AddFin(ItemData __state)
			{
				s_incoming = __state;
			}

			[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
			{
				typeof(ItemData),
				typeof(Vector2i)
			})]
			[HarmonyPrefix]
			private static void AddPosPre(ItemData item, ref ItemData __state)
			{
				Incoming(item, ref __state);
			}

			[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
			{
				typeof(ItemData),
				typeof(Vector2i)
			})]
			[HarmonyFinalizer]
			private static void AddPosFin(ItemData __state)
			{
				s_incoming = __state;
			}

			[HarmonyPatch(typeof(Inventory), "FindFreeStackItem")]
			[HarmonyPostfix]
			private static void FreeStack(Inventory __instance, string name, int quality, float worldLevel, ref ItemData __result)
			{
				try
				{
					ItemData s_incoming = Plugin.s_incoming;
					if (__result == null || s_incoming == null || SameTag(__result, s_incoming))
					{
						return;
					}
					ItemData val = null;
					foreach (ItemData allItem in __instance.GetAllItems())
					{
						if (allItem != s_incoming && allItem.m_shared.m_name == name && allItem.m_quality == quality && allItem.m_stack < allItem.m_shared.m_maxStackSize && (float)allItem.m_worldLevel == worldLevel && SameTag(allItem, s_incoming))
						{
							val = allItem;
							break;
						}
					}
					__result = val;
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(ItemData), "IsSameType")]
			[HarmonyPostfix]
			private static void SameType(ItemData __instance, ItemData other, ref bool __result)
			{
				try
				{
					if (__result && other != null && !SameTag(__instance, other))
					{
						__result = false;
					}
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(ItemDrop), "AutoStackItems")]
			[HarmonyPrefix]
			private static bool GroundStack(ItemDrop __instance)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					ItemData itemData = __instance.m_itemData;
					if (itemData == null || s_stacked.Invoke(__instance) || !IsFood(itemData.m_shared))
					{
						return true;
					}
					Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 4f, LayerMask.GetMask(new string[1] { "item" }));
					foreach (Collider val in array)
					{
						ItemDrop val2 = (((Object)(object)val != (Object)null && (Object)(object)val.attachedRigidbody != (Object)null) ? ((Component)val.attachedRigidbody).GetComponent<ItemDrop>() : null);
						if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)__instance && val2.m_itemData != null && val2.m_itemData.m_shared.m_name == itemData.m_shared.m_name && !SameTag(val2.m_itemData, itemData))
						{
							s_stacked.Invoke(__instance) = true;
							return false;
						}
					}
				}
				catch
				{
				}
				return true;
			}

			[HarmonyPatch(typeof(Player), "EatFood")]
			[HarmonyPostfix]
			private static void Eat(Player __instance, ItemData item, bool __result)
			{
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!__result || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Parse(item, out var flags, out var cook))
					{
						return;
					}
					if (flags.Contains("P"))
					{
						foreach (Food food in __instance.GetFoods())
						{
							if (food.m_item != null && food.m_item.m_shared.m_name == item.m_shared.m_name && food.m_time <= item.m_shared.m_foodBurnTime + 1f)
							{
								food.m_time = item.m_shared.m_foodBurnTime * (1f + PreserveBonus.Value);
							}
						}
					}
					if (!flags.Contains("C") || (!(cook == __instance.GetPlayerName()) && !Api.GroupMemberNames().Contains(cook)) || !NearStation(((Component)__instance).transform.position))
					{
						return;
					}
					SEMan sEMan = ((Character)__instance).GetSEMan();
					StatusEffect statusEffect = sEMan.GetStatusEffect(SEMan.s_statusEffectRested);
					if ((Object)(object)statusEffect == (Object)null)
					{
						statusEffect = sEMan.AddStatusEffect(SEMan.s_statusEffectRested, true, 0, 0f, (short)0);
						if ((Object)(object)statusEffect != (Object)null)
						{
							statusEffect.m_ttl = CampMinutes.Value * 60f;
						}
					}
					else
					{
						StatusEffect obj = statusEffect;
						obj.m_ttl += CampMinutes.Value * 60f;
					}
					Api.Note("Camp cook: " + cook + "'s food keeps you rested longer.");
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
			[HarmonyPostfix]
			private static void Total(Player __instance, ref float hp, ref float stamina, ref float eitr)
			{
				try
				{
					foreach (Food food in __instance.GetFoods())
					{
						if (Parse(food.m_item, out var flags, out var _) && flags.Contains("S"))
						{
							hp += food.m_health * SignatureBonus.Value;
							stamina += food.m_stamina * SignatureBonus.Value;
							eitr += food.m_eitr * SignatureBonus.Value;
						}
					}
				}
				catch
				{
				}
			}
		}

		public const string Guid = "digi.vargheim.cooking";

		public const string Version = "1.0.1";

		private const string Prof = "Cooking";

		private const string Key = "vp_cook";

		internal static ConfigEntry<int> PreserveLevel;

		internal static ConfigEntry<int> CampLevel;

		internal static ConfigEntry<int> SignatureLevel;

		internal static ConfigEntry<float> PreserveBonus;

		internal static ConfigEntry<float> CampRange;

		internal static ConfigEntry<float> CampMinutes;

		internal static ConfigEntry<float> SignatureBonus;

		[ThreadStatic]
		private static string s_tag;

		[ThreadStatic]
		private static string s_tagItem;

		[ThreadStatic]
		private static ItemData s_incoming;

		private static readonly FieldRef<List<CraftingStation>> s_stations = AccessTools.StaticFieldRefAccess<List<CraftingStation>>(AccessTools.Field(typeof(CraftingStation), "m_allStations"));

		private void Awake()
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Expected O, but got Unknown
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			PreserveLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "PreservedLevel", 40, "Preserved level.");
			PreserveBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "PreservedBonus", 0.2f, "Preserved: food you cook lasts this much longer.");
			CampLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "CampCookLevel", 60, "Camp cook level.");
			CampRange = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "CampCookRange", 30f, "Camp cook: the eater must be this close to a crafting or cooking station.");
			CampMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "CampCookRestedMinutes", 10f, "Camp cook: extra Rested minutes.");
			SignatureLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "SignatureDishLevel", 75, "Signature dish level.");
			SignatureBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "SignatureDishBonus", 0.1f, "Signature dish: extra health, stamina and eitr from food you cook.");
			Content.AddTooltip((Func<ItemData, string>)Tooltip);
			Api.RegisterLadder("Cooking", "VargheimCooking 1.0.1", "Modded dishes (CookingAdditions, RtDOcean) are cooked by cooks, by tier. Smoothbrain Cooking: up to x1.3 food stats at 100, extra portions and the happy buff.", (Perk[])(object)new Perk[7]
			{
				new Perk(25, "Modded recipes I", "Meadows and Black Forest dishes from the cooking mods."),
				new Perk(30, "Extra portion", "Chance of an extra serving, rising to 25% at level 100 (Smoothbrain Cooking)."),
				new Perk(35, "Modded recipes", "Higher-tier modded dishes unlock with the tier levels."),
				new Perk(PreserveLevel.Value, "Preserved", "Food you cook lasts " + Mathf.RoundToInt(PreserveBonus.Value * 100f) + "% longer."),
				new Perk(50, "Happy", "Perfectly cooked food can make people happy (Smoothbrain Cooking)."),
				new Perk(CampLevel.Value, "Camp cook", "Group members who eat your food within " + CampRange.Value + " m of a crafting or cooking station get +" + CampMinutes.Value + " minutes of Rested."),
				new Perk(SignatureLevel.Value, "Signature dish", "Your food shows \"Cooked by <name>\" and gives " + Mathf.RoundToInt(SignatureBonus.Value * 100f) + "% more.")
			});
			new Harmony("digi.vargheim.cooking").PatchAll(typeof(Patches));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"VargheimCooking 1.0.1 loaded.");
		}

		private static bool IsFood(SharedData s)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if (s != null && (int)s.m_itemType == 2)
			{
				if (!(s.m_food > 0f) && !(s.m_foodStamina > 0f))
				{
					return s.m_foodEitr > 0f;
				}
				return true;
			}
			return false;
		}

		private static bool Parse(ItemData i, out string flags, out string cook)
		{
			flags = (cook = "");
			if (i == null || i.m_customData == null || !i.m_customData.TryGetValue("vp_cook", out var value))
			{
				return false;
			}
			int num = value.IndexOf('|');
			flags = ((num >= 0) ? value.Substring(0, num) : value);
			cook = ((num >= 0) ? value.Substring(num + 1) : "");
			return true;
		}

		private static string Tooltip(ItemData i)
		{
			if (!Parse(i, out var flags, out var cook))
			{
				return null;
			}
			List<string> list = new List<string>();
			if (flags.Contains("P"))
			{
				list.Add("lasts " + Mathf.RoundToInt(PreserveBonus.Value * 100f) + "% longer");
			}
			if (flags.Contains("C"))
			{
				list.Add("camp cook");
			}
			if (flags.Contains("S"))
			{
				list.Add("signature dish, +" + Mathf.RoundToInt(SignatureBonus.Value * 100f) + "%");
			}
			return "<color=#ffd27a>Cooked by " + cook + "</color>" + ((list.Count > 0) ? (": " + string.Join(", ", list.ToArray())) : "");
		}

		internal static string TagOf(ItemData i)
		{
			if (i == null || i.m_customData == null || !i.m_customData.TryGetValue("vp_cook", out var value))
			{
				return "";
			}
			return value ?? "";
		}

		internal static bool SameTag(ItemData a, ItemData b)
		{
			return TagOf(a) == TagOf(b);
		}

		private static bool NearStation(Vector3 pos)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			List<CraftingStation> list = s_stations.Invoke();
			if (list != null)
			{
				foreach (CraftingStation item in list)
				{
					if ((Object)(object)item != (Object)null && Vector3.Distance(((Component)item).transform.position, pos) <= CampRange.Value)
					{
						return true;
					}
				}
			}
			Collider[] array = Physics.OverlapSphere(pos, CampRange.Value);
			foreach (Collider val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInParent<CookingStation>() != (Object)null)
				{
					return true;
				}
			}
			return false;
		}
	}
}