Decompiled source of GraveOfTruth v0.1.2

GraveOfTruth.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("GraveOfTruth")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e767994ce9bdaec30138d634b986fca6a07f0174")]
[assembly: AssemblyProduct("GraveOfTruth")]
[assembly: AssemblyTitle("GraveOfTruth")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace GraveOfTruth
{
	[BepInPlugin("rauschekuh.graveoftruth", "GraveOfTruth", "0.1.2")]
	public class GraveOfTruthPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Game), "Start")]
		public static class RegisterRpc
		{
			private static void Postfix()
			{
				ZRoutedRpc instance = ZRoutedRpc.instance;
				if (instance != null && instance != registeredOn)
				{
					registeredOn = instance;
					instance.Register<Vector3, bool>("GraveOfTruth_Wail", (Action<long, Vector3, bool>)RPC_Wail);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnDeath")]
		public static class WailOnDeath
		{
			private static void Postfix(Player __instance)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
					{
						Wail(((Character)__instance).GetCenterPoint(), strike: true);
					}
				}
				catch (Exception ex)
				{
					log.LogWarning((object)("death effects failed: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(TombStone), "Interact")]
		public static class WailOnLoot
		{
			private static void Postfix(TombStone __instance, Humanoid character, bool hold, bool __result)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!hold && __result && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && __instance.IsOwner())
					{
						Wail(((Component)__instance).transform.position, strike: false);
					}
				}
				catch (Exception ex)
				{
					log.LogWarning((object)("grave effects failed: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(EnvMan), "SetEnv")]
		public static class StormSky
		{
			private static void Prefix(EnvMan __instance, ref EnvSetup env)
			{
				float num = Time.time - stormStart;
				if (num >= 9f || env == null)
				{
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null && ((Character)localPlayer).InInterior())
				{
					return;
				}
				EnvSetup env2 = __instance.GetEnv("ThunderStorm");
				if (env2 != null)
				{
					float num2 = Mathf.Clamp01(Mathf.Min(num, 9f - num) / 2f);
					EnvSetup val = __instance.InterpolateEnvironment(env, env2, num2);
					val.m_ambientLoop = env.m_ambientLoop;
					val.m_ambientVol = env.m_ambientVol;
					if (num2 >= 0.5f)
					{
						val.m_envObject = env2.m_envObject;
					}
					env = val;
				}
			}
		}

		public const string GUID = "rauschekuh.graveoftruth";

		public const string NAME = "GraveOfTruth";

		public const string VERSION = "0.1.2";

		private const string WailRpc = "GraveOfTruth_Wail";

		private const float MinDistance = 6f;

		private const float MaxDistance = 96f;

		private const float WailCooldown = 2f;

		private const float StrikeLeadIn = 1.7f;

		private const float EchoDelay = 0.9f;

		private const float EchoVolume = 0.35f;

		private const float TailDelay = 2f;

		private const float TailVolume = 0.14f;

		private const float DistantOffset = 40f;

		private const float DistantVolume = 0.5f;

		private const string StormEnv = "ThunderStorm";

		private const float StormDuration = 9f;

		private const float StormFade = 2f;

		private const float StormRadius = 150f;

		private const float StrikeAltitude = 12f;

		private static GraveOfTruthPlugin instance;

		private static ManualLogSource log;

		private static AudioClip audioClip;

		private static AudioMixerGroup mixer;

		private static GameObject boltPrefab;

		private static Thunder thunder;

		private static ZRoutedRpc registeredOn;

		private static float lastWail = -100f;

		private static float stormStart = -100f;

		private void Awake()
		{
			instance = this;
			log = ((BaseUnityPlugin)this).Logger;
			((MonoBehaviour)this).StartCoroutine(LoadClip());
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "rauschekuh.graveoftruth");
		}

		private static void Wail(Vector3 pos, bool strike)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "GraveOfTruth_Wail", new object[2] { pos, strike });
			}
			else
			{
				RPC_Wail(0L, pos, strike);
			}
		}

		private static void RPC_Wail(long sender, Vector3 pos, bool strike)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) || Time.time - lastWail < 2f)
			{
				return;
			}
			lastWail = Time.time;
			try
			{
				if (!strike)
				{
					((MonoBehaviour)instance).StartCoroutine(WailRoutine(pos, 0f, 1f));
					return;
				}
				if (TryGetOrigin(out var pos2) && Vector3.Distance(pos2, pos) > 150f)
				{
					((MonoBehaviour)instance).StartCoroutine(DistantThunder(pos2, pos));
					return;
				}
				if (!StrikeGrave(pos))
				{
					SkyFlash(pos);
				}
				stormStart = Time.time;
				((MonoBehaviour)instance).StartCoroutine(WailRoutine(pos, 1.7f, 1f));
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("wail failed: " + ex));
			}
		}

		private static IEnumerator WailRoutine(Vector3 pos, float leadIn, float volume)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (leadIn > 0f)
			{
				yield return (object)new WaitForSeconds(leadIn);
			}
			PlayAt(pos, volume, 1f);
			yield return (object)new WaitForSeconds(0.9f);
			PlayAt(pos, volume * 0.35f, 0.97f);
			yield return (object)new WaitForSeconds(1.1f);
			PlayAt(pos, volume * 0.14f, 0.97f);
		}

		private static void PlayAt(Vector3 pos, float volume, float pitch)
		{
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_00ae: Expected O, but got Unknown
			if (!((Object)(object)audioClip == (Object)null))
			{
				GameObject val = new GameObject("GraveOfTruthWail");
				val.transform.position = pos + Vector3.up;
				AudioSource val2 = val.AddComponent<AudioSource>();
				val2.clip = audioClip;
				val2.spatialBlend = 1f;
				val2.rolloffMode = (AudioRolloffMode)1;
				val2.minDistance = 6f;
				val2.maxDistance = 96f;
				val2.dopplerLevel = 0f;
				val2.volume = volume;
				val2.pitch = pitch;
				val2.outputAudioMixerGroup = SfxMixer();
				val2.Play();
				Object.Destroy((Object)val, audioClip.length / val2.pitch + 0.5f);
			}
		}

		private static AudioMixerGroup SfxMixer()
		{
			if ((Object)(object)mixer != (Object)null)
			{
				return mixer;
			}
			AudioMan val = AudioMan.instance;
			if ((Object)(object)val == (Object)null || (Object)(object)val.m_masterMixer == (Object)null)
			{
				return null;
			}
			string[] array = new string[3] { "SFX", "Sfx", "sfx" };
			foreach (string text in array)
			{
				AudioMixerGroup[] array2 = val.m_masterMixer.FindMatchingGroups(text);
				if (array2 != null && array2.Length != 0)
				{
					mixer = array2[0];
					return mixer;
				}
			}
			mixer = val.m_ambientMixer;
			return mixer;
		}

		private static bool StrikeGrave(Vector3 pos)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindBolt();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			bool activeSelf = val.activeSelf;
			bool forceDisableInit = ZNetView.m_forceDisableInit;
			val.SetActive(false);
			ZNetView.m_forceDisableInit = true;
			try
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, pos, Quaternion.identity);
				Aoe[] componentsInChildren = val2.GetComponentsInChildren<Aoe>(true);
				foreach (Aoe obj in componentsInChildren)
				{
					obj.m_damage = default(DamageTypes);
					obj.m_damagePerLevel = default(DamageTypes);
					obj.m_damageSelf = 0f;
					obj.m_attackForce = 0f;
					obj.m_hitCharacters = false;
					obj.m_hitProps = false;
					obj.m_hitTerrain = false;
					obj.m_hitOwner = false;
					obj.m_hitParent = false;
					obj.m_launchCharacters = false;
				}
				val2.SetActive(true);
			}
			finally
			{
				ZNetView.m_forceDisableInit = forceDisableInit;
				val.SetActive(activeSelf);
			}
			return true;
		}

		private static GameObject FindBolt()
		{
			if ((Object)(object)boltPrefab != (Object)null)
			{
				return boltPrefab;
			}
			Incinerator[] array = Resources.FindObjectsOfTypeAll<Incinerator>();
			foreach (Incinerator val in array)
			{
				if ((Object)(object)val.m_lightingAOEs != (Object)null)
				{
					boltPrefab = val.m_lightingAOEs;
					return boltPrefab;
				}
			}
			log.LogWarning((object)"no obliterator lightning found, falling back to a sky flash");
			return null;
		}

		private static void SkyFlash(Vector3 pos)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Thunder val = FindThunder();
			if (!((Object)(object)val == (Object)null))
			{
				Flash(val, pos + Vector3.up * 12f, Quaternion.LookRotation(Vector3.down));
				val.m_thunderEffect.Create(pos, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
		}

		private static IEnumerator DistantThunder(Vector3 origin, Vector3 grave)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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)
			Thunder t = FindThunder();
			if (!((Object)(object)t == (Object)null))
			{
				Vector3 toGrave = grave - origin;
				toGrave.y = 0f;
				((Vector3)(ref toGrave)).Normalize();
				Vector3 flashPos = origin + toGrave * t.m_flashDistanceMax + Vector3.up * t.m_flashAltitude;
				Vector3 val = origin - flashPos;
				Flash(t, flashPos, Quaternion.LookRotation(((Vector3)(ref val)).normalized));
				StrikeGrave(grave);
				yield return (object)new WaitForSeconds(Random.Range(t.m_thunderDelayMin, t.m_thunderDelayMax));
				t.m_thunderEffect.Create(flashPos, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				yield return WailRoutine(origin + toGrave * 40f, 1.7f, 0.5f);
			}
		}

		private static void Flash(Thunder t, Vector3 pos, Quaternion rotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			GameObject[] array = t.m_flashEffect.Create(pos, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			for (int i = 0; i < array.Length; i++)
			{
				Light[] componentsInChildren = array[i].GetComponentsInChildren<Light>();
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					((Component)componentsInChildren[j]).transform.rotation = rotation;
				}
			}
		}

		private static Thunder FindThunder()
		{
			if ((Object)(object)thunder != (Object)null)
			{
				return thunder;
			}
			Thunder[] array = Resources.FindObjectsOfTypeAll<Thunder>();
			if (array.Length != 0)
			{
				thunder = array[0];
			}
			else
			{
				log.LogWarning((object)"no Thunder component found, skipping lightning");
			}
			return thunder;
		}

		private static bool TryGetOrigin(out Vector3 pos)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				pos = ((Component)localPlayer).transform.position;
				return true;
			}
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)mainCamera != (Object)null)
			{
				pos = ((Component)mainCamera).transform.position;
				return true;
			}
			pos = Vector3.zero;
			return false;
		}

		private static IEnumerator LoadClip()
		{
			string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "sound.ogg");
			if (!File.Exists(path))
			{
				log.LogWarning((object)(path + " does not exist"));
				yield break;
			}
			UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, (AudioType)14);
			try
			{
				yield return www.SendWebRequest();
				if ((int)www.result != 1)
				{
					log.LogWarning((object)("could not load " + path + ": " + www.error));
					yield break;
				}
				audioClip = DownloadHandlerAudioClip.GetContent(www);
			}
			finally
			{
				((IDisposable)www)?.Dispose();
			}
		}
	}
}