Decompiled source of Stones v0.1.5

plugins/q4y.Stones.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using PEAKLib.Items.UnityEditor;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("q4y.Stones")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.5.0")]
[assembly: AssemblyInformationalVersion("0.1.5+7c32d1127e92ebd11313bfa50c7c85b13755c261")]
[assembly: AssemblyProduct("q4y.Stones")]
[assembly: AssemblyTitle("Stones")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace Stones
{
	[RequireComponent(typeof(Item))]
	public class AutoLightBehavior : MonoBehaviourPun
	{
		private Item item;

		private bool hasTriggered;

		private void Awake()
		{
			item = ((Component)this).GetComponent<Item>();
		}

		private void Update()
		{
			if (!hasTriggered && ((MonoBehaviourPun)this).photonView.IsMine && IsOnGround())
			{
				TriggerExplosiveSwap();
			}
		}

		private bool IsOnGround()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			return (int)item.itemState == 0;
		}

		private void TriggerExplosiveSwap()
		{
			hasTriggered = true;
			ModLogger.LogInfo("[AutoLight] Custom explosive dropped/thrown. Spawning native vanilla Dynamite swap...");
			SpawnAndIgniteVanillaDynamite();
			DespawnCustomItem();
		}

		private void SpawnAndIgniteVanillaDynamite()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = PhotonNetwork.Instantiate("0_Items/Dynamite", ((Component)this).transform.position, ((Component)this).transform.rotation, (byte)0, (object[])null);
				if ((Object)(object)val != (Object)null)
				{
					Dynamite component = val.GetComponent<Dynamite>();
					if ((Object)(object)component != (Object)null)
					{
						component.startingFuseTime = 0.01f;
						component.LightFlare();
					}
				}
			}
			catch (Exception ex)
			{
				ModLogger.LogError("[AutoLight] Failed to spawn native dynamite: " + ex.Message);
			}
		}

		private void DespawnCustomItem()
		{
			item.ClearDataFromBackpack();
			PhotonNetwork.Destroy(((Component)this).gameObject);
		}
	}
	[RequireComponent(typeof(Item))]
	public class GrenadeCookBehavior : MonoBehaviourPun
	{
		private Item item;

		private bool hasExploded;

		private void Awake()
		{
			item = ((Component)this).GetComponent<Item>();
		}

		private void Update()
		{
			if (!hasExploded && ((MonoBehaviourPun)this).photonView.IsMine && IsCooked(item))
			{
				TriggerExplosion();
			}
		}

		private void TriggerExplosion()
		{
			hasExploded = true;
			ModLogger.LogInfo("[GrenadeCook] Grenade cooked! Spawning custom 'Explosion' item via Photon...");
			SpawnExplosionPrefab();
			RemoveFromPlayerHands();
			DespawnGrenade();
		}

		private void DespawnGrenade()
		{
			item.ClearDataFromBackpack();
			PhotonNetwork.Destroy(((Component)this).gameObject);
		}

		private void RemoveFromPlayerHands()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data.currentItem == (Object)(object)item)
			{
				Player.localPlayer.EmptySlot(Character.localCharacter.refs.items.currentSelectedSlot);
			}
		}

		private void SpawnExplosionPrefab()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			Vector3 position = ((Component)this).transform.position;
			Quaternion rotation = ((Component)this).transform.rotation;
			try
			{
				string text = "0_Items/" + Plugin.ModId + ":Explosion";
				GameObject val = PhotonNetwork.Instantiate(text, position, rotation, (byte)0, (object[])null);
				if ((Object)(object)val != (Object)null)
				{
					Item component = val.GetComponent<Item>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.rig != (Object)null)
					{
						component.rig.linearVelocity = (((Object)(object)item.rig != (Object)null) ? item.rig.linearVelocity : Vector3.zero);
					}
				}
			}
			catch (Exception ex)
			{
				ModLogger.LogError("[GrenadeCook] Failed to spawn custom explosion item: " + ex.Message);
			}
		}

		private bool IsCooked(Item item)
		{
			IntItemData val = default(IntItemData);
			if (item.data != null && item.data.TryGetDataEntry<IntItemData>((DataEntryKey)1, ref val) && val.Value > 0)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Spawner), "GetObjectsToSpawn")]
	public class SpawnerGrenadePatch
	{
		private static void Postfix(Spawner __instance, ref List<GameObject> __result)
		{
			if (!StonesConfig.EnableGrenades.Value && __result != null && __result.Count != 0)
			{
				ReplaceGrenadesInSpawnList(__instance, __result);
			}
		}

		private static void ReplaceGrenadesInSpawnList(Spawner spawner, List<GameObject> spawnList)
		{
			for (int i = 0; i < spawnList.Count; i++)
			{
				if (IsGrenade(spawnList[i]))
				{
					spawnList[i] = DetermineReplacementItem(spawner, spawnList);
				}
			}
		}

		private static bool IsGrenade(GameObject? obj)
		{
			if ((Object)(object)obj != (Object)null)
			{
				return ((Object)obj).name.Contains("Grenade");
			}
			return false;
		}

		private static GameObject? DetermineReplacementItem(Spawner spawner, List<GameObject> spawnList)
		{
			GameObject val = FindSafeItemInList(spawnList);
			if ((Object)(object)val == (Object)null && (Object)(object)spawner.fallbackSpawn != (Object)null)
			{
				val = spawner.fallbackSpawn;
			}
			return val;
		}

		private static GameObject? FindSafeItemInList(List<GameObject> spawnList)
		{
			foreach (GameObject spawn in spawnList)
			{
				if (!IsGrenade(spawn))
				{
					return spawn;
				}
			}
			return null;
		}
	}
	public static class ItemSpawnHelper
	{
		public static GameObject? SpawnStone(string prefabId, Vector3 pos, Quaternion rot, bool startSleeping = true)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				ModLogger.LogWarning("[Stones] Aborting SpawnStone: Only the Master Client should spawn networked stones.");
				return null;
			}
			if (string.IsNullOrEmpty(prefabId))
			{
				ModLogger.LogError("[Stones] SpawnStone called with null/empty prefabId.");
				return null;
			}
			string modId = Plugin.ModId;
			string text = "0_Items/" + modId + ":" + prefabId;
			object[] array = new object[1] { startSleeping };
			GameObject val = PhotonNetwork.Instantiate(text, pos, rot, (byte)0, array);
			if ((Object)(object)val == (Object)null)
			{
				ModLogger.LogError("[Stones] PhotonNetwork.Instantiate returned null - '" + text + "' not registered. Did PEAKLib.ItemsPlugin.RegisterContent run for this tier before this call?");
				return null;
			}
			Item component = val.GetComponent<Item>();
			if ((Object)(object)component == (Object)null)
			{
				ModLogger.LogWarning("[Stones] Spawned '" + prefabId + "' has no Item component - pickup/throw won't work.");
				return val;
			}
			component.itemState = (ItemState)0;
			component.SetKinematicNetworked(false, pos, rot);
			return val;
		}

		public static GameObject? SpawnRandomStone(Vector3 pos, Quaternion rot)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return SpawnRandomFromTiers(Plugin.StoneTiers, pos, rot);
		}

		public static GameObject? SpawnRandomStormStone(Vector3 pos, Quaternion rot)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return SpawnRandomFromTiers(Plugin.StormStoneTiers, pos, rot);
		}

		private static GameObject? SpawnRandomFromTiers(StonesItem[] tiers, Vector3 pos, Quaternion rot)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (tiers.Length <= 1)
			{
				ModLogger.LogError("[Stones] No stone tiers registered - cannot spawn random stone.");
				return null;
			}
			StonesItem stonesItem = tiers[Random.Range(1, tiers.Length)];
			return SpawnStone(stonesItem.PrefabName, pos, rot);
		}

		public static void LogSpawned(string label, GameObject go, Vector3 pos)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			Item component = go.GetComponent<Item>();
			Rigidbody component2 = go.GetComponent<Rigidbody>();
			Collider component3 = go.GetComponent<Collider>();
			PhotonView component4 = go.GetComponent<PhotonView>();
			StoneBehavior component5 = go.GetComponent<StoneBehavior>();
			ModLogger.LogDebug("[Stones] " + label + " spawned:\n  Name: " + ((Object)go).name + "\n" + $"  Position: {pos}\n" + "  PhotonView: " + (((Object)(object)component4 != (Object)null) ? $"yes(viewID={component4.ViewID})" : "MISSING") + "\n  Item: " + (((Object)(object)component != (Object)null) ? $"yes(state={component.itemState}, itemID={component.itemID})" : "MISSING") + "\n  Rigidbody: " + (((Object)(object)component2 != (Object)null) ? $"yes(mass={component2.mass:F2})" : "MISSING") + "\n  Collider: " + (((Object)(object)component3 != (Object)null) ? ((object)component3).GetType().Name : "MISSING") + "\n  StoneBehavior: " + (((Object)(object)component5 != (Object)null) ? "yes" : "MISSING") + "\n" + $"  IsMasterClient: {PhotonNetwork.IsMasterClient}");
		}
	}
	public static class Localization
	{
		private const int LocaleCount = 13;

		private const string KeyPebble = "NAME_PEBBLE";

		private const string KeyRock = "NAME_ROCK";

		private const string KeyBoulder = "NAME_BOULDER";

		private const string KeyLargeBoulder = "NAME_100-POUNDER";

		private const string KeyImpactGrenade = "NAME_IMPACT GRENADE";

		public static void CILocalization()
		{
			AddEntry("NAME_PEBBLE", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble", "Pebble");
			AddEntry("NAME_ROCK", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock", "Rock");
			AddEntry("NAME_BOULDER", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder", "Boulder");
			AddEntry("NAME_100-POUNDER", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder", "100-Pounder");
			AddEntry("NAME_IMPACT GRENADE", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade", "Impact Grenade");
			Plugin.logger.LogInfo((object)"[Stones] Localization injection complete (keys: NAME_PEBBLE, NAME_ROCK, NAME_BOULDER, NAME_100-POUNDER).");
		}

		private static void AddEntry(string key, params string[] localeStrings)
		{
			if (!LocalizedText.mainTable.ContainsKey(key))
			{
				if (localeStrings.Length != 13)
				{
					ModLogger.LogError("[Stones] Localization for '" + key + "' has " + $"{localeStrings.Length} entries, expected {13}. " + "Skipped to avoid corrupting the locale table.");
				}
				else
				{
					LocalizedText.mainTable.Add(key, new List<string>(localeStrings));
				}
			}
		}
	}
	public static class ModLogger
	{
		public static void LogDebug(object message)
		{
			if (StonesConfig.MinLogLevel.Value <= LogLevel.Debug)
			{
				Plugin.logger.LogDebug(message);
			}
		}

		public static void LogInfo(object message)
		{
			if (StonesConfig.MinLogLevel.Value <= LogLevel.Info)
			{
				Plugin.logger.LogInfo(message);
			}
		}

		public static void LogWarning(object message)
		{
			if (StonesConfig.MinLogLevel.Value <= LogLevel.Warning)
			{
				Plugin.logger.LogWarning(message);
			}
		}

		public static void LogError(object message)
		{
			if (StonesConfig.MinLogLevel.Value <= LogLevel.Error)
			{
				Plugin.logger.LogError(message);
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("q4y.Stones", "Stones", "0.1.5")]
	public class Plugin : BaseUnityPlugin
	{
		private const string HarmonyId = "q4y.Stones";

		private const string BundleFileName = "stones.peakbundle";

		internal static readonly StonesItem[] StoneTiers = new StonesItem[4]
		{
			new StonesItem("PebbleContent", "Item_Small_Stone"),
			new StonesItem("RockContent", "Item_Medium_Stone"),
			new StonesItem("BoulderContent", "Item_Big_Stone"),
			new StonesItem("LargeBoulderContent", "Item_Very_Big_Stone")
		};

		internal static readonly StonesItem[] StormStoneTiers = new StonesItem[4]
		{
			new StonesItem("StormPebbleContent", "Item_Small_Storm_Stone"),
			new StonesItem("StormRockContent", "Item_Medium_Storm_Stone"),
			new StonesItem("StormBoulderContent", "Item_Big_Storm_Stone"),
			new StonesItem("StormLargeBoulderContent", "Item_Very_Big_Storm_Stone")
		};

		internal static readonly StonesItem[] OtherItems = new StonesItem[2]
		{
			new StonesItem("GrenadeContent", "Item_Grenade"),
			new StonesItem("ExplosionContent", "Explosion")
		};

		public const string Id = "q4y.Stones";

		internal static ManualLogSource logger { get; private set; } = null;

		internal static string ModId { get; private set; } = null;

		public static PeakBundle PeakBundle { get; private set; } = null;

		public static string Name => "Stones";

		public static string Version => "0.1.5";

		private void Awake()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			logger = ((BaseUnityPlugin)this).Logger;
			ModId = ((BaseUnityPlugin)this).Info.Metadata.GUID;
			logger.LogInfo((object)("Plugin Stones is loaded! (GUID = " + ModId + ")"));
			StonesConfig.Bind(((BaseUnityPlugin)this).Config);
			Localization.CILocalization();
			new Harmony("q4y.Stones").PatchAll(typeof(Plugin).Assembly);
			VulcanManager.EnsureInstance();
			BundleLoader.LoadBundleWithName((BaseUnityPlugin)(object)this, "stones.peakbundle", (Action<PeakBundle>)RegisterStonesContent);
		}

		private void RegisterStonesContent(PeakBundle peakBundle)
		{
			PeakBundle = peakBundle;
			ModLogger.LogInfo("[Stones] Registering stone content from 'stones.peakbundle'...");
			ProcessTierList(StoneTiers, delegate(UnityItemContent content2, string name)
			{
				AttachBehavior<StoneBehavior>(content2, name);
				AttachBehavior<MapStoneBehavior>(content2, name);
			});
			ProcessTierList(StormStoneTiers, delegate(UnityItemContent content2, string name)
			{
				AttachBehavior<StoneBehavior>(content2, name);
				AttachBehavior<StormStoneBehavior>(content2, name);
			});
			UnityItemContent content = peakBundle.LoadAsset<UnityItemContent>("ExplosionContent");
			AttachBehavior<AutoLightBehavior>(content, "ExplosionContent");
			content = peakBundle.LoadAsset<UnityItemContent>("GrenadeContent");
			AttachBehavior<GrenadeCookBehavior>(content, "GrenadeContent");
			ProcessTierList(OtherItems, delegate
			{
			});
			peakBundle.Mod.RegisterContent();
			ModLogger.LogInfo("[Stones] PEAKLib content registration batch complete.");
			void ProcessTierList(StonesItem[] tiers, Action<UnityItemContent, string> attachBehaviors)
			{
				for (int i = 0; i < tiers.Length; i++)
				{
					StonesItem stonesItem = tiers[i];
					UnityItemContent val = peakBundle.LoadAsset<UnityItemContent>(stonesItem.ContentName);
					if ((Object)(object)val == (Object)null)
					{
						ModLogger.LogError("[Stones] UnityItemContent '" + stonesItem.ContentName + "' not found in bundle 'stones.peakbundle'. Re-author the asset in the Unity Editor and re-export the bundle.");
					}
					else
					{
						attachBehaviors(val, stonesItem.ContentName);
					}
				}
			}
		}

		private static void AttachBehavior<T>(UnityItemContent content, string contentName) where T : Component
		{
			if (!((Object)(object)content == (Object)null))
			{
				GameObject itemPrefab = content.ItemPrefab;
				if ((Object)(object)itemPrefab == (Object)null)
				{
					ModLogger.LogError("[Stones] UnityItemContent '" + contentName + "' has no ItemPrefab assigned. Re-author the asset in the Unity Editor.");
				}
				else if ((Object)(object)itemPrefab.GetComponent<T>() == (Object)null)
				{
					itemPrefab.AddComponent<T>();
					ModLogger.LogInfo("[Stones] Attached " + typeof(T).Name + " to '" + contentName + "' ItemPrefab.");
				}
			}
		}

		private void Update()
		{
		}

		private void HandleF2()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			//IL_0067: 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)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			if ((Object)(object)Player.localPlayer == (Object)null || (Object)(object)Player.localPlayer.character == (Object)null)
			{
				ModLogger.LogWarning("F2: Local player or character is null - not in a map?");
				return;
			}
			Vector3 center = Player.localPlayer.character.Center;
			Vector3 right = ((Component)Player.localPlayer.character).transform.right;
			Vector3 val = center + Vector3.up * 1f;
			ModLogger.LogInfo("F2 pressed! Spawning one random stone + all four tiers (Pebble, Rock, Boulder, LargeBoulder) in a row...");
			Vector3 pos = val + right * -3f;
			GameObject val2 = ItemSpawnHelper.SpawnRandomStone(pos, Quaternion.identity);
			if ((Object)(object)val2 == (Object)null)
			{
				ModLogger.LogError("[Stones] SpawnRandomStone returned null - none of the stone tiers are registered by PEAKLib?");
				return;
			}
			ItemSpawnHelper.LogSpawned("F2 (random)", val2, pos);
			SpawnStoneRow(val, center, right);
		}

		private void SpawnStoneRow(Vector3 chestPos, Vector3 playerVektor, Vector3 playerRight)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[4] { -2.25f, -0.75f, 0.75f, 2.25f };
			for (int i = 0; i < StoneTiers.Length; i++)
			{
				StonesItem stonesItem = StoneTiers[i];
				Vector3 val = chestPos + playerRight * array[i];
				ModLogger.LogInfo($"Spawning {stonesItem.PrefabName} at: {val}");
				GameObject val2 = ItemSpawnHelper.SpawnStone(stonesItem.PrefabName, val, Quaternion.identity);
				if ((Object)(object)val2 == (Object)null)
				{
					ModLogger.LogError("[Stones] SpawnStone returned null - '" + stonesItem.PrefabName + "' not registered by PEAKLib?");
				}
				else
				{
					ItemSpawnHelper.LogSpawned("F2 (row: " + stonesItem.PrefabName + ")", val2, val);
				}
			}
		}

		private void HandleF4()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.IsMasterClient)
			{
				if ((Object)(object)Player.localPlayer != (Object)null && (Object)(object)Player.localPlayer.character != (Object)null)
				{
					Vector3 center = Player.localPlayer.character.Center;
					ModLogger.LogInfo($"[Stones] DEBUG F4: Player Center is exactly at X={center.x:F2}, Y={center.y:F2}, Z={center.z:F2}");
				}
				else if ((Object)(object)Camera.main != (Object)null)
				{
					Vector3 position = ((Component)Camera.main).transform.position;
					ModLogger.LogInfo($"[Stones] DEBUG F4: Camera is exactly at X={position.x:F2}, Y={position.y:F2}, Z={position.z:F2}");
				}
			}
		}

		private void HandleF3()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				if (!StonesConfig.EnableVolcanoEvent.Value)
				{
					ModLogger.LogInfo("F3: forcing a volcanic outbreak for debugging even though EnableVolcanoEvent is false.");
				}
				VulcanManager vulcanManager = VulcanManager.EnsureInstance();
				ModLogger.LogInfo("F3 pressed: forcing the volcanic outbreak immediately for debugging.");
				vulcanManager.StartVulcanOutbreak();
			}
		}
	}
	internal readonly struct StonesItem
	{
		public readonly string ContentName;

		public readonly string PrefabName;

		public StonesItem(string contentName, string prefabName)
		{
			ContentName = contentName;
			PrefabName = prefabName;
		}
	}
	[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
	public static class CampfireRetryScatterPatch
	{
		[HarmonyPostfix]
		public static void Postfix(bool updateSegment, Campfire __instance)
		{
			if (IsMaster() && updateSegment && (Object)(object)MapStoneSpawner.Instance != (Object)null)
			{
				((MonoBehaviour)MapStoneSpawner.Instance).StartCoroutine(MapStoneSpawner.Instance.DelayedRetryQueue());
			}
		}

		private static bool IsMaster()
		{
			return PhotonNetwork.IsMasterClient;
		}
	}
	[RequireComponent(typeof(PhotonView))]
	public class MapStoneBehavior : MonoBehaviourPun
	{
		private void Start()
		{
			object[] instantiationData = ((MonoBehaviourPun)this).photonView.InstantiationData;
			bool flag = default(bool);
			int num;
			if (instantiationData != null && instantiationData.Length != 0)
			{
				object obj = instantiationData[0];
				if (obj is bool)
				{
					flag = (bool)obj;
					num = 1;
				}
				else
				{
					num = 0;
				}
			}
			else
			{
				num = 0;
			}
			if (((uint)num & (flag ? 1u : 0u)) != 0)
			{
				Rigidbody component = ((Component)this).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.isKinematic = true;
				}
			}
		}
	}
	[DisallowMultipleComponent]
	[AddComponentMenu("Stones/Map Stone Spawner")]
	public class MapStoneSpawner : MonoBehaviourPunCallbacks
	{
		[Header("Spawn Volume")]
		public float mapMinX = -175f;

		public float mapMaxX = 175f;

		public float mapMinZ = -300f;

		public float mapMaxZ = 2500f;

		[Header("Bounds")]
		public float lobbyExclusionRadius = 25f;

		[Min(0f)]
		public int maxExclusionRetries = 8;

		[Header("Raycast")]
		public float skySpawnHeight = 4000f;

		public float raycastMaxDistance = 5000f;

		public LayerMask groundLayerMask;

		public QueryTriggerInteraction triggerInteraction = (QueryTriggerInteraction)1;

		public float groundOffset = 0.01f;

		[Header("Performance")]
		[Min(1f)]
		public int spawnsPerFrame = 5;

		public static bool _hasSpawnedThisRun;

		private List<Vector2> pendingSpawns = new List<Vector2>();

		public static MapStoneSpawner? Instance { get; private set; }

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			groundLayerMask = BuildDefaultGroundMask();
		}

		public override void OnEnable()
		{
			((MonoBehaviourPunCallbacks)this).OnEnable();
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
		}

		private void OnDestroy()
		{
			ModLogger.LogDebug("[Stones] MapStoneSpawner destroyed.");
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public override void OnLeftRoom()
		{
			_hasSpawnedThisRun = false;
			pendingSpawns.Clear();
		}

		private void OnValidate()
		{
			ClampConfigurationValues();
		}

		public void InitializeSpawnQueue()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			pendingSpawns.Clear();
			int value = StonesConfig.MaxStones.Value;
			for (int i = 0; i < value; i++)
			{
				if (TryGenerateValidCoordinate(out var result))
				{
					pendingSpawns.Add(result);
				}
			}
			ModLogger.LogDebug($"[Stones] Queued {pendingSpawns.Count} stone locations.");
			((MonoBehaviour)this).StartCoroutine(ProcessPendingSpawns());
		}

		public IEnumerator ProcessPendingSpawns()
		{
			if (!PhotonNetwork.IsMasterClient || pendingSpawns.Count == 0)
			{
				yield break;
			}
			List<Vector2> stillPending = new List<Vector2>();
			int successfulThisBatch = 0;
			for (int i = 0; i < pendingSpawns.Count; i++)
			{
				Vector2 val = pendingSpawns[i];
				if (TrySpawnStoneAt(val))
				{
					successfulThisBatch++;
				}
				else
				{
					stillPending.Add(val);
				}
				if (ShouldYieldThisFrame(i))
				{
					yield return null;
				}
			}
			pendingSpawns = stillPending;
			ModLogger.LogInfo($"[Stones] Spawned {successfulThisBatch} stones this batch. {pendingSpawns.Count} waiting for unloaded chunks.");
		}

		public IEnumerator DelayedRetryQueue()
		{
			float num = 10f;
			ModLogger.LogInfo($"[Stones] Waiting {num}s for new chunks to load before retrying stone spawns...");
			yield return (object)new WaitForSeconds(num);
			yield return ((MonoBehaviour)this).StartCoroutine(ProcessPendingSpawns());
		}

		private bool TryGenerateValidCoordinate(out Vector2 result)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			float num = lobbyExclusionRadius * lobbyExclusionRadius;
			int num2 = 1 + Mathf.Max(0, maxExclusionRetries);
			for (int i = 0; i < num2; i++)
			{
				float num3 = Random.Range(mapMinX, mapMaxX);
				float num4 = Random.Range(mapMinZ, mapMaxZ);
				if (num3 * num3 + num4 * num4 >= num)
				{
					result = new Vector2(num3, num4);
					return true;
				}
			}
			result = Vector2.zero;
			return false;
		}

		private bool TrySpawnStoneAt(Vector2 pos)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_001a: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(pos.x, skySpawnHeight, pos.y);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, Vector3.down, ref val2, raycastMaxDistance, ((LayerMask)(ref groundLayerMask)).value, triggerInteraction))
			{
				Vector3 pos2 = ((RaycastHit)(ref val2)).point + Vector3.up * groundOffset;
				GameObject val3 = ItemSpawnHelper.SpawnRandomStone(pos2, Random.rotation);
				return (Object)(object)val3 != (Object)null;
			}
			return false;
		}

		private bool ShouldYieldThisFrame(int currentIndex)
		{
			if (spawnsPerFrame > 0)
			{
				return (currentIndex + 1) % spawnsPerFrame == 0;
			}
			return false;
		}

		private void ClampConfigurationValues()
		{
			if (lobbyExclusionRadius < 0f)
			{
				lobbyExclusionRadius = 0f;
			}
			if (maxExclusionRetries < 0)
			{
				maxExclusionRetries = 0;
			}
			if (skySpawnHeight < 0f)
			{
				skySpawnHeight = 0f;
			}
			if (groundOffset < 0f)
			{
				groundOffset = 0f;
			}
			if (raycastMaxDistance < 0f)
			{
				raycastMaxDistance = 0f;
			}
			if (spawnsPerFrame < 1)
			{
				spawnsPerFrame = 1;
			}
			if (mapMinX > mapMaxX)
			{
				float num = mapMaxX;
				float num2 = mapMinX;
				mapMinX = num;
				mapMaxX = num2;
			}
			if (mapMinZ > mapMaxZ)
			{
				float num2 = mapMaxZ;
				float num = mapMinZ;
				mapMinZ = num2;
				mapMaxZ = num;
			}
		}

		private static LayerMask BuildDefaultGroundMask()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return LayerMask.op_Implicit(LayerMask.GetMask(new string[2] { "Terrain", "Map" }));
		}
	}
	[HarmonyPatch(typeof(RunManager))]
	public static class RunManagerStoneScatterPatches
	{
		public const byte CUSTOM_START_RUN_EVENT = 43;

		static RunManagerStoneScatterPatches()
		{
			PhotonNetwork.NetworkingClient.EventReceived += OnNetworkEventReceived;
		}

		[HarmonyPatch("StartRun")]
		[HarmonyPostfix]
		public static void StartRun_Postfix()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				ExecuteMasterClientScatterLogic();
			}
			else
			{
				BroadcastStartRunEvent();
			}
		}

		[HarmonyPatch("EndGame")]
		[HarmonyPostfix]
		public static void EndGame_Postfix()
		{
			ResetScatterFlag();
		}

		private static void BroadcastStartRunEvent()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			ModLogger.LogInfo("[RunManager] A player started the run. Broadcasting StartRun event to all clients...");
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)2
			};
			SendOptions val2 = default(SendOptions);
			((SendOptions)(ref val2)).Reliability = true;
			SendOptions val3 = val2;
			PhotonNetwork.RaiseEvent((byte)43, (object)null, val, val3);
		}

		private static void OnNetworkEventReceived(EventData photonEvent)
		{
			if (photonEvent.Code == 43)
			{
				ModLogger.LogInfo("[RunManager] StartRun network event received!");
				if (PhotonNetwork.IsMasterClient)
				{
					ExecuteMasterClientScatterLogic();
				}
			}
		}

		private static void ExecuteMasterClientScatterLogic()
		{
			if (MapStoneSpawner._hasSpawnedThisRun)
			{
				ModLogger.LogInfo("[Stones] Scatter already fired for this run. Skipping duplicate.");
				return;
			}
			MapStoneSpawner._hasSpawnedThisRun = true;
			MapStoneSpawner mapStoneSpawner = EnsureMapStoneSpawnerExists();
			if ((Object)(object)mapStoneSpawner == (Object)null)
			{
				MapStoneSpawner._hasSpawnedThisRun = false;
				ModLogger.LogError("[Stones] Failed to create MapStoneSpawner host GameObject; scatter aborted.");
			}
			else
			{
				mapStoneSpawner.InitializeSpawnQueue();
				ModLogger.LogInfo("[Stones] RunStart_StoneScatter_Patch: triggered queue initialization " + $"(host='{((Object)mapStoneSpawner).name}', totalStones={StonesConfig.MaxStones.Value}, " + $"X=[{mapStoneSpawner.mapMinX}..{mapStoneSpawner.mapMaxX}] m, " + $"Z=[{mapStoneSpawner.mapMinZ}..{mapStoneSpawner.mapMaxZ}] m).");
			}
		}

		private static MapStoneSpawner EnsureMapStoneSpawnerExists()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			MapStoneSpawner mapStoneSpawner = MapStoneSpawner.Instance;
			if ((Object)(object)mapStoneSpawner == (Object)null)
			{
				GameObject val = new GameObject("MapStoneSpawner (RunStart)");
				Object.DontDestroyOnLoad((Object)(object)val);
				mapStoneSpawner = val.AddComponent<MapStoneSpawner>();
			}
			return mapStoneSpawner;
		}

		private static void ResetScatterFlag()
		{
			if (MapStoneSpawner._hasSpawnedThisRun)
			{
				ModLogger.LogInfo("[Stones] RunManager.EndGame fired — resetting scatter flag for next run.");
				MapStoneSpawner._hasSpawnedThisRun = false;
			}
		}
	}
	[RequireComponent(typeof(PhotonView))]
	[RequireComponent(typeof(Item))]
	public class StoneBehavior : MonoBehaviourPun
	{
		private float _lastHitTime = -1f;

		private float _lastTimeHeld = -1f;

		private int _lastHolderActorNumber = -1;

		public required Item stoneItem;

		private void Awake()
		{
			stoneItem = ((Component)this).GetComponent<Item>();
			if ((Object)(object)stoneItem == (Object)null)
			{
				ModLogger.LogError("[Stone] Missing Item component on " + ((Object)((Component)this).gameObject).name + "! Destroying StoneBehavior.");
				Object.Destroy((Object)(object)this);
			}
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if ((int)stoneItem.itemState != 0)
			{
				_lastTimeHeld = Time.time;
				_lastHolderActorNumber = ((MonoBehaviourPun)this).photonView.OwnerActorNr;
			}
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if ((int)stoneItem.itemState != 0)
			{
				return;
			}
			Bodypart component = collision.gameObject.GetComponent<Bodypart>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Character componentInParent = ((Component)component).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			float num = Time.time - _lastTimeHeld;
			if (((MonoBehaviourPun)componentInParent).photonView.OwnerActorNr == _lastHolderActorNumber && num < 1f)
			{
				return;
			}
			Vector3 relativeVelocity = collision.relativeVelocity;
			float magnitude = ((Vector3)(ref relativeVelocity)).magnitude;
			if (((MonoBehaviourPun)componentInParent).photonView.IsMine)
			{
				if (Time.time - _lastHitTime < 1f)
				{
					return;
				}
				float num2 = stoneItem.CarryWeight;
				if (num2 <= 4f)
				{
					return;
				}
				float num3 = Mathf.Clamp01(num2 / 20f);
				float num4 = Mathf.InverseLerp(10f, 25f, magnitude);
				float num5 = num4 * num3 * 0.3f;
				if (num5 > 0f)
				{
					_lastHitTime = Time.time;
					try
					{
						componentInParent.refs.afflictions.AddStatus((STATUSTYPE)0, num5, false, true, true);
						ModLogger.LogInfo("[Stone] Injury -> victim='" + componentInParent.characterName + "', " + $"weight={num2:F2}, speed={magnitude:F2}m/s, " + $"stoneFactor={num3:F3}, amount={num5:F3}.");
					}
					catch (Exception ex)
					{
						ModLogger.LogError("[Stone] AddStatus threw " + ex.GetType().Name + ": " + ex.Message);
					}
				}
			}
			if (PhotonNetwork.IsMasterClient)
			{
				((MonoBehaviourPun)this).photonView.RPC("PlayImpactVisuals", (RpcTarget)0, new object[1] { magnitude });
			}
		}

		[PunRPC]
		private void PlayImpactVisuals(float impactSpeed, PhotonMessageInfo info)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			ModLogger.LogInfo($"[Stone] PlayImpactVisuals - speed={impactSpeed:F2}m/s, " + $"sender={info.Sender.ActorNumber}, " + $"IsMasterClient={PhotonNetwork.IsMasterClient}, " + "ItemState=" + GetItemStateString());
		}

		private string GetItemStateString()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return ((object)stoneItem.itemState/*cast due to .constrained prefix*/).ToString();
		}
	}
	public enum LogLevel
	{
		Debug,
		Info,
		Warning,
		Error
	}
	public static class StonesConfig
	{
		public static ConfigEntry<LogLevel> MinLogLevel { get; private set; }

		public static ConfigEntry<int> MaxStones { get; private set; }

		public static ConfigEntry<bool> EnableGrenades { get; private set; }

		public static ConfigEntry<int> VolcanoMaxStones { get; private set; }

		public static ConfigEntry<bool> EnableVolcanoEvent { get; private set; }

		public static ConfigEntry<float> VulcanOutbreakChance { get; private set; }

		public static ConfigEntry<int> VulcanStoneBurstCount { get; private set; }

		public static void Bind(ConfigFile config)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			MaxStones = config.Bind<int>("1. Spawning", "Max Stones", 700, "The maximum number of items allowed in the world.");
			EnableVolcanoEvent = config.Bind<bool>("2. Events", "Enable Volcano Event", true, "Set to true to allow the volcanic outbreak hijack.");
			VolcanoMaxStones = config.Bind<int>("2. Events", "Volcano Max Stones", 30, "The maximum number of items allowed in a volcanic outbreak.");
			VulcanOutbreakChance = config.Bind<float>("2. Events", "Vulcan Outbreak Chance", 0.2f, new ConfigDescription("Chance for a normal storm start to become a volcanic outbreak. (0.0 = 0%, 0.5 = 50%, 1.0 = 100%)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			VulcanStoneBurstCount = config.Bind<int>("2. Events", "Vulcan Stone Burst Count", 5, "How many stones to burst into the sky when the outbreak starts.");
			EnableGrenades = config.Bind<bool>("1. Spawning", "Enable Grenades", true, "If true, grenades are allowed to spawn in chests/world.");
			MinLogLevel = config.Bind<LogLevel>("Logging", "Minimum Log Level", LogLevel.Error, "Minimum severity level of logs to display in the console. Options: Debug, Info, Warning, Error, None.");
		}
	}
	public class StormStoneBehavior : MonoBehaviour
	{
		private float maxLife = 25f;

		private float gracePeriod = 2f;

		private float tumbleSpeed = 15f;

		private float lifeTimer;

		private Rigidbody? rb;

		private Item? itemComponent;

		private Breakable? breakableComponent;

		private PhotonView? view;

		private void Awake()
		{
			FetchComponents();
			MakeUnpickupable();
			DisableBreakableBehaviors();
		}

		private void Start()
		{
			ApplyRandomTumble();
		}

		private void Update()
		{
			if (IsMaster())
			{
				HandleLifetimeAndDespawn();
			}
		}

		private void FetchComponents()
		{
			rb = ((Component)this).GetComponent<Rigidbody>();
			itemComponent = ((Component)this).GetComponent<Item>();
			breakableComponent = ((Component)this).GetComponent<Breakable>();
			view = ((Component)this).GetComponent<PhotonView>();
		}

		private void MakeUnpickupable()
		{
			if ((Object)(object)itemComponent != (Object)null)
			{
				itemComponent.blockInteraction = true;
			}
		}

		private void DisableBreakableBehaviors()
		{
			if ((Object)(object)breakableComponent != (Object)null)
			{
				breakableComponent.breakOnCollision = false;
				((Behaviour)breakableComponent).enabled = false;
			}
			MonoBehaviour[] componentsInChildren = ((Component)this).GetComponentsInChildren<MonoBehaviour>(true);
			MonoBehaviour[] array = componentsInChildren;
			foreach (MonoBehaviour val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string text = ((object)val).GetType().Name.ToLowerInvariant();
					if (text.Contains("break") || text.Contains("damage"))
					{
						((Behaviour)val).enabled = false;
					}
				}
			}
		}

		private void ApplyRandomTumble()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (IsMaster() && !((Object)(object)rb == (Object)null))
			{
				rb.angularVelocity = Random.insideUnitSphere * tumbleSpeed;
			}
		}

		private void HandleLifetimeAndDespawn()
		{
			lifeTimer += Time.deltaTime;
			if (lifeTimer >= maxLife)
			{
				Despawn();
			}
			else if (lifeTimer >= gracePeriod && HasStoppedMoving())
			{
				Despawn();
			}
		}

		private bool HasStoppedMoving()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rb == (Object)null)
			{
				return false;
			}
			Vector3 linearVelocity = rb.linearVelocity;
			return ((Vector3)(ref linearVelocity)).sqrMagnitude < 0.1f;
		}

		private void Despawn()
		{
			if ((Object)(object)view != (Object)null && view.IsMine)
			{
				PhotonNetwork.Destroy(((Component)this).gameObject);
			}
			else if ((Object)(object)view == (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private bool IsMaster()
		{
			return PhotonNetwork.IsMasterClient;
		}
	}
	public static class VolcanoEvent
	{
		private struct AtmosphereState
		{
			public Color OriginalAmbient;

			public Color OriginalFogColor;

			public float OriginalFogDensity;

			public Color OriginalSunColor;

			public float OriginalSunIntensity;

			public bool OriginalFog;
		}

		private const float FadeInDuration = 5f;

		private const float FadeOutDuration = 5f;

		private const float ShakeDuration = 2f;

		private const float ShakeMagnitude = 2f;

		private const float BuildupDelay = 5f;

		private const float RainRadiusXZ = 10f;

		private const float RainHeightOffset = 70f;

		private static readonly Color StormAmbient = new Color(0.35f, 0.08f, 0.08f, 1f);

		private static readonly Color StormFogColor = new Color(0.45f, 0.05f, 0.05f, 1f);

		private const float StormFogDensity = 0.16f;

		private static readonly Color StormSunColor = new Color(1f, 0.45f, 0.15f, 1f);

		private const float StormSunIntensity = 1.5f;

		private static VolcanoVisuals? _visualEnforcer;

		private static AtmosphereState? _originalState;

		public static IEnumerator Run()
		{
			float startTime = Time.time;
			ModLogger.LogInfo($"[Volcano] === EVENT START === Current Time: {startTime:F2}");
			GameObject enforcerObject = CreateVisualEnforcer();
			SetupAudio(enforcerObject);
			Light sun = FindMainDirectionalLight();
			_visualEnforcer.sun = sun;
			_visualEnforcer.enforceEnvironment = true;
			_originalState = CaptureAtmosphere(sun);
			yield return ExecutePhase1_FadeIn(sun);
			yield return ExecutePhase2_CameraShake();
			yield return ExecutePhase3_Delay();
			yield return ExecutePhase4_StoneRain();
			yield return ExecutePhase5_FadeOut(sun, _originalState);
			ExecutePhase6_Cleanup();
			ModLogger.LogInfo($"[Volcano] === EVENT COMPLETE === Total Time Elapsed: {Time.time - startTime:F2}s");
		}

		private static IEnumerator ExecutePhase1_FadeIn(Light? sun)
		{
			ModLogger.LogInfo($"[Volcano] Phase 1 (Fade In) starting. Expected duration: {5f}s");
			yield return FadeEnvironment(sun, StormAmbient, StormFogColor, 0.16f, StormSunColor, 1.5f, 5f);
			ModLogger.LogInfo("[Volcano] Phase 1 completed.");
		}

		private static IEnumerator ExecutePhase2_CameraShake()
		{
			ModLogger.LogInfo($"[Volcano] Phase 2 (Camera Shake) starting. Duration: {2f}s");
			yield return ShakeCamera(2f, 2f);
			ModLogger.LogInfo("[Volcano] Phase 2 completed.");
		}

		private static IEnumerator ExecutePhase3_Delay()
		{
			ModLogger.LogInfo($"[Volcano] Phase 3 (Buildup Delay) starting. Holding for {5f}s...");
			yield return (object)new WaitForSeconds(5f);
			ModLogger.LogInfo("[Volcano] Phase 3 completed.");
		}

		private static IEnumerator ExecutePhase4_StoneRain()
		{
			if (!IsMaster())
			{
				ModLogger.LogInfo("[Volcano] Client waiting 7s for Master to spawn stones.");
				yield return (object)new WaitForSeconds(7f);
				ModLogger.LogInfo("[Volcano] Phase 4 completed (Client).");
				yield break;
			}
			float safeDropRate = GetSafeDropRate();
			int burstCount = Mathf.Max(1, StonesConfig.VulcanStoneBurstCount.Value);
			int itemsToDrop = StonesConfig.VolcanoMaxStones.Value;
			LayerMask groundMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[2] { "Terrain", "Map" }));
			float skySpawnHeight = 4000f;
			float raycastMaxDistance = 5000f;
			Player[] allPlayers = Object.FindObjectsByType<Player>((FindObjectsSortMode)0);
			if (allPlayers.Length == 0)
			{
				yield return (object)new WaitForSeconds(7f);
				yield break;
			}
			float interval = safeDropRate / (float)allPlayers.Length;
			for (int i = 0; i < itemsToDrop; i += burstCount)
			{
				foreach (Player val in allPlayers)
				{
					if ((Object)(object)val != (Object)null && (Object)(object)val.character != (Object)null)
					{
						for (int j = 0; j < burstCount; j++)
						{
							SpawnStoneAbovePlayer(val, groundMask, skySpawnHeight, raycastMaxDistance);
						}
					}
					yield return (object)new WaitForSeconds(interval);
				}
			}
			ModLogger.LogInfo("[Volcano] Phase 4 completed.");
		}

		private static IEnumerator ExecutePhase5_FadeOut(Light? sun, AtmosphereState? state)
		{
			if (state.HasValue)
			{
				AtmosphereState valueOrDefault = state.GetValueOrDefault();
				ModLogger.LogInfo($"[Volcano] Phase 5 (Fade Out) starting. Expected duration: {5f}s");
				yield return FadeEnvironment(sun, valueOrDefault.OriginalAmbient, valueOrDefault.OriginalFogColor, valueOrDefault.OriginalFogDensity, valueOrDefault.OriginalSunColor, valueOrDefault.OriginalSunIntensity, 5f);
				ModLogger.LogInfo("[Volcano] Phase 5 completed.");
			}
		}

		private static void ExecutePhase6_Cleanup()
		{
			ModLogger.LogInfo("[Volcano] Phase 6 (Cleanup) starting...");
			VulcanManager.EnsureInstance().StopVulcanOutbreak();
		}

		public static void CleanupVisuals()
		{
			ModLogger.LogInfo("[Volcano] Cleaning up visuals...");
			if ((Object)(object)_visualEnforcer != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_visualEnforcer).gameObject);
				_visualEnforcer = null;
			}
			if (_originalState.HasValue)
			{
				RenderSettings.fog = _originalState.Value.OriginalFog;
			}
		}

		private static GameObject CreateVisualEnforcer()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			ModLogger.LogInfo("[Volcano] Creating VolcanoVisualEnforcer GameObject...");
			GameObject val = new GameObject("VolcanoVisualEnforcer");
			_visualEnforcer = val.AddComponent<VolcanoVisuals>();
			return val;
		}

		private static void SetupAudio(GameObject enforcerObject)
		{
			ModLogger.LogInfo("[Volcano] Setting up AudioSources...");
			AudioSource val = enforcerObject.AddComponent<AudioSource>();
			val.spatialBlend = 0f;
			val.loop = true;
			val.volume = 0.1f;
			AudioSource val2 = enforcerObject.AddComponent<AudioSource>();
			val2.spatialBlend = 0f;
			val2.loop = false;
			val2.volume = 0.4f;
			AudioClip val3 = Plugin.PeakBundle.LoadAsset<AudioClip>("Au_Fire_Loop");
			AudioClip val4 = Plugin.PeakBundle.LoadAsset<AudioClip>("Au_Explosion_Debris");
			if ((Object)(object)val3 != (Object)null)
			{
				val.clip = val3;
				val.Play();
			}
			else
			{
				ModLogger.LogError("[Volcano] FAILED to load Au_Fire_Loop! Check asset name or bundle.");
			}
			if ((Object)(object)val4 != (Object)null)
			{
				val2.clip = val4;
				val2.Play();
			}
			else
			{
				ModLogger.LogError("[Volcano] FAILED to load Au_Explosion_Debris! Check asset name or bundle.");
			}
		}

		private static float GetSafeDropRate()
		{
			float num = 0.5f;
			try
			{
				int num2 = Mathf.Max(1, StonesConfig.VolcanoMaxStones.Value);
				int num3 = Mathf.Max(1, StonesConfig.VulcanStoneBurstCount.Value);
				float num4 = Mathf.Ceil((float)num2 / (float)num3);
				num = 7f / num4;
			}
			catch (Exception ex)
			{
				ModLogger.LogError("[Volcano] Error calculating dynamic drop rate: " + ex.Message);
			}
			if (num <= 0.1f)
			{
				num = 0.1f;
				ModLogger.LogWarning($"[Volcano] Calculated drop rate was under safe threshold! Clamped to {num}s.");
			}
			return num;
		}

		private static Vector3 ComputeBurstSpawnPosition(Vector3 playerCenter)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.Range(-8f, 8f);
			float num2 = Random.Range(-8f, 8f);
			return playerCenter + new Vector3(num, 18f, num2);
		}

		private static void SpawnStoneAbovePlayer(Player p, LayerMask groundMask, float skyHeight, float maxDistance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ComputeBurstSpawnPosition(p.character.Center);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.x, skyHeight, val.z);
			float y = p.character.Center.y;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(val2, Vector3.down, ref val3, maxDistance, ((LayerMask)(ref groundMask)).value, (QueryTriggerInteraction)1))
			{
				y = ((RaycastHit)(ref val3)).point.y;
			}
			float num = y + 30f;
			float num2 = p.character.Center.y + 60f;
			float num3 = Mathf.Max(num, num2);
			Vector3 pos = default(Vector3);
			((Vector3)(ref pos))..ctor(val.x, num3, val.z);
			GameObject val4 = ItemSpawnHelper.SpawnRandomStormStone(pos, Random.rotation);
			if ((Object)(object)val4 == (Object)null)
			{
				ModLogger.LogWarning("[Vulcan] Burst stone failed to spawn above player " + ((Object)p).name + ".");
			}
		}

		private static AtmosphereState CaptureAtmosphere(Light? sun)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			return new AtmosphereState
			{
				OriginalAmbient = RenderSettings.ambientLight,
				OriginalFogColor = RenderSettings.fogColor,
				OriginalFogDensity = RenderSettings.fogDensity,
				OriginalSunColor = (((Object)(object)sun != (Object)null) ? sun.color : Color.white),
				OriginalSunIntensity = (((Object)(object)sun != (Object)null) ? sun.intensity : 1f),
				OriginalFog = RenderSettings.fog
			};
		}

		private static IEnumerator FadeEnvironment(Light? sun, Color targetAmbient, Color targetFogColor, float targetFogDensity, Color targetSunColor, float targetSunIntensity, float duration)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Color startAmbient = RenderSettings.ambientLight;
			Color startFogColor = RenderSettings.fogColor;
			float startFogDensity = RenderSettings.fogDensity;
			Color startSunColor = (((Object)(object)sun != (Object)null) ? sun.color : Color.white);
			float startSunIntensity = (((Object)(object)sun != (Object)null) ? sun.intensity : 1f);
			if ((Object)(object)_visualEnforcer == (Object)null)
			{
				ModLogger.LogError("[Volcano] visualEnforcer is NULL inside FadeEnvironment! Aborting fade step.");
				yield break;
			}
			float elapsed = 0f;
			while (elapsed < duration)
			{
				float num = elapsed / duration;
				_visualEnforcer.ambient = Color.Lerp(startAmbient, targetAmbient, num);
				_visualEnforcer.fogColor = Color.Lerp(startFogColor, targetFogColor, num);
				_visualEnforcer.fogDensity = Mathf.Lerp(startFogDensity, targetFogDensity, num);
				_visualEnforcer.sunColor = Color.Lerp(startSunColor, targetSunColor, num);
				_visualEnforcer.sunIntensity = Mathf.Lerp(startSunIntensity, targetSunIntensity, num);
				elapsed += Time.deltaTime;
				yield return null;
			}
			_visualEnforcer.ambient = targetAmbient;
			_visualEnforcer.fogColor = targetFogColor;
			_visualEnforcer.fogDensity = targetFogDensity;
			_visualEnforcer.sunColor = targetSunColor;
			_visualEnforcer.sunIntensity = targetSunIntensity;
		}

		private static IEnumerator ShakeCamera(float duration, float magnitude)
		{
			if (!((Object)(object)_visualEnforcer == (Object)null))
			{
				_visualEnforcer.shakeMagnitude = magnitude;
				_visualEnforcer.isShaking = true;
				yield return (object)new WaitForSeconds(duration);
				_visualEnforcer.isShaking = false;
			}
		}

		private static Light? FindMainDirectionalLight()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			Light[] array = Object.FindObjectsByType<Light>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			Light result = null;
			float num = float.NegativeInfinity;
			Light[] array2 = array;
			foreach (Light val in array2)
			{
				if ((int)val.type == 1 && ((Behaviour)val).enabled && val.intensity > num)
				{
					result = val;
					num = val.intensity;
				}
			}
			return result;
		}

		private static bool IsMaster()
		{
			return PhotonNetwork.IsMasterClient;
		}
	}
	public class VolcanoVisuals : MonoBehaviour
	{
		public Light? sun;

		public Color ambient;

		public Color fogColor;

		public Color sunColor;

		public float fogDensity;

		public float sunIntensity;

		private bool _enforceEnvironment;

		private bool _isShaking;

		public float shakeMagnitude;

		private Camera? targetCam;

		private Vector3 shakeBasePosition;

		private bool shakeBaseCaptured;

		public bool enforceEnvironment
		{
			get
			{
				return _enforceEnvironment;
			}
			set
			{
				if (_enforceEnvironment != value)
				{
					ModLogger.LogInfo($"[VolcanoVisuals] enforceEnvironment changed: {_enforceEnvironment} -> {value}");
				}
				_enforceEnvironment = value;
			}
		}

		public bool isShaking
		{
			get
			{
				return _isShaking;
			}
			set
			{
				if (_isShaking != value)
				{
					ModLogger.LogInfo($"[VolcanoVisuals] isShaking changed: {_isShaking} -> {value} (Magnitude: {shakeMagnitude})");
				}
				_isShaking = value;
			}
		}

		private void Start()
		{
			EnsureCameraAssigned();
			if ((Object)(object)sun == (Object)null)
			{
				ModLogger.LogWarning("[VolcanoVisuals] Warning: Sun light reference is null. Environment sun color/intensity will not be enforced.");
			}
		}

		private void LateUpdate()
		{
			if (enforceEnvironment)
			{
				ApplyEnvironmentalVisuals();
			}
			if (isShaking)
			{
				ApplyCameraShake();
			}
			else if (shakeBaseCaptured)
			{
				RestoreCameraPosition();
			}
		}

		private void OnDestroy()
		{
			ModLogger.LogInfo("[VolcanoVisuals] Component destroyed / cleaned up.");
		}

		private void ApplyEnvironmentalVisuals()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			RenderSettings.ambientLight = ambient;
			RenderSettings.fogColor = fogColor;
			RenderSettings.fogDensity = fogDensity;
			RenderSettings.fog = true;
			RenderSettings.fogMode = (FogMode)3;
			if ((Object)(object)sun != (Object)null)
			{
				sun.color = sunColor;
				sun.intensity = sunIntensity;
			}
			Shader.SetGlobalColor("SkyTopColor", new Color(0.2f, 0f, 0f));
			Shader.SetGlobalColor("SkyMidColor", new Color(0.8f, 0.3f, 0f));
			Shader.SetGlobalColor("SkyBottomColor", new Color(1f, 0.2f, 0f));
			Shader.SetGlobalFloat("GlobalWind", 1f);
		}

		private void ApplyCameraShake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			if (EnsureCameraAssigned())
			{
				if (!shakeBaseCaptured)
				{
					CaptureBaseCameraPosition();
				}
				float num = Random.Range(-1f, 1f) * shakeMagnitude;
				float num2 = Random.Range(-1f, 1f) * shakeMagnitude;
				((Component)targetCam).transform.localPosition = shakeBasePosition + new Vector3(num, num2, 0f);
			}
		}

		private void CaptureBaseCameraPosition()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			shakeBasePosition = ((Component)targetCam).transform.localPosition;
			shakeBaseCaptured = true;
			ModLogger.LogInfo($"[VolcanoVisuals] Captured base camera position for shake: {shakeBasePosition}");
		}

		private void RestoreCameraPosition()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)targetCam != (Object)null)
			{
				((Component)targetCam).transform.localPosition = shakeBasePosition;
				ModLogger.LogInfo("[VolcanoVisuals] Shake ended. Camera position restored to base.");
			}
			shakeBaseCaptured = false;
		}

		private bool EnsureCameraAssigned()
		{
			if ((Object)(object)targetCam != (Object)null)
			{
				return true;
			}
			targetCam = Camera.main ?? Object.FindAnyObjectByType<Camera>();
			if ((Object)(object)targetCam != (Object)null)
			{
				ModLogger.LogInfo("[VolcanoVisuals] Target camera acquired: '" + ((Object)targetCam).name + "'");
				return true;
			}
			ModLogger.LogWarning("[VolcanoVisuals] Cannot apply camera effects: targetCam is null!");
			return false;
		}
	}
	[DisallowMultipleComponent]
	public sealed class VulcanManager : MonoBehaviourPunCallbacks
	{
		private const string VulcanOutbreakRoomKey = "Stones.VulcanOutbreakActive";

		private Coroutine? _activeOutbreakCoroutine;

		private bool _isVulcanOutbreakActive;

		public static VulcanManager? Instance { get; private set; }

		public bool IsVulcanOutbreakActive => _isVulcanOutbreakActive;

		public static VulcanManager EnsureInstance()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance;
			}
			GameObject val = new GameObject("VulcanStormManager");
			Object.DontDestroyOnLoad((Object)(object)val);
			return val.AddComponent<VulcanManager>();
		}

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			SyncFromRoomProperties();
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public override void OnJoinedRoom()
		{
			SyncFromRoomProperties();
		}

		public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"Stones.VulcanOutbreakActive"))
			{
				SyncFromRoomProperties();
			}
		}

		public override void OnLeftRoom()
		{
			ClearLocalState();
		}

		public void StartVulcanOutbreak()
		{
			if (!_isVulcanOutbreakActive)
			{
				_isVulcanOutbreakActive = true;
				ModLogger.LogInfo("[Vulcan] A volcanic outbreak has begun.");
				if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
				{
					SetRoomOutbreakState(active: true);
				}
				_activeOutbreakCoroutine = ((MonoBehaviour)this).StartCoroutine(VolcanoEvent.Run());
			}
		}

		public void StopVulcanOutbreak()
		{
			if (_isVulcanOutbreakActive)
			{
				_isVulcanOutbreakActive = false;
				ModLogger.LogInfo("[Vulcan] The volcanic outbreak has cleared.");
				if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
				{
					SetRoomOutbreakState(active: false);
				}
				if (_activeOutbreakCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_activeOutbreakCoroutine);
					_activeOutbreakCoroutine = null;
				}
				VolcanoEvent.CleanupVisuals();
			}
		}

		private void SyncFromRoomProperties()
		{
			if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
			{
				return;
			}
			object obj = null;
			if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"Stones.VulcanOutbreakActive", out object value) && value is bool)
			{
				if ((bool)value)
				{
					StartVulcanOutbreak();
				}
				else
				{
					StopVulcanOutbreak();
				}
			}
		}

		private void ClearLocalState()
		{
			_isVulcanOutbreakActive = false;
		}

		private void SetRoomOutbreakState(bool active)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (PhotonNetwork.CurrentRoom != null)
			{
				Hashtable val = new Hashtable { [(object)"Stones.VulcanOutbreakActive"] = active };
				PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			}
		}

		public bool VulcanOutbreakEnabled()
		{
			return StonesConfig.EnableVolcanoEvent.Value;
		}
	}
	[HarmonyPatch(typeof(WindChillZone), "RPCA_ToggleWind")]
	public static class VulcanPatches
	{
		[HarmonyPrefix]
		public static bool Prefix(bool set, Vector3 windDir, float untilSwitch, WindChillZone __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			VulcanManager vulcanManager = VulcanManager.EnsureInstance();
			if (!set)
			{
				vulcanManager.StopVulcanOutbreak();
				return true;
			}
			if (!vulcanManager.VulcanOutbreakEnabled())
			{
				return true;
			}
			if (RollForVulcanOutbreak(windDir, untilSwitch))
			{
				ModLogger.LogInfo("[Vulcan] Hijacked storm start. Launching volcanic outbreak.");
				vulcanManager.StartVulcanOutbreak();
				return false;
			}
			Traverse.Create((object)WindChillZone.instance).Field("untilSwitch").SetValue((object)(-1f));
			return true;
		}

		private static bool IsMaster()
		{
			return PhotonNetwork.IsMasterClient;
		}

		private unsafe static bool RollForVulcanOutbreak(Vector3 windDir, float untilSwitch)
		{
			int num = ((object)(*(Vector3*)(&windDir))/*cast due to .constrained prefix*/).GetHashCode() ^ untilSwitch.GetHashCode();
			Random random = new Random(num);
			double num2 = random.NextDouble();
			double num3 = StonesConfig.VulcanOutbreakChance.Value;
			bool flag = num2 <= num3;
			string text = (PhotonNetwork.IsMasterClient ? "Master" : "Client");
			ModLogger.LogInfo($"[Vulcan] {text} Roll -> Seed: {num} | Rolled: {num2:F4} | Target: <= {num3} | Result: {flag}");
			return flag;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}