Decompiled source of Hikers Hunger v2.0.0

tony4twentys-Hikers Hunger.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Hikers Hunger")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Hikers Hunger")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("99b406ad-6d25-4637-9908-9ab308ceb06e")]
[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")]
namespace HikersHunger;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("tony4twentys.Hikers_Hunger", "Hikers Hunger", "2.0.0")]
public class HikersHungerPlugin : BaseUnityPlugin, IInRoomCallbacks, IMatchmakingCallbacks, IOnEventCallback
{
	[Serializable]
	public struct HostCfg
	{
		public bool manualCannibalSelection;

		public int initialSelectionDelay;

		public int postSelectionDelay;

		public bool enableCustomEatTime;

		public float customEatTime;

		public bool constantCannibal;

		public float safeZoneDelay;
	}

	[HarmonyPatch(typeof(Action_RestoreHunger), "RunAction")]
	public class RestoreHungerPatch
	{
		private static bool Prefix(Action_RestoreHunger __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<Character>() != (Object)null)
			{
				int cannibalViewID = Instance.cannibalViewID;
				Character localCharacter = Character.localCharacter;
				int? obj;
				if (localCharacter == null)
				{
					obj = null;
				}
				else
				{
					PhotonView photonView = ((MonoBehaviourPun)localCharacter).photonView;
					obj = ((photonView != null) ? new int?(photonView.ViewID) : null);
				}
				if (cannibalViewID == obj)
				{
					return true;
				}
			}
			else
			{
				int cannibalViewID2 = Instance.cannibalViewID;
				Character localCharacter2 = Character.localCharacter;
				int? obj2;
				if (localCharacter2 == null)
				{
					obj2 = null;
				}
				else
				{
					PhotonView photonView2 = ((MonoBehaviourPun)localCharacter2).photonView;
					obj2 = ((photonView2 != null) ? new int?(photonView2.ViewID) : null);
				}
				if (cannibalViewID2 == obj2)
				{
					return false;
				}
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(RunManager), "StartRun")]
	public class StartRunPatch
	{
		private static void Postfix()
		{
			if (!((Object)(object)Singleton<MapHandler>.Instance == (Object)null))
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[HikersHunger] Run started!");
				((MonoBehaviour)Instance).StartCoroutine(Instance.SelectRandomCannibalAfterDelay());
			}
		}
	}

	[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
	public class CampfireLight_RpcPatch
	{
		private static void Postfix(Campfire __instance)
		{
			Instance.fireCount++;
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"[HikersHunger] Campfire lit! Total fires: {Instance.fireCount}");
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!allCharacter.isBot && !allCharacter.data.dead && (Object)(object)allCharacter.refs?.customization != (Object)null && allCharacter.IsLocal)
				{
					allCharacter.refs.customization.BecomeHuman();
				}
			}
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[HikersHunger] All players restored to human appearance");
			Instance.ForceRefreshSafeZoneStatus();
			Instance.SelectNewCannibalAtCampfire();
		}
	}

	[HarmonyPatch(typeof(CharacterInteractible), "GetInteractTime")]
	public class CharacterInteractible_GetInteractTime_Patch
	{
		private static void Postfix(CharacterInteractible __instance, Character interactor, ref float __result)
		{
			if (Synced.enableCustomEatTime && Instance.cannibalViewID == ((MonoBehaviourPun)interactor).photonView.ViewID)
			{
				if (IsCharacterNearCampfire(interactor))
				{
					__result = 999f;
				}
				else if (Instance.inSafeZoneDelay)
				{
					((BaseUnityPlugin)Instance).Logger.LogDebug((object)"[HikersHunger] Blocking eating during safe zone delay period");
					__result = 999f;
				}
				else
				{
					__result = Synced.customEatTime;
				}
			}
		}
	}

	[HarmonyPatch(typeof(CharacterInteractible), "GetEaten")]
	public class CharacterInteractible_GetEaten_Patch
	{
		private static bool Prefix(CharacterInteractible __instance, Character eater)
		{
			if (Instance.cannibalViewID == ((MonoBehaviourPun)eater).photonView.ViewID)
			{
				if (IsCharacterNearCampfire(eater))
				{
					((BaseUnityPlugin)Instance).Logger.LogWarning((object)"[HikersHunger] BLOCKED: Cannibal attempted to eat player in safe zone!");
					return false;
				}
				if (Instance.inSafeZoneDelay)
				{
					((BaseUnityPlugin)Instance).Logger.LogWarning((object)"[HikersHunger] BLOCKED: Cannibal attempted to eat player during safe zone delay!");
					((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"[HikersHunger] Safe zone delay state: inSafeZoneDelay={Instance.inSafeZoneDelay}, inSafeZone={Instance.inSafeZone}");
					return false;
				}
			}
			return true;
		}

		private static void Postfix(CharacterInteractible __instance, Character eater)
		{
			if (Instance.cannibalViewID == ((MonoBehaviourPun)eater).photonView.ViewID)
			{
				eater.refs.afflictions.SetStatus((STATUSTYPE)5, 0f);
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[HikersHunger] Removed curse from cannibal after eating player");
			}
		}
	}

	[HarmonyPatch(typeof(CharacterInteractible), "IsConstantlyInteractable")]
	public class CharacterInteractible_IsConstantlyInteractable_Patch
	{
		private static bool Postfix(bool __result, CharacterInteractible __instance, Character interactor)
		{
			if (__result && Instance.cannibalViewID == ((MonoBehaviourPun)interactor).photonView.ViewID)
			{
				if (IsCharacterNearCampfire(interactor))
				{
					return false;
				}
				if (Instance.inSafeZoneDelay)
				{
					((BaseUnityPlugin)Instance).Logger.LogDebug((object)"[HikersHunger] Blocking interaction during safe zone delay period");
					return false;
				}
			}
			return __result;
		}
	}

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

		private object <>2__current;

		public int viewID;

		public HikersHungerPlugin <>4__this;

		private float <delay>5__1;

		private float <elapsed>5__2;

		private Exception <ex>5__3;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<ex>5__3 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<delay>5__1 = Synced.postSelectionDelay;
				<elapsed>5__2 = 0f;
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[HikersHunger] Waiting {<delay>5__1} seconds before granting powers...");
				break;
			case 1:
				<>1__state = -1;
				<elapsed>5__2 += 1f;
				break;
			}
			if (<elapsed>5__2 < <delay>5__1)
			{
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			}
			try
			{
				<>4__this.manager.SetRoomProperty("cannibalViewId", (object)viewID);
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[HikersHunger] Cannibal powers now active!");
			}
			catch (Exception ex)
			{
				<ex>5__3 = ex;
				((BaseUnityPlugin)<>4__this).Logger.LogError((object)("[HikersHunger] Failed to set room property: " + <ex>5__3.Message));
			}
			return false;
		}

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

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

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

		private object <>2__current;

		public HikersHungerPlugin <>4__this;

		private float <delay>5__1;

		private float <elapsed>5__2;

		private Exception <ex>5__3;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<ex>5__3 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<delay>5__1 = Synced.safeZoneDelay;
				<elapsed>5__2 = 0f;
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[HikersHunger] Starting {<delay>5__1}s safe zone delay before restoring powers...");
				break;
			case 1:
				<>1__state = -1;
				<elapsed>5__2 += 0.5f;
				if (IsCharacterNearCampfire(Character.localCharacter))
				{
					<>4__this.inSafeZone = true;
					((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[HikersHunger] Re-entered safe zone during delay - powers remain revoked");
					return false;
				}
				if (Mathf.FloorToInt(<elapsed>5__2) % 5 == 0)
				{
					((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[HikersHunger] Safe zone delay: {<elapsed>5__2:F1}s / {<delay>5__1}s remaining");
				}
				break;
			}
			if (<elapsed>5__2 < <delay>5__1 && !<>4__this.inSafeZone)
			{
				<>2__current = (object)new WaitForSeconds(0.5f);
				<>1__state = 1;
				return true;
			}
			if (!<>4__this.inSafeZone && <>4__this.IsLocalPlayerCannibal())
			{
				<>4__this.inSafeZoneDelay = false;
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[HikersHunger] Safe zone delay completed - powers restored");
				if (<>4__this.cannibalViewID != -1)
				{
					int cannibalViewID = <>4__this.cannibalViewID;
					Character localCharacter = Character.localCharacter;
					int? obj;
					if (localCharacter == null)
					{
						obj = null;
					}
					else
					{
						PhotonView photonView = ((MonoBehaviourPun)localCharacter).photonView;
						obj = ((photonView != null) ? new int?(photonView.ViewID) : null);
					}
					if (cannibalViewID == obj)
					{
						((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[HikersHunger] Cannibal was reselected during delay (ViewID: {<>4__this.cannibalViewID}) - updating room property");
						try
						{
							<>4__this.manager.SetRoomProperty("cannibalViewId", (object)<>4__this.cannibalViewID);
							((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[HikersHunger] Room property updated after safe zone delay completion");
						}
						catch (Exception ex)
						{
							<ex>5__3 = ex;
							((BaseUnityPlugin)<>4__this).Logger.LogError((object)("[HikersHunger] Failed to update room property after delay: " + <ex>5__3.Message));
						}
						goto IL_02a8;
					}
				}
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[HikersHunger] No room property update needed - cannibal not reselected during delay");
				goto IL_02a8;
			}
			goto IL_02b5;
			IL_02a8:
			<>4__this.GrantCannibalPowers();
			goto IL_02b5;
			IL_02b5:
			return false;
		}

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

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

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

		private object <>2__current;

		public HikersHungerPlugin <>4__this;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			<>4__this.CheckAllPlayersSafeZoneStatus();
			<>2__current = (object)new WaitForSeconds(1f);
			<>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();
		}
	}

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

		private object <>2__current;

		public HikersHungerPlugin <>4__this;

		private float <delay>5__1;

		private float <elapsed>5__2;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<delay>5__1 = Synced.initialSelectionDelay;
				<elapsed>5__2 = 0f;
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[HikersHunger] Waiting {<delay>5__1} seconds before selecting cannibal...");
				break;
			case 1:
				<>1__state = -1;
				<elapsed>5__2 += 1f;
				break;
			}
			if (<elapsed>5__2 < <delay>5__1)
			{
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			if (Synced.manualCannibalSelection)
			{
				<>4__this.isWaitingForCannibalSelection = true;
				<>4__this.showCannibalSelectionGUI = true;
			}
			else
			{
				<>4__this.SelectRandomCannibal();
			}
			return false;
		}

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

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

	private const string ROOM_CFG_KEY = "HIKERS_HUNGER_CFG_V1";

	private const float CAMPFIRE_SAFE_RADIUS = 15f;

	private const float DEFAULT_SAFE_ZONE_DELAY = 30f;

	public static HikersHungerPlugin Instance;

	private int cannibalViewID = -1;

	private int fireCount = 0;

	private bool showCannibalSelectionGUI = false;

	private bool isWaitingForCannibalSelection = false;

	private bool cannibalPowersActive = false;

	private float safeZoneExitTime = 0f;

	private bool inSafeZone = false;

	private bool inSafeZoneDelay = false;

	private ConfigEntry<bool> manualCannibalSelection;

	private ConfigEntry<int> initialSelectionDelay;

	private ConfigEntry<int> postSelectionDelay;

	private ConfigEntry<bool> enableCustomEatTime;

	private ConfigEntry<float> customEatTime;

	private ConfigEntry<bool> constantCannibal;

	private ConfigEntry<float> safeZoneDelay;

	public static HostCfg Synced;

	private PhotonScopedManager manager;

	private Harmony harmony;

	private Coroutine safeZoneCheckCoroutine;

	private Coroutine powerRestorationCoroutine;

	private void Awake()
	{
		Instance = this;
		InitializeConfiguration();
		InitializeHarmony();
		InitializePhotonManager();
		StartSafeZoneMonitoring();
		SceneManager.activeSceneChanged += OnSceneChanged;
		UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Plugin initialized successfully");
	}

	private void InitializeConfiguration()
	{
		manualCannibalSelection = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ManualCannibalSelection", false, "When enabled, the host can manually select who becomes the cannibal using a GUI instead of random selection.");
		initialSelectionDelay = ((BaseUnityPlugin)this).Config.Bind<int>("General", "InitialSelectionDelay", 20, "The initial delay (in seconds) before the game starts attempting to select a cannibal.");
		postSelectionDelay = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PostSelectionDelay", 120, "The delay (in seconds) after selecting a cannibal before actually giving them cannibal powers.");
		enableCustomEatTime = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableCustomEatTime", false, "When enabled, allows hosts to customize how long it takes to eat players.");
		customEatTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CustomEatTime", 0.01f, "The time (in seconds) it takes to eat a player. Lower values = faster eating. 0.01 = almost instant.");
		constantCannibal = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ConstantCannibal", false, "When enabled, the first person chosen as cannibal remains cannibal for the entire game until a new run starts.");
		safeZoneDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SafeZoneDelay", 30f, "The delay (in seconds) after leaving a safe zone before cannibal powers are restored.");
		Synced = BuildFromHostConfig();
		manualCannibalSelection.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		initialSelectionDelay.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		postSelectionDelay.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		enableCustomEatTime.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		customEatTime.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		constantCannibal.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		safeZoneDelay.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
	}

	private void InitializeHarmony()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		harmony = new Harmony("tony4twentys.Hikers_Hunger");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Harmony patches applied");
	}

	private void InitializePhotonManager()
	{
		manager = PhotonCustomPropsUtilsPlugin.GetManager("tony4twentys.Hikers_Hunger");
		manager.RegisterRoomProperty<int>("cannibalViewId", (RoomEventType)2, (Action<int>)delegate(int value)
		{
			cannibalViewID = value;
			OnCannibalChanged();
		});
	}

	private void StartSafeZoneMonitoring()
	{
		if (safeZoneCheckCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(safeZoneCheckCoroutine);
		}
		safeZoneCheckCoroutine = ((MonoBehaviour)this).StartCoroutine(SafeZoneMonitoringLoop());
	}

	private void OnCannibalChanged()
	{
		if (cannibalViewID == -1)
		{
			return;
		}
		Character characterByViewID = GetCharacterByViewID(cannibalViewID);
		if ((Object)(object)characterByViewID != (Object)null)
		{
			ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
			Player owner = characterByViewID.refs.view.Owner;
			logger.LogInfo((object)("[HikersHunger] " + (((owner != null) ? owner.NickName : null) ?? "Unknown") + " is now the cannibal"));
		}
		if (IsLocalPlayerCannibal())
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HikersHunger] Local player is now cannibal - checking safe zone delay state: inSafeZoneDelay={inSafeZoneDelay}");
			if (inSafeZoneDelay)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Local player is cannibal but still in safe zone delay - powers will be granted when delay completes");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] No safe zone delay active - granting powers immediately");
			GrantCannibalPowers();
		}
	}

	private Character GetCharacterByViewID(int viewID)
	{
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if (allCharacter != null)
			{
				CharacterRefs refs = allCharacter.refs;
				int? obj;
				if (refs == null)
				{
					obj = null;
				}
				else
				{
					PhotonView view = refs.view;
					obj = ((view != null) ? new int?(view.ViewID) : null);
				}
				if (obj == viewID)
				{
					return allCharacter;
				}
			}
		}
		return null;
	}

	private bool IsLocalPlayerCannibal()
	{
		int num = cannibalViewID;
		Character localCharacter = Character.localCharacter;
		int? obj;
		if (localCharacter == null)
		{
			obj = null;
		}
		else
		{
			PhotonView photonView = ((MonoBehaviourPun)localCharacter).photonView;
			obj = ((photonView != null) ? new int?(photonView.ViewID) : null);
		}
		return num == obj;
	}

	private void GrantCannibalPowers()
	{
		if (IsLocalPlayerCannibal())
		{
			UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = -1f;
			cannibalPowersActive = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Local player cannibal powers granted");
			CheckSafeZoneStatus();
		}
	}

	private void RevokeCannibalPowers()
	{
		if (IsLocalPlayerCannibal())
		{
			UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
			cannibalPowersActive = false;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Local player cannibal powers revoked");
		}
	}

	private void StripCannibalPowers()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Stripping cannibal powers from all players");
		UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
		if (IsLocalPlayerCannibal())
		{
			cannibalPowersActive = false;
			inSafeZone = false;
			safeZoneExitTime = 0f;
			if (powerRestorationCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(powerRestorationCoroutine);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HikersHunger] Local cannibal powers stripped (inSafeZoneDelay={inSafeZoneDelay})");
		}
	}

	private void CheckSafeZoneStatus()
	{
		if (!IsLocalPlayerCannibal())
		{
			return;
		}
		bool flag = IsCharacterNearCampfire(Character.localCharacter);
		((BaseUnityPlugin)this).Logger.LogDebug((object)$"[HikersHunger] Safe zone check: currentlyInSafeZone={flag}, inSafeZone={inSafeZone}");
		if (flag && !inSafeZone)
		{
			inSafeZone = true;
			RevokeCannibalPowers();
			safeZoneExitTime = 0f;
			if (powerRestorationCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(powerRestorationCoroutine);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Entered campfire safe zone - powers revoked");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HikersHunger] Safe zone state: inSafeZone={inSafeZone}, inSafeZoneDelay={inSafeZoneDelay}");
		}
		else if (!flag && inSafeZone)
		{
			inSafeZone = false;
			inSafeZoneDelay = true;
			safeZoneExitTime = Time.time;
			if (powerRestorationCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(powerRestorationCoroutine);
			}
			powerRestorationCoroutine = ((MonoBehaviour)this).StartCoroutine(RestorePowersAfterDelay());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Exited campfire safe zone - starting power restoration timer");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HikersHunger] Safe zone state: inSafeZone={inSafeZone}, inSafeZoneDelay={inSafeZoneDelay}");
		}
	}

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

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

	private void CheckAllPlayersSafeZoneStatus()
	{
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if ((Object)(object)allCharacter == (Object)null || allCharacter.isBot || allCharacter.data.dead)
			{
				continue;
			}
			CharacterRefs refs = allCharacter.refs;
			int? obj;
			if (refs == null)
			{
				obj = null;
			}
			else
			{
				PhotonView view = refs.view;
				obj = ((view != null) ? new int?(view.ViewID) : null);
			}
			if (obj == cannibalViewID)
			{
				if (allCharacter.IsLocal)
				{
					CheckSafeZoneStatus();
				}
				else
				{
					CheckRemoteCannibalSafeZoneStatus(allCharacter);
				}
			}
		}
	}

	private void CheckRemoteCannibalSafeZoneStatus(Character remoteCannibal)
	{
		bool flag = IsCharacterNearCampfire(remoteCannibal);
	}

	private void ForceRefreshSafeZoneStatus()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Force refreshing safe zone status for all players");
		CheckAllPlayersSafeZoneStatus();
		if (IsLocalPlayerCannibal())
		{
			CheckSafeZoneStatus();
		}
	}

	public static bool IsCharacterNearCampfire(Character character)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null)
		{
			return false;
		}
		Vector3 center = character.Center;
		float num = 225f;
		try
		{
			Campfire[] array = Object.FindObjectsOfType<Campfire>();
			if (array != null && array.Length != 0)
			{
				HikersHungerPlugin instance = Instance;
				if (instance != null)
				{
					ManualLogSource logger = ((BaseUnityPlugin)instance).Logger;
					if (logger != null)
					{
						object arg = array.Length;
						CharacterRefs refs = character.refs;
						object obj;
						if (refs == null)
						{
							obj = null;
						}
						else
						{
							PhotonView view = refs.view;
							if (view == null)
							{
								obj = null;
							}
							else
							{
								Player owner = view.Owner;
								obj = ((owner != null) ? owner.NickName : null);
							}
						}
						if (obj == null)
						{
							obj = "Unknown";
						}
						logger.LogDebug((object)$"[HikersHunger] Found {arg} campfires, checking proximity for {obj}");
					}
				}
				for (int i = 0; i < array.Length; i++)
				{
					Campfire val = array[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Vector3 val2 = ((Component)val).transform.position - center;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (!(sqrMagnitude <= num))
					{
						continue;
					}
					HikersHungerPlugin instance2 = Instance;
					if (instance2 != null)
					{
						ManualLogSource logger2 = ((BaseUnityPlugin)instance2).Logger;
						if (logger2 != null)
						{
							CharacterRefs refs2 = character.refs;
							object obj2;
							if (refs2 == null)
							{
								obj2 = null;
							}
							else
							{
								PhotonView view2 = refs2.view;
								if (view2 == null)
								{
									obj2 = null;
								}
								else
								{
									Player owner2 = view2.Owner;
									obj2 = ((owner2 != null) ? owner2.NickName : null);
								}
							}
							if (obj2 == null)
							{
								obj2 = "Unknown";
							}
							logger2.LogDebug((object)$"[HikersHunger] {obj2} is within {Mathf.Sqrt(sqrMagnitude):F1}m of campfire {i + 1}");
						}
					}
					return true;
				}
				HikersHungerPlugin instance3 = Instance;
				if (instance3 != null)
				{
					ManualLogSource logger3 = ((BaseUnityPlugin)instance3).Logger;
					if (logger3 != null)
					{
						CharacterRefs refs3 = character.refs;
						object obj3;
						if (refs3 == null)
						{
							obj3 = null;
						}
						else
						{
							PhotonView view3 = refs3.view;
							if (view3 == null)
							{
								obj3 = null;
							}
							else
							{
								Player owner3 = view3.Owner;
								obj3 = ((owner3 != null) ? owner3.NickName : null);
							}
						}
						if (obj3 == null)
						{
							obj3 = "Unknown";
						}
						logger3.LogDebug((object)("[HikersHunger] " + (string?)obj3 + " is not near any campfires"));
					}
				}
			}
			else
			{
				HikersHungerPlugin instance4 = Instance;
				if (instance4 != null)
				{
					ManualLogSource logger4 = ((BaseUnityPlugin)instance4).Logger;
					if (logger4 != null)
					{
						logger4.LogDebug((object)"[HikersHunger] No campfires found in scene");
					}
				}
			}
		}
		catch (Exception ex)
		{
			HikersHungerPlugin instance5 = Instance;
			if (instance5 != null)
			{
				ManualLogSource logger5 = ((BaseUnityPlugin)instance5).Logger;
				if (logger5 != null)
				{
					logger5.LogWarning((object)("[HikersHunger] Campfire search failed: " + ex.Message));
				}
			}
		}
		return false;
	}

	private void OnEnable()
	{
		PhotonNetwork.AddCallbackTarget((object)this);
	}

	private void OnDisable()
	{
		PhotonNetwork.RemoveCallbackTarget((object)this);
	}

	private void OnDestroy()
	{
		if (safeZoneCheckCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(safeZoneCheckCoroutine);
		}
		if (powerRestorationCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(powerRestorationCoroutine);
		}
		PhotonNetwork.RemoveCallbackTarget((object)this);
	}

	private void OnSceneChanged(Scene oldScene, Scene newScene)
	{
		if (((Scene)(ref newScene)).name == "Airport")
		{
			ResetPluginState();
		}
		TryReadConfigFromRoom();
	}

	private void ResetPluginState()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Returned to Airport - resetting plugin state");
		cannibalViewID = -1;
		fireCount = 0;
		showCannibalSelectionGUI = false;
		isWaitingForCannibalSelection = false;
		cannibalPowersActive = false;
		inSafeZone = false;
		inSafeZoneDelay = false;
		safeZoneExitTime = 0f;
		UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if ((Object)(object)allCharacter?.refs?.customization != (Object)null)
			{
				allCharacter.refs.customization.BecomeHuman();
			}
		}
	}

	public void OnJoinedRoom()
	{
		if (PhotonNetwork.IsMasterClient)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Joined room as HOST");
			PublishConfig();
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Joined room as CLIENT; reading config");
			TryReadConfigFromRoom();
		}
	}

	public void OnCreatedRoom()
	{
	}

	public void OnCreateRoomFailed(short returnCode, string message)
	{
	}

	public void OnFriendListUpdate(List<FriendInfo> friendList)
	{
	}

	public void OnJoinRandomFailed(short returnCode, string message)
	{
	}

	public void OnJoinRoomFailed(short returnCode, string message)
	{
	}

	public void OnLeftRoom()
	{
	}

	public void OnPlayerEnteredRoom(Player newPlayer)
	{
		if (PhotonNetwork.IsMasterClient)
		{
			PublishConfig();
		}
	}

	public void OnPlayerLeftRoom(Player otherPlayer)
	{
		if (cannibalViewID == -1 || otherPlayer == null)
		{
			return;
		}
		foreach (Character allCharacter in Character.AllCharacters)
		{
			object obj;
			if (allCharacter == null)
			{
				obj = null;
			}
			else
			{
				CharacterRefs refs = allCharacter.refs;
				if (refs == null)
				{
					obj = null;
				}
				else
				{
					PhotonView view = refs.view;
					obj = ((view != null) ? view.Owner : null);
				}
			}
			if (obj == otherPlayer && allCharacter.refs.view.ViewID == cannibalViewID)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[HikersHunger] The cannibal (" + otherPlayer.NickName + ") has left the game!"));
				cannibalViewID = -1;
				cannibalPowersActive = false;
				inSafeZone = false;
				inSafeZoneDelay = false;
				UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
				break;
			}
		}
	}

	public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
	{
		if (propertiesThatChanged != null && ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"HIKERS_HUNGER_CFG_V1") && propertiesThatChanged[(object)"HIKERS_HUNGER_CFG_V1"] is string s)
		{
			HostCfg synced = Synced;
			Synced = UnpackCfg(s);
			if (ConfigChanged(synced, Synced))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Config updated from room");
			}
		}
	}

	public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
	{
	}

	public void OnMasterClientSwitched(Player newMasterClient)
	{
		if (PhotonNetwork.IsMasterClient)
		{
			PublishConfig();
		}
	}

	public void OnEvent(EventData photonEvent)
	{
	}

	private HostCfg BuildFromHostConfig()
	{
		HostCfg result = default(HostCfg);
		result.manualCannibalSelection = manualCannibalSelection.Value;
		result.initialSelectionDelay = initialSelectionDelay.Value;
		result.postSelectionDelay = postSelectionDelay.Value;
		result.enableCustomEatTime = enableCustomEatTime.Value;
		result.customEatTime = customEatTime.Value;
		result.constantCannibal = constantCannibal.Value;
		result.safeZoneDelay = safeZoneDelay.Value;
		return result;
	}

	private static string PackCfg(HostCfg c)
	{
		CultureInfo invariantCulture = CultureInfo.InvariantCulture;
		return $"{c.manualCannibalSelection}|{c.initialSelectionDelay}|{c.postSelectionDelay}|{c.enableCustomEatTime}|{c.customEatTime}|{c.constantCannibal}|{c.safeZoneDelay}";
	}

	private static HostCfg UnpackCfg(string s)
	{
		CultureInfo invariantCulture = CultureInfo.InvariantCulture;
		string[] array = (s ?? string.Empty).Split(new char[1] { '|' });
		HostCfg hostCfg = default(HostCfg);
		hostCfg.manualCannibalSelection = false;
		hostCfg.initialSelectionDelay = 20;
		hostCfg.postSelectionDelay = 120;
		hostCfg.enableCustomEatTime = false;
		hostCfg.customEatTime = 0.01f;
		hostCfg.constantCannibal = false;
		hostCfg.safeZoneDelay = 30f;
		HostCfg result = hostCfg;
		if (array.Length >= 7)
		{
			bool.TryParse(array[0], out result.manualCannibalSelection);
			int.TryParse(array[1], NumberStyles.Integer, invariantCulture, out result.initialSelectionDelay);
			int.TryParse(array[2], NumberStyles.Integer, invariantCulture, out result.postSelectionDelay);
			bool.TryParse(array[3], out result.enableCustomEatTime);
			float.TryParse(array[4], NumberStyles.Float, invariantCulture, out result.customEatTime);
			bool.TryParse(array[5], out result.constantCannibal);
			float.TryParse(array[6], NumberStyles.Float, invariantCulture, out result.safeZoneDelay);
		}
		return result;
	}

	private bool ConfigChanged(HostCfg old, HostCfg newCfg)
	{
		return old.manualCannibalSelection != newCfg.manualCannibalSelection || old.initialSelectionDelay != newCfg.initialSelectionDelay || old.postSelectionDelay != newCfg.postSelectionDelay || old.enableCustomEatTime != newCfg.enableCustomEatTime || old.customEatTime != newCfg.customEatTime || old.constantCannibal != newCfg.constantCannibal || old.safeZoneDelay != newCfg.safeZoneDelay;
	}

	private void TryReadConfigFromRoom()
	{
		Room currentRoom = PhotonNetwork.CurrentRoom;
		object value = default(object);
		if (currentRoom != null && (((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties)?.TryGetValue((object)"HIKERS_HUNGER_CFG_V1", out value)).GetValueOrDefault() && value is string s)
		{
			Synced = UnpackCfg(s);
		}
	}

	private void OnHostConfigChanged()
	{
		if (PhotonNetwork.IsMasterClient)
		{
			PublishConfig();
		}
	}

	private void PublishConfig()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		Room currentRoom = PhotonNetwork.CurrentRoom;
		if (currentRoom != null)
		{
			Synced = BuildFromHostConfig();
			string text = PackCfg(Synced);
			Hashtable val = new Hashtable { [(object)"HIKERS_HUNGER_CFG_V1"] = text };
			currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Host published config to room");
		}
	}

	private void OnGUI()
	{
		if (showCannibalSelectionGUI && PhotonNetwork.IsMasterClient && isWaitingForCannibalSelection)
		{
			DrawCannibalSelectionGUI();
		}
	}

	private void DrawCannibalSelectionGUI()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		HandleMenuInput();
		GUI.color = new Color(0f, 0f, 0f, 0.8f);
		GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), "");
		GUI.color = Color.white;
		float num = 400f;
		float num2 = 300f;
		float num3 = ((float)Screen.width - num) / 2f;
		float num4 = ((float)Screen.height - num2) / 2f;
		GUI.Box(new Rect(num3, num4, num, num2), "Select Cannibal");
		GUI.Label(new Rect(num3 + 10f, num4 + 20f, num - 20f, 30f), "Choose who will become the cannibal:", new GUIStyle(GUI.skin.label)
		{
			fontSize = 16,
			alignment = (TextAnchor)4
		});
		float num5 = num4 + 60f;
		float num6 = 40f;
		float num7 = 5f;
		List<Character> validCandidates = GetValidCandidates();
		foreach (Character item in validCandidates)
		{
			if (num5 + num6 > num4 + num2 - 60f)
			{
				break;
			}
			Player owner = item.refs.view.Owner;
			string text = ((owner != null) ? owner.NickName : null) ?? "Unknown Player";
			if (GUI.Button(new Rect(num3 + 20f, num5, num - 40f, num6), text))
			{
				if (cannibalViewID != -1)
				{
					StripCannibalPowers();
				}
				SelectCannibal(item, isInitialSelection: true);
				CloseGUI();
			}
			num5 += num6 + num7;
		}
		if (GUI.Button(new Rect(num3 + 20f, num4 + num2 - 40f, num - 40f, 30f), "Cancel (Random Selection)"))
		{
			CloseGUI();
			((MonoBehaviour)this).StartCoroutine(SelectRandomCannibalAfterDelay());
		}
	}

	private void HandleMenuInput()
	{
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
	}

	private void CloseGUI()
	{
		showCannibalSelectionGUI = false;
		isWaitingForCannibalSelection = false;
		Cursor.lockState = (CursorLockMode)1;
		Cursor.visible = false;
	}

	private List<Character> GetValidCandidates()
	{
		List<Character> list = new List<Character>();
		foreach (Character allCharacter in Character.AllCharacters)
		{
			object obj;
			if (allCharacter == null)
			{
				obj = null;
			}
			else
			{
				CharacterRefs refs = allCharacter.refs;
				if (refs == null)
				{
					obj = null;
				}
				else
				{
					PhotonView view = refs.view;
					obj = ((view != null) ? view.Owner : null);
				}
			}
			if (obj != null && !allCharacter.isBot && !allCharacter.data.dead)
			{
				list.Add(allCharacter);
			}
		}
		return list;
	}

	private void SelectCannibal(Character character, bool isInitialSelection = false)
	{
		if ((Object)(object)character?.refs?.view == (Object)null)
		{
			return;
		}
		int viewID = character.refs.view.ViewID;
		bool flag = cannibalViewID == viewID;
		string text = (isInitialSelection ? "initial" : "campfire");
		ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
		Player owner = character.refs.view.Owner;
		logger.LogInfo((object)("[HikersHunger] " + text + " cannibal selected: " + (((owner != null) ? owner.NickName : null) ?? "Unknown")));
		if (isInitialSelection)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Applying initial selection delay...");
			cannibalViewID = viewID;
			((MonoBehaviour)this).StartCoroutine(DelayCannibalPowers(viewID));
			return;
		}
		if (flag && inSafeZoneDelay)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Reselecting same cannibal who was in safe zone delay - powers will be granted when delay completes");
			cannibalViewID = viewID;
			return;
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Granting campfire selection powers immediately...");
		cannibalViewID = viewID;
		try
		{
			manager.SetRoomProperty("cannibalViewId", (object)viewID);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Cannibal powers now active!");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[HikersHunger] Failed to set room property: " + ex.Message));
		}
	}

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

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

	private void SelectRandomCannibal()
	{
		if (PhotonNetwork.IsMasterClient)
		{
			List<Character> validCandidates = GetValidCandidates();
			if (validCandidates.Count > 0)
			{
				int index = Random.Range(0, validCandidates.Count);
				SelectCannibal(validCandidates[index], isInitialSelection: true);
			}
		}
	}

	private void SelectNewCannibalAtCampfire()
	{
		if (!PhotonNetwork.IsMasterClient)
		{
			return;
		}
		if (Synced.constantCannibal)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Constant cannibal mode - keeping current cannibal");
			return;
		}
		if (cannibalViewID != -1 && inSafeZoneDelay)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Current cannibal is in safe zone delay - will be reselected but powers delayed");
			ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
			object arg = cannibalViewID;
			Character localCharacter = Character.localCharacter;
			int? obj;
			if (localCharacter == null)
			{
				obj = null;
			}
			else
			{
				PhotonView photonView = ((MonoBehaviourPun)localCharacter).photonView;
				obj = ((photonView != null) ? new int?(photonView.ViewID) : null);
			}
			logger.LogInfo((object)$"[HikersHunger] Current cannibal ViewID: {arg}, Local player ViewID: {obj}");
		}
		if (cannibalViewID != -1)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[HikersHunger] Stripping powers from current cannibal before selecting new one");
			StripCannibalPowers();
		}
		if (Synced.manualCannibalSelection)
		{
			isWaitingForCannibalSelection = true;
			showCannibalSelectionGUI = true;
		}
		else
		{
			SelectRandomCannibalAtCampfire();
		}
	}

	private void SelectRandomCannibalAtCampfire()
	{
		if (PhotonNetwork.IsMasterClient)
		{
			List<Character> validCandidates = GetValidCandidates();
			if (validCandidates.Count > 0)
			{
				int index = Random.Range(0, validCandidates.Count);
				Character val = validCandidates[index];
				ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
				Player owner = val.refs.view.Owner;
				logger.LogInfo((object)("[HikersHunger] Randomly selecting " + (((owner != null) ? owner.NickName : null) ?? "Unknown") + " as cannibal at campfire"));
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HikersHunger] Selected character ViewID: {val.refs.view.ViewID}, Current cannibal ViewID: {cannibalViewID}");
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[HikersHunger] Safe zone delay state: inSafeZoneDelay={inSafeZoneDelay}");
				SelectCannibal(val);
			}
		}
	}
}