Decompiled source of Bonelab Weather v0.1.0

Mods/WeatherMod.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using WeatherMod;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "Weather", "0.1.0", "You", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("WeatherMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WeatherMod")]
[assembly: AssemblyTitle("WeatherMod")]
[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 WeatherMod
{
	public class Mod : MelonMod
	{
		private const float RainRate = 1500f;

		private const float SnowRate = 500f;

		private GameObject _root;

		private ParticleSystem _rain;

		private ParticleSystem _snow;

		private AudioSource _rainAudio;

		private AudioClip _rainClip;

		private float _rainVolume = 0.4f;

		private float _skyAmount = 0.7f;

		private float _skyBlend;

		private bool _skyDirty;

		private bool _skyCaptured;

		private bool _origFog;

		private Color _origFogColor;

		private FogMode _origFogMode;

		private float _origFogDensity;

		private float _origAmbientIntensity;

		private Material _origSky;

		private Material _skyMat;

		private bool _hasTint;

		private bool _hasSkyTint;

		private bool _hasExposure;

		private Color _origTint;

		private Color _origSkyTint;

		private float _origExposure;

		private readonly List<Light> _sunLights = new List<Light>();

		private readonly List<float> _sunOrig = new List<float>();

		private bool _rainOn;

		private bool _snowOn;

		private float _intensity = 1f;

		private float _wind;

		public override void OnInitializeMelon()
		{
			BuildMenu();
			((MelonBase)this).LoggerInstance.Msg("Weather loaded. Open BoneMenu > Weather. (F2 = rain, F3 = snow as a backup.)");
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			_root = null;
			_rain = null;
			_snow = null;
			_rainAudio = null;
			_skyCaptured = false;
			_skyBlend = 0f;
			_skyMat = null;
			_origSky = null;
			_sunLights.Clear();
			_sunOrig.Clear();
			Refresh();
		}

		public override void OnUpdate()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)283))
			{
				_rainOn = !_rainOn;
				Refresh();
			}
			if (Input.GetKeyDown((KeyCode)284))
			{
				_snowOn = !_snowOn;
				Refresh();
			}
			UpdateSky(Time.deltaTime);
			if ((Object)(object)_root != (Object)null)
			{
				Camera main = Camera.main;
				if ((Object)(object)main != (Object)null)
				{
					_root.transform.position = ((Component)main).transform.position + Vector3.up * 8f;
				}
			}
		}

		private void BuildMenu()
		{
			//IL_000a: 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)
			//IL_003a: 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_0089: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("Weather", Color.cyan, 0, true);
			obj.CreateBool("Rain", Color.cyan, false, (Action<bool>)delegate(bool v)
			{
				_rainOn = v;
				Refresh();
			});
			obj.CreateBool("Snow", Color.white, false, (Action<bool>)delegate(bool v)
			{
				_snowOn = v;
				Refresh();
			});
			obj.CreateFloat("Intensity", Color.yellow, 1f, 0.25f, 0.25f, 3f, (Action<float>)delegate(float v)
			{
				_intensity = v;
				Refresh();
			});
			obj.CreateFloat("Rain Volume", Color.cyan, 0.4f, 0.1f, 0f, 1f, (Action<float>)delegate(float v)
			{
				_rainVolume = v;
				Refresh();
			});
			obj.CreateFloat("Sky Darkness", Color.gray, 0.7f, 0.1f, 0f, 1f, (Action<float>)delegate(float v)
			{
				_skyAmount = v;
				_skyDirty = true;
			});
			obj.CreateFloat("Wind", Color.green, 0f, 1f, -10f, 10f, (Action<float>)delegate(float v)
			{
				_wind = v;
				Refresh();
			});
		}

		private void Refresh()
		{
			if ((_rainOn || _snowOn) && (Object)(object)_root == (Object)null)
			{
				Build();
			}
			if (!((Object)(object)_root == (Object)null))
			{
				Apply(_rain, _rainOn, 1500f);
				Apply(_snow, _snowOn, 500f);
				UpdateAudio();
			}
		}

		private void Apply(ParticleSystem ps, bool on, float baseRate)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0048: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ps == (Object)null))
			{
				ps.emission.rateOverTime = new MinMaxCurve(on ? (baseRate * _intensity) : 0f);
				((Component)ps).transform.localRotation = Quaternion.Euler(0f, 0f, _wind * 5f) * Quaternion.Euler(90f, 0f, 0f);
			}
		}

		private void Build()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_root = new GameObject("WeatherRoot");
			_rain = MakeSystem("Rain", snow: false);
			_snow = MakeSystem("Snow", snow: true);
			BuildAudio();
		}

		private void UpdateSky(float dt)
		{
			float num = ((_rainOn || _snowOn) ? 1f : 0f);
			float skyBlend = _skyBlend;
			_skyBlend = Mathf.MoveTowards(_skyBlend, num, dt * 0.4f);
			if (_skyBlend == skyBlend && !_skyDirty)
			{
				return;
			}
			_skyDirty = false;
			if (!_skyCaptured)
			{
				if (_skyBlend <= 0f)
				{
					return;
				}
				CaptureSky();
			}
			ApplySky(_skyBlend * _skyAmount);
		}

		private void CaptureSky()
		{
			//IL_0013: 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: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Invalid comparison between Unknown and I4
			_skyCaptured = true;
			_origFog = RenderSettings.fog;
			_origFogColor = RenderSettings.fogColor;
			_origFogMode = RenderSettings.fogMode;
			_origFogDensity = RenderSettings.fogDensity;
			_origAmbientIntensity = RenderSettings.ambientIntensity;
			_origSky = RenderSettings.skybox;
			_skyMat = null;
			_hasTint = (_hasSkyTint = (_hasExposure = false));
			if ((Object)(object)_origSky != (Object)null)
			{
				_skyMat = new Material(_origSky);
				if (_skyMat.HasProperty("_Tint"))
				{
					_hasTint = true;
					_origTint = _skyMat.GetColor("_Tint");
				}
				if (_skyMat.HasProperty("_SkyTint"))
				{
					_hasSkyTint = true;
					_origSkyTint = _skyMat.GetColor("_SkyTint");
				}
				if (_skyMat.HasProperty("_Exposure"))
				{
					_hasExposure = true;
					_origExposure = _skyMat.GetFloat("_Exposure");
				}
				if (!_hasTint && !_hasSkyTint && !_hasExposure)
				{
					((MelonBase)this).LoggerInstance.Msg("This level's sky shader has no tint/exposure setting, so only fog and light are changed.");
				}
			}
			_sunLights.Clear();
			_sunOrig.Clear();
			foreach (Light item in Object.FindObjectsOfType<Light>())
			{
				if ((int)item.type == 1)
				{
					_sunLights.Add(item);
					_sunOrig.Add(item.intensity);
				}
			}
		}

		private void ApplySky(float b)
		{
			//IL_0037: 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_004a: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(0.5f, 0.54f, 0.58f);
			RenderSettings.fog = _origFog || b > 0f;
			RenderSettings.fogMode = (FogMode)((b > 0f) ? 3 : ((int)_origFogMode));
			RenderSettings.fogColor = Color.Lerp(_origFogColor, val, b);
			RenderSettings.fogDensity = Mathf.Lerp(_origFogDensity, 0.025f, b);
			RenderSettings.ambientIntensity = Mathf.Lerp(_origAmbientIntensity, _origAmbientIntensity * 0.6f, b);
			for (int i = 0; i < _sunLights.Count; i++)
			{
				if ((Object)(object)_sunLights[i] != (Object)null)
				{
					_sunLights[i].intensity = Mathf.Lerp(_sunOrig[i], _sunOrig[i] * 0.4f, b);
				}
			}
			if ((Object)(object)_skyMat != (Object)null)
			{
				if (_hasTint)
				{
					_skyMat.SetColor("_Tint", Color.Lerp(_origTint, new Color(0.42f, 0.45f, 0.5f), b));
				}
				if (_hasSkyTint)
				{
					_skyMat.SetColor("_SkyTint", Color.Lerp(_origSkyTint, val, b));
				}
				if (_hasExposure)
				{
					_skyMat.SetFloat("_Exposure", Mathf.Lerp(_origExposure, _origExposure * 0.5f, b));
				}
				RenderSettings.skybox = ((b > 0f) ? _skyMat : _origSky);
			}
		}

		private void BuildAudio()
		{
			try
			{
				AudioClip val = LoadRainClip();
				if (!((Object)(object)val == (Object)null))
				{
					_rainAudio = _root.AddComponent<AudioSource>();
					_rainAudio.clip = val;
					_rainAudio.loop = true;
					_rainAudio.playOnAwake = false;
					_rainAudio.spatialBlend = 0f;
					_rainAudio.volume = _rainVolume;
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Could not set up rain sound: " + ex.Message);
			}
		}

		private void UpdateAudio()
		{
			if (!((Object)(object)_rainAudio == (Object)null))
			{
				_rainAudio.volume = _rainVolume;
				if (_rainOn && !_rainAudio.isPlaying)
				{
					_rainAudio.Play();
				}
				else if (!_rainOn && _rainAudio.isPlaying)
				{
					_rainAudio.Stop();
				}
			}
		}

		private AudioClip LoadRainClip()
		{
			if ((Object)(object)_rainClip != (Object)null)
			{
				return _rainClip;
			}
			string text = Path.Combine(MelonEnvironment.UserDataDirectory, "WeatherMod");
			string text2 = Path.Combine(text, "rain.wav");
			Directory.CreateDirectory(text);
			if (!File.Exists(text2))
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				foreach (string text3 in manifestResourceNames)
				{
					if (!text3.EndsWith("rain.wav", StringComparison.OrdinalIgnoreCase))
					{
						continue;
					}
					using (Stream stream = executingAssembly.GetManifestResourceStream(text3))
					{
						using FileStream destination = File.Create(text2);
						stream.CopyTo(destination);
					}
					break;
				}
			}
			if (!File.Exists(text2))
			{
				((MelonBase)this).LoggerInstance.Warning("rain.wav not found: " + text2);
				return null;
			}
			AudioClip val = ParseWav(File.ReadAllBytes(text2), "WeatherRain");
			if ((Object)(object)val != (Object)null)
			{
				((Object)val).hideFlags = (HideFlags)32;
				_rainClip = val;
				((MelonBase)this).LoggerInstance.Msg("Rain sound loaded from " + text2);
			}
			return val;
		}

		private AudioClip ParseWav(byte[] b, string name)
		{
			if (b.Length < 44 || b[0] != 82 || b[1] != 73 || b[2] != 70 || b[3] != 70)
			{
				((MelonBase)this).LoggerInstance.Warning("rain.wav is not a valid WAV file.");
				return null;
			}
			int num = 1;
			int num2 = 22050;
			int num3 = 16;
			int num4 = -1;
			int num5 = 0;
			int num6 = 12;
			while (num6 + 8 <= b.Length)
			{
				string text = Encoding.ASCII.GetString(b, num6, 4);
				int num7 = BitConverter.ToInt32(b, num6 + 4);
				int num8 = num6 + 8;
				if (text == "fmt ")
				{
					num = BitConverter.ToInt16(b, num8 + 2);
					num2 = BitConverter.ToInt32(b, num8 + 4);
					num3 = BitConverter.ToInt16(b, num8 + 14);
				}
				else if (text == "data")
				{
					num4 = num8;
					num5 = Math.Min(num7, b.Length - num8);
					break;
				}
				num6 = num8 + num7 + (num7 & 1);
			}
			if (num4 < 0 || num3 != 16)
			{
				((MelonBase)this).LoggerInstance.Warning("rain.wav must be a 16-bit PCM WAV.");
				return null;
			}
			int num9 = num5 / 2;
			float[] array = new float[num9];
			for (int i = 0; i < num9; i++)
			{
				array[i] = (float)BitConverter.ToInt16(b, num4 + i * 2) / 32768f;
			}
			AudioClip obj = AudioClip.Create(name, num9 / num, num, num2, false);
			obj.SetData(new Il2CppStructArray<float>(array), 0);
			return obj;
		}

		private ParticleSystem MakeSystem(string name, bool snow)
		{
			//IL_0001: 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)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject(name);
				val.transform.SetParent(_root.transform, false);
				val.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
				ParticleSystem val2 = val.AddComponent<ParticleSystem>();
				val2.Stop(true, (ParticleSystemStopBehavior)0);
				MainModule main = val2.main;
				main.loop = true;
				main.duration = 5f;
				main.simulationSpace = (ParticleSystemSimulationSpace)1;
				main.maxParticles = (snow ? 4000 : 8000);
				main.startLifetime = new MinMaxCurve(snow ? 6f : 1.2f);
				main.startSpeed = new MinMaxCurve(snow ? 1.5f : 12f);
				main.startSize = new MinMaxCurve(snow ? 0.04f : 0.02f);
				main.startColor = new MinMaxGradient(snow ? new Color(1f, 1f, 1f, 0.9f) : new Color(0.75f, 0.85f, 1f, 0.5f));
				main.gravityModifier = new MinMaxCurve(0f);
				EmissionModule emission = val2.emission;
				emission.enabled = true;
				emission.rateOverTime = new MinMaxCurve(0f);
				ShapeModule shape = val2.shape;
				shape.shapeType = (ParticleSystemShapeType)5;
				shape.scale = new Vector3(24f, 24f, 0.1f);
				if (snow)
				{
					NoiseModule noise = val2.noise;
					noise.enabled = true;
					noise.strength = new MinMaxCurve(0.4f);
					noise.frequency = 0.5f;
				}
				ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					Material val3 = MakeMaterial();
					if ((Object)(object)val3 != (Object)null)
					{
						((Renderer)component).material = val3;
					}
					if (!snow)
					{
						component.renderMode = (ParticleSystemRenderMode)1;
						component.lengthScale = 6f;
					}
				}
				val2.Play();
				return val2;
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Could not build " + name + ": " + ex.Message);
				return null;
			}
		}

		private Material MakeMaterial()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			string[] array = new string[4] { "Universal Render Pipeline/Particles/Unlit", "Sprites/Default", "Particles/Standard Unlit", "Hidden/Internal-Colored" };
			foreach (string text in array)
			{
				Shader val = Shader.Find(text);
				if ((Object)(object)val != (Object)null)
				{
					((MelonBase)this).LoggerInstance.Msg("Weather shader: " + text);
					return new Material(val);
				}
			}
			((MelonBase)this).LoggerInstance.Warning("No particle shader found; using the default material.");
			return null;
		}
	}
}