Decompiled source of WeatherToggle v1.0.0

WeatherToggle.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Photon.Pun;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WeatherToggle")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WeatherToggle")]
[assembly: AssemblyTitle("WeatherToggle")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 WeatherToggle
{
	[HarmonyPatch(typeof(WindChillZone), "Update")]
	internal static class WindChillZone_Update
	{
		internal struct State
		{
			public bool swapped;

			public Bounds bounds;
		}

		private static readonly Dictionary<WindChillZone, WeatherKind> Kinds = new Dictionary<WindChillZone, WeatherKind>();

		private static readonly Bounds Nowhere = new Bounds(new Vector3(0f, -10000000f, 0f), Vector3.zero);

		internal static WeatherKind KindOf(WindChillZone zone)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Invalid comparison between Unknown and I4
			if (Kinds.TryGetValue(zone, out var value))
			{
				return value;
			}
			SETTINGTYPE disableIfSettingDisabled = zone.disableIfSettingDisabled;
			if ((int)disableIfSettingDisabled != 1250)
			{
				if ((int)disableIfSettingDisabled != 1800)
				{
					if ((int)disableIfSettingDisabled == 1900)
					{
						value = WeatherKind.AlpineStorm;
					}
					else
					{
						StormVisual componentInChildren = ((Component)zone).GetComponentInChildren<StormVisual>(true);
						value = ((Object.op_Implicit((Object)(object)RootsWind.instance) && (Object)(object)RootsWind.instance.windZone == (Object)(object)zone) ? WeatherKind.RootsWind : ((Object.op_Implicit((Object)(object)componentInChildren) && (int)componentInChildren.stormType == 2) ? WeatherKind.RootsWind : (((Object.op_Implicit((Object)(object)componentInChildren) && (int)componentInChildren.stormType == 1) || (int)zone.statusType == 2) ? WeatherKind.AlpineStorm : WeatherKind.Rain)));
					}
				}
				else
				{
					value = WeatherKind.RootsWind;
				}
			}
			else
			{
				value = WeatherKind.Rain;
			}
			if (Kinds.Count > 64)
			{
				Kinds.Clear();
			}
			Kinds[zone] = value;
			Plugin.Log.LogDebug((object)$"WindChillZone '{((Object)zone).name}' classified as {value}");
			return value;
		}

		private static void Prefix(WindChillZone __instance, out State __state)
		{
			//IL_001e: 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_0029: 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)
			__state = default(State);
			if (Plugin.Blocks(KindOf(__instance)))
			{
				__state.swapped = true;
				__state.bounds = __instance.windZoneBounds;
				__instance.windZoneBounds = Nowhere;
			}
		}

		private static void Postfix(WindChillZone __instance, State __state)
		{
			//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)
			if (__state.swapped)
			{
				__instance.windZoneBounds = __state.bounds;
			}
		}
	}
	[HarmonyPatch(typeof(HotSun), "Update")]
	internal static class HotSun_Update
	{
		private static bool Prefix()
		{
			return !Plugin.BlocksHeat;
		}
	}
	[HarmonyPatch(typeof(TornadoSpawner), "Update")]
	internal static class TornadoSpawner_Update
	{
		private static bool Prefix()
		{
			if (Plugin.BlocksTornado)
			{
				return !Plugin.AffectLobbyAsHost;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Tornado), "FixedUpdate")]
	internal static class Tornado_FixedUpdate
	{
		private static bool Prefix()
		{
			return !Plugin.BlocksTornado;
		}
	}
	[HarmonyPatch(typeof(Tornado), "Update")]
	internal static class Tornado_Update
	{
		private static readonly FieldRef<Tornado, PhotonView> ViewRef = AccessTools.FieldRefAccess<Tornado, PhotonView>("view");

		private static readonly FieldRef<Tornado, bool> DyingRef = AccessTools.FieldRefAccess<Tornado, bool>("dying");

		private static readonly HashSet<Tornado> Hidden = new HashSet<Tornado>();

		private static void Postfix(Tornado __instance)
		{
			bool blocksTornado = Plugin.BlocksTornado;
			if (blocksTornado && Plugin.AffectLobbyAsHost && !DyingRef.Invoke(__instance))
			{
				PhotonView val = ViewRef.Invoke(__instance);
				if (Object.op_Implicit((Object)(object)val) && val.IsMine)
				{
					val.RPC("RPCA_TornadoDie", (RpcTarget)0, Array.Empty<object>());
				}
			}
			bool flag = Hidden.Contains(__instance);
			if (blocksTornado != flag)
			{
				Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = !blocksTornado;
				}
				AudioSource[] componentsInChildren2 = ((Component)__instance).GetComponentsInChildren<AudioSource>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					componentsInChildren2[i].mute = blocksTornado;
				}
				if (blocksTornado)
				{
					Hidden.Add(__instance);
				}
				else
				{
					Hidden.Remove(__instance);
				}
				Hidden.RemoveWhere((Tornado t) => !Object.op_Implicit((Object)(object)t));
			}
		}
	}
	[HarmonyPatch(typeof(FogSphere), "SetSharderVars")]
	internal static class FogSphere_SetShaderVars
	{
		private static readonly HashSet<FogSphere> Hidden = new HashSet<FogSphere>();

		private static void Prefix(FogSphere __instance, out float __state)
		{
			__state = __instance.ENABLE;
			if (Plugin.BlocksRisingFog)
			{
				__instance.ENABLE = 0f;
			}
		}

		private static void Postfix(FogSphere __instance, float __state)
		{
			__instance.ENABLE = __state;
			bool blocksRisingFog = Plugin.BlocksRisingFog;
			if (blocksRisingFog != Hidden.Contains(__instance))
			{
				Renderer component = ((Component)__instance).GetComponent<Renderer>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.enabled = !blocksRisingFog;
				}
				if (blocksRisingFog)
				{
					Hidden.Add(__instance);
				}
				else
				{
					Hidden.Remove(__instance);
				}
			}
		}
	}
	[HarmonyPatch(typeof(OrbFogHandler), "Update")]
	internal static class OrbFogHandler_Update
	{
		private static void Prefix(OrbFogHandler __instance)
		{
			if (Plugin.BlocksRisingFog && Plugin.AffectLobbyAsHost && __instance.isMoving)
			{
				__instance.isMoving = false;
			}
		}
	}
	[HarmonyPatch(typeof(OrbFogHandler), "WaitToMove")]
	internal static class OrbFogHandler_WaitToMove
	{
		private static bool Prefix()
		{
			if (Plugin.BlocksRisingFog)
			{
				return !Plugin.AffectLobbyAsHost;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(LavaRising), "Update")]
	internal static class LavaRising_Update
	{
		private static bool Prefix(LavaRising __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			bool num;
			if ((int)__instance.risingFieldType != 1)
			{
				if ((int)__instance.risingFieldType != 0)
				{
					goto IL_0030;
				}
				num = Plugin.BlocksRisingLava;
			}
			else
			{
				num = Plugin.BlocksRisingFog;
			}
			if (num && Plugin.AffectLobbyAsHost)
			{
				return __instance.started;
			}
			goto IL_0030;
			IL_0030:
			return true;
		}
	}
	[HarmonyPatch(typeof(StatusFieldGloom), "Update")]
	internal static class StatusFieldGloom_Update
	{
		private static readonly FieldRef<StatusFieldBase, bool> InField = AccessTools.FieldRefAccess<StatusFieldBase, bool>("characterInField");

		private static readonly Dictionary<StatusFieldGloom, bool> IsRising = new Dictionary<StatusFieldGloom, bool>();

		private static bool Prefix(StatusFieldGloom __instance)
		{
			if (!IsRising.TryGetValue(__instance, out var value))
			{
				value = (Object)(object)((Component)__instance).GetComponentInParent<LavaRising>() != (Object)null;
				if (IsRising.Count > 64)
				{
					IsRising.Clear();
				}
				IsRising[__instance] = value;
			}
			if (!(value ? Plugin.BlocksRisingFog : Plugin.BlocksSleepyGloom))
			{
				return true;
			}
			InField.Invoke((StatusFieldBase)(object)__instance) = false;
			if (Object.op_Implicit((Object)(object)__instance.ambience))
			{
				__instance.ambience.volume = Mathf.Lerp(__instance.ambience.volume, __instance.ambienceOutOfFog, Time.deltaTime * 4f);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(GUIManager), "TheFogRises")]
	internal static class GUIManager_TheFogRises
	{
		private static bool Prefix()
		{
			return !Plugin.BlocksRisingFog;
		}
	}
	[HarmonyPatch(typeof(GUIManager), "TheGloomRises")]
	internal static class GUIManager_TheGloomRises
	{
		private static bool Prefix()
		{
			return !Plugin.BlocksRisingFog;
		}
	}
	[HarmonyPatch(typeof(GUIManager), "TheLavaRises")]
	internal static class GUIManager_TheLavaRises
	{
		private static bool Prefix()
		{
			return !Plugin.BlocksRisingLava;
		}
	}
	public enum WeatherKind
	{
		Rain,
		AlpineStorm,
		RootsWind
	}
	[BepInPlugin("xtyob.weathertoggle", "WeatherToggle", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "xtyob.weathertoggle";

		public const string Name = "WeatherToggle";

		public const string Version = "1.0.0";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private ConfigEntry<Key> _key;

		private ConfigEntry<bool> _startDisabled;

		private ConfigEntry<bool> _showIndicator;

		private ConfigEntry<bool> _rain;

		private ConfigEntry<bool> _alpine;

		private ConfigEntry<bool> _roots;

		private ConfigEntry<bool> _heat;

		private ConfigEntry<bool> _tornado;

		private ConfigEntry<bool> _risingFog;

		private ConfigEntry<bool> _risingLava;

		private ConfigEntry<bool> _sleepyGloom;

		private ConfigEntry<bool> _stopRisingAsHost;

		private ConfigEntry<float> _hazeTransparency;

		private ConfigEntry<bool> _hazeAlways;

		private ConfigEntry<string> _hazeProperties;

		internal static bool WeatherOff;

		private readonly HazeScaler _haze = new HazeScaler();

		private string _toast;

		private float _toastUntil;

		private GUIStyle _style;

		internal static bool BlocksHeat
		{
			get
			{
				if (WeatherOff && (Object)(object)Instance != (Object)null)
				{
					return Instance._heat.Value;
				}
				return false;
			}
		}

		internal static bool BlocksRisingFog
		{
			get
			{
				if (WeatherOff && (Object)(object)Instance != (Object)null)
				{
					return Instance._risingFog.Value;
				}
				return false;
			}
		}

		internal static bool BlocksRisingLava
		{
			get
			{
				if (WeatherOff && (Object)(object)Instance != (Object)null)
				{
					return Instance._risingLava.Value;
				}
				return false;
			}
		}

		internal static bool BlocksSleepyGloom
		{
			get
			{
				if (WeatherOff && (Object)(object)Instance != (Object)null)
				{
					return Instance._sleepyGloom.Value;
				}
				return false;
			}
		}

		internal static bool BlocksTornado
		{
			get
			{
				if (WeatherOff && (Object)(object)Instance != (Object)null)
				{
					return Instance._tornado.Value;
				}
				return false;
			}
		}

		internal static bool AffectLobbyAsHost
		{
			get
			{
				if ((Object)(object)Instance != (Object)null && Instance._stopRisingAsHost.Value)
				{
					return PhotonNetwork.IsMasterClient;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Expected O, but got Unknown
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			_key = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Key", (Key)24, "Key that switches weather off/on. Unity Input System key names (e.g. J, F3, Backquote, Numpad1).");
			_startDisabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "StartWithWeatherOff", false, "If true, weather starts switched off when the game launches.");
			_showIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "ShowIndicator", true, "Show a small \"Weather OFF\" note in the corner while weather is switched off.");
			_rain = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "Rain", true, "Tropics rain storms (wetness/slipperiness, rain visuals and sound).");
			_alpine = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "AlpineColdWind", true, "Alpine blizzard / cold wind (cold status, push force, snow visuals).");
			_roots = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "RootsWind", true, "Roots wind gusts (push force, wind visuals).");
			_heat = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "MesaSunHeat", true, "Mesa sun heat (heat status from standing in direct sunlight).");
			_tornado = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "MesaTornadoes", true, "Mesa tornadoes: no pull/fling/camera shake on you, tornadoes hidden and silent. As host, none spawn and existing ones die out.");
			_risingFog = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "RisingFog", true, "The fog that rises on every level to force you onward, plus the rising gloom in the Temple: no cold/drowsiness from it, fog wall hidden, \"The fog/gloom rises\" banner hidden.");
			_risingLava = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "RisingLava", true, "The Kiln's rising lava. Only the host can stop it (see AffectLobbyAsHost); it only hides the \"The lava rises\" banner for non-hosts.");
			_sleepyGloom = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "GloomSleepiness", false, "Also block the drowsiness from simply standing in the Gloom biome's haze (not just the rising gloom).");
			_stopRisingAsHost = ((BaseUnityPlugin)this).Config.Bind<bool>("Weather", "AffectLobbyAsHost", true, "When you are the lobby host, also stop the rising fog/gloom/lava from advancing and tornadoes from spawning for EVERYONE (everything resumes normally once weather is switched back on). Non-hosts only ever change their own game.");
			_hazeTransparency = ((BaseUnityPlugin)this).Config.Bind<float>("GloomHaze", "Transparency", 0.35f, new ConfigDescription("How much more transparent the Gloom biome haze becomes while weather is off. 0 = unchanged, 1 = gone.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_hazeAlways = ((BaseUnityPlugin)this).Config.Bind<bool>("GloomHaze", "ApplyAlways", false, "Apply the haze transparency even while weather is switched on.");
			_hazeProperties = ((BaseUnityPlugin)this).Config.Bind<string>("GloomHaze", "ShaderProperties", "HeightFogAmount", "Comma-separated global shader floats that drive the haze. Advanced: only change if the haze isn't affected.");
			WeatherOff = _startDisabled.Value;
			new Harmony("xtyob.weathertoggle").PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to toggle weather.", "WeatherToggle", "1.0.0", _key.Value));
		}

		internal static bool Blocks(WeatherKind kind)
		{
			if (!WeatherOff || (Object)(object)Instance == (Object)null)
			{
				return false;
			}
			return kind switch
			{
				WeatherKind.Rain => Instance._rain.Value, 
				WeatherKind.AlpineStorm => Instance._alpine.Value, 
				WeatherKind.RootsWind => Instance._roots.Value, 
				_ => false, 
			};
		}

		private void Update()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null || (int)_key.Value == 0)
			{
				return;
			}
			try
			{
				if (!((ButtonControl)current[_key.Value]).wasPressedThisFrame)
				{
					return;
				}
			}
			catch (ArgumentException)
			{
				return;
			}
			WeatherOff = !WeatherOff;
			_toast = (WeatherOff ? "Weather OFF" : "Weather ON");
			_toastUntil = Time.unscaledTime + 2f;
			Log.LogInfo((object)_toast);
		}

		private void LateUpdate()
		{
			float transparency = ((WeatherOff || _hazeAlways.Value) ? Mathf.Clamp01(_hazeTransparency.Value) : 0f);
			_haze.Apply(_hazeProperties.Value, transparency);
		}

		private void OnGUI()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Time.unscaledTime < _toastUntil;
			if ((flag || (WeatherOff && _showIndicator.Value)) && (int)Event.current.type == 7)
			{
				if (_style == null)
				{
					_style = new GUIStyle(GUI.skin.label)
					{
						fontSize = 16,
						fontStyle = (FontStyle)1,
						alignment = (TextAnchor)2
					};
				}
				string text = (flag ? _toast : "Weather OFF");
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((float)(Screen.width - 410), 10f, 400f, 30f);
				_style.normal.textColor = new Color(0f, 0f, 0f, 0.8f);
				GUI.Label(new Rect(((Rect)(ref val)).x + 1f, ((Rect)(ref val)).y + 1f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text, _style);
				_style.normal.textColor = (WeatherOff ? new Color(0.6f, 0.9f, 1f) : new Color(1f, 0.85f, 0.5f));
				GUI.Label(val, text, _style);
			}
		}

		private void OnDestroy()
		{
			_haze.Apply(_hazeProperties.Value, 0f);
		}
	}
	internal sealed class HazeScaler
	{
		private sealed class Entry
		{
			public int id;

			public float gameValue;

			public float written;

			public bool active;
		}

		private readonly Dictionary<string, Entry> _entries = new Dictionary<string, Entry>();

		private string _lastList;

		private readonly List<string> _names = new List<string>();

		public void Apply(string list, float transparency)
		{
			if (list != _lastList)
			{
				foreach (Entry value in _entries.Values)
				{
					Restore(value);
				}
				_entries.Clear();
				_names.Clear();
				string[] array = (list ?? "").Split(',');
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (text.Length > 0 && !_entries.ContainsKey(text))
					{
						_entries[text] = new Entry
						{
							id = Shader.PropertyToID(text)
						};
						_names.Add(text);
					}
				}
				_lastList = list;
			}
			foreach (string name in _names)
			{
				Entry entry = _entries[name];
				float globalFloat = Shader.GetGlobalFloat(entry.id);
				if (!entry.active || !Mathf.Approximately(globalFloat, entry.written))
				{
					entry.gameValue = globalFloat;
				}
				if (transparency <= 0f)
				{
					Restore(entry);
					continue;
				}
				entry.written = entry.gameValue * (1f - transparency);
				entry.active = true;
				Shader.SetGlobalFloat(entry.id, entry.written);
			}
		}

		private static void Restore(Entry e)
		{
			if (e.active)
			{
				if (Mathf.Approximately(Shader.GetGlobalFloat(e.id), e.written))
				{
					Shader.SetGlobalFloat(e.id, e.gameValue);
				}
				e.active = false;
			}
		}
	}
}