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 System.Security;
using System.Security.Permissions;
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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[BepInPlugin("tony4twentys.Healing_Campfires", "Healing Campfires", "3.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class CampfireHealingMod : BaseUnityPlugin
{
internal static class CampfireHelper
{
private static float lastBlockingRefresh;
public static bool ShouldBlockStatus(STATUSTYPE statusType)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected I4, but got Unknown
return (int)statusType switch
{
0 => syncedBlockInjury,
1 => syncedBlockHunger,
2 => syncedBlockCold,
3 => syncedBlockPoison,
4 => syncedBlockCrab,
5 => syncedBlockCurse,
6 => syncedBlockDrowsy,
8 => syncedBlockHot,
9 => syncedBlockThorns,
10 => syncedBlockSpores,
11 => syncedBlockWeb,
_ => false,
};
}
public static bool IsPlayerNearCampfire(CharacterAfflictions afflictions)
{
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Invalid comparison between Unknown and I4
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)afflictions == (Object)null)
{
return false;
}
if (Time.time - lastBlockingRefresh > 10f)
{
lastBlockingRefresh = Time.time;
DiscoverCampfires();
}
Character component = ((Component)afflictions).GetComponent<Character>();
if ((Object)(object)component == (Object)null || (Object)(object)component.data == (Object)null || !component.IsLocal || component.data.dead || component.isBot)
{
return false;
}
if (component.refs == null)
{
return false;
}
Vector3 center = component.Center;
List<Campfire> list = new List<Campfire>(campfiresCache);
foreach (Campfire item in list)
{
if ((Object)(object)item == (Object)null)
{
continue;
}
try
{
bool flag = false;
try
{
flag = (int)item.state == 1;
}
catch
{
try
{
flag = item.Lit;
goto end_IL_00f2;
}
catch
{
}
goto end_IL_00de;
end_IL_00f2:;
}
if (flag)
{
float num = ((item.moraleBoostRadius > 0f) ? item.moraleBoostRadius : syncedHealingRadius);
if (num <= 0f)
{
num = syncedHealingRadius;
}
float num2 = num * num;
Vector3 position = ((Component)item).transform.position;
Vector3 val = position - center;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
if (sqrMagnitude <= num2)
{
return true;
}
}
end_IL_00de:;
}
catch
{
}
}
return false;
}
catch (Exception arg)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogError((object)$"Error in IsPlayerNearCampfire: {arg}");
}
return false;
}
}
public static void DiscoverCampfires()
{
try
{
Campfire[] array = Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0);
if (array == null || array.Length == 0)
{
return;
}
int num = 0;
int num2 = 0;
Campfire[] array2 = array;
foreach (Campfire val in array2)
{
if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
{
continue;
}
try
{
string name = val.GetName();
if (string.Equals(name, "PORTABLE STOVE", StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (!campfiresCache.Contains(val))
{
campfiresCache.Add(val);
num++;
if (syncedInfiniteBurnTime)
{
val.burnsFor = float.PositiveInfinity;
val.beenBurningFor = 0f;
}
}
else if (syncedInfiniteBurnTime && val.burnsFor != float.PositiveInfinity)
{
val.burnsFor = float.PositiveInfinity;
val.beenBurningFor = 0f;
num2++;
}
}
catch
{
}
}
if ((num > 0 || num2 > 0) && (Object)(object)Instance != (Object)null)
{
if (num > 0)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Discovered {num} new campfires (total: {campfiresCache.Count})");
}
if (num2 > 0)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"Updated {num2} campfires with infinite burn time");
}
}
}
catch (Exception ex)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Error discovering campfires: " + ex.Message));
}
}
}
}
[HarmonyPatch(typeof(Campfire), "Awake")]
public class CampfireAwakePatch
{
public static void Postfix(Campfire __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
try
{
string name = __instance.GetName();
bool flag = string.Equals(name, "PORTABLE STOVE", StringComparison.OrdinalIgnoreCase);
if (!flag)
{
campfiresCache.Add(__instance);
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)("Registered campfire: " + name));
}
}
if (syncedInfiniteBurnTime && !flag)
{
__instance.burnsFor = float.PositiveInfinity;
__instance.beenBurningFor = 0f;
}
}
catch (Exception arg)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogError((object)$"Error in CampfireAwakePatch: {arg}");
}
}
}
}
[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
public class CampfireLightPatch
{
public static void Postfix(Campfire __instance)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[PATCH FIRED] CampfireLightPatch: Campfire lit at {((Component)__instance).transform.position}, syncedRespawnEnabled={syncedRespawnEnabled}, IsMasterClient={PhotonNetwork.IsMasterClient}");
}
if (syncedRespawnEnabled)
{
if (PhotonNetwork.IsMasterClient)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[PATCH FIRED] CampfireLightPatch: Master client calling RespawnAllDeadPlayers");
}
RespawnAllDeadPlayers(((Component)__instance).transform.position);
}
else
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[PATCH FIRED] CampfireLightPatch: Not master client, but calling RespawnAllDeadPlayers anyway (fallback)");
}
RespawnAllDeadPlayers(((Component)__instance).transform.position);
}
}
else if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[PATCH FIRED] CampfireLightPatch: Respawn disabled, skipping");
}
}
}
[HarmonyPatch(typeof(Campfire), "Interact_CastFinished")]
public class CampfireInteractPatch
{
internal static Campfire lastLitCampfire;
internal static float lastLitTime;
public static void Postfix(Campfire __instance, Character interactor)
{
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance != (Object)null && __instance.Lit && syncedRespawnEnabled && (Object)(object)lastLitCampfire == (Object)(object)__instance && Time.time - lastLitTime < 0.1f)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[BACKUP PATCH FIRED] CampfireInteractPatch: Campfire lit via Interact_CastFinished at {((Component)__instance).transform.position}");
}
RespawnAllDeadPlayers(((Component)__instance).transform.position);
lastLitCampfire = null;
}
}
}
[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
public class CampfireLightRpcTracker
{
public static void Prefix(Campfire __instance)
{
CampfireInteractPatch.lastLitCampfire = __instance;
CampfireInteractPatch.lastLitTime = Time.time;
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
public class BlockNegativeStatusPatch
{
public static bool Prefix(STATUSTYPE statusType, float amount, CharacterAfflictions __instance)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!syncedBlockNegativeStatus)
{
return true;
}
if (!CampfireHelper.ShouldBlockStatus(statusType))
{
return true;
}
if (CampfireHelper.IsPlayerNearCampfire(__instance))
{
if ((Object)(object)Instance != (Object)null && amount > 0f)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"Blocked {statusType} status (amount: {amount})");
}
return false;
}
return true;
}
catch (Exception arg)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogError((object)$"Error in BlockNegativeStatusPatch: {arg}");
}
return true;
}
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AdjustStatus")]
public class BlockAdjustStatusPatch
{
public static bool Prefix(STATUSTYPE statusType, float amount, CharacterAfflictions __instance)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
try
{
if (amount <= 0f)
{
return true;
}
if (!syncedBlockNegativeStatus)
{
return true;
}
if (!CampfireHelper.ShouldBlockStatus(statusType))
{
return true;
}
if (CampfireHelper.IsPlayerNearCampfire(__instance))
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"Blocked AdjustStatus {statusType} (amount: {amount})");
}
return false;
}
return true;
}
catch (Exception arg)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogError((object)$"Error in BlockAdjustStatusPatch: {arg}");
}
return true;
}
}
}
[HarmonyPatch(typeof(RunManager), "StartRun")]
public class RunManagerStartPatch
{
public static void Postfix()
{
CampfireHealingMod component = Chainloader.ManagerObject.GetComponent<CampfireHealingMod>();
if ((Object)(object)component == (Object)null)
{
Debug.LogError((object)"[Healing Campfires] Instance not found!");
return;
}
((BaseUnityPlugin)component).Logger.LogInfo((object)"Run started - initializing Healing Campfires");
if ((Object)(object)component.view == (Object)null)
{
try
{
component.view = ((Component)component).gameObject.GetComponent<PhotonView>();
if ((Object)(object)component.view == (Object)null)
{
component.view = ((Component)component).gameObject.AddComponent<PhotonView>();
}
if (component.view.ViewID == 0)
{
component.view.ViewID = 999999;
}
}
catch (Exception ex)
{
((BaseUnityPlugin)component).Logger.LogWarning((object)("Could not setup PhotonView: " + ex.Message));
}
}
campfiresCache.Clear();
if (PhotonNetwork.IsMasterClient && (Object)(object)component.view != (Object)null)
{
component.view.RPC("SyncHostSettings", (RpcTarget)1, new object[27]
{
HealPerSecond.Value, HealingRadius.Value, HealInjury.Value, HealDrowsy.Value, HealPoison.Value, HealCold.Value, HealCurse.Value, RespawnEnabled.Value, BlockNegativeStatus.Value, InfiniteBurnTime.Value,
BlockInjury.Value, BlockHunger.Value, BlockCold.Value, BlockPoison.Value, BlockCrab.Value, BlockCurse.Value, BlockDrowsy.Value, BlockHot.Value, BlockThorns.Value, BlockSpores.Value,
BlockWeb.Value, HealHunger.Value, HealHot.Value, HealThorns.Value, HealSpores.Value, HealWeb.Value, HealCrab.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());
((BaseUnityPlugin)component).Logger.LogInfo((object)$"Healing loop started - BlockStatus: {syncedBlockNegativeStatus}, HealRate: {syncedHealPerSecond}/s");
}
}
[HarmonyPatch(typeof(EndScreen), "Start")]
public class EndScreenPatch
{
public static void Postfix()
{
campfiresCache.Clear();
}
}
[CompilerGenerated]
private sealed class <GlobalHealLoop>d__63 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public CampfireHealingMod <>4__this;
private List<Character> <players>5__1;
private List<Character>.Enumerator <>s__2;
private Character <character>5__3;
private Vector3 <playerPos>5__4;
private bool <inRange>5__5;
private List<Campfire> <campfiresToCheck>5__6;
private List<Campfire>.Enumerator <>s__7;
private Campfire <fire>5__8;
private bool <isLit>5__9;
private float <radius>5__10;
private float <r2>5__11;
private Vector3 <firePos>5__12;
private Vector3 <offset>5__13;
private float <distanceSq>5__14;
private float <heal>5__15;
private Exception <ex>5__16;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GlobalHealLoop>d__63(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<players>5__1 = null;
<>s__2 = default(List<Character>.Enumerator);
<character>5__3 = null;
<campfiresToCheck>5__6 = null;
<>s__7 = default(List<Campfire>.Enumerator);
<fire>5__8 = null;
<ex>5__16 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
//IL_05b5: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_0207: Invalid comparison between Unknown and I4
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Expected O, but got Unknown
//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Unknown result type (might be due to invalid IL or missing references)
//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"Healing loop started");
break;
case 2:
<>1__state = -1;
break;
case 3:
<>1__state = -1;
<players>5__1 = null;
break;
}
CleanupNullCampfires();
if (Time.time - lastCampfireSearch > 10f)
{
lastCampfireSearch = Time.time;
CampfireHelper.DiscoverCampfires();
}
<players>5__1 = PlayerHandler.GetAllPlayerCharacters();
if (<players>5__1 == null)
{
<>2__current = (object)new WaitForSeconds(tickInterval);
<>1__state = 2;
return true;
}
try
{
<>s__2 = <players>5__1.GetEnumerator();
try
{
while (<>s__2.MoveNext())
{
<character>5__3 = <>s__2.Current;
if ((Object)(object)<character>5__3 == (Object)null || (Object)(object)<character>5__3.data == (Object)null || <character>5__3.data.dead || !<character>5__3.IsLocal || <character>5__3.refs == null || (Object)(object)<character>5__3.refs.afflictions == (Object)null)
{
continue;
}
<playerPos>5__4 = <character>5__3.Center;
<inRange>5__5 = false;
<campfiresToCheck>5__6 = new List<Campfire>(campfiresCache);
<>s__7 = <campfiresToCheck>5__6.GetEnumerator();
try
{
while (<>s__7.MoveNext())
{
<fire>5__8 = <>s__7.Current;
if ((Object)(object)<fire>5__8 == (Object)null)
{
continue;
}
try
{
<isLit>5__9 = false;
try
{
<isLit>5__9 = (int)<fire>5__8.state == 1;
}
catch
{
try
{
<isLit>5__9 = <fire>5__8.Lit;
goto end_IL_0211;
}
catch
{
}
goto end_IL_01f1;
end_IL_0211:;
}
if (<isLit>5__9)
{
<radius>5__10 = ((<fire>5__8.moraleBoostRadius > 0f) ? <fire>5__8.moraleBoostRadius : syncedHealingRadius);
if (<radius>5__10 <= 0f)
{
<radius>5__10 = syncedHealingRadius;
}
<r2>5__11 = <radius>5__10 * <radius>5__10;
<firePos>5__12 = ((Component)<fire>5__8).transform.position;
<offset>5__13 = <firePos>5__12 - <playerPos>5__4;
<distanceSq>5__14 = ((Vector3)(ref <offset>5__13)).sqrMagnitude;
if (<distanceSq>5__14 <= <r2>5__11)
{
<inRange>5__5 = true;
break;
}
}
goto IL_0307;
end_IL_01f1:;
}
catch
{
}
continue;
IL_0307:
<fire>5__8 = null;
}
}
finally
{
((IDisposable)<>s__7).Dispose();
}
<>s__7 = default(List<Campfire>.Enumerator);
if (<inRange>5__5)
{
<heal>5__15 = syncedHealPerSecond * tickInterval;
if (syncedHealInjury)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)0, <heal>5__15, false, false);
}
if (syncedHealDrowsy)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)6, <heal>5__15, false, false);
}
if (syncedHealPoison)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)3, <heal>5__15, false, false);
}
if (syncedHealCold)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)2, <heal>5__15, false, false);
}
if (syncedHealCurse)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)5, <heal>5__15, false, false);
}
if (syncedHealHunger)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)1, <heal>5__15, false, false);
}
if (syncedHealHot)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)8, <heal>5__15, false, false);
}
if (syncedHealThorns)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)9, <heal>5__15, false, false);
}
if (syncedHealSpores)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)10, <heal>5__15, false, false);
}
if (syncedHealWeb)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)11, <heal>5__15, false, false);
}
if (syncedHealCrab)
{
<character>5__3.refs.afflictions.SubtractStatus((STATUSTYPE)4, <heal>5__15, false, false);
}
}
<campfiresToCheck>5__6 = null;
<character>5__3 = null;
}
}
finally
{
((IDisposable)<>s__2).Dispose();
}
<>s__2 = default(List<Character>.Enumerator);
}
catch (Exception ex)
{
<ex>5__16 = ex;
((BaseUnityPlugin)<>4__this).Logger.LogError((object)$"Error in healing loop: {<ex>5__16}");
}
<>2__current = (object)new WaitForSeconds(tickInterval);
<>1__state = 3;
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> HealHunger;
private static ConfigEntry<bool> HealHot;
private static ConfigEntry<bool> HealThorns;
private static ConfigEntry<bool> HealSpores;
private static ConfigEntry<bool> HealWeb;
private static ConfigEntry<bool> HealCrab;
private static ConfigEntry<bool> RespawnEnabled;
private static ConfigEntry<float> TickRateHz;
private static ConfigEntry<bool> BlockNegativeStatus;
private static ConfigEntry<bool> InfiniteBurnTime;
private static ConfigEntry<bool> BlockInjury;
private static ConfigEntry<bool> BlockHunger;
private static ConfigEntry<bool> BlockCold;
private static ConfigEntry<bool> BlockPoison;
private static ConfigEntry<bool> BlockCrab;
private static ConfigEntry<bool> BlockCurse;
private static ConfigEntry<bool> BlockDrowsy;
private static ConfigEntry<bool> BlockHot;
private static ConfigEntry<bool> BlockThorns;
private static ConfigEntry<bool> BlockSpores;
private static ConfigEntry<bool> BlockWeb;
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 syncedHealHunger;
private static bool syncedHealHot;
private static bool syncedHealThorns;
private static bool syncedHealSpores;
private static bool syncedHealWeb;
private static bool syncedHealCrab;
private static bool syncedRespawnEnabled;
private static bool syncedBlockNegativeStatus;
private static bool syncedInfiniteBurnTime;
private static bool syncedBlockInjury;
private static bool syncedBlockHunger;
private static bool syncedBlockCold;
private static bool syncedBlockPoison;
private static bool syncedBlockCrab;
private static bool syncedBlockCurse;
private static bool syncedBlockDrowsy;
private static bool syncedBlockHot;
private static bool syncedBlockThorns;
private static bool syncedBlockSpores;
private static bool syncedBlockWeb;
private PhotonView view;
private Coroutine healCoroutine;
private static readonly HashSet<Campfire> campfiresCache = new HashSet<Campfire>();
private static float tickInterval = 0.5f;
private static float lastCampfireSearch = 0f;
private void Awake()
{
//IL_054d: Unknown result type (might be due to invalid IL or missing references)
//IL_0553: Expected O, but got Unknown
try
{
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", true, "Heal Drowsy affliction");
HealPoison = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealPoison", true, "Heal Poison affliction");
HealCold = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealCold", true, "Heal Cold affliction");
HealCurse = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealCurse", true, "Heal Curse affliction");
HealHunger = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealHunger", true, "Heal Hunger affliction");
HealHot = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealHot", true, "Heal Hot affliction");
HealThorns = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealThorns", true, "Heal Thorns affliction");
HealSpores = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealSpores", true, "Heal Spores affliction");
HealWeb = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealWeb", true, "Heal Web affliction");
HealCrab = ((BaseUnityPlugin)this).Config.Bind<bool>("Afflictions", "HealCrab", true, "Heal Crab affliction");
RespawnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RespawnOnCampfire", true, "Whether lighting a campfire respawns all dead players");
BlockNegativeStatus = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "BlockNegativeStatus", true, "Enable blocking negative status effects when near campfire");
InfiniteBurnTime = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "InfiniteBurnTime", true, "Make campfires burn forever (except portable stoves)");
BlockInjury = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockInjury", true, "Block Injury affliction");
BlockHunger = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockHunger", true, "Block Hunger affliction");
BlockCold = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockCold", true, "Block Cold affliction");
BlockPoison = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockPoison", true, "Block Poison affliction");
BlockCrab = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockCrab", true, "Block Crab affliction");
BlockCurse = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockCurse", true, "Block Curse affliction");
BlockDrowsy = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockDrowsy", true, "Block Drowsy affliction");
BlockHot = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockHot", true, "Block Hot affliction");
BlockThorns = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockThorns", true, "Block Thorns affliction");
BlockSpores = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockSpores", true, "Block Spores affliction");
BlockWeb = ((BaseUnityPlugin)this).Config.Bind<bool>("Block Afflictions", "BlockWeb", true, "Block Web affliction");
syncedHealPerSecond = HealPerSecond.Value;
syncedHealingRadius = HealingRadius.Value;
syncedHealInjury = HealInjury.Value;
syncedHealDrowsy = HealDrowsy.Value;
syncedHealPoison = HealPoison.Value;
syncedHealCold = HealCold.Value;
syncedHealCurse = HealCurse.Value;
syncedHealHunger = HealHunger.Value;
syncedHealHot = HealHot.Value;
syncedHealThorns = HealThorns.Value;
syncedHealSpores = HealSpores.Value;
syncedHealWeb = HealWeb.Value;
syncedHealCrab = HealCrab.Value;
syncedRespawnEnabled = RespawnEnabled.Value;
syncedBlockNegativeStatus = BlockNegativeStatus.Value;
syncedInfiniteBurnTime = InfiniteBurnTime.Value;
syncedBlockInjury = BlockInjury.Value;
syncedBlockHunger = BlockHunger.Value;
syncedBlockCold = BlockCold.Value;
syncedBlockPoison = BlockPoison.Value;
syncedBlockCrab = BlockCrab.Value;
syncedBlockCurse = BlockCurse.Value;
syncedBlockDrowsy = BlockDrowsy.Value;
syncedBlockHot = BlockHot.Value;
syncedBlockThorns = BlockThorns.Value;
syncedBlockSpores = BlockSpores.Value;
syncedBlockWeb = BlockWeb.Value;
tickInterval = 1f / Mathf.Max(0.1f, TickRateHz.Value);
Harmony val = new Harmony("tony4twentys.Healing_Campfires");
val.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Healing Campfires v3.0.0 initialized!");
((BaseUnityPlugin)this).Logger.LogInfo((object)$"BlockNegativeStatus: {BlockNegativeStatus.Value}, InfiniteBurnTime: {InfiniteBurnTime.Value}");
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Healing enabled - Injury: {HealInjury.Value}, Hunger: {HealHunger.Value}, Cold: {HealCold.Value}");
((BaseUnityPlugin)this).Logger.LogInfo((object)$"HealPerSecond: {HealPerSecond.Value}, HealingRadius: {HealingRadius.Value}");
}
catch (Exception arg)
{
Debug.LogError((object)$"[Healing Campfires] Error in Awake: {arg}");
if (((BaseUnityPlugin)this).Logger != null)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Error in Awake: {arg}");
}
}
}
[PunRPC]
public void SyncHostSettings(float healRate, float radius, bool injury, bool drowsy, bool poison, bool cold, bool curse, bool respawn, bool blockStatus, bool infiniteBurn, bool blockInjury, bool blockHunger, bool blockCold, bool blockPoison, bool blockCrab, bool blockCurse, bool blockDrowsy, bool blockHot, bool blockThorns, bool blockSpores, bool blockWeb, bool healHunger, bool healHot, bool healThorns, bool healSpores, bool healWeb, bool healCrab)
{
syncedHealPerSecond = healRate;
syncedHealingRadius = radius;
syncedHealInjury = injury;
syncedHealDrowsy = drowsy;
syncedHealPoison = poison;
syncedHealCold = cold;
syncedHealCurse = curse;
syncedRespawnEnabled = respawn;
syncedBlockNegativeStatus = blockStatus;
syncedInfiniteBurnTime = infiniteBurn;
syncedBlockInjury = blockInjury;
syncedBlockHunger = blockHunger;
syncedBlockCold = blockCold;
syncedBlockPoison = blockPoison;
syncedBlockCrab = blockCrab;
syncedBlockCurse = blockCurse;
syncedBlockDrowsy = blockDrowsy;
syncedBlockHot = blockHot;
syncedBlockThorns = blockThorns;
syncedBlockSpores = blockSpores;
syncedBlockWeb = blockWeb;
syncedHealHunger = healHunger;
syncedHealHot = healHot;
syncedHealThorns = healThorns;
syncedHealSpores = healSpores;
syncedHealWeb = healWeb;
syncedHealCrab = healCrab;
}
[IteratorStateMachine(typeof(<GlobalHealLoop>d__63))]
private IEnumerator GlobalHealLoop()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <GlobalHealLoop>d__63(0)
{
<>4__this = this
};
}
private static void CleanupNullCampfires()
{
if (campfiresCache.Count == 0)
{
return;
}
List<Campfire> list = new List<Campfire>(campfiresCache.Count);
foreach (Campfire item in campfiresCache)
{
try
{
if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).transform != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null && ((Component)item).gameObject.activeInHierarchy)
{
list.Add(item);
}
}
catch
{
}
}
if (list.Count == campfiresCache.Count)
{
return;
}
campfiresCache.Clear();
foreach (Campfire item2 in list)
{
campfiresCache.Add(item2);
}
}
public static void RespawnAllDeadPlayers(Vector3 position)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_0296: Unknown result type (might be due to invalid IL or missing references)
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Unknown result type (might be due to invalid IL or missing references)
//IL_0326: Unknown result type (might be due to invalid IL or missing references)
//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"RespawnAllDeadPlayers called at position {position}, IsMasterClient={PhotonNetwork.IsMasterClient}");
}
if (!PhotonNetwork.IsMasterClient && (Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)"RespawnAllDeadPlayers: Not master client, but allowing anyway (patch fired on client)");
}
int num = 0;
int num2 = 0;
List<Character> allCharacters = Character.AllCharacters;
if (allCharacters == null)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)"RespawnAllDeadPlayers: Character.AllCharacters is null!");
}
return;
}
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"RespawnAllDeadPlayers: Checking {allCharacters.Count} characters (IsMasterClient={PhotonNetwork.IsMasterClient})");
}
foreach (Character item in allCharacters)
{
num2++;
if ((Object)(object)item == (Object)null)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"RespawnAllDeadPlayers: Character {num2} is null");
}
continue;
}
if ((Object)(object)item.data == (Object)null)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"RespawnAllDeadPlayers: Character {num2} has null data");
}
continue;
}
if (item.isBot)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"RespawnAllDeadPlayers: Character {num2} is bot, skipping");
}
continue;
}
bool dead = item.data.dead;
bool fullyPassedOut = item.data.fullyPassedOut;
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"RespawnAllDeadPlayers: Character {num2} - dead={dead}, passedOut={fullyPassedOut}");
}
if (!(dead || fullyPassedOut))
{
continue;
}
if ((Object)(object)((MonoBehaviourPun)item).photonView == (Object)null)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"RespawnAllDeadPlayers: Character {num2} has no PhotonView");
}
continue;
}
try
{
Vector3 val = position + Vector3.up * 1.5f + Random.insideUnitSphere * 2f;
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)string.Format("RespawnAllDeadPlayers: Attempting to respawn {0} at {1} (from {2})", ((Object)((Component)item).gameObject).name, val, PhotonNetwork.IsMasterClient ? "HOST" : "CLIENT"));
}
((MonoBehaviourPun)item).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[2] { val, true });
num++;
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)("RespawnAllDeadPlayers: Successfully called RPC for " + ((Object)((Component)item).gameObject).name));
}
}
catch (Exception arg)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogError((object)$"Failed to respawn {((Object)((Component)item).gameObject).name}: {arg}");
}
}
}
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)string.Format("RespawnAllDeadPlayers: Checked {0} characters, respawned {1} player(s) (from {2})", num2, num, PhotonNetwork.IsMasterClient ? "HOST" : "CLIENT"));
}
}
}