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.2.0")] [assembly: AssemblyInformationalVersion("0.1.2+83a32adcc880411693731e4c30bdb893eada8c95")] [assembly: AssemblyProduct("q4y.Stones")] [assembly: AssemblyTitle("Stones")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.2.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(); } private void Update() { //IL_001d: 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_0039: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) if (hasTriggered || !((MonoBehaviourPun)this).photonView.IsMine || (int)item.itemState != 0) { return; } hasTriggered = true; Vector3 position = ((Component)this).transform.position; Quaternion rotation = ((Component)this).transform.rotation; ModLogger.LogInfo("[AutoLight] Custom explosive dropped/thrown. Spawning native vanilla Dynamite swap..."); try { GameObject val = PhotonNetwork.Instantiate("0_Items/Dynamite", position, rotation, (byte)0, (object[])null); if ((Object)(object)val != (Object)null) { Dynamite component = val.GetComponent(); 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); } 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(); } private void Update() { //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_008d: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (hasExploded || !((MonoBehaviourPun)this).photonView.IsMine) { return; } bool flag = false; IntItemData val = default(IntItemData); if (item.data != null && item.data.TryGetDataEntry((DataEntryKey)1, ref val) && val.Value > 0) { flag = true; } if (!flag) { return; } hasExploded = true; Vector3 position = ((Component)this).transform.position; Quaternion rotation = ((Component)this).transform.rotation; ModLogger.LogInfo("[GrenadeCook] Grenade cooked! Spawning custom 'Explosion' item via Photon..."); try { string text = "0_Items/" + Plugin.ModId + ":Explosion"; GameObject val2 = PhotonNetwork.Instantiate(text, position, rotation, (byte)0, (object[])null); if ((Object)(object)val2 != (Object)null) { Item component = val2.GetComponent(); 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); } if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data.currentItem == (Object)(object)item) { Player.localPlayer.EmptySlot(Character.localCharacter.refs.items.currentSelectedSlot); } item.ClearDataFromBackpack(); PhotonNetwork.Destroy(((Component)this).gameObject); } } 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(); 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(); Rigidbody component2 = go.GetComponent(); Collider component3 = go.GetComponent(); PhotonView component4 = go.GetComponent(); StoneBehavior component5 = go.GetComponent(); 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(localeStrings)); } } } } [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(); if ((Object)(object)component != (Object)null) { component.isKinematic = true; } } } } public static class ModLogger { private static bool ShouldLog(LogLevel level) { if (!StonesConfig.EnableDebugLogging.Value) { return false; } return StonesConfig.MinLogLevel.Value <= level; } 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.2")] 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.2"; 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); VulcanStormManager.EnsureInstance(); BundleLoader.LoadBundleWithName((BaseUnityPlugin)(object)this, "stones.peakbundle", (Action)RegisterStonesContent); } private void RegisterStonesContent(PeakBundle peakBundle) { Plugin.peakBundle = peakBundle; ModLogger.LogInfo("[Stones] Registering stone content from 'stones.peakbundle'..."); ProcessTierList(StoneTiers, delegate(UnityItemContent content2, string name) { AttachBehavior(content2, name); AttachBehavior(content2, name); }); ProcessTierList(StormStoneTiers, delegate(UnityItemContent content2, string name) { AttachBehavior(content2, name); AttachBehavior(content2, name); }); UnityItemContent content = peakBundle.LoadAsset("ExplosionContent"); AttachBehavior(content, "ExplosionContent"); content = peakBundle.LoadAsset("GrenadeContent"); AttachBehavior(content, "GrenadeContent"); ProcessTierList(OtherItems, delegate { }); peakBundle.Mod.RegisterContent(); ModLogger.LogInfo("[Stones] PEAKLib content registration batch complete."); void ProcessTierList(StonesItem[] tiers, Action attachBehaviors) { for (int i = 0; i < tiers.Length; i++) { StonesItem stonesItem = tiers[i]; UnityItemContent val = peakBundle.LoadAsset(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(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() == (Object)null) { itemPrefab.AddComponent(); ModLogger.LogInfo("[Stones] Attached " + typeof(T).Name + " to '" + contentName + "' ItemPrefab."); } } } private void Update() { if (Input.GetKeyDown((KeyCode)283)) { HandleF2(); } if (Input.GetKeyDown((KeyCode)284)) { HandleF3(); } if (Input.GetKeyDown((KeyCode)285)) { HandleF4(); } } 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."); } VulcanStormManager vulcanStormManager = VulcanStormManager.EnsureInstance(); ModLogger.LogInfo("F3 pressed: forcing the volcanic outbreak immediately for debugging."); vulcanStormManager.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 (PhotonNetwork.IsMasterClient && updateSegment && (Object)(object)MapStoneSpawner.Instance != (Object)null) { ((MonoBehaviour)MapStoneSpawner.Instance).StartCoroutine(MapStoneSpawner.Instance.DelayedRetryQueue()); } } } [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 pendingSpawns = new List(); 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(); } private void OnDestroy() { ModLogger.LogDebug("[Stones] MapStoneSpawner destroyed."); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } public override void OnEnable() { ((MonoBehaviourPunCallbacks)this).OnEnable(); if ((Object)(object)Instance == (Object)null) { Instance = this; } } public override void OnLeftRoom() { _hasSpawnedThisRun = false; pendingSpawns.Clear(); } public void InitializeSpawnQueue() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } pendingSpawns.Clear(); float num = lobbyExclusionRadius * lobbyExclusionRadius; int value = StonesConfig.MaxStones.Value; for (int i = 0; i < value; i++) { float num2 = 0f; float num3 = 0f; bool flag = false; int num4 = 1 + Mathf.Max(0, maxExclusionRetries); for (int j = 0; j < num4; j++) { num2 = Random.Range(mapMinX, mapMaxX); num3 = Random.Range(mapMinZ, mapMaxZ); if (num2 * num2 + num3 * num3 >= num) { flag = true; break; } } if (flag) { pendingSpawns.Add(new Vector2(num2, num3)); } } ModLogger.LogDebug($"[Stones] Queued {pendingSpawns.Count} stone locations."); ((MonoBehaviour)this).StartCoroutine(ProcessPendingSpawns()); } public IEnumerator ProcessPendingSpawns() { if (!PhotonNetwork.IsMasterClient || pendingSpawns.Count == 0) { yield break; } List stillPending = new List(); int successfulThisBatch = 0; Vector3 val2 = default(Vector3); RaycastHit val3 = default(RaycastHit); for (int i = 0; i < pendingSpawns.Count; i++) { Vector2 val = pendingSpawns[i]; ((Vector3)(ref val2))..ctor(val.x, skySpawnHeight, val.y); if (Physics.Raycast(val2, Vector3.down, ref val3, raycastMaxDistance, ((LayerMask)(ref groundLayerMask)).value, triggerInteraction)) { Vector3 pos = ((RaycastHit)(ref val3)).point + Vector3.up * groundOffset; if ((Object)(object)ItemSpawnHelper.SpawnRandomStone(pos, Random.rotation) != (Object)null) { successfulThisBatch++; } } else { stillPending.Add(val); } if (spawnsPerFrame > 0 && (i + 1) % spawnsPerFrame == 0) { yield return null; } } pendingSpawns = stillPending; ModLogger.LogInfo($"[Stones] Spawned {successfulThisBatch} stones this batch. {pendingSpawns.Count} waiting for unloaded chunks."); } public IEnumerator DelayedRetryQueue() { ModLogger.LogInfo("[Stones] Waiting 3s for new chunks to load before retrying stone spawns..."); yield return (object)new WaitForSeconds(10f); yield return ((MonoBehaviour)this).StartCoroutine(ProcessPendingSpawns()); } private void OnValidate() { int value = StonesConfig.MaxStones.Value; if (value < 0) { value = 0; } 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 { [HarmonyPatch("StartRun")] [HarmonyPostfix] public static void StartRun_Postfix() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown if (!PhotonNetwork.IsMasterClient) { return; } if (MapStoneSpawner._hasSpawnedThisRun) { ModLogger.LogInfo("[Stones] RunStart_StoneScatter_Patch: scatter already fired for this run, skipping duplicate RunManager.StartRun call."); return; } MapStoneSpawner._hasSpawnedThisRun = true; MapStoneSpawner mapStoneSpawner = MapStoneSpawner.Instance; if ((Object)(object)mapStoneSpawner == (Object)null) { GameObject val = new GameObject("MapStoneSpawner (RunStart)"); Object.DontDestroyOnLoad((Object)(object)val); mapStoneSpawner = val.AddComponent(); } if ((Object)(object)mapStoneSpawner == (Object)null) { MapStoneSpawner._hasSpawnedThisRun = false; ModLogger.LogError("[Stones] RunStart_StoneScatter_Patch: failed to create MapStoneSpawner host GameObject; scatter aborted for this run."); } 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)."); } } [HarmonyPatch("EndGame")] [HarmonyPostfix] public static void EndGame_Postfix() { if (MapStoneSpawner._hasSpawnedThisRun) { ModLogger.LogInfo("[Stones] RunEnd_StoneScatter_FlagReset_Patch: RunManager.EndGame fired — resetting scatter flag for next run."); MapStoneSpawner._hasSpawnedThisRun = false; } } } [RequireComponent(typeof(PhotonView))] public class StoneBehavior : MonoBehaviourPun { private float lastHitTime = -1f; private void OnCollisionEnter(Collision collision) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) Item component = ((Component)this).GetComponent(); if ((Object)(object)component == (Object)null || (int)component.itemState != 0) { return; } Bodypart component2 = collision.gameObject.GetComponent(); if ((Object)(object)component2 == (Object)null) { return; } Character componentInParent = ((Component)component2).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || Time.time - lastHitTime < 1f) { return; } lastHitTime = Time.time; Vector3 relativeVelocity = collision.relativeVelocity; float magnitude = ((Vector3)(ref relativeVelocity)).magnitude; if (((MonoBehaviourPun)componentInParent).photonView.IsMine) { float num = component.CarryWeight; if (num <= 4f) { return; } float num2 = Mathf.Clamp01(num / 20f); float num3 = Mathf.InverseLerp(10f, 25f, magnitude); float num4 = num3 * num2 * 0.3f; if (num4 > 0f) { try { componentInParent.refs.afflictions.AddStatus((STATUSTYPE)0, num4, false, true, true); ModLogger.LogInfo("[Stone] Injury -> victim='" + componentInParent.characterName + "', " + $"weight={num:F2}, speed={magnitude:F2}m/s, " + $"stoneFactor={num2:F3}, amount={num4:F3}."); } catch (Exception ex) { ModLogger.LogError("[Stone] AddStatus threw " + ex.GetType().Name + ": " + ex.Message); } } } if (PhotonNetwork.IsMasterClient) { ((MonoBehaviourPun)this).photonView.RPC("PlayImpactVisuals", (RpcTarget)3, 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) Item component = ((Component)this).GetComponent(); if (!((Object)(object)component != (Object)null)) { return "(no Item)"; } return ((object)component.itemState/*cast due to .constrained prefix*/).ToString(); } } public enum LogLevel { Debug, Info, Warning, Error, None } public static class StonesConfig { public static ConfigEntry EnableDebugLogging { get; private set; } public static ConfigEntry EnableDebug { get; private set; } public static ConfigEntry MinLogLevel { get; private set; } public static ConfigEntry MaxStones { get; private set; } public static ConfigEntry VolcanoMaxStones { get; private set; } public static ConfigEntry EnableVolcanoEvent { get; private set; } public static ConfigEntry VulcanOutbreakChance { get; private set; } public static ConfigEntry VulcanStoneBurstCount { get; private set; } public static ConfigEntry StoneRainDropRate { get; private set; } public static void Bind(ConfigFile config) { EnableDebugLogging = config.Bind("Debug", "EnableLogging", true, "If true, enables detailed debug logging in the console."); EnableDebug = config.Bind("Debug", "EnableDebug", true, "If true, enables debug commands."); MinLogLevel = config.Bind("Debug", "MinimumLogLevel", LogLevel.None, "Minimum severity level of logs to display in the console. Options: Debug, Info, Warning, Error, None."); MaxStones = config.Bind("1. Spawning", "MaxStones", 700, "The maximum number of items allowed in the world."); EnableVolcanoEvent = config.Bind("2. Events", "EnableVolcanoEvent", true, "Set to true to allow the volcanic outbreak hijack."); VolcanoMaxStones = config.Bind("2. Events", "VolcanoMaxStones", 30, "The maximum number of items allowed in a volcanic outbreak."); VulcanOutbreakChance = config.Bind("2. Events", "VulcanOutbreakChance", 1f, "Chance for a normal storm start to become a volcanic outbreak."); VulcanStoneBurstCount = config.Bind("2. Events", "VulcanStoneBurstCount", 5, "How many stones to burst into the sky when the outbreak starts."); StoneRainDropRate = config.Bind("2. Events", "StoneRainDropRate", 2f, "Legacy setting kept for compatibility with the old coroutine path."); } } public class StormStoneBehavior : MonoBehaviour { private Rigidbody? rb; private Item? itemComponent; private Breakable? breakableComponent; private PhotonView? view; private float lifeTimer; private float maxLife = 25f; private float gracePeriod = 2f; private float tumbleSpeed = 15f; private void Awake() { rb = ((Component)this).GetComponent(); itemComponent = ((Component)this).GetComponent(); breakableComponent = ((Component)this).GetComponent(); view = ((Component)this).GetComponent(); if ((Object)(object)itemComponent != (Object)null) { itemComponent.blockInteraction = true; } if ((Object)(object)breakableComponent != (Object)null) { breakableComponent.breakOnCollision = false; ((Behaviour)breakableComponent).enabled = false; } MonoBehaviour[] componentsInChildren = ((Component)this).GetComponentsInChildren(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 Start() { //IL_001b: 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) if (PhotonNetwork.IsMasterClient && (Object)(object)rb != (Object)null) { rb.angularVelocity = Random.insideUnitSphere * tumbleSpeed; } } private void Update() { //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) if (!PhotonNetwork.IsMasterClient) { return; } lifeTimer += Time.deltaTime; if (lifeTimer >= maxLife) { Despawn(); } else if (lifeTimer >= gracePeriod && (Object)(object)rb != (Object)null) { Vector3 linearVelocity = rb.linearVelocity; if (((Vector3)(ref linearVelocity)).sqrMagnitude < 0.1f) { Despawn(); } } } 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); } } } [HarmonyPatch(typeof(WindChillZone), "RPCA_ToggleWind")] public static class WindChillZone_VulcanHijack_Patch { [HarmonyPrefix] public static bool Prefix(bool set, Vector3 windDir, float untilSwitch, WindChillZone __instance) { if (!StonesConfig.EnableVolcanoEvent.Value) { return true; } VulcanStormManager.EnsureInstance(); if (!set) { VulcanStormManager.Instance?.StopVulcanOutbreak(); return true; } if (PhotonNetwork.IsMasterClient) { if (Random.value <= StonesConfig.VulcanOutbreakChance.Value) { ModLogger.LogInfo("[Vulcan] Hijacked storm start. Launching volcanic outbreak."); VulcanStormManager.Instance?.StartVulcanOutbreak(); return false; } } else if ((Object)(object)VulcanStormManager.Instance != (Object)null && VulcanStormManager.Instance.IsVulcanOutbreakActive) { return false; } Traverse.Create((object)WindChillZone.instance).Field("untilSwitch").SetValue((object)(-1f)); return true; } } [HarmonyPatch(typeof(WindChillZone), "ApplyStatus")] public static class WindChillZone_VulcanStatus_Patch { private static bool s_loggedMissingBurnStatus; [HarmonyPrefix] public static bool Prefix(Character character, WindChillZone __instance) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!StonesConfig.EnableVolcanoEvent.Value) { return true; } VulcanStormManager instance = VulcanStormManager.Instance; if ((Object)(object)instance == (Object)null) { return true; } if (!instance.IsVulcanOutbreakActive) { return true; } float num = Mathf.Clamp01(__instance.windIntensity); float climbingStamMinimumMultiplier = Mathf.Max(__instance.grabStaminaMultiplierDuringWind * num * 4f, 1f); character.refs.climbing.climbingStamMinimumMultiplier = climbingStamMinimumMultiplier; if (TryGetVulcanStatusType(out var statusType)) { float num2 = num * __instance.statusApplicationPerSecond * Time.deltaTime * 2f; character.refs.afflictions.AddStatus(statusType, num2, false, true, true); } else if (!s_loggedMissingBurnStatus) { s_loggedMissingBurnStatus = true; ModLogger.LogWarning("[Vulcan] No burn-like status enum found. The outbreak will only increase wind strain and skip the custom affliction."); } return false; } private static bool TryGetVulcanStatusType(out STATUSTYPE statusType) { string[] array = new string[4] { "Burning", "Burn", "Heat", "Fire" }; string[] array2 = array; foreach (string value in array2) { if (Enum.TryParse(value, ignoreCase: true, out statusType)) { return true; } } statusType = (STATUSTYPE)0; return false; } } 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; public static IEnumerator Run() { float startTime = Time.time; Plugin.logger.LogInfo((object)$"[Volcano] === EVENT START === Current Time: {startTime:F2}"); Plugin.logger.LogInfo((object)"[Volcano] Creating VolcanoVisualEnforcer GameObject..."); GameObject enforcerObject = new GameObject("VolcanoVisualEnforcer"); visualEnforcer = enforcerObject.AddComponent(); Plugin.logger.LogInfo((object)"[Volcano] Setting up AudioSource for Au_Fire_Loop..."); AudioSource val = enforcerObject.AddComponent(); val.spatialBlend = 0f; val.loop = true; val.volume = 0.1f; AudioSource val2 = enforcerObject.AddComponent(); val2.spatialBlend = 0f; val2.loop = false; val2.volume = 0.4f; AudioClip val3 = Plugin.peakBundle.LoadAsset("Au_Fire_Loop"); AudioClip val4 = Plugin.peakBundle.LoadAsset("Au_Explosion_Debris"); if ((Object)(object)val3 != (Object)null) { val.clip = val3; val.Play(); Plugin.logger.LogInfo((object)"[Volcano] Successfully loaded and playing Au_Fire_Loop from bundle."); } if ((Object)(object)val4 != (Object)null) { val2.clip = val4; val2.Play(); Plugin.logger.LogInfo((object)"[Volcano] Successfully loaded and playing Au_Explosion_Debris from bundle."); } Light sun = FindMainDirectionalLight(); visualEnforcer.sun = sun; visualEnforcer.enforceEnvironment = true; Plugin.logger.LogInfo((object)("[Volcano] Enforcer attached and initialized. Sun reference: " + (((Object)(object)sun != (Object)null) ? ((Object)sun).name : "null"))); AtmosphereState state = CaptureAtmosphere(sun); Plugin.logger.LogInfo((object)$"[Volcano] Captured original atmosphere state (Fog enabled: {state.OriginalFog}, Fog Density: {state.OriginalFogDensity:F3})"); Plugin.logger.LogInfo((object)$"[Volcano] Phase 1 (Fade In) starting. Expected duration: {5f}s"); yield return FadeEnvironment(sun, StormAmbient, StormFogColor, 0.16f, StormSunColor, 1.5f, 5f); Plugin.logger.LogInfo((object)$"[Volcano] Phase 1 completed. (Elapsed: {Time.time - startTime:F2}s)"); float shakeStart = Time.time; Plugin.logger.LogInfo((object)$"[Volcano] Phase 2 (Camera Shake) starting. Duration: {2f}s, Magnitude: {2f}"); yield return ShakeCamera(2f, 2f); Plugin.logger.LogInfo((object)$"[Volcano] Phase 2 completed. (Phase Duration: {Time.time - shakeStart:F2}s)"); float delayStart = Time.time; Plugin.logger.LogInfo((object)$"[Volcano] Phase 3 (Buildup Delay) starting. Holding for {5f}s..."); yield return (object)new WaitForSeconds(5f); Plugin.logger.LogInfo((object)$"[Volcano] Phase 3 completed. (Phase Duration: {Time.time - delayStart:F2}s)"); float rainStart = Time.time; Plugin.logger.LogInfo((object)$"[Volcano] Phase 4 (Stone Rain) starting. Target drops: {StonesConfig.VolcanoMaxStones.Value}"); float dropRate = 0.8f; try { dropRate = StonesConfig.StoneRainDropRate.Value; } catch (Exception ex) { Plugin.logger.LogError((object)("[Volcano] Error reading StonesConfig.StoneRainDropRate: " + ex.Message)); } Plugin.logger.LogInfo((object)$"[Volcano] Drop Interval: {dropRate}s"); if (dropRate <= 0.1f) { dropRate = 0.5f; Plugin.logger.LogWarning((object)$"[Volcano] Drop rate was under safe threshold! Forcing to {dropRate}s."); } int burstCount = Mathf.Max(1, StonesConfig.VulcanStoneBurstCount.Value); int ItemsToDrop = StonesConfig.VolcanoMaxStones.Value; for (int i = 0; i < ItemsToDrop; i += burstCount) { SpawnVulcanStoneBurst(); yield return (object)new WaitForSeconds(dropRate); } Plugin.logger.LogInfo((object)$"[Volcano] Phase 4 completed. (Phase Duration: {Time.time - rainStart:F2}s)"); float fadeOutStart = Time.time; Plugin.logger.LogInfo((object)$"[Volcano] Phase 5 (Fade Out) starting. Expected duration: {5f}s"); yield return FadeEnvironment(sun, state.OriginalAmbient, state.OriginalFogColor, state.OriginalFogDensity, state.OriginalSunColor, state.OriginalSunIntensity, 5f); Plugin.logger.LogInfo((object)$"[Volcano] Phase 5 completed. (Phase Duration: {Time.time - fadeOutStart:F2}s)"); Plugin.logger.LogInfo((object)"[Volcano] Cleaning up enforcer object..."); if ((Object)(object)enforcerObject != (Object)null) { Object.Destroy((Object)(object)enforcerObject); visualEnforcer = null; } RenderSettings.fog = state.OriginalFog; Plugin.logger.LogInfo((object)$"[Volcano] === EVENT COMPLETE === Total Time Elapsed: {Time.time - startTime:F2}s"); } 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(-6f, 6f); float num2 = Random.Range(-6f, 6f); return playerCenter + new Vector3(num, 18f, num2); } private static void SpawnVulcanStoneBurst() { //IL_0053: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } int num = Mathf.Max(1, StonesConfig.VulcanStoneBurstCount.Value); Player[] array = Object.FindObjectsByType((FindObjectsSortMode)0); Player[] array2 = array; foreach (Player val in array2) { if ((Object)(object)val == (Object)null || (Object)(object)val.character == (Object)null) { continue; } for (int j = 0; j < num; j++) { Vector3 pos = ComputeBurstSpawnPosition(val.character.Center); GameObject val2 = ItemSpawnHelper.SpawnRandomStormStone(pos, Random.rotation); if ((Object)(object)val2 == (Object)null) { Plugin.logger.LogWarning((object)$"[Vulcan] Burst stone {j + 1}/{num} failed to spawn."); } } } } 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; } ModLogger.LogInfo($"[Volcano] FadeEnvironment started over {duration:F1}s."); 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; ModLogger.LogInfo("[Volcano] FadeEnvironment target values locked in."); } private static IEnumerator ShakeCamera(float duration, float magnitude) { if ((Object)(object)visualEnforcer == (Object)null) { ModLogger.LogError("[Volcano] visualEnforcer is NULL inside ShakeCamera! Aborting shake step."); yield break; } ModLogger.LogInfo($"[Volcano] Enabling camera shake on visualEnforcer (mag={magnitude}, duration={duration}s)"); visualEnforcer.shakeMagnitude = magnitude; visualEnforcer.isShaking = true; yield return (object)new WaitForSeconds(duration); ModLogger.LogInfo("[Volcano] Disabling camera shake on visualEnforcer."); 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((FindObjectsInactive)0, (FindObjectsSortMode)0); Light val = null; float num = float.NegativeInfinity; Light[] array2 = array; foreach (Light val2 in array2) { if ((int)val2.type == 1 && ((Behaviour)val2).enabled && val2.intensity > num) { val = val2; num = val2.intensity; } } if ((Object)(object)val == (Object)null) { ModLogger.LogWarning("[Volcano] No active directional light found in scene."); return val; } ModLogger.LogInfo($"[Volcano] Found primary directional light: '{((Object)val).name}' (Intensity: {val.intensity})"); return val; } } 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 shakeBaseEuler; 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() { targetCam = Camera.main ?? Object.FindAnyObjectByType(); if ((Object)(object)targetCam != (Object)null) { ModLogger.LogInfo("[VolcanoVisuals] Initialized successfully. Target camera found: '" + ((Object)targetCam).name + "'"); } else { ModLogger.LogWarning("[VolcanoVisuals] Initialized, but NO camera could be found in the scene yet!"); } 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() { //IL_000c: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) if (enforceEnvironment) { 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); } if (!isShaking) { if (shakeBaseCaptured && (Object)(object)targetCam != (Object)null) { ((Component)targetCam).transform.localEulerAngles = shakeBaseEuler; ModLogger.LogInfo("[VolcanoVisuals] Shake ended. Camera rotation restored to base."); } shakeBaseCaptured = false; return; } if ((Object)(object)targetCam == (Object)null) { targetCam = Camera.main ?? Object.FindAnyObjectByType(); if ((Object)(object)targetCam != (Object)null) { ModLogger.LogInfo("[VolcanoVisuals] Target camera re-acquired during shake: '" + ((Object)targetCam).name + "'"); } } if ((Object)(object)targetCam == (Object)null) { ModLogger.LogWarning("[VolcanoVisuals] Cannot shake camera: targetCam is still null!"); return; } if (!shakeBaseCaptured) { shakeBaseEuler = ((Component)targetCam).transform.localPosition; shakeBaseCaptured = true; ModLogger.LogInfo($"[VolcanoVisuals] Captured base camera position for shake: {shakeBaseEuler}"); } float num = Random.Range(-1f, 1f) * shakeMagnitude; float num2 = Random.Range(-1f, 1f) * shakeMagnitude; ((Component)targetCam).transform.localPosition = shakeBaseEuler + new Vector3(num, num2, 0f); } private void OnDestroy() { ModLogger.LogInfo("[VolcanoVisuals] Component destroyed / cleaned up."); } } [DisallowMultipleComponent] public sealed class VulcanStormManager : MonoBehaviourPunCallbacks { private const string VulcanOutbreakRoomKey = "Stones.VulcanOutbreakActive"; private bool isVulcanOutbreakActive; public static VulcanStormManager? Instance { get; private set; } public bool IsVulcanOutbreakActive => isVulcanOutbreakActive; public static VulcanStormManager 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(); } 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)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); } ((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); } } } private void SyncFromRoomProperties() { if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { object obj = null; if (((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"Stones.VulcanOutbreakActive", out object value)) { obj = value; } bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { 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); } } } } 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 { } }