Decompiled source of Healing Campfires v2.1.0

tony4twentys-Healing Campfires.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Healing Campfires")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Healing Campfires")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("56f9024b-9ced-4a82-bd45-483d74b8ea2e")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("tony4twentys.Healing_Campfires", "Healing Campfires", "2.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class CampfireHealingMod : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
	public class CampfireLightPatch
	{
		public static void Postfix(Campfire __instance)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (syncedRespawnEnabled)
			{
				RespawnAllDeadPlayers(((Component)__instance).transform.position);
			}
		}
	}

	[HarmonyPatch(typeof(RunManager), "StartRun")]
	public class RunManagerStartPatch
	{
		public static void Postfix()
		{
			CampfireHealingMod component = Chainloader.ManagerObject.GetComponent<CampfireHealingMod>();
			if (!((Object)(object)component == (Object)null))
			{
				if (PhotonNetwork.IsMasterClient)
				{
					component.view.RPC("SyncHostSettings", (RpcTarget)1, new object[8] { HealPerSecond.Value, HealingRadius.Value, HealInjury.Value, HealDrowsy.Value, HealPoison.Value, HealCold.Value, HealCurse.Value, RespawnEnabled.Value });
				}
				tickInterval = 1f / Mathf.Max(0.1f, TickRateHz.Value);
				if (component.healCoroutine != null)
				{
					((MonoBehaviour)component).StopCoroutine(component.healCoroutine);
				}
				component.healCoroutine = ((MonoBehaviour)component).StartCoroutine(component.GlobalHealLoop());
			}
		}
	}

	[CompilerGenerated]
	private sealed class <GlobalHealLoop>d__25 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public CampfireHealingMod <>4__this;

		private float <cacheRefreshEvery>5__1;

		private bool <anyLit>5__2;

		private int <i>5__3;

		private Campfire <f>5__4;

		private float <r2>5__5;

		private List<Character>.Enumerator <>s__6;

		private Character <character>5__7;

		private Vector3 <p>5__8;

		private bool <inRange>5__9;

		private int <i>5__10;

		private Campfire <f>5__11;

		private Vector3 <d>5__12;

		private float <heal>5__13;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <GlobalHealLoop>d__25(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<f>5__4 = null;
			<>s__6 = default(List<Character>.Enumerator);
			<character>5__7 = null;
			<f>5__11 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Invalid comparison between Unknown and I4
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Invalid comparison between Unknown and I4
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				RebuildCampfireCache();
				<cacheRefreshEvery>5__1 = 5f;
				campfireRebuildTimer = <cacheRefreshEvery>5__1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			campfireRebuildTimer -= tickInterval;
			if (campfireRebuildTimer <= 0f)
			{
				RebuildCampfireCache();
				campfireRebuildTimer = <cacheRefreshEvery>5__1;
			}
			<anyLit>5__2 = false;
			<i>5__3 = 0;
			while (<i>5__3 < campfiresCache.Count)
			{
				<f>5__4 = campfiresCache[<i>5__3];
				if ((Object)(object)<f>5__4 != (Object)null && (int)<f>5__4.state == 1)
				{
					<anyLit>5__2 = true;
					break;
				}
				<f>5__4 = null;
				<i>5__3++;
			}
			if (<anyLit>5__2)
			{
				<r2>5__5 = syncedHealingRadius * syncedHealingRadius;
				<>s__6 = PlayerHandler.GetAllPlayerCharacters().GetEnumerator();
				try
				{
					while (<>s__6.MoveNext())
					{
						<character>5__7 = <>s__6.Current;
						if ((Object)(object)<character>5__7 == (Object)null || (Object)(object)<character>5__7.data == (Object)null || <character>5__7.data.dead)
						{
							continue;
						}
						<p>5__8 = <character>5__7.Center;
						<inRange>5__9 = false;
						<i>5__10 = 0;
						while (<i>5__10 < campfiresCache.Count)
						{
							<f>5__11 = campfiresCache[<i>5__10];
							if (!((Object)(object)<f>5__11 == (Object)null) && (int)<f>5__11.state == 1)
							{
								<d>5__12 = ((Component)<f>5__11).transform.position - <p>5__8;
								if (((Vector3)(ref <d>5__12)).sqrMagnitude <= <r2>5__5)
								{
									<inRange>5__9 = true;
									break;
								}
								<f>5__11 = null;
							}
							<i>5__10++;
						}
						if (<inRange>5__9)
						{
							<heal>5__13 = syncedHealPerSecond * tickInterval;
							if (syncedHealInjury)
							{
								<character>5__7.refs.afflictions.SubtractStatus((STATUSTYPE)0, <heal>5__13, false);
							}
							if (syncedHealDrowsy)
							{
								<character>5__7.refs.afflictions.SubtractStatus((STATUSTYPE)6, <heal>5__13, false);
							}
							if (syncedHealPoison)
							{
								<character>5__7.refs.afflictions.SubtractStatus((STATUSTYPE)3, <heal>5__13, false);
							}
							if (syncedHealCold)
							{
								<character>5__7.refs.afflictions.SubtractStatus((STATUSTYPE)2, <heal>5__13, false);
							}
							if (syncedHealCurse)
							{
								<character>5__7.refs.afflictions.SubtractStatus((STATUSTYPE)5, <heal>5__13, false);
							}
						}
						<character>5__7 = null;
					}
				}
				finally
				{
					((IDisposable)<>s__6).Dispose();
				}
				<>s__6 = default(List<Character>.Enumerator);
			}
			<>2__current = (object)new WaitForSeconds(tickInterval);
			<>1__state = 1;
			return true;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public static CampfireHealingMod Instance;

	private static ConfigEntry<float> HealingRadius;

	private static ConfigEntry<float> HealPerSecond;

	private static ConfigEntry<bool> HealInjury;

	private static ConfigEntry<bool> HealDrowsy;

	private static ConfigEntry<bool> HealPoison;

	private static ConfigEntry<bool> HealCold;

	private static ConfigEntry<bool> HealCurse;

	private static ConfigEntry<bool> RespawnEnabled;

	private static ConfigEntry<float> TickRateHz;

	private static float syncedHealPerSecond;

	private static float syncedHealingRadius;

	private static bool syncedHealInjury;

	private static bool syncedHealDrowsy;

	private static bool syncedHealPoison;

	private static bool syncedHealCold;

	private static bool syncedHealCurse;

	private static bool syncedRespawnEnabled;

	private PhotonView view;

	private Coroutine healCoroutine;

	private static readonly List<Campfire> campfiresCache = new List<Campfire>(64);

	private static float campfireRebuildTimer = 0f;

	private static float tickInterval = 0.5f;

	private void Awake()
	{
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Expected O, but got Unknown
		Instance = this;
		HealPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HealPerSecond", 0.025f, "Amount of status to subtract per second");
		HealingRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HealingRadius", 15f, "Distance from campfire to apply healing and respawn");
		TickRateHz = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TickRateHz", 2f, "Healing scan frequency (Hz). Lower to reduce CPU usage.");
		HealInjury = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealInjury", true, "Heal Injury affliction");
		HealDrowsy = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealDrowsy", false, "Heal Drowsy affliction");
		HealPoison = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealPoison", false, "Heal Poison affliction");
		HealCold = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealCold", true, "Heal Cold affliction");
		HealCurse = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealCurse", false, "Heal Curse affliction");
		RespawnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RespawnOnCampfire", true, "Whether lighting a campfire respawns all dead players");
		syncedHealPerSecond = HealPerSecond.Value;
		syncedHealingRadius = HealingRadius.Value;
		syncedHealInjury = HealInjury.Value;
		syncedHealDrowsy = HealDrowsy.Value;
		syncedHealPoison = HealPoison.Value;
		syncedHealCold = HealCold.Value;
		syncedHealCurse = HealCurse.Value;
		syncedRespawnEnabled = RespawnEnabled.Value;
		tickInterval = 1f / Mathf.Max(0.1f, TickRateHz.Value);
		view = ((Component)this).gameObject.AddComponent<PhotonView>();
		view.ViewID = 9999;
		Harmony val = new Harmony("tony4twentys.Healing_Campfires");
		val.PatchAll();
	}

	[PunRPC]
	public void SyncHostSettings(float healRate, float radius, bool injury, bool drowsy, bool poison, bool cold, bool curse, bool respawn)
	{
		syncedHealPerSecond = healRate;
		syncedHealingRadius = radius;
		syncedHealInjury = injury;
		syncedHealDrowsy = drowsy;
		syncedHealPoison = poison;
		syncedHealCold = cold;
		syncedHealCurse = curse;
		syncedRespawnEnabled = respawn;
	}

	[IteratorStateMachine(typeof(<GlobalHealLoop>d__25))]
	private IEnumerator GlobalHealLoop()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <GlobalHealLoop>d__25(0)
		{
			<>4__this = this
		};
	}

	private static void RebuildCampfireCache()
	{
		campfiresCache.Clear();
		Campfire[] array = Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0);
		if (array != null && array.Length != 0)
		{
			campfiresCache.AddRange(array);
		}
	}

	public static void RespawnAllDeadPlayers(Vector3 position)
	{
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		if (!PhotonNetwork.IsMasterClient)
		{
			return;
		}
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if ((Object)(object)allCharacter != (Object)null && (allCharacter.data.dead || allCharacter.data.fullyPassedOut))
			{
				((MonoBehaviourPun)allCharacter).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[2]
				{
					position + Vector3.up * 1.5f + Random.insideUnitSphere * 2f,
					true
				});
			}
		}
	}
}