Decompiled source of KeepFoodOnDeath v1.0.0

plugins/KeepFoodOnDeath/KeepFoodOnDeath.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace KeepFoodOnDeath;

[BepInPlugin("local.keepfoodondeath", "Keep Food On Death", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string Id = "local.keepfoodondeath";

	internal const string PendingKey = "local.keepfoodondeath.restoreVitals";

	private Harmony harmony;

	private void Awake()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		if (SpawnPatch.TotalFood == null || SpawnPatch.SetEitr == null || SpawnPatch.Stamina == null || SpawnPatch.Eitr == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Unsupported Valheim version: required food APIs were not found.");
			return;
		}
		harmony = new Harmony("local.keepfoodondeath");
		try
		{
			harmony.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Keep Food On Death 1.0.0 loaded. Food timers pause while dead.");
		}
		catch (Exception ex)
		{
			harmony.UnpatchSelf();
			((BaseUnityPlugin)this).Logger.LogError((object)ex);
		}
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
[HarmonyPatch(typeof(Player), "OnDeath")]
internal static class DeathPatch
{
	[HarmonyPrefix]
	[HarmonyPriority(800)]
	internal static void Prefix(Player __instance, out List<Food> __state)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		__state = null;
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || ((Character)__instance).IsDead())
		{
			return;
		}
		__state = new List<Food>();
		foreach (Food food in __instance.GetFoods())
		{
			if (!(food.m_time <= 0f))
			{
				List<Food> obj = __state;
				Food val = new Food();
				val.m_name = food.m_name;
				val.m_item = food.m_item;
				val.m_time = food.m_time;
				val.m_health = food.m_health;
				val.m_stamina = food.m_stamina;
				val.m_eitr = food.m_eitr;
				obj.Add(val);
			}
		}
	}

	[HarmonyPriority(0)]
	[HarmonyPostfix]
	internal static void Postfix(Player __instance, List<Food> __state)
	{
		if (__state != null && ((Character)__instance).IsDead())
		{
			List<Food> foods = __instance.GetFoods();
			foods.Clear();
			foods.AddRange(__state);
			if (foods.Count > 0)
			{
				__instance.m_customData["local.keepfoodondeath.restoreVitals"] = "1";
			}
			else
			{
				__instance.m_customData.Remove("local.keepfoodondeath.restoreVitals");
			}
		}
	}
}
[HarmonyPatch(typeof(Player), "UpdateFood")]
internal static class FoodTickPatch
{
	[HarmonyPrefix]
	internal static bool Prefix(Player __instance)
	{
		if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			return !((Character)__instance).IsDead();
		}
		return true;
	}
}
[HarmonyPatch(typeof(Player), "OnSpawned")]
internal static class SpawnPatch
{
	internal static readonly MethodInfo TotalFood = AccessTools.Method(typeof(Player), "GetTotalFoodValue", (Type[])null, (Type[])null);

	internal static readonly MethodInfo SetEitr = AccessTools.Method(typeof(Player), "SetMaxEitr", (Type[])null, (Type[])null);

	internal static readonly FieldInfo Stamina = AccessTools.Field(typeof(Player), "m_stamina");

	internal static readonly FieldInfo Eitr = AccessTools.Field(typeof(Player), "m_eitr");

	[HarmonyPostfix]
	[HarmonyPriority(0)]
	internal static void Postfix(Player __instance)
	{
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || ((Character)__instance).IsDead() || !__instance.m_customData.ContainsKey("local.keepfoodondeath.restoreVitals"))
		{
			return;
		}
		foreach (Food food in __instance.GetFoods())
		{
			SharedData shared = food.m_item.m_shared;
			float num = ((shared.m_foodBurnTime > 0f) ? Mathf.Pow(Mathf.Clamp01(food.m_time / shared.m_foodBurnTime), 0.3f) : 0f);
			food.m_health = shared.m_food * num;
			food.m_stamina = shared.m_foodStamina * num;
			food.m_eitr = shared.m_foodEitr * num;
		}
		object[] array = new object[3] { 0f, 0f, 0f };
		TotalFood.Invoke(__instance, array);
		float num2 = (float)array[0];
		float num3 = (float)array[1];
		float num4 = (float)array[2];
		__instance.SetMaxHealth(num2, false);
		__instance.SetMaxStamina(num3, false);
		SetEitr.Invoke(__instance, new object[2] { num4, false });
		((Character)__instance).SetHealth(num2);
		Stamina.SetValue(__instance, num3);
		Eitr.SetValue(__instance, num4);
		__instance.m_customData.Remove("local.keepfoodondeath.restoreVitals");
	}
}