Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ElementalStorms v1.0.0
ElementalStorms.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ElementalStorms")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("A progression-driven storm system that adds dynamic hazards and atmospheric effects based on boss progression")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ElementalStorms")] [assembly: AssemblyTitle("ElementalStorms")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 ElementalStorms { [BepInPlugin("com.ruijven.elementalstorms", "ElementalStorms", "1.0.0")] internal class ElementalStormsPlugin : BaseUnityPlugin { private class StormClonerRunner : MonoBehaviour { private void Update() { if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)EnvMan.instance != (Object)null) { StormEnvironmentCloner.Initialize(); Object.Destroy((Object)(object)((Component)this).gameObject); } } } public const string PluginGUID = "com.ruijven.elementalstorms"; public const string PluginName = "ElementalStorms"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Logger; public static ConfigEntry<bool> EnableMod; public static ConfigEntry<bool> EnableStructuralDamage; public static ConfigEntry<float> DungeonProtectionAltitude; public static ConfigEntry<float> StructuralDamageAmount; public static float s_hudMessageTimer; public static bool s_hudMessageActive; public const float HUD_MESSAGE_DURATION = 5f; internal static ElementalStormsPlugin Instance { get; private set; } private void Awake() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; InitializeConfig(); ScheduleStormCloning(); ProjectileSpawner.Initialize(); StatusEffectManager.Initialize(); CreateUpdaterComponents(); CreateStormEventManager(); Harmony val = new Harmony("com.ruijven.elementalstorms"); val.PatchAll(Assembly.GetExecutingAssembly()); Logger.LogInfo((object)"ElementalStorms v1.0.0 loaded successfully!"); Logger.LogInfo((object)"Progression-driven storm hazards activated!"); } private void CreateUpdaterComponents() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("ElementalWeather_Updaters"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<LightningSystemUpdater>(); val.AddComponent<HUDMessageUpdater>(); } private void CreateStormEventManager() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("ElementalStorms_StormEventManager"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<ElementalStormManager>(); } private void ScheduleStormCloning() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("ElementalWeather_StormCloner"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<StormClonerRunner>(); } private void InitializeConfig() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, new ConfigDescription("Master toggle for the entire ElementalWeather mod.", (AcceptableValueBase)null, Array.Empty<object>())); EnableStructuralDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Structural Damage", "EnableStructuralDamage", true, new ConfigDescription("Enable wind damage to exposed structures.", (AcceptableValueBase)null, Array.Empty<object>())); DungeonProtectionAltitude = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DungeonProtectionAltitude", 2000f, new ConfigDescription("Altitude threshold above which weather hazards are disabled (protects dungeons).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1000f, 5000f), Array.Empty<object>())); StructuralDamageAmount = ((BaseUnityPlugin)this).Config.Bind<float>("Structural Damage", "StructuralDamageAmount", 0.5f, new ConfigDescription("Damage dealt to structures per update when conditions are met.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); } public static bool IsInDungeonAltitude() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (EnableMod == null) { return false; } if (!EnableMod.Value) { return false; } if (DungeonProtectionAltitude == null) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } return ((Component)localPlayer).transform.position.y > DungeonProtectionAltitude.Value; } public static bool IsBossDefeated(string bossKey) { if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } return ZoneSystem.instance.GetGlobalKey(bossKey); } public static void ShowWeatherWarning(string message) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false); } } public static void ShowWeatherWarningTopLeft(string message) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)1, message, 0, (Sprite)null, false); s_hudMessageActive = true; s_hudMessageTimer = 0f; } } public static void ShowWeatherWarningTopCenter(string message) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false); s_hudMessageActive = true; s_hudMessageTimer = 0f; } } } public class HUDMessageUpdater : MonoBehaviour { private void Update() { if (!ElementalStormsPlugin.s_hudMessageActive) { return; } ElementalStormsPlugin.s_hudMessageTimer += Time.deltaTime; if (ElementalStormsPlugin.s_hudMessageTimer >= 5f) { ElementalStormsPlugin.s_hudMessageActive = false; ElementalStormsPlugin.s_hudMessageTimer = 0f; if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)1, "", 0, (Sprite)null, false); } } } } public class ElementalStormManager : MonoBehaviour { private float checkTimer = 0f; private const float CheckInterval = 1656f; private const float TriggerChance = 0.2f; private void Awake() { } private void Update() { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { checkTimer += Time.deltaTime; if (checkTimer >= 1656f) { checkTimer = 0f; TryTriggerElementalStorm(); } } } private void TryTriggerElementalStorm() { if (Random.value > 0.2f) { return; } List<string> list = new List<string>(); if (ZoneSystem.instance.GetGlobalKey("defeated_eikthyr")) { list.Add("ES_Eikthyr"); } if (ZoneSystem.instance.GetGlobalKey("defeated_gdking")) { list.Add("ES_Elder"); } if (ZoneSystem.instance.GetGlobalKey("defeated_bonemass")) { list.Add("ES_Bonemass"); } if (ZoneSystem.instance.GetGlobalKey("defeated_moder")) { list.Add("ES_Moder"); } if (ZoneSystem.instance.GetGlobalKey("defeated_goblinking")) { list.Add("ES_Yagluth"); } if (ZoneSystem.instance.GetGlobalKey("defeated_thequeen")) { list.Add("ES_Queen"); } if (ZoneSystem.instance.GetGlobalKey("defeated_fader")) { list.Add("ES_Fader"); } if (list.Count == 0) { return; } string stormName = list[Random.Range(0, list.Count)]; Player randomActivePlayer = GetRandomActivePlayer(); if ((Object)(object)randomActivePlayer != (Object)null) { if (IsNearActiveBoss(randomActivePlayer)) { ElementalStormsPlugin.Logger.LogInfo((object)"ElementalStorm: Aborted trigger. Target player is in a boss fight."); } else { TriggerStormForPlayer(randomActivePlayer, stormName); } } } private bool IsNearActiveBoss(Player player) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = 150f; List<Character> list = new List<Character>(); Character.GetCharactersInRange(((Component)player).transform.position, num, list); foreach (Character item in list) { if (item.IsBoss() && !item.IsDead()) { return true; } } return false; } private Player GetRandomActivePlayer() { List<Player> list = new List<Player>(); foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null) { list.Add(allPlayer); } } if (list.Count == 0) { return null; } return list[Random.Range(0, list.Count)]; } private void TriggerStormForPlayer(Player player, string stormName) { if ((Object)(object)EnvMan.instance != (Object)null) { EnvSetup customStorm = StormEnvironmentCloner.GetCustomStorm(stormName); if (customStorm != null) { EnvMan.instance.SetEnv(customStorm, 0f, 0f, 0f, 0f, 0f); ElementalStormsPlugin.Logger.LogInfo((object)("ElementalStorm: Triggered " + stormName + " for player " + player.GetPlayerName())); ElementalStormsPlugin.ShowWeatherWarningTopCenter(stormName.Replace("ES_", "") + "'s storm is approaching!"); } else { ElementalStormsPlugin.Logger.LogWarning((object)("ElementalStorm: Could not find storm environment " + stormName)); } } } } public class LightningSystem { private static LightningSystem s_instance; private float m_lightningTimer = 0f; private float m_nextLightningTime = 0f; private bool m_isActive = false; public static LightningSystem Instance { get { if (s_instance == null) { s_instance = new LightningSystem(); } return s_instance; } } private LightningSystem() { ResetTimer(); } public void Update(float dt) { if (ElementalStormsPlugin.EnableMod == null) { return; } if (!ElementalStormsPlugin.EnableMod.Value) { m_isActive = false; return; } if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).IsDead()) { m_isActive = false; return; } bool flag = ShouldBeActive(); if (flag && !m_isActive) { m_isActive = true; ResetTimer(); ElementalStormsPlugin.Logger.LogDebug((object)"Lightning system activated"); } else if (!flag && m_isActive) { m_isActive = false; ElementalStormsPlugin.Logger.LogDebug((object)"Lightning system deactivated"); return; } if (m_isActive && !ElementalStormsPlugin.IsInDungeonAltitude()) { m_lightningTimer += dt; if (m_lightningTimer >= m_nextLightningTime) { StrikeLightning(); ResetTimer(); } } } private bool ShouldBeActive() { if ((Object)(object)EnvMan.instance == (Object)null) { return false; } if (EnvMan.instance.m_currentEnv == null) { return false; } string name = EnvMan.instance.m_currentEnv.m_name; return name == "Eikthyr" || name == "ES_Eikthyr"; } private void ResetTimer() { m_lightningTimer = 0f; float num = 4f; float num2 = 12f; m_nextLightningTime = Random.Range(num, num2); } private void StrikeLightning() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { return; } float radialDistance = GetRadialDistance(); if (radialDistance < 0f) { ElementalStormsPlugin.Logger.LogDebug((object)"Lightning strike skipped (RNG roll)"); return; } if (localPlayer.InShelter() && radialDistance < 50f) { ElementalStormsPlugin.Logger.LogDebug((object)"Lightning strike skipped (player in shelter, distance < 50m)"); return; } Vector3 val = CalculateStrikePosition(((Component)localPlayer).transform.position, radialDistance); if ((Object)(object)ZoneSystem.instance != (Object)null) { val.y = ZoneSystem.instance.GetSolidHeight(val); } CreateLightningEffect(val); ApplyLightningDamage(val); ElementalStormsPlugin.Logger.LogDebug((object)$"Lightning struck at position: {val}"); } private Vector3 CalculateStrikePosition(Vector3 playerPosition, float distance) { //IL_002d: 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_0034: 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) float num = Random.Range(0f, MathF.PI * 2f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Cos(num) * distance, 0f, Mathf.Sin(num) * distance); return playerPosition + val; } private float GetRadialDistance() { float num = Random.Range(0f, 1f); if (num < 0.05f) { return Random.Range(0f, 10f); } if (num < 0.55f) { return Random.Range(10f, 25f); } if (num < 0.8f) { return Random.Range(25f, 35f); } return -1f; } private void CreateLightningEffect(Vector3 position) { //IL_0012: 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_0038: 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) if ((Object)(object)ZNetScene.instance == (Object)null) { CreateFallbackLightningEffect(position); return; } GameObject prefab = ZNetScene.instance.GetPrefab("fx_eikthyr_stomp"); if ((Object)(object)prefab != (Object)null) { GameObject val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity); ZNetView component = val.GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null && (Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val, 1f); } } else { CreateFallbackLightningEffect(position); } } private void CreateFallbackLightningEffect(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0012: 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) GameObject val = new GameObject("LightningFlash"); val.transform.position = position; Light val2 = val.AddComponent<Light>(); val2.type = (LightType)2; val2.color = Color.white; val2.intensity = 10f; val2.range = 50f; Object.Destroy((Object)(object)val, 0.1f); } private void ApplyLightningDamage(Vector3 position) { //IL_0015: 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_005f: Expected O, but got Unknown //IL_0073: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_0102: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) float baseDamage = 20f; float num = CalculateScaledDamage(baseDamage); float num2 = 4f; Collider[] array = Physics.OverlapSphere(position, num2); Collider[] array2 = array; foreach (Collider val in array2) { Player component = ((Component)val).GetComponent<Player>(); if ((Object)(object)component != (Object)null && !component.InShelter()) { HitData val2 = new HitData(); val2.m_damage.m_lightning = num; val2.m_attacker = default(ZDOID); val2.m_pushForce = 10f; Vector3 val3 = ((Component)component).transform.position - position; val2.m_dir = ((Vector3)(ref val3)).normalized; ((Character)component).Damage(val2); ElementalStormsPlugin.Logger.LogDebug((object)$"Lightning dealt {num} damage to player"); continue; } WearNTear component2 = ((Component)val).GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.m_piece != (Object)null) { HitData val4 = new HitData(); val4.m_damage.m_lightning = num; val4.m_attacker = default(ZDOID); val4.m_pushForce = 5f; val4.m_dir = Vector3.up; component2.Damage(val4); ElementalStormsPlugin.Logger.LogDebug((object)$"Lightning dealt {num} damage to structure: {((Object)component2).name}"); } } } private float CalculateScaledDamage(float baseDamage) { int num = 0; if (ElementalStormsPlugin.IsBossDefeated("defeated_eikthyr")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_gdking")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_bonemass")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_moder")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_goblinking")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_thequeen")) { num++; } float num2 = 1f + (float)num * 0.1f; return baseDamage * num2; } public void ForceStrike(Vector3 position) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (ElementalStormsPlugin.EnableMod.Value) { CreateLightningEffect(position); ApplyLightningDamage(position); } } public string GetDebugInfo() { return $"Lightning System - Active: {m_isActive}, Timer: {m_lightningTimer:F1}s/{m_nextLightningTime:F1}s"; } } public class FireballSystem { private static FireballSystem s_instance; private float m_fireballTimer = 0f; private float m_nextFireballTime = 0f; private bool m_isActive = false; public static FireballSystem Instance { get { if (s_instance == null) { s_instance = new FireballSystem(); } return s_instance; } } private FireballSystem() { ResetTimer(); } public void Update(float dt) { if (ElementalStormsPlugin.EnableMod == null) { return; } if (!ElementalStormsPlugin.EnableMod.Value) { m_isActive = false; return; } if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).IsDead()) { m_isActive = false; return; } bool flag = ShouldBeActive(); if (flag && !m_isActive) { m_isActive = true; ResetTimer(); ElementalStormsPlugin.Logger.LogDebug((object)"Fireball system activated"); } else if (!flag && m_isActive) { m_isActive = false; ElementalStormsPlugin.Logger.LogDebug((object)"Fireball system deactivated"); return; } if (m_isActive && !ElementalStormsPlugin.IsInDungeonAltitude()) { m_fireballTimer += dt; if (m_fireballTimer >= m_nextFireballTime) { DropFireball(); ResetTimer(); } } } private bool ShouldBeActive() { if ((Object)(object)EnvMan.instance == (Object)null) { return false; } if (EnvMan.instance.m_currentEnv == null) { return false; } string name = EnvMan.instance.m_currentEnv.m_name; return name == "Fader" || name == "GoblinKing"; } private void ResetTimer() { m_fireballTimer = 0f; float num = 2f; float num2 = 9f; m_nextFireballTime = Random.Range(num, num2); } private void DropFireball() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { return; } float radialDistance = GetRadialDistance(); if (radialDistance < 0f) { ElementalStormsPlugin.Logger.LogDebug((object)"Fireball dropped (RNG roll)"); return; } if (localPlayer.InShelter() && radialDistance < 10f) { ElementalStormsPlugin.Logger.LogDebug((object)"Meteor skipped (player in shelter, distance < 10m)"); return; } Vector3 val = CalculateDropPosition(((Component)localPlayer).transform.position, radialDistance); if ((Object)(object)ZoneSystem.instance != (Object)null) { val.y = ZoneSystem.instance.GetSolidHeight(val); } CreateFireballEffect(val); ElementalStormsPlugin.Logger.LogDebug((object)$"Meteor dropped at position: {val}"); } private Vector3 CalculateDropPosition(Vector3 playerPosition, float distance) { //IL_002d: 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_0034: 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) float num = Random.Range(0f, MathF.PI * 2f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Cos(num) * distance, 0f, Mathf.Sin(num) * distance); return playerPosition + val; } private float GetRadialDistance() { float num = Random.Range(0f, 1f); if (num < 0.01f) { return Random.Range(0f, 10f); } if (num < 0.16f) { return Random.Range(10f, 50f); } if (num < 0.36f) { return Random.Range(50f, 100f); } return -1f; } private void CreateFireballEffect(Vector3 position) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { CreateFallbackFireballEffect(position); return; } string name = EnvMan.instance.m_currentEnv.m_name; GameObject val = null; if (name == "GoblinKing") { val = ZNetScene.instance.GetPrefab("projectile_meteor"); } else if (name == "Fader") { val = ZNetScene.instance.GetPrefab("projectile_ashlandmeteor"); if ((Object)(object)val == (Object)null) { val = ZNetScene.instance.GetPrefab("projectile_ashlandmeteor2"); } } if ((Object)(object)val == (Object)null) { val = ZNetScene.instance.GetPrefab("fx_bonemass_explosion"); } if ((Object)(object)val == (Object)null) { val = ZNetScene.instance.GetPrefab("fx_eikthyr_stomp"); } if ((Object)(object)val != (Object)null) { GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity); ZNetView component = val2.GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null) { MeteorSmash component2 = val2.GetComponent<MeteorSmash>(); if ((Object)(object)component2 == (Object)null && (Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2, 1f); } } } else { CreateFallbackFireballEffect(position); } } private void CreateFallbackFireballEffect(Vector3 position) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0012: 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) GameObject val = new GameObject("FireballFlash"); val.transform.position = position; Light val2 = val.AddComponent<Light>(); val2.type = (LightType)2; val2.color = Color.red; val2.intensity = 10f; val2.range = 50f; Object.Destroy((Object)(object)val, 0.1f); } private void ApplyFireballDamage(Vector3 position) { //IL_0015: 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_005f: Expected O, but got Unknown //IL_0073: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_0102: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) float baseDamage = 15f; float num = CalculateScaledDamage(baseDamage); float num2 = 4f; Collider[] array = Physics.OverlapSphere(position, num2); Collider[] array2 = array; foreach (Collider val in array2) { Player component = ((Component)val).GetComponent<Player>(); if ((Object)(object)component != (Object)null && !component.InShelter()) { HitData val2 = new HitData(); val2.m_damage.m_fire = num; val2.m_attacker = default(ZDOID); val2.m_pushForce = 5f; Vector3 val3 = ((Component)component).transform.position - position; val2.m_dir = ((Vector3)(ref val3)).normalized; ((Character)component).Damage(val2); ElementalStormsPlugin.Logger.LogDebug((object)$"Fireball dealt {num} fire damage to player"); continue; } WearNTear component2 = ((Component)val).GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.m_piece != (Object)null) { HitData val4 = new HitData(); val4.m_damage.m_fire = num; val4.m_attacker = default(ZDOID); val4.m_pushForce = 3f; val4.m_dir = Vector3.up; component2.Damage(val4); ElementalStormsPlugin.Logger.LogDebug((object)$"Fireball dealt {num} fire damage to structure: {((Object)component2).name}"); } } } private float CalculateScaledDamage(float baseDamage) { int num = 0; if (ElementalStormsPlugin.IsBossDefeated("defeated_eikthyr")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_gdking")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_bonemass")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_moder")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_goblinking")) { num++; } if (ElementalStormsPlugin.IsBossDefeated("defeated_thequeen")) { num++; } float num2 = 1f + (float)num * 0.1f; return baseDamage * num2; } public string GetDebugInfo() { return $"Fireball System - Active: {m_isActive}, Timer: {m_fireballTimer:F1}s/{m_nextFireballTime:F1}s"; } } public class LightningSystemUpdater : MonoBehaviour { private void Update() { LightningSystem.Instance.Update(Time.deltaTime); FireballSystem.Instance.Update(Time.deltaTime); } } [HarmonyPatch] internal class ElementalWeatherPatches { private static string s_previousWeather; [HarmonyPatch(typeof(EnvMan), "SetEnv")] [HarmonyPostfix] private static void OnEnvironmentChanged() { if (ElementalStormsPlugin.EnableMod == null || !ElementalStormsPlugin.EnableMod.Value || (Object)(object)EnvMan.instance == (Object)null || EnvMan.instance.m_currentEnv == null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } string name = EnvMan.instance.m_currentEnv.m_name; if (s_previousWeather != null && s_previousWeather != name) { ElementalStormsPlugin.Logger.LogInfo((object)("[DEBUG] Weather system ending: " + s_previousWeather)); ElementalStormsPlugin.Logger.LogInfo((object)("[DEBUG] Weather system starting: " + name)); } s_previousWeather = name; switch (name) { case "Eikthyr": if (ElementalStormsPlugin.IsBossDefeated("defeated_eikthyr")) { ElementalStormsPlugin.ShowWeatherWarningTopCenter("Eikthyr's Thunderstorm"); } break; case "GDKing": if (ElementalStormsPlugin.IsBossDefeated("defeated_gdking")) { ElementalStormsPlugin.ShowWeatherWarningTopCenter("The Elder's Curse"); } break; case "Bonemass": if (ElementalStormsPlugin.IsBossDefeated("defeated_bonemass")) { ElementalStormsPlugin.ShowWeatherWarningTopCenter("Poisoned Rain"); } break; case "Moder": if (ElementalStormsPlugin.IsBossDefeated("defeated_moder")) { ElementalStormsPlugin.ShowWeatherWarningTopCenter("Blizzard"); } break; case "GoblinKing": if (ElementalStormsPlugin.IsBossDefeated("defeated_goblinking")) { ElementalStormsPlugin.ShowWeatherWarningTopCenter("Yagluth's Curse"); } break; case "Queen": if (ElementalStormsPlugin.IsBossDefeated("defeated_thequeen")) { ElementalStormsPlugin.ShowWeatherWarningTopCenter("Creeping Mist"); } break; case "Fader": if (ElementalStormsPlugin.IsBossDefeated("defeated_fader")) { ElementalStormsPlugin.ShowWeatherWarningTopCenter("Fader's Tears"); } break; } } } public static class PrefabDiscoverySystem { private class DiscoveryRunner : MonoBehaviour { private float m_delayTimer = 0f; private const float INITIALIZATION_DELAY = 5f; private void Update() { m_delayTimer += Time.deltaTime; if (m_delayTimer >= 5f) { if ((Object)(object)EnvMan.instance != (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { ElementalStormsPlugin.Logger.LogInfo((object)"Game systems initialized, running prefab discovery..."); RunDiscovery(); Object.Destroy((Object)(object)((Component)this).gameObject); } else if (m_delayTimer >= 15f) { ElementalStormsPlugin.Logger.LogWarning((object)("Prefab discovery timeout - core systems not available. EnvMan: " + ((Object)(object)EnvMan.instance != (Object)null) + ", ZNetScene: " + ((Object)(object)ZNetScene.instance != (Object)null))); Object.Destroy((Object)(object)((Component)this).gameObject); } } } } private static bool s_hasRun = false; private static bool s_hasScheduled = false; private static readonly string DISCOVERY_FILE_PATH = Paths.ConfigPath + "/ElementalStorms_PrefabDiscovery.txt"; public static void ScheduleDiscovery() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown if (s_hasScheduled) { ElementalStormsPlugin.Logger.LogInfo((object)"Prefab discovery already scheduled, skipping."); return; } s_hasScheduled = true; ElementalStormsPlugin.Logger.LogInfo((object)"Scheduling prefab discovery system..."); GameObject val = new GameObject("ElementalWeather_Discovery"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<DiscoveryRunner>(); } public static void RunDiscovery() { if (s_hasRun) { ElementalStormsPlugin.Logger.LogInfo((object)"Prefab discovery already run, skipping."); return; } s_hasRun = true; ElementalStormsPlugin.Logger.LogInfo((object)"Starting prefab discovery system..."); try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("=== Elemental Storms - Prefab Discovery Log ==="); stringBuilder.AppendLine($"Generated: {DateTime.Now:yyyy-MM-dd HH:mm:ss}"); stringBuilder.AppendLine("Valheim Version: " + Application.version); stringBuilder.AppendLine(); DiscoverEnvironments(stringBuilder); DiscoverZNetScenePrefabs(stringBuilder); File.WriteAllText(DISCOVERY_FILE_PATH, stringBuilder.ToString()); ElementalStormsPlugin.Logger.LogInfo((object)("Prefab discovery complete. Log saved to: " + DISCOVERY_FILE_PATH)); } catch (Exception ex) { ElementalStormsPlugin.Logger.LogError((object)("Prefab discovery failed: " + ex.Message)); ElementalStormsPlugin.Logger.LogError((object)ex.StackTrace); } } private static void DiscoverEnvironments(StringBuilder logBuilder) { logBuilder.AppendLine("=== AVAILABLE ENVIRONMENTS ==="); if ((Object)(object)EnvMan.instance == (Object)null) { logBuilder.AppendLine("EnvMan.instance is null - cannot discover environments."); logBuilder.AppendLine(); return; } FieldInfo field = typeof(EnvMan).GetField("m_environments", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { logBuilder.AppendLine("Could not access m_environments field via reflection."); logBuilder.AppendLine(); return; } if (!(field.GetValue(EnvMan.instance) is List<EnvSetup> list)) { logBuilder.AppendLine("m_environments is null or not a List<EnvSetup>."); logBuilder.AppendLine(); return; } logBuilder.AppendLine($"Total environments found: {list.Count}"); logBuilder.AppendLine(); List<EnvSetup> list2 = (from e in list where IsBossEnvironment(e.m_name) orderby e.m_name select e).ToList(); List<EnvSetup> list3 = (from e in list where IsBiomeEnvironment(e.m_name) orderby e.m_name select e).ToList(); List<EnvSetup> list4 = (from e in list where IsWeatherEnvironment(e.m_name) orderby e.m_name select e).ToList(); List<EnvSetup> list5 = (from e in list where !IsBossEnvironment(e.m_name) && !IsBiomeEnvironment(e.m_name) && !IsWeatherEnvironment(e.m_name) orderby e.m_name select e).ToList(); if (list2.Count > 0) { logBuilder.AppendLine("--- BOSS ENVIRONMENTS ---"); foreach (EnvSetup item in list2) { LogEnvironmentDetails(item, logBuilder); } logBuilder.AppendLine(); } if (list3.Count > 0) { logBuilder.AppendLine("--- BIOME ENVIRONMENTS ---"); foreach (EnvSetup item2 in list3) { LogEnvironmentDetails(item2, logBuilder); } logBuilder.AppendLine(); } if (list4.Count > 0) { logBuilder.AppendLine("--- WEATHER ENVIRONMENTS ---"); foreach (EnvSetup item3 in list4) { LogEnvironmentDetails(item3, logBuilder); } logBuilder.AppendLine(); } if (list5.Count <= 0) { return; } logBuilder.AppendLine("--- OTHER ENVIRONMENTS ---"); foreach (EnvSetup item4 in list5) { LogEnvironmentDetails(item4, logBuilder); } logBuilder.AppendLine(); } private static void LogEnvironmentDetails(EnvSetup env, StringBuilder logBuilder) { logBuilder.AppendLine("Name: " + env.m_name); logBuilder.AppendLine($" Default: {env.m_default}"); logBuilder.AppendLine($" Wet: {env.m_isWet}, Freezing: {env.m_isFreezing}, Cold: {env.m_isCold}"); logBuilder.AppendLine($" Always Dark: {env.m_alwaysDark}"); logBuilder.AppendLine($" Wind Min: {env.m_windMin}, Wind Max: {env.m_windMax}"); if (env.m_psystems != null && env.m_psystems.Length != 0) { logBuilder.AppendLine($" Particle Systems ({env.m_psystems.Length}):"); for (int i = 0; i < env.m_psystems.Length; i++) { if ((Object)(object)env.m_psystems[i] != (Object)null) { logBuilder.AppendLine($" [{i}] {((Object)env.m_psystems[i]).name}"); } } } if ((Object)(object)env.m_envObject != (Object)null) { logBuilder.AppendLine(" Environment Object: " + ((Object)env.m_envObject).name); } AudioClip ambientLoop = env.m_ambientLoop; if (!string.IsNullOrEmpty((ambientLoop != null) ? ((Object)ambientLoop).name : null)) { logBuilder.AppendLine(" Ambient Loop: " + ((Object)env.m_ambientLoop).name); } logBuilder.AppendLine(); } private static void DiscoverZNetScenePrefabs(StringBuilder logBuilder) { logBuilder.AppendLine("=== ZNETSCENE PREFABS ==="); if ((Object)(object)ZNetScene.instance == (Object)null) { logBuilder.AppendLine("ZNetScene.instance is null - cannot discover prefabs."); logBuilder.AppendLine(); return; } FieldInfo field = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { logBuilder.AppendLine("Could not access m_namedPrefabs field via reflection."); logBuilder.AppendLine(); return; } if (!(field.GetValue(ZNetScene.instance) is Dictionary<int, GameObject> dictionary)) { logBuilder.AppendLine("m_namedPrefabs is null or not a Dictionary<int, GameObject>."); logBuilder.AppendLine(); return; } logBuilder.AppendLine($"Total prefabs found: {dictionary.Count}"); logBuilder.AppendLine(); List<GameObject> list = (from p in dictionary.Values where (Object)(object)p != (Object)null where IsStormRelatedPrefab(((Object)p).name) orderby ((Object)p).name select p).ToList(); if (list.Count > 0) { logBuilder.AppendLine("--- STORM-RELATED PREFABS ---"); foreach (GameObject item in list) { logBuilder.AppendLine(" " + ((Object)item).name); } logBuilder.AppendLine(); } List<GameObject> list2 = (from p in dictionary.Values where (Object)(object)p != (Object)null where IsBossRelatedPrefab(((Object)p).name) orderby ((Object)p).name select p).ToList(); if (list2.Count <= 0) { return; } logBuilder.AppendLine("--- BOSS-RELATED PREFABS ---"); foreach (GameObject item2 in list2) { logBuilder.AppendLine(" " + ((Object)item2).name); } logBuilder.AppendLine(); } private static bool IsBossEnvironment(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLower(); return text.Contains("eikthyr") || text.Contains("gdking") || text.Contains("elder") || text.Contains("bonemass") || text.Contains("moder") || text.Contains("dragon") || text.Contains("goblin") || text.Contains("yagluth") || text.Contains("queen") || text.Contains("seeker") || text.Contains("fader"); } private static bool IsBiomeEnvironment(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLower(); return text.Contains("meadow") || text.Contains("forest") || text.Contains("blackforest") || text.Contains("swamp") || text.Contains("mountain") || text.Contains("plains") || text.Contains("mistland") || text.Contains("ashland") || text.Contains("deepnorth") || text.Contains("ocean") || text.Contains("ashlands"); } private static bool IsWeatherEnvironment(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLower(); return text.Contains("rain") || text.Contains("thunder") || text.Contains("snow") || text.Contains("storm") || text.Contains("fog") || text.Contains("mist") || text.Contains("clear") || text.Contains("cinder") || text.Contains("cloud"); } private static bool IsStormRelatedPrefab(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLower(); return text.Contains("meteor") || text.Contains("fireball") || text.Contains("lightning") || text.Contains("thunder") || text.Contains("rain") || text.Contains("snow") || text.Contains("fog") || text.Contains("mist") || text.Contains("storm") || text.Contains("tornado") || text.Contains("wind") || text.Contains("cinder") || text.Contains("ash"); } private static bool IsBossRelatedPrefab(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLower(); return text.Contains("eikthyr") || text.Contains("gd_king") || text.Contains("gdking") || text.Contains("elder") || text.Contains("bonemass") || text.Contains("moder") || text.Contains("dragon") || text.Contains("goblin") || text.Contains("yagluth") || text.Contains("queen") || text.Contains("seeker") || text.Contains("fader") || text.Contains("boss"); } } public static class ProjectileSpawner { public class ProjectileConfig { public string PrefabName { get; set; } public float SpawnInterval { get; set; } = 5f; public float MinDistance { get; set; } = 1f; public float MaxDistance { get; set; } = 5f; public float Damage { get; set; } = 10f; public string StormName { get; set; } public string BossKey { get; set; } public float DamageMultiplier { get; set; } = 1f; public float SpawnRadius { get; set; } = 0f; public int SpawnCount { get; set; } = 1; public bool CheckEnvActive { get; set; } = false; } private class ProjectileSpawnerUpdater : MonoBehaviour { private Dictionary<string, Dictionary<string, float>> m_spawnTimers = new Dictionary<string, Dictionary<string, float>>(); private Dictionary<string, List<GameObject>> m_spawnedObjects = new Dictionary<string, List<GameObject>>(); private void Start() { foreach (KeyValuePair<string, List<ProjectileConfig>> s_projectileConfig in s_projectileConfigs) { m_spawnTimers[s_projectileConfig.Key] = new Dictionary<string, float>(); foreach (ProjectileConfig item in s_projectileConfig.Value) { m_spawnTimers[s_projectileConfig.Key][item.PrefabName] = 0f; } m_spawnedObjects[s_projectileConfig.Key] = new List<GameObject>(); } } private void Update() { string text = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetCurrentEnvironment().m_name : ""); if (text == "ES_Queen" && (Object)(object)Player.m_localPlayer != (Object)null && !Object.op_Implicit((Object)(object)((Component)Player.m_localPlayer).GetComponent<QueenStormMistEffect>())) { TriggerQueenMist(); } foreach (KeyValuePair<string, List<ProjectileConfig>> s_projectileConfig in s_projectileConfigs) { string key = s_projectileConfig.Key; List<ProjectileConfig> value = s_projectileConfig.Value; string text2 = ((value.Count > 0) ? value[0].StormName : key); if (text != text2) { if (!m_spawnedObjects.ContainsKey(key)) { continue; } foreach (GameObject item in m_spawnedObjects[key]) { if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)item); } } m_spawnedObjects[key].Clear(); continue; } foreach (ProjectileConfig item2 in value) { m_spawnTimers[key][item2.PrefabName] += Time.deltaTime; if (m_spawnTimers[key][item2.PrefabName] >= item2.SpawnInterval) { m_spawnTimers[key][item2.PrefabName] = 0f; TrySpawnProjectile(item2); } } } } private void TrySpawnProjectile(ProjectileConfig config) { if (!ElementalStormsPlugin.IsBossDefeated(config.BossKey)) { ElementalStormsPlugin.Logger.LogDebug((object)("Boss " + config.BossKey + " not defeated, skipping spawn of " + config.PrefabName)); } else { if ((Object)(object)EnvMan.instance == (Object)null) { return; } string name = EnvMan.instance.GetCurrentEnvironment().m_name; if (name != config.StormName) { ElementalStormsPlugin.Logger.LogDebug((object)("Current env " + name + " != " + config.StormName + ", skipping spawn of " + config.PrefabName)); return; } if (config.CheckEnvActive) { } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { float minDistance = (localPlayer.InShelter() ? 20f : config.MinDistance); float maxDistance = (localPlayer.InShelter() ? 35f : config.MaxDistance); SpawnPrefabNearPlayer(config, localPlayer, minDistance, maxDistance); } } } private void SpawnPrefabNearPlayer(ProjectileConfig config, Player player, float minDistance, float maxDistance) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_000f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) try { Vector3 position = ((Component)player).transform.position; Vector3 val = position; int num = ((config.SpawnCount <= 0) ? 1 : config.SpawnCount); if (config.SpawnRadius > 0f) { val = position; num = 1; } else { float num2 = Random.Range(minDistance, maxDistance); float num3 = Random.Range(0f, 360f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Cos(num3) * num2, 0f, Mathf.Sin(num3) * num2); val = position + val2; } if ((Object)(object)ZNetScene.instance == (Object)null) { ElementalStormsPlugin.Logger.LogWarning((object)"ZNetScene.instance is null, cannot spawn prefab."); return; } GameObject prefab = ZNetScene.instance.GetPrefab(StringExtensionMethods.GetStableHashCode(config.PrefabName)); if ((Object)(object)prefab == (Object)null) { ElementalStormsPlugin.Logger.LogWarning((object)("Could not find prefab: " + config.PrefabName)); return; } ElementalStormsPlugin.Logger.LogDebug((object)$"Spawning prefab {config.PrefabName} at {val}"); for (int i = 0; i < num; i++) { GameObject val3 = Object.Instantiate<GameObject>(prefab, val, Quaternion.identity); if (config.SpawnRadius > 0f && config.PrefabName == "MistArea") { Mister val4 = val3.GetComponent<Mister>(); if ((Object)(object)val4 == (Object)null) { val4 = val3.AddComponent<Mister>(); ElementalStormsPlugin.Logger.LogInfo((object)"Added Mister component to MistArea prefab"); } val4.m_radius = config.SpawnRadius; ElementalStormsPlugin.Logger.LogInfo((object)$"Set MistArea radius to {config.SpawnRadius}m at {val}"); } if (m_spawnedObjects.ContainsKey(config.StormName)) { m_spawnedObjects[config.StormName].Add(val3); } } ElementalStormsPlugin.Logger.LogDebug((object)$"Spawned {num} {config.PrefabName}(s) at {val}"); } catch (Exception ex) { ElementalStormsPlugin.Logger.LogError((object)("Failed to spawn prefab " + config.PrefabName + ": " + ex.Message)); } } } private class QueenStormMistEffect : MonoBehaviour { private GameObject instantiatedMist; private void Start() { SpawnMist(); } private void Update() { if ((Object)(object)EnvMan.instance != (Object)null) { string name = EnvMan.instance.GetCurrentEnvironment().m_name; if (name != "ES_Queen") { RemoveMist(); } } } private void SpawnMist() { //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) GameObject prefab = ZNetScene.instance.GetPrefab(StringExtensionMethods.GetStableHashCode("MistArea")); if ((Object)(object)prefab != (Object)null) { instantiatedMist = Object.Instantiate<GameObject>(prefab, ((Component)this).transform.position, Quaternion.identity); instantiatedMist.transform.SetParent(((Component)this).transform); Mister val = instantiatedMist.GetComponent<Mister>(); if ((Object)(object)val == (Object)null) { val = instantiatedMist.AddComponent<Mister>(); } val.m_radius = 20f; ElementalStormsPlugin.Logger.LogInfo((object)"Queen mist spawned and attached to player"); } else { ElementalStormsPlugin.Logger.LogWarning((object)"QueenStormMod: MistArea prefab not found!"); } } public void RemoveMist() { if ((Object)(object)instantiatedMist != (Object)null) { Object.Destroy((Object)(object)instantiatedMist); } Object.Destroy((Object)(object)this); } private void OnDestroy() { if ((Object)(object)instantiatedMist != (Object)null) { Object.Destroy((Object)(object)instantiatedMist); } } } private static Dictionary<string, List<ProjectileConfig>> s_projectileConfigs = new Dictionary<string, List<ProjectileConfig>>(); private static GameObject s_spawnerHolder; public static void Initialize() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if ((Object)(object)s_spawnerHolder == (Object)null) { s_spawnerHolder = new GameObject("ElementalStorms_ProjectileSpawner"); Object.DontDestroyOnLoad((Object)(object)s_spawnerHolder); } s_projectileConfigs.Clear(); ConfigureElderProjectiles(); ConfigureBonemassAOEs(); ConfigureModerProjectiles(); ConfigureYagluthMeteors(); ConfigureFaderMeteors(); ConfigureQueenMist(); if ((Object)(object)s_spawnerHolder.GetComponent<ProjectileSpawnerUpdater>() == (Object)null) { s_spawnerHolder.AddComponent<ProjectileSpawnerUpdater>(); } } private static void ConfigureElderProjectiles() { ProjectileConfig item = new ProjectileConfig { PrefabName = "TentaRoot", SpawnInterval = 2f, MinDistance = 1f, MaxDistance = 3f, Damage = 10f, StormName = "ES_Elder", BossKey = "defeated_gdking", SpawnCount = 1 }; s_projectileConfigs["Elder"] = new List<ProjectileConfig> { item }; } private static void ConfigureBonemassAOEs() { ProjectileConfig item = new ProjectileConfig { PrefabName = "bonemass_aoe", SpawnInterval = 5f, MinDistance = 1f, MaxDistance = 3f, Damage = 0f, StormName = "ES_Bonemass", BossKey = "defeated_bonemass" }; ProjectileConfig item2 = new ProjectileConfig { PrefabName = "bee_aoe", SpawnInterval = 15f, MinDistance = 1f, MaxDistance = 3f, Damage = 0f, StormName = "ES_Bonemass", BossKey = "defeated_bonemass", CheckEnvActive = true }; s_projectileConfigs["Bonemass"] = new List<ProjectileConfig> { item, item2 }; } private static void ConfigureModerProjectiles() { s_projectileConfigs["Moder"] = new List<ProjectileConfig>(); } private static void ConfigureYagluthMeteors() { ProjectileConfig item = new ProjectileConfig { PrefabName = "DvergerStaffFire_clusterbomb_aoe", SpawnInterval = 3f, MinDistance = 1f, MaxDistance = 10f, Damage = 10f, StormName = "ES_Yagluth", BossKey = "defeated_goblinking", DamageMultiplier = 0.33f }; s_projectileConfigs["Yagluth"] = new List<ProjectileConfig> { item }; } private static void ConfigureFaderMeteors() { ProjectileConfig item = new ProjectileConfig { PrefabName = "Fader_DroppedFire_AOE", SpawnInterval = 5f, MinDistance = 3f, MaxDistance = 10f, Damage = 10f, StormName = "ES_Fader", BossKey = "defeated_fader", DamageMultiplier = 0.33f }; s_projectileConfigs["Fader"] = new List<ProjectileConfig> { item }; } private static void ConfigureQueenMist() { ProjectileConfig item = new ProjectileConfig { PrefabName = "MistArea", SpawnInterval = 10f, MinDistance = 0f, MaxDistance = 0f, Damage = 0f, StormName = "ES_Queen", BossKey = "defeated_thequeen", SpawnRadius = 20f }; s_projectileConfigs["Queen"] = new List<ProjectileConfig> { item }; } public static List<ProjectileConfig> GetConfigs(string name) { if (s_projectileConfigs.TryGetValue(name, out var value)) { return value; } return null; } public static void UpdateConfig(string name, Action<ProjectileConfig> updateAction) { if (!s_projectileConfigs.TryGetValue(name, out var value)) { return; } foreach (ProjectileConfig item in value) { updateAction(item); } } public static void TriggerQueenMist() { if ((Object)(object)Player.m_localPlayer != (Object)null && !Object.op_Implicit((Object)(object)((Component)Player.m_localPlayer).GetComponent<QueenStormMistEffect>())) { ((Component)Player.m_localPlayer).gameObject.AddComponent<QueenStormMistEffect>(); ElementalStormsPlugin.Logger.LogInfo((object)"Queen mist effect triggered on player"); } } } public class SE_GaleExposure : StatusEffect { private float m_originalStaminaRegenTimeMultiplier = 1f; private bool m_shouldRemove = false; public SE_GaleExposure() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown ((Object)this).name = "Moder's Blizzard"; base.m_icon = null; base.m_tooltip = "Moder's Blizzard: Severe winds are draining your stamina."; base.m_ttl = 0f; base.m_startEffects = new EffectList(); base.m_stopEffects = new EffectList(); } public override void Setup(Character character) { ((StatusEffect)this).Setup(character); Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { m_originalStaminaRegenTimeMultiplier = val.m_staminaRegenTimeMultiplier; ElementalStormsPlugin.Logger.LogDebug((object)("SE_GaleExposure applied to player, storing original stamina regen multiplier: " + m_originalStaminaRegenTimeMultiplier)); } } public override void UpdateStatusEffect(float dt) { ((StatusEffect)this).UpdateStatusEffect(dt); if (m_shouldRemove) { Character character = base.m_character; RestoreStaminaRegen((Player)(object)((character is Player) ? character : null)); base.m_ttl = 0f; } else { if (ElementalStormsPlugin.EnableMod == null || !ElementalStormsPlugin.EnableMod.Value) { return; } Character character2 = base.m_character; Player val = (Player)(object)((character2 is Player) ? character2 : null); if (val != null) { if (val.InShelter()) { ElementalStormsPlugin.Logger.LogDebug((object)"Player found shelter, removing Gale Exposure"); m_shouldRemove = true; } else { ApplyStaminaPenalty(val); } } } } private void ApplyStaminaPenalty(Player player) { float num = 0.4f; player.m_staminaRegenTimeMultiplier = m_originalStaminaRegenTimeMultiplier * (1f + num); } private void RestoreStaminaRegen(Player player) { player.m_staminaRegenTimeMultiplier = m_originalStaminaRegenTimeMultiplier; } } public class SE_ForestRain : StatusEffect { private float m_originalStaminaRegenTimeMultiplier = 1f; private bool m_shouldRemove = false; public SE_ForestRain() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown ((Object)this).name = "The Elder's Curse"; base.m_icon = null; base.m_tooltip = "The Elder's Curse: The Elder's curse makes you weary."; base.m_ttl = 0f; base.m_startEffects = new EffectList(); base.m_stopEffects = new EffectList(); } public override void Setup(Character character) { ((StatusEffect)this).Setup(character); Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { m_originalStaminaRegenTimeMultiplier = val.m_staminaRegenTimeMultiplier; ElementalStormsPlugin.Logger.LogDebug((object)("SE_ForestRain applied to player, storing original stamina regen multiplier: " + m_originalStaminaRegenTimeMultiplier)); } } public override void UpdateStatusEffect(float dt) { ((StatusEffect)this).UpdateStatusEffect(dt); if (m_shouldRemove) { Character character = base.m_character; RestoreStaminaRegen((Player)(object)((character is Player) ? character : null)); base.m_ttl = 0f; } else { if (ElementalStormsPlugin.EnableMod == null || !ElementalStormsPlugin.EnableMod.Value) { return; } Character character2 = base.m_character; Player val = (Player)(object)((character2 is Player) ? character2 : null); if (val != null) { if (val.InShelter()) { ElementalStormsPlugin.Logger.LogDebug((object)"Player found shelter, removing Forest Rain"); m_shouldRemove = true; } else { ApplyStaminaPenalty(val); } } } } private void ApplyStaminaPenalty(Player player) { float num = 0.5f; player.m_staminaRegenTimeMultiplier = m_originalStaminaRegenTimeMultiplier * (1f + num); } private void RestoreStaminaRegen(Player player) { player.m_staminaRegenTimeMultiplier = m_originalStaminaRegenTimeMultiplier; } } public static class StatusEffectManager { private static SE_GaleExposure s_galeExposureTemplate; private static SE_ForestRain s_forestRainTemplate; public static void Initialize() { s_galeExposureTemplate = ScriptableObject.CreateInstance<SE_GaleExposure>(); s_forestRainTemplate = ScriptableObject.CreateInstance<SE_ForestRain>(); } public static void ApplyGaleExposure(Character character) { if (ElementalStormsPlugin.EnableMod != null && ElementalStormsPlugin.EnableMod.Value && !((Object)(object)character == (Object)null) && !character.IsDead()) { int stableHashCode = StringExtensionMethods.GetStableHashCode("Moder's Blizzard"); if (!((Object)(object)character.GetSEMan().GetStatusEffect(stableHashCode) != (Object)null)) { SE_GaleExposure sE_GaleExposure = Object.Instantiate<SE_GaleExposure>(s_galeExposureTemplate); character.GetSEMan().AddStatusEffect((StatusEffect)(object)sE_GaleExposure, false, 0, 0f); ElementalStormsPlugin.Logger.LogDebug((object)("Applied Moder's Blizzard to: " + ((Object)character).name)); } } } public static void ApplyForestRain(Character character) { if (ElementalStormsPlugin.EnableMod != null && ElementalStormsPlugin.EnableMod.Value && !((Object)(object)character == (Object)null) && !character.IsDead()) { int stableHashCode = StringExtensionMethods.GetStableHashCode("The Elder's Curse"); if (!((Object)(object)character.GetSEMan().GetStatusEffect(stableHashCode) != (Object)null)) { SE_ForestRain sE_ForestRain = Object.Instantiate<SE_ForestRain>(s_forestRainTemplate); character.GetSEMan().AddStatusEffect((StatusEffect)(object)sE_ForestRain, false, 0, 0f); ElementalStormsPlugin.Logger.LogDebug((object)("Applied The Elder's Curse to: " + ((Object)character).name)); } } } public static void RemoveAllCustomEffects(Character character) { if ((Object)(object)character == (Object)null) { return; } SEMan sEMan = character.GetSEMan(); if (sEMan != null) { int stableHashCode = StringExtensionMethods.GetStableHashCode("Moder's Blizzard"); StatusEffect statusEffect = sEMan.GetStatusEffect(stableHashCode); if ((Object)(object)statusEffect != (Object)null) { sEMan.RemoveStatusEffect(statusEffect, false); } int stableHashCode2 = StringExtensionMethods.GetStableHashCode("The Elder's Curse"); StatusEffect statusEffect2 = sEMan.GetStatusEffect(stableHashCode2); if ((Object)(object)statusEffect2 != (Object)null) { sEMan.RemoveStatusEffect(statusEffect2, false); } } } } public static class StormEnvironmentCloner { private class PoisonMonitor : MonoBehaviour { private const float CHECK_INTERVAL = 0.5f; private float m_checkTimer = 0f; private void Update() { if (!((Object)(object)EnvMan.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { m_checkTimer += Time.deltaTime; if (!(m_checkTimer < 0.5f)) { m_checkTimer = 0f; Player localPlayer = Player.m_localPlayer; string name = EnvMan.instance.GetCurrentEnvironment().m_name; bool flag = name == "ES_Bonemass"; } } } } private static Dictionary<string, EnvSetup> s_customEnvironments = new Dictionary<string, EnvSetup>(); public static void Initialize() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if ((Object)(object)EnvMan.instance == (Object)null) { ElementalStormsPlugin.Logger.LogWarning((object)"EnvMan not available, cannot initialize storm environments yet."); return; } try { CreateCustomStorms(); RegisterCustomEnvironments(); GameObject val = new GameObject("ES_PoisonMonitor"); val.AddComponent<PoisonMonitor>(); Object.DontDestroyOnLoad((Object)(object)val); } catch (Exception ex) { ElementalStormsPlugin.Logger.LogError((object)("Failed to initialize storm environment cloner: " + ex.Message)); ElementalStormsPlugin.Logger.LogError((object)ex.StackTrace); } } private static void CreateCustomStorms() { if ((Object)(object)EnvMan.instance == (Object)null) { ElementalStormsPlugin.Logger.LogWarning((object)"EnvMan.instance is null, cannot create custom storms."); return; } CreateEikthyrStorm(); CreateElderStorm(); CreateBonemassStorm(); CreateModerStorm(); CreateYagluthStorm(); CreateQueenStorm(); CreateFaderStorm(); } private static void CreateEikthyrStorm() { EnvSetup env = EnvMan.instance.GetEnv("ThunderStorm"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find ThunderStorm environment, trying Eikthyr."); env = EnvMan.instance.GetEnv("Eikthyr"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find Eikthyr environment for cloning."); return; } } EnvSetup val = env.Clone(); val.m_name = "ES_Eikthyr"; val.m_windMin = 1.4f; val.m_windMax = 2f; s_customEnvironments["ES_Eikthyr"] = val; } private static void CreateElderStorm() { EnvSetup env = EnvMan.instance.GetEnv("Darklands_dark"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find Darklands_dark environment, trying GDKing."); env = EnvMan.instance.GetEnv("GDKing"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find GDKing environment for cloning."); return; } } EnvSetup val = env.Clone(); val.m_name = "ES_Elder"; val.m_isWet = true; val.m_windMin = 0.8f; val.m_windMax = 1.6f; s_customEnvironments["ES_Elder"] = val; } private static void CreateBonemassStorm() { EnvSetup env = EnvMan.instance.GetEnv("Bonemass"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find Bonemass environment for cloning."); return; } EnvSetup val = env.Clone(); val.m_name = "ES_Bonemass"; val.m_isWet = true; val.m_windMin = 0.6f; val.m_windMax = 1.4f; s_customEnvironments["ES_Bonemass"] = val; } private static void CreateModerStorm() { EnvSetup env = EnvMan.instance.GetEnv("SnowStorm"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find SnowStorm environment for cloning."); return; } EnvSetup val = env.Clone(); val.m_name = "ES_Moder"; val.m_isFreezing = true; val.m_isFreezingAtNight = true; val.m_isCold = true; val.m_windMin = 1.6f; val.m_windMax = 2f; s_customEnvironments["ES_Moder"] = val; } private static void CreateYagluthStorm() { EnvSetup env = EnvMan.instance.GetEnv("GoblinKing"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find GoblinKing environment for cloning."); return; } EnvSetup val = env.Clone(); val.m_name = "ES_Yagluth"; val.m_windMin = 1.4f; val.m_windMax = 2f; s_customEnvironments["ES_Yagluth"] = val; } private static void CreateQueenStorm() { EnvSetup env = EnvMan.instance.GetEnv("Mistlands_rain"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find Mistlands_rain environment for cloning."); return; } EnvSetup val = env.Clone(); val.m_name = "ES_Queen"; val.m_windMin = 1.4f; val.m_windMax = 2f; s_customEnvironments["ES_Queen"] = val; } private static void CreateFaderStorm() { EnvSetup env = EnvMan.instance.GetEnv("Fader"); if (env == null) { ElementalStormsPlugin.Logger.LogWarning((object)"Could not find Fader environment for cloning."); return; } EnvSetup val = env.Clone(); val.m_name = "ES_Fader"; val.m_windMin = 1.6f; val.m_windMax = 2f; s_customEnvironments["ES_Fader"] = val; } private static void RegisterCustomEnvironments() { foreach (KeyValuePair<string, EnvSetup> s_customEnvironment in s_customEnvironments) { try { if (EnvMan.instance.GetEnv(s_customEnvironment.Key) == null) { EnvMan.instance.AppendEnvironment(s_customEnvironment.Value); ElementalStormsPlugin.Logger.LogDebug((object)("Registered custom environment: " + s_customEnvironment.Key)); } else { ElementalStormsPlugin.Logger.LogDebug((object)("Environment " + s_customEnvironment.Key + " already registered, skipping.")); } } catch (Exception ex) { ElementalStormsPlugin.Logger.LogError((object)("Failed to register environment " + s_customEnvironment.Key + ": " + ex.Message)); } } } public static EnvSetup GetCustomStorm(string stormName) { if (s_customEnvironments.TryGetValue(stormName, out var value)) { return value; } return null; } public static string[] GetCustomStormNames() { return new List<string>(s_customEnvironments.Keys).ToArray(); } } [HarmonyPatch] internal class WindSystem { [HarmonyPatch(typeof(WearNTear), "UpdateWear")] [HarmonyPostfix] private static void ApplyWindDamage(WearNTear __instance) { if (ElementalStormsPlugin.EnableMod == null || ElementalStormsPlugin.EnableStructuralDamage == null || !ElementalStormsPlugin.EnableMod.Value || !ElementalStormsPlugin.EnableStructuralDamage.Value || ElementalStormsPlugin.IsInDungeonAltitude() || (Object)(object)__instance.m_piece == (Object)null || (Object)(object)EnvMan.instance == (Object)null || EnvMan.instance.m_currentEnv == null) { return; } string name = EnvMan.instance.m_currentEnv.m_name; if (name.StartsWith("ES_")) { float windIntensity = EnvMan.instance.GetWindIntensity(); if (!float.IsNaN(windIntensity)) { windIntensity = GetEqualWindIntensity(windIntensity); ElementalStormsPlugin.Logger.LogDebug((object)$"Structural wind intensity: {windIntensity:F2}"); ApplyWindStructuralDamage(__instance); } } } private static float GetEqualWindIntensity(float baseIntensity) { if ((Object)(object)EnvMan.instance == (Object)null || EnvMan.instance.m_currentEnv == null) { return baseIntensity; } string name = EnvMan.instance.m_currentEnv.m_name; if (name.StartsWith("ES_")) { return Mathf.Max(baseIntensity, 0.7f); } return baseIntensity; } private static void ApplyWindStructuralDamage(WearNTear wearNTear) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_003d: 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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (ElementalStormsPlugin.StructuralDamageAmount != null) { float value = ElementalStormsPlugin.StructuralDamageAmount.Value; value *= 0.2f; HitData val = new HitData(); val.m_damage.m_pickaxe = value; val.m_attacker = default(ZDOID); val.m_pushForce = 0f; val.m_dir = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetWindDir() : Vector3.up); wearNTear.Damage(val); ElementalStormsPlugin.Logger.LogDebug((object)$"Applied wind damage: {value:F1} to {((Object)wearNTear).name}"); } } } [HarmonyPatch] internal class WeatherStatusEffects { private static float m_statusCheckTimer; private const float STATUS_CHECK_INTERVAL = 1f; [HarmonyPatch(typeof(Player), "Update")] [HarmonyPostfix] private static void CheckWeatherStatusEffects(Player __instance) { if (ElementalStormsPlugin.EnableMod == null || !ElementalStormsPlugin.EnableMod.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || ElementalStormsPlugin.IsInDungeonAltitude()) { return; } m_statusCheckTimer += Time.deltaTime; if (m_statusCheckTimer < 1f) { return; } m_statusCheckTimer = 0f; if ((Object)(object)EnvMan.instance == (Object)null || EnvMan.instance.m_currentEnv == null) { return; } string name = EnvMan.instance.m_currentEnv.m_name; if (!string.IsNullOrEmpty(name)) { switch (name) { case "ES_Eikthyr": HandleEikthyr(__instance); break; case "ES_Bonemass": break; case "ES_Moder": HandleModer(__instance); break; case "ES_Yagluth": HandleGoblinKing(__instance); break; case "ES_Queen": HandleQueen(__instance); break; case "ES_Fader": HandleFader(__instance); break; default: StatusEffectManager.RemoveAllCustomEffects((Character)(object)__instance); break; } } } private static void HandleEikthyr(Player player) { } private static void HandleBonemass(Player player) { } private static void HandleModer(Player player) { if (ElementalStormsPlugin.IsBossDefeated("defeated_moder") && !player.InShelter()) { StatusEffectManager.ApplyGaleExposure((Character)(object)player); } } private static void HandleGoblinKing(Player player) { } private static void HandleQueen(Player player) { } private static void HandleFader(Player player) { } } }