Decompiled source of Deathrattle v2.0.1

plugins/Deathrattle/Deathrattle.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Deathrattle;

[BepInPlugin("com.server.deathrattle", "Deathrattle", "2.0.1")]
public class DeathrattlePlugin : BaseUnityPlugin
{
	private class ActiveMessage
	{
		public GameObject Copy;

		public int Slot;

		public Coroutine Routine;
	}

	private class ShatterMark
	{
		public Mesh Scorch;

		public Mesh Glow;

		public void Set(float scorchAlpha, float glowAlpha)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			SetMeshAlpha(Scorch, new Color(1f, 1f, 1f, Mathf.Clamp01(scorchAlpha)));
			SetMeshAlpha(Glow, new Color(EffectColor.r, EffectColor.g, EffectColor.b, Mathf.Clamp01(glowAlpha)));
		}

		private static void SetMeshAlpha(Mesh m, Color c)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)m == (Object)null))
			{
				Color[] array = (Color[])(object)new Color[m.vertexCount];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = c;
				}
				m.colors = array;
			}
		}
	}

	public const string PluginGuid = "com.server.deathrattle";

	public const string PluginName = "Deathrattle";

	public const string PluginVersion = "2.0.1";

	internal const string RpcName = "Deathrattle_PlayerDied";

	internal static DeathrattlePlugin Instance;

	internal static ManualLogSource Log;

	private static AudioClip _clip;

	private static AudioClip _layerClip;

	private static AudioSource _source;

	internal static float LocalDeathTime = -100f;

	internal static string PendingLocalMessage;

	internal static float PendingLocalTime = -100f;

	internal static HitData LastLocalHit;

	private ConfigEntry<string> _fileName;

	private ConfigEntry<bool> _layerEnabled;

	private ConfigEntry<bool> _showMessage;

	private ConfigEntry<bool> _showCause;

	private ConfigEntry<bool> _beamEnabled;

	private ConfigEntry<float> _beamDuration;

	private ConfigEntry<float> _beamWidth;

	private ConfigEntry<float> _beamHeight;

	private ConfigEntry<bool> _particlesEnabled;

	private ConfigEntry<float> _particleRate;

	private ConfigEntry<float> _particleRadius;

	private ConfigEntry<string> _effectColor;

	internal static Color EffectColor = new Color(1f, 0.125f, 0.125f);

	private ConfigEntry<string> _unknownMessage;

	private ConfigEntry<string> _creatureMessage;

	private ConfigEntry<string> _bossMessage;

	private ConfigEntry<string> _playerMessage;

	private readonly Dictionary<string, ConfigEntry<string>> _typeMessages = new Dictionary<string, ConfigEntry<string>>();

	private readonly Dictionary<string, string> _creatureMessages = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

	private const string CreatureFileName = "creature_messages.txt";

	private Harmony _harmony;

	private const string DefaultCreatureFile = "# Deathrattle: creature-specific death messages\n# Format:  PrefabName = message\n# {0} = dead player's name, {1} = creature's in-game name\n# Creatures not listed here use KilledByCreature / KilledByBoss from the .cfg file.\n# The game log (BepInEx\\LogOutput.log) prints the prefab name of whatever killed\n# you, so you can add any creature that's missing.\n\n# ---- Bosses ----\nEikthyr = {0} was gored by Eikthyr\ngd_king = {0} was crushed by The Elder\nBonemass = {0} was smothered by Bonemass\nDragon = {0} was frozen solid by Moder\nGoblinKing = {0} was obliterated by Yagluth\nSeekerQueen = {0} was devoured by The Queen\nFader = {0} was erased by Fader\n\n# ---- Meadows ----\nBoar = {0} was gored by a Boar\nNeck = {0} was nibbled to death by a Neck\nDeer = {0} was trampled by a Deer\n\n# ---- Black Forest ----\nGreyling = {0} was swarmed by a Greyling\nGreydwarf = {0} was pelted to death by a Greydwarf\nGreydwarf_Elite = {0} was clobbered by a Greydwarf Brute\nGreydwarf_Shaman = {0} was cursed by a Greydwarf Shaman\nTroll = {0} was smashed by a Troll\nSkeleton = {0} was cut down by a Skeleton\nSkeleton_Poison = {0} was poisoned by a Rancid Remains\nGhost = {0} was haunted to death by a Ghost\n\n# ---- Swamp ----\nDraugr = {0} was hacked apart by a Draugr\nDraugr_Elite = {0} was cleaved by a Draugr Elite\nDraugr_Ranged = {0} was shot down by a Draugr archer\nBlob = {0} was dissolved by a Blob\nBlobElite = {0} was dissolved by an Oozer\nLeech = {0} was drained by a Leech\nWraith = {0} was claimed by a Wraith\nAbomination = {0} was flattened by an Abomination\nSurtling = {0} was set ablaze by a Surtling\n\n# ---- Mountains ----\nWolf = {0} was mauled by a Wolf\nHatchling = {0} was frozen by a Drake\nFenring = {0} was torn to shreds by a Fenring. To shreds you say?\nFenring_Cultist = {0} was burned by a Cultist\nUlv = {0} was savaged by an Ulv\nBat = {0} was nibbled to death by a Bat\nStoneGolem = {0} was pulverized by a Stone Golem\n\n# ---- Plains ----\nLox = {0} was stomped by a Lox\nDeathsquito = {0} was skewered by a Deathsquito\nGoblin = {0} was butchered by a Fuling\nGoblinArcher = {0} was shot down by a Fuling archer\nGoblinBrute = {0} was crushed by a Fuling Berserker\nGoblinShaman = {0} was hexed by a Fuling Shaman\n\n# ---- Ocean ----\nSerpent = {0} was swallowed by a Sea Serpent\n\n# ---- Mistlands ----\nSeeker = {0} was impaled by a Seeker\nSeekerBrute = {0} was crushed by a Seeker Soldier\nSeekerBrood = {0} was overrun by Seeker Brood\nTick = {0} was drained dry by a Tick\nGjall = {0} was bombarded by a Gjall\nDverger = {0} was cut down by a Dvergr\nDvergerMage = {0} was blasted by a Dvergr Mage\nHare = {0} was somehow killed by a Hare\n\n# ---- Ashlands ----\nCharred_Melee = {0} was cut down by a Charred Warrior\nCharred_Archer = {0} was shot down by a Charred Marksman\nCharred_Mage = {0} was incinerated by a Charred Warlock\nCharred_Twitcher = {0} was shredded by a Charred Twitcher\nMorgen = {0} was mauled by a Morgen\nFallenValkyrie = {0} was struck down by a Fallen Valkyrie\nAsksvin = {0} was trampled by an Asksvin\nVolture = {0} was picked apart by a Volture\nBonemawSerpent = {0} was devoured by a Bonemaw Serpent\n";

	private static readonly string[][] DefaultTypeMessages = new string[22][]
	{
		new string[2] { "Fall", "{0} broke their legs falling" },
		new string[2] { "Drowning", "{0} drowned" },
		new string[2] { "Burning", "{0} burned to death" },
		new string[2] { "Freezing", "{0} froze to death" },
		new string[2] { "Poisoned", "{0} succumbed to poison" },
		new string[2] { "Water", "{0} was claimed by the water" },
		new string[2] { "Smoke", "{0} choked on smoke" },
		new string[2] { "EdgeOfWorld", "{0} fell off the edge of the world" },
		new string[2] { "Impact", "{0} was crushed by a heavy impact" },
		new string[2] { "Cart", "{0} was run over by a cart" },
		new string[2] { "Tree", "{0} was crushed by a falling tree" },
		new string[2] { "Self", "{0} was undone by their own doing" },
		new string[2] { "Structural", "{0} was crushed by a collapsing structure" },
		new string[2] { "Turret", "{0} was shot by a turret" },
		new string[2] { "Boat", "{0} was struck by a boat" },
		new string[2] { "Stalagtite", "{0} was impaled by a falling stalactite" },
		new string[2] { "Catapult", "{0} was struck by a catapult" },
		new string[2] { "CinderFire", "{0} was scorched by cinder fire" },
		new string[2] { "AshlandsOcean", "{0} was boiled alive in the Ashlands sea" },
		new string[2] { "AshlandsLava", "{0} melted in Ashlands lava" },
		new string[2] { "Incinerator", "{0} was incinerated" },
		new string[2] { "DrawBridge", "{0} was crushed by a drawbridge" }
	};

	private const float MessageVisibleSeconds = 6.5f;

	private const float MessageFadeSeconds = 1.5f;

	private const int MaxStackedMessages = 5;

	private readonly List<ActiveMessage> _activeMessages = new List<ActiveMessage>();

	private static Material _beamMaterial;

	private const int BeamSegments = 32;

	private static Material _beamGlowMaterial;

	private const float BoltHeight = 250f;

	private const float HoldSeconds = 1.5f;

	private const float ArcTailSeconds = 0.9f;

	private const float ReshapeSeconds = 0.09f;

	private const int BoltPoints = 40;

	private const int ArcCount = 4;

	private const int ArcPoints = 8;

	private const float MarkRadius = 3f;

	private static Material _scorchMaterial;

	private static Material _crackGlowMaterial;

	private const int MarkGrid = 16;

	private static int _surfaceMask = -1;

	private const float ParticleMaxLifetime = 2f;

	private static Material _particleMaterial;

	internal bool MessagesEnabled
	{
		[CompilerGenerated]
		get
		{
			return _showMessage.Value;
		}
	}

	private void Awake()
	{
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		_fileName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "SoundFile", "wilhelm.wav", "Optional audio file (.wav or .ogg) in the plugins folder. If not found, the built-in Wilhelm scream is used.");
		_layerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PlayLayer", true, "Play the low, pitched-down sound layered under the scream.");
		_showMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("Message", "ShowMessage", true, "Show a message in the center of the screen when a player dies.");
		_showCause = ((BaseUnityPlugin)this).Config.Bind<bool>("Message", "ShowCauseOfDeath", true, "Use cause-of-death messages. If false, always uses UnknownCause.");
		_beamEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Beam", "ShowBeam", true, "Show a beam of light into the sky where a player died.");
		_beamDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Beam", "Duration", 12f, "Seconds the beam lasts while fading out.");
		_beamWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Beam", "Width", 0.6f, "Width of the bright core of the beam, in meters.");
		_beamHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Beam", "Height", 3000f, "How far up the beam reaches, in meters.");
		_particlesEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Beam", "ShowParticles", true, "Show glowing particles around the spot where the player died.");
		_particleRate = ((BaseUnityPlugin)this).Config.Bind<float>("Beam", "ParticlesPerSecond", 8f, "How many glow particles appear per second.");
		_particleRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Beam", "ParticleRadius", 1.2f, "How far from the body the particles spread, in meters.");
		_effectColor = ((BaseUnityPlugin)this).Config.Bind<string>("Beam", "Color", "#FF2020", "Color of the beam, light, and particles, as a hex code (e.g. #FF2020 red, #FFFFFF white).");
		UpgradeOldDefaults();
		if (!ColorUtility.TryParseHtmlString(_effectColor.Value, ref EffectColor))
		{
			Log.LogWarning((object)$"Couldn't read beam color '{_effectColor.Value}', using red.");
			EffectColor = new Color(1f, 0.125f, 0.125f);
		}
		_unknownMessage = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "UnknownCause", "{0} had fallen", "Used when the cause can't be determined. {0} = player name.");
		_creatureMessage = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "KilledByCreature", "{0} was slain by a {1}", "Killed by a creature. {0} = player name, {1} = creature name.");
		_bossMessage = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "KilledByBoss", "{0} was slain by {1}", "Killed by a boss. {0} = player name, {1} = boss name.");
		_playerMessage = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "KilledByPlayer", "{0} was slain by {1}", "Killed by another player. {0} = player name, {1} = killer's name.");
		string[][] defaultTypeMessages = DefaultTypeMessages;
		foreach (string[] array in defaultTypeMessages)
		{
			_typeMessages[array[0]] = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", array[0], array[1], $"Death by {array[0]}. {{0}} = player name.");
		}
		LoadCreatureMessages();
		_harmony = new Harmony("com.server.deathrattle");
		_harmony.PatchAll();
		((MonoBehaviour)this).StartCoroutine(LoadClip());
	}

	private void UpgradeOldDefaults()
	{
		ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Internal", "ConfigVersion", 0, "Used by the mod to update old default settings. Don't change this.");
		if (val.Value < 2)
		{
			if (Mathf.Approximately(_beamDuration.Value, 5f))
			{
				_beamDuration.Value = 12f;
			}
			val.Value = 2;
			((BaseUnityPlugin)this).Config.Save();
			Log.LogInfo((object)$"Updated old config defaults (Duration {_beamDuration.Value}).");
		}
	}

	private void OnDestroy()
	{
		if (_harmony != null)
		{
			_harmony.UnpatchSelf();
		}
	}

	private IEnumerator LoadClip()
	{
		_layerClip = LoadEmbeddedWav("Deathrattle.teleport.wav", "DeathrattleLayer");
		string path = FindSoundFile();
		if (path == null)
		{
			_clip = LoadEmbeddedWav("Deathrattle.wilhelm.wav", "DeathrattleScream");
			if ((Object)(object)_clip != (Object)null)
			{
				Log.LogInfo((object)"Loaded built-in death sound.");
			}
			else
			{
				Log.LogError((object)$"Sound file '{_fileName.Value}' not found and built-in sound failed to load.");
			}
			yield break;
		}
		AudioType type = (AudioType)((!path.EndsWith(".ogg", StringComparison.OrdinalIgnoreCase)) ? 20 : 14);
		string uri = new Uri(path).AbsoluteUri;
		UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(uri, type);
		try
		{
			yield return req.SendWebRequest();
			if ((int)req.result != 1)
			{
				Log.LogError((object)$"Failed to load sound: {req.error}");
				yield break;
			}
			_clip = DownloadHandlerAudioClip.GetContent(req);
			Log.LogInfo((object)$"Loaded death sound: {path}");
		}
		finally
		{
			((IDisposable)req)?.Dispose();
		}
	}

	private string FindSoundFile()
	{
		string value = _fileName.Value;
		if (string.IsNullOrEmpty(value))
		{
			return null;
		}
		try
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			string text = Path.Combine(directoryName, value);
			if (File.Exists(text))
			{
				return text;
			}
			string pluginPath = Paths.PluginPath;
			if (Directory.Exists(pluginPath))
			{
				string[] files = Directory.GetFiles(pluginPath, value, SearchOption.AllDirectories);
				if (files.Length > 0)
				{
					return files[0];
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)$"Error searching for sound file: {ex.Message}");
		}
		return null;
	}

	private static AudioClip LoadEmbeddedWav(string resourceName, string clipName)
	{
		try
		{
			Stream manifestResourceStream = typeof(DeathrattlePlugin).Assembly.GetManifestResourceStream(resourceName);
			if (manifestResourceStream == null)
			{
				return null;
			}
			byte[] array;
			using (manifestResourceStream)
			{
				using MemoryStream memoryStream = new MemoryStream();
				manifestResourceStream.CopyTo(memoryStream);
				array = memoryStream.ToArray();
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = -1;
			int num5 = 0;
			int num6;
			for (int i = 12; i + 8 <= array.Length; i += 8 + num6 + (num6 & 1))
			{
				string text = Encoding.ASCII.GetString(array, i, 4);
				num6 = BitConverter.ToInt32(array, i + 4);
				if (text == "fmt ")
				{
					num = BitConverter.ToInt16(array, i + 10);
					num2 = BitConverter.ToInt32(array, i + 12);
					num3 = BitConverter.ToInt16(array, i + 22);
				}
				else if (text == "data")
				{
					num4 = i + 8;
					num5 = Math.Min(num6, array.Length - num4);
					break;
				}
			}
			if (num3 != 16 || num <= 0 || num2 <= 0 || num4 < 0)
			{
				Log.LogError((object)"Built-in sound is not a 16-bit PCM WAV.");
				return null;
			}
			int num7 = num5 / 2;
			float[] array2 = new float[num7];
			for (int j = 0; j < num7; j++)
			{
				array2[j] = (float)BitConverter.ToInt16(array, num4 + j * 2) / 32768f;
			}
			AudioClip val = AudioClip.Create(clipName, num7 / num, num, num2, false);
			val.SetData(array2, 0);
			return val;
		}
		catch (Exception ex)
		{
			Log.LogError((object)$"Failed to read built-in sound: {ex.Message}");
			return null;
		}
	}

	internal string BuildDeathMessage(Player player)
	{
		string playerName = player.GetPlayerName();
		if (!_showCause.Value)
		{
			return SafeFormat(_unknownMessage.Value, playerName, string.Empty);
		}
		HitData killingHit = GetKillingHit(player);
		if (killingHit == null)
		{
			return SafeFormat(_unknownMessage.Value, playerName, string.Empty);
		}
		string hitTypeName = GetHitTypeName(killingHit);
		Character val = null;
		try
		{
			val = killingHit.GetAttacker();
		}
		catch
		{
		}
		int num;
		switch (hitTypeName)
		{
		default:
			num = ((hitTypeName == string.Empty) ? 1 : 0);
			break;
		case "EnemyHit":
		case "PlayerHit":
		case "Undefined":
			num = 1;
			break;
		}
		bool flag = (byte)num != 0;
		if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)player && flag)
		{
			object obj2 = ((val is Player) ? val : null);
			Player val2 = default(Player);
			if (obj2 != null)
			{
				val2 = (Player)obj2;
				obj2 = val2;
			}
			if (obj2 != null)
			{
				return SafeFormat(_playerMessage.Value, playerName, val2.GetPlayerName());
			}
			string hoverName = val.GetHoverName();
			string prefabName = GetPrefabName(val);
			Log.LogInfo((object)$"Killed by creature prefab '{prefabName}' ({hoverName}).");
			string text = FindCreatureMessage(prefabName);
			if (text != null)
			{
				return SafeFormat(text, playerName, hoverName);
			}
			return (!val.IsBoss()) ? SafeFormat(_creatureMessage.Value, playerName, hoverName) : SafeFormat(_bossMessage.Value, playerName, hoverName);
		}
		if (_typeMessages.TryGetValue(hitTypeName, out var value))
		{
			return SafeFormat(value.Value, playerName, string.Empty);
		}
		Log.LogInfo((object)$"No message for hit type '{hitTypeName}', using UnknownCause.");
		return SafeFormat(_unknownMessage.Value, playerName, string.Empty);
	}

	private static string GetPrefabName(Character c)
	{
		string text = ((Object)((Component)c).gameObject).name;
		int num = text.IndexOf("(Clone)", StringComparison.Ordinal);
		if (num >= 0)
		{
			text = text.Substring(0, num);
		}
		return text.Trim();
	}

	private string FindCreatureMessage(string prefab)
	{
		if (string.IsNullOrEmpty(prefab))
		{
			return null;
		}
		if (_creatureMessages.TryGetValue(prefab, out var value))
		{
			return value;
		}
		int num = prefab.IndexOf('_');
		if (num > 0 && _creatureMessages.TryGetValue(prefab.Substring(0, num), out value))
		{
			return value;
		}
		return null;
	}

	private void LoadCreatureMessages()
	{
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		string path = Path.Combine(directoryName, "creature_messages.txt");
		if (!File.Exists(path))
		{
			try
			{
				File.WriteAllText(path, "# Deathrattle: creature-specific death messages\n# Format:  PrefabName = message\n# {0} = dead player's name, {1} = creature's in-game name\n# Creatures not listed here use KilledByCreature / KilledByBoss from the .cfg file.\n# The game log (BepInEx\\LogOutput.log) prints the prefab name of whatever killed\n# you, so you can add any creature that's missing.\n\n# ---- Bosses ----\nEikthyr = {0} was gored by Eikthyr\ngd_king = {0} was crushed by The Elder\nBonemass = {0} was smothered by Bonemass\nDragon = {0} was frozen solid by Moder\nGoblinKing = {0} was obliterated by Yagluth\nSeekerQueen = {0} was devoured by The Queen\nFader = {0} was erased by Fader\n\n# ---- Meadows ----\nBoar = {0} was gored by a Boar\nNeck = {0} was nibbled to death by a Neck\nDeer = {0} was trampled by a Deer\n\n# ---- Black Forest ----\nGreyling = {0} was swarmed by a Greyling\nGreydwarf = {0} was pelted to death by a Greydwarf\nGreydwarf_Elite = {0} was clobbered by a Greydwarf Brute\nGreydwarf_Shaman = {0} was cursed by a Greydwarf Shaman\nTroll = {0} was smashed by a Troll\nSkeleton = {0} was cut down by a Skeleton\nSkeleton_Poison = {0} was poisoned by a Rancid Remains\nGhost = {0} was haunted to death by a Ghost\n\n# ---- Swamp ----\nDraugr = {0} was hacked apart by a Draugr\nDraugr_Elite = {0} was cleaved by a Draugr Elite\nDraugr_Ranged = {0} was shot down by a Draugr archer\nBlob = {0} was dissolved by a Blob\nBlobElite = {0} was dissolved by an Oozer\nLeech = {0} was drained by a Leech\nWraith = {0} was claimed by a Wraith\nAbomination = {0} was flattened by an Abomination\nSurtling = {0} was set ablaze by a Surtling\n\n# ---- Mountains ----\nWolf = {0} was mauled by a Wolf\nHatchling = {0} was frozen by a Drake\nFenring = {0} was torn to shreds by a Fenring. To shreds you say?\nFenring_Cultist = {0} was burned by a Cultist\nUlv = {0} was savaged by an Ulv\nBat = {0} was nibbled to death by a Bat\nStoneGolem = {0} was pulverized by a Stone Golem\n\n# ---- Plains ----\nLox = {0} was stomped by a Lox\nDeathsquito = {0} was skewered by a Deathsquito\nGoblin = {0} was butchered by a Fuling\nGoblinArcher = {0} was shot down by a Fuling archer\nGoblinBrute = {0} was crushed by a Fuling Berserker\nGoblinShaman = {0} was hexed by a Fuling Shaman\n\n# ---- Ocean ----\nSerpent = {0} was swallowed by a Sea Serpent\n\n# ---- Mistlands ----\nSeeker = {0} was impaled by a Seeker\nSeekerBrute = {0} was crushed by a Seeker Soldier\nSeekerBrood = {0} was overrun by Seeker Brood\nTick = {0} was drained dry by a Tick\nGjall = {0} was bombarded by a Gjall\nDverger = {0} was cut down by a Dvergr\nDvergerMage = {0} was blasted by a Dvergr Mage\nHare = {0} was somehow killed by a Hare\n\n# ---- Ashlands ----\nCharred_Melee = {0} was cut down by a Charred Warrior\nCharred_Archer = {0} was shot down by a Charred Marksman\nCharred_Mage = {0} was incinerated by a Charred Warlock\nCharred_Twitcher = {0} was shredded by a Charred Twitcher\nMorgen = {0} was mauled by a Morgen\nFallenValkyrie = {0} was struck down by a Fallen Valkyrie\nAsksvin = {0} was trampled by an Asksvin\nVolture = {0} was picked apart by a Volture\nBonemawSerpent = {0} was devoured by a Bonemaw Serpent\n");
				Log.LogInfo((object)string.Format("Created default {0}.", "creature_messages.txt"));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)string.Format("Couldn't write {0}: {1}", "creature_messages.txt", ex.Message));
			}
		}
		string[] array;
		try
		{
			array = ((!File.Exists(path)) ? "# Deathrattle: creature-specific death messages\n# Format:  PrefabName = message\n# {0} = dead player's name, {1} = creature's in-game name\n# Creatures not listed here use KilledByCreature / KilledByBoss from the .cfg file.\n# The game log (BepInEx\\LogOutput.log) prints the prefab name of whatever killed\n# you, so you can add any creature that's missing.\n\n# ---- Bosses ----\nEikthyr = {0} was gored by Eikthyr\ngd_king = {0} was crushed by The Elder\nBonemass = {0} was smothered by Bonemass\nDragon = {0} was frozen solid by Moder\nGoblinKing = {0} was obliterated by Yagluth\nSeekerQueen = {0} was devoured by The Queen\nFader = {0} was erased by Fader\n\n# ---- Meadows ----\nBoar = {0} was gored by a Boar\nNeck = {0} was nibbled to death by a Neck\nDeer = {0} was trampled by a Deer\n\n# ---- Black Forest ----\nGreyling = {0} was swarmed by a Greyling\nGreydwarf = {0} was pelted to death by a Greydwarf\nGreydwarf_Elite = {0} was clobbered by a Greydwarf Brute\nGreydwarf_Shaman = {0} was cursed by a Greydwarf Shaman\nTroll = {0} was smashed by a Troll\nSkeleton = {0} was cut down by a Skeleton\nSkeleton_Poison = {0} was poisoned by a Rancid Remains\nGhost = {0} was haunted to death by a Ghost\n\n# ---- Swamp ----\nDraugr = {0} was hacked apart by a Draugr\nDraugr_Elite = {0} was cleaved by a Draugr Elite\nDraugr_Ranged = {0} was shot down by a Draugr archer\nBlob = {0} was dissolved by a Blob\nBlobElite = {0} was dissolved by an Oozer\nLeech = {0} was drained by a Leech\nWraith = {0} was claimed by a Wraith\nAbomination = {0} was flattened by an Abomination\nSurtling = {0} was set ablaze by a Surtling\n\n# ---- Mountains ----\nWolf = {0} was mauled by a Wolf\nHatchling = {0} was frozen by a Drake\nFenring = {0} was torn to shreds by a Fenring. To shreds you say?\nFenring_Cultist = {0} was burned by a Cultist\nUlv = {0} was savaged by an Ulv\nBat = {0} was nibbled to death by a Bat\nStoneGolem = {0} was pulverized by a Stone Golem\n\n# ---- Plains ----\nLox = {0} was stomped by a Lox\nDeathsquito = {0} was skewered by a Deathsquito\nGoblin = {0} was butchered by a Fuling\nGoblinArcher = {0} was shot down by a Fuling archer\nGoblinBrute = {0} was crushed by a Fuling Berserker\nGoblinShaman = {0} was hexed by a Fuling Shaman\n\n# ---- Ocean ----\nSerpent = {0} was swallowed by a Sea Serpent\n\n# ---- Mistlands ----\nSeeker = {0} was impaled by a Seeker\nSeekerBrute = {0} was crushed by a Seeker Soldier\nSeekerBrood = {0} was overrun by Seeker Brood\nTick = {0} was drained dry by a Tick\nGjall = {0} was bombarded by a Gjall\nDverger = {0} was cut down by a Dvergr\nDvergerMage = {0} was blasted by a Dvergr Mage\nHare = {0} was somehow killed by a Hare\n\n# ---- Ashlands ----\nCharred_Melee = {0} was cut down by a Charred Warrior\nCharred_Archer = {0} was shot down by a Charred Marksman\nCharred_Mage = {0} was incinerated by a Charred Warlock\nCharred_Twitcher = {0} was shredded by a Charred Twitcher\nMorgen = {0} was mauled by a Morgen\nFallenValkyrie = {0} was struck down by a Fallen Valkyrie\nAsksvin = {0} was trampled by an Asksvin\nVolture = {0} was picked apart by a Volture\nBonemawSerpent = {0} was devoured by a Bonemaw Serpent\n".Split('\n') : File.ReadAllLines(path));
		}
		catch (Exception ex2)
		{
			Log.LogWarning((object)string.Format("Couldn't read {0}: {1}", "creature_messages.txt", ex2.Message));
			array = "# Deathrattle: creature-specific death messages\n# Format:  PrefabName = message\n# {0} = dead player's name, {1} = creature's in-game name\n# Creatures not listed here use KilledByCreature / KilledByBoss from the .cfg file.\n# The game log (BepInEx\\LogOutput.log) prints the prefab name of whatever killed\n# you, so you can add any creature that's missing.\n\n# ---- Bosses ----\nEikthyr = {0} was gored by Eikthyr\ngd_king = {0} was crushed by The Elder\nBonemass = {0} was smothered by Bonemass\nDragon = {0} was frozen solid by Moder\nGoblinKing = {0} was obliterated by Yagluth\nSeekerQueen = {0} was devoured by The Queen\nFader = {0} was erased by Fader\n\n# ---- Meadows ----\nBoar = {0} was gored by a Boar\nNeck = {0} was nibbled to death by a Neck\nDeer = {0} was trampled by a Deer\n\n# ---- Black Forest ----\nGreyling = {0} was swarmed by a Greyling\nGreydwarf = {0} was pelted to death by a Greydwarf\nGreydwarf_Elite = {0} was clobbered by a Greydwarf Brute\nGreydwarf_Shaman = {0} was cursed by a Greydwarf Shaman\nTroll = {0} was smashed by a Troll\nSkeleton = {0} was cut down by a Skeleton\nSkeleton_Poison = {0} was poisoned by a Rancid Remains\nGhost = {0} was haunted to death by a Ghost\n\n# ---- Swamp ----\nDraugr = {0} was hacked apart by a Draugr\nDraugr_Elite = {0} was cleaved by a Draugr Elite\nDraugr_Ranged = {0} was shot down by a Draugr archer\nBlob = {0} was dissolved by a Blob\nBlobElite = {0} was dissolved by an Oozer\nLeech = {0} was drained by a Leech\nWraith = {0} was claimed by a Wraith\nAbomination = {0} was flattened by an Abomination\nSurtling = {0} was set ablaze by a Surtling\n\n# ---- Mountains ----\nWolf = {0} was mauled by a Wolf\nHatchling = {0} was frozen by a Drake\nFenring = {0} was torn to shreds by a Fenring. To shreds you say?\nFenring_Cultist = {0} was burned by a Cultist\nUlv = {0} was savaged by an Ulv\nBat = {0} was nibbled to death by a Bat\nStoneGolem = {0} was pulverized by a Stone Golem\n\n# ---- Plains ----\nLox = {0} was stomped by a Lox\nDeathsquito = {0} was skewered by a Deathsquito\nGoblin = {0} was butchered by a Fuling\nGoblinArcher = {0} was shot down by a Fuling archer\nGoblinBrute = {0} was crushed by a Fuling Berserker\nGoblinShaman = {0} was hexed by a Fuling Shaman\n\n# ---- Ocean ----\nSerpent = {0} was swallowed by a Sea Serpent\n\n# ---- Mistlands ----\nSeeker = {0} was impaled by a Seeker\nSeekerBrute = {0} was crushed by a Seeker Soldier\nSeekerBrood = {0} was overrun by Seeker Brood\nTick = {0} was drained dry by a Tick\nGjall = {0} was bombarded by a Gjall\nDverger = {0} was cut down by a Dvergr\nDvergerMage = {0} was blasted by a Dvergr Mage\nHare = {0} was somehow killed by a Hare\n\n# ---- Ashlands ----\nCharred_Melee = {0} was cut down by a Charred Warrior\nCharred_Archer = {0} was shot down by a Charred Marksman\nCharred_Mage = {0} was incinerated by a Charred Warlock\nCharred_Twitcher = {0} was shredded by a Charred Twitcher\nMorgen = {0} was mauled by a Morgen\nFallenValkyrie = {0} was struck down by a Fallen Valkyrie\nAsksvin = {0} was trampled by an Asksvin\nVolture = {0} was picked apart by a Volture\nBonemawSerpent = {0} was devoured by a Bonemaw Serpent\n".Split('\n');
		}
		_creatureMessages.Clear();
		string[] array2 = array;
		foreach (string text in array2)
		{
			string text2 = text.Trim();
			if (text2.Length == 0 || text2.StartsWith("#"))
			{
				continue;
			}
			int num = text2.IndexOf('=');
			if (num > 0)
			{
				string text3 = text2.Substring(0, num).Trim();
				string text4 = text2.Substring(num + 1).Trim();
				if (text3.Length > 0 && text4.Length > 0)
				{
					_creatureMessages[text3] = text4;
				}
			}
		}
		Log.LogInfo((object)$"Loaded {_creatureMessages.Count} creature-specific death messages.");
	}

	private static HitData GetKillingHit(Player player)
	{
		HitData val = null;
		try
		{
			val = Traverse.Create((object)player).Field("m_lastHit").GetValue<HitData>();
		}
		catch
		{
		}
		return val ?? LastLocalHit;
	}

	private static string GetHitTypeName(HitData hit)
	{
		try
		{
			return Traverse.Create((object)hit).Field("m_hitType").GetValue()?.ToString() ?? string.Empty;
		}
		catch
		{
			return string.Empty;
		}
	}

	private static string SafeFormat(string format, string name, string other)
	{
		try
		{
			return string.Format(format, name, other);
		}
		catch (FormatException)
		{
			return $"{name} had fallen";
		}
	}

	internal void OnPlayerDied(string message, Vector3 position)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		Log.LogInfo((object)message);
		Play();
		if (_beamEnabled.Value)
		{
			((MonoBehaviour)this).StartCoroutine(BeamRoutine(position));
		}
		ShowMessage(message);
	}

	private void ShowMessage(string message)
	{
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		if (!_showMessage.Value || (Object)(object)MessageHud.instance == (Object)null || string.IsNullOrEmpty(message))
		{
			return;
		}
		Component centerText = GetCenterText();
		if ((Object)(object)centerText == (Object)null)
		{
			MessageHud.instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false, true);
			return;
		}
		int num = FreeSlot();
		if (num < 0)
		{
			ActiveMessage activeMessage = _activeMessages[0];
			RemoveMessage(activeMessage);
			num = activeMessage.Slot;
		}
		GameObject val = Object.Instantiate<GameObject>(centerText.gameObject, centerText.transform.parent, false);
		((Object)val).name = "DeathrattleMessage";
		val.transform.SetSiblingIndex(centerText.transform.GetSiblingIndex() + 1);
		val.SetActive(true);
		Transform transform = val.transform;
		RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		Transform transform2 = centerText.transform;
		RectTransform val3 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
		if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
		{
			val2.anchoredPosition = val3.anchoredPosition + new Vector2(0f, (float)(-num) * LineSpacing(centerText));
		}
		Component component = val.GetComponent(((object)centerText).GetType());
		ActiveMessage activeMessage2 = new ActiveMessage();
		activeMessage2.Copy = val;
		activeMessage2.Slot = num;
		ActiveMessage activeMessage3 = activeMessage2;
		_activeMessages.Add(activeMessage3);
		activeMessage3.Routine = ((MonoBehaviour)this).StartCoroutine(MessageRoutine(activeMessage3, component, message));
	}

	private int FreeSlot()
	{
		for (int i = 0; i < 5; i++)
		{
			bool flag = false;
			foreach (ActiveMessage activeMessage in _activeMessages)
			{
				if (activeMessage.Slot == i)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return i;
			}
		}
		return -1;
	}

	private void RemoveMessage(ActiveMessage m)
	{
		if (m.Routine != null)
		{
			((MonoBehaviour)this).StopCoroutine(m.Routine);
		}
		if ((Object)(object)m.Copy != (Object)null)
		{
			Object.Destroy((Object)(object)m.Copy);
		}
		_activeMessages.Remove(m);
	}

	private static float LineSpacing(Component text)
	{
		object property = GetProperty(text, "fontSize", null);
		float num = 0f;
		try
		{
			if (property != null)
			{
				num = Convert.ToSingle(property);
			}
		}
		catch
		{
		}
		return (!(num > 0f)) ? 40f : (num * 1.3f);
	}

	private IEnumerator MessageRoutine(ActiveMessage entry, Component text, string message)
	{
		SetProperty(text, "text", message);
		SetProperty(text, "color", (object)new Color(44f / 51f, 4f / 51f, 0.23529412f, 1f));
		CrossFade(text, 1f, 0f);
		yield return (object)new WaitForSeconds(6.5f);
		CrossFade(text, 0f, 1.5f);
		yield return (object)new WaitForSeconds(1.6f);
		entry.Routine = null;
		RemoveMessage(entry);
	}

	private static Component GetCenterText()
	{
		try
		{
			object? obj = typeof(MessageHud).GetField("m_messageCenterText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(MessageHud.instance);
			return (Component)((obj is Component) ? obj : null);
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)$"Couldn't find the game's center text: {ex.Message}");
			return null;
		}
	}

	private static object GetProperty(object obj, string name, object fallback)
	{
		try
		{
			PropertyInfo property = obj.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
			return (!(property != null)) ? fallback : property.GetValue(obj, null);
		}
		catch
		{
			return fallback;
		}
	}

	private static void SetProperty(object obj, string name, object value)
	{
		try
		{
			PropertyInfo property = obj.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
			if (property != null && property.CanWrite)
			{
				property.SetValue(obj, value, null);
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)$"Couldn't set {name} on death message: {ex.Message}");
		}
	}

	private static void CrossFade(object obj, float alpha, float duration)
	{
		try
		{
			obj.GetType().GetMethod("CrossFadeAlpha", new Type[3]
			{
				typeof(float),
				typeof(float),
				typeof(bool)
			})?.Invoke(obj, new object[3] { alpha, duration, true });
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)$"Couldn't fade death message: {ex.Message}");
		}
	}

	private static Material GetBeamMaterial()
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		if ((Object)(object)_beamMaterial != (Object)null)
		{
			return _beamMaterial;
		}
		string[] array = new string[6] { "Sprites/Default", "Legacy Shaders/Particles/Additive", "Particles/Standard Unlit", "Unlit/Transparent", "Unlit/Color", "Standard" };
		string[] array2 = array;
		foreach (string text in array2)
		{
			Shader val = Shader.Find(text);
			if ((Object)(object)val != (Object)null)
			{
				_beamMaterial = new Material(val);
				Log.LogInfo((object)$"Beam using shader '{text}'.");
				return _beamMaterial;
			}
		}
		Log.LogWarning((object)"No beam shader found; beam disabled.");
		return null;
	}

	private static LineRenderer MakeBeamLine(Transform parent, Material mat, float width)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		GameObject val = new GameObject("DeathrattleBeamLine");
		val.transform.SetParent(parent, false);
		LineRenderer val2 = val.AddComponent<LineRenderer>();
		((Renderer)val2).material = mat;
		val2.useWorldSpace = true;
		val2.positionCount = 33;
		val2.startWidth = width;
		val2.endWidth = width;
		((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)val2).receiveShadows = false;
		val2.alignment = (LineAlignment)0;
		val2.textureMode = (LineTextureMode)0;
		return val2;
	}

	private static Vector3[] BeamPoints(Vector3 bottom, Vector3 top)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[33];
		for (int i = 0; i <= 32; i++)
		{
			float num = (float)i / 32f;
			ref Vector3 reference = ref array[i];
			reference = Vector3.Lerp(bottom, top, num * num);
		}
		return array;
	}

	private static Material GetBeamGlowMaterial()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Expected O, but got Unknown
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_beamGlowMaterial != (Object)null)
		{
			return _beamGlowMaterial;
		}
		Material beamMaterial = GetBeamMaterial();
		if ((Object)(object)beamMaterial == (Object)null)
		{
			return null;
		}
		Texture2D val = new Texture2D(4, 128, (TextureFormat)4, false);
		((Texture)val).wrapMode = (TextureWrapMode)1;
		((Texture)val).filterMode = (FilterMode)1;
		for (int i = 0; i < 128; i++)
		{
			float num = (float)i / 127f;
			float num2 = Mathf.Abs(num * 2f - 1f);
			float num3 = Mathf.Exp((0f - num2) * num2 * 6f);
			num3 *= Mathf.Clamp01((1f - num2) * 4f);
			for (int j = 0; j < 4; j++)
			{
				val.SetPixel(j, i, new Color(1f, 1f, 1f, num3));
			}
		}
		val.Apply();
		_beamGlowMaterial = new Material(beamMaterial.shader);
		_beamGlowMaterial.mainTexture = (Texture)(object)val;
		return _beamGlowMaterial;
	}

	private IEnumerator BeamRoutine(Vector3 position)
	{
		//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)
		Material mat = GetBeamGlowMaterial();
		if ((Object)(object)mat == (Object)null)
		{
			yield break;
		}
		GameObject root = new GameObject("DeathrattleLightning");
		root.transform.position = position;
		float w = _beamWidth.Value;
		Vector3 ground = position + Vector3.up * 0.2f;
		Vector3 sky = position + Vector3.up * 250f;
		LineRenderer core = MakeBeamLine(root.transform, mat, w * 2f);
		LineRenderer glow = MakeBeamLine(root.transform, mat, w * 10f);
		core.positionCount = 40;
		glow.positionCount = 40;
		LineRenderer[] arcs = (LineRenderer[])(object)new LineRenderer[4];
		for (int i = 0; i < 4; i++)
		{
			arcs[i] = MakeBeamLine(root.transform, mat, w * 0.35f);
			arcs[i].positionCount = 8;
			SetBoltAlpha(arcs[i], 0f);
		}
		GameObject lightGo = new GameObject("DeathrattleLightningLight");
		lightGo.transform.SetParent(root.transform, false);
		lightGo.transform.position = position + Vector3.up * 2f;
		Light light = lightGo.AddComponent<Light>();
		light.type = (LightType)2;
		light.color = EffectColor;
		light.range = 30f;
		ParticleSystem particles = null;
		if (_particlesEnabled.Value)
		{
			particles = MakeGlowParticles(root.transform, position);
		}
		ShatterMark mark = MakeShatterMark(root.transform, position);
		float t = 0f;
		float nextReshape = 0f;
		float nextArcShape = 0f;
		float terrain = GroundHeight(position, position.y);
		while (t < 2.4f)
		{
			float k = 0f;
			if (t < 1.5f)
			{
				if (t >= nextReshape)
				{
					nextReshape = t + 0.09f;
					Vector3 val = sky + new Vector3(Random.Range(-3f, 3f), 0f, Random.Range(-3f, 3f));
					Vector3[] positions = BoltPath(val, ground, 40, 4f);
					core.SetPositions(positions);
					glow.SetPositions(positions);
				}
				float num = Mathf.Clamp01((1.5f - t) / 0.3f);
				k = ((t != 0f) ? Random.Range(0.75f, 1f) : 1f) * num;
			}
			SetBoltAlpha(core, k);
			SetBoltAlpha(glow, k * 0.5f);
			float arcK = 0f;
			if (t > 0.3f)
			{
				arcK = ((!(t < 1.5f)) ? (0.8f * (1f - (t - 1.5f) / 0.9f)) : 0.8f);
			}
			if (arcK > 0f && t >= nextArcShape)
			{
				nextArcShape = t + 0.06f;
				for (int j = 0; j < 4; j++)
				{
					arcs[j].SetPositions(GroundArc(position, terrain));
				}
			}
			for (int l = 0; l < 4; l++)
			{
				bool flag = arcK > 0f && Random.value < 0.85f;
				SetBoltAlpha(arcs[l], (!flag) ? 0f : (arcK * Random.Range(0.5f, 1f)));
			}
			light.intensity = 3f + 9f * Mathf.Max(k, arcK * 0.4f);
			mark?.Set(1f, 0.6f + 0.4f * Mathf.Max(k, arcK * 0.5f));
			t += Time.deltaTime;
			yield return null;
		}
		((Renderer)core).enabled = false;
		((Renderer)glow).enabled = false;
		LineRenderer[] array = arcs;
		foreach (LineRenderer val2 in array)
		{
			((Renderer)val2).enabled = false;
		}
		float duration = Mathf.Max(0.1f, _beamDuration.Value);
		t = 0f;
		while (t < duration)
		{
			float k2 = 1f - t / duration;
			light.intensity = 4f * k2;
			mark?.Set(Mathf.Clamp01((duration - t) / 2f), 0.6f * k2);
			t += Time.deltaTime;
			yield return null;
		}
		((Behaviour)light).enabled = false;
		mark?.Set(0f, 0f);
		if ((Object)(object)particles != (Object)null)
		{
			particles.Stop(true, (ParticleSystemStopBehavior)1);
			Object.Destroy((Object)(object)root, 2.5f);
		}
		else
		{
			Object.Destroy((Object)(object)root);
		}
	}

	private ShatterMark MakeShatterMark(Transform parent, Vector3 position)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Material beamMaterial = GetBeamMaterial();
			if ((Object)(object)beamMaterial == (Object)null)
			{
				return null;
			}
			if ((Object)(object)_scorchMaterial == (Object)null || (Object)(object)_crackGlowMaterial == (Object)null)
			{
				BuildShatterTextures(out var scorch, out var glow);
				Material val = new Material(beamMaterial.shader);
				val.mainTexture = (Texture)(object)scorch;
				_scorchMaterial = val;
				val = new Material(beamMaterial.shader);
				val.mainTexture = (Texture)(object)glow;
				_crackGlowMaterial = val;
			}
			float fallback = GroundHeight(position, position.y);
			float[,] array = new float[17, 17];
			for (int i = 0; i <= 16; i++)
			{
				for (int j = 0; j <= 16; j++)
				{
					float num = ((float)j / 16f * 2f - 1f) * 3f;
					float num2 = ((float)i / 16f * 2f - 1f) * 3f;
					array[j, i] = SurfaceHeight(position + new Vector3(num, 0f, num2), position.y, fallback);
				}
			}
			float spin = Random.Range(0f, (float)Math.PI * 2f);
			ShatterMark shatterMark = new ShatterMark();
			shatterMark.Scorch = MakeDecal(parent, "DeathrattleScorch", position, array, 0.06f, spin, _scorchMaterial);
			shatterMark.Glow = MakeDecal(parent, "DeathrattleCracks", position, array, 0.08f, spin, _crackGlowMaterial);
			ShatterMark shatterMark2 = shatterMark;
			shatterMark2.Set(1f, 1f);
			return shatterMark2;
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)$"Couldn't create ground mark: {ex.Message}");
			return null;
		}
	}

	private static float SurfaceHeight(Vector3 p, float bodyY, float fallback)
	{
		//IL_0067: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (_surfaceMask == -1)
			{
				_surfaceMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(p.x, bodyY + 2f, p.z);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, Vector3.down, ref val2, 10f, _surfaceMask, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val2)).point.y;
			}
		}
		catch
		{
		}
		return GroundHeight(p, fallback);
	}

	private static float GroundHeight(Vector3 p, float fallback)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				return ZoneSystem.instance.GetGroundHeight(p);
			}
		}
		catch
		{
		}
		return fallback;
	}

	private static Mesh MakeDecal(Transform parent, string name, Vector3 center, float[,] heights, float lift, float spin, Material mat)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_002d: 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)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: 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)
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Expected O, but got Unknown
		GameObject val = new GameObject(name);
		val.transform.SetParent(parent, true);
		val.transform.position = new Vector3(center.x, 0f, center.z);
		val.transform.rotation = Quaternion.identity;
		int num = 17;
		Vector3[] array = (Vector3[])(object)new Vector3[num * num];
		Vector2[] array2 = (Vector2[])(object)new Vector2[num * num];
		float num2 = Mathf.Cos(spin);
		float num3 = Mathf.Sin(spin);
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num4 = (float)j / 16f;
				float num5 = (float)i / 16f;
				float num6 = (num4 * 2f - 1f) * 3f;
				float num7 = (num5 * 2f - 1f) * 3f;
				int num8 = i * num + j;
				ref Vector3 reference = ref array[num8];
				reference = new Vector3(num6, heights[j, i] + lift, num7);
				float num9 = num4 - 0.5f;
				float num10 = num5 - 0.5f;
				ref Vector2 reference2 = ref array2[num8];
				reference2 = new Vector2(num9 * num2 - num10 * num3 + 0.5f, num9 * num3 + num10 * num2 + 0.5f);
			}
		}
		int[] array3 = new int[1536];
		int num11 = 0;
		for (int k = 0; k < 16; k++)
		{
			for (int l = 0; l < 16; l++)
			{
				int num12 = k * num + l;
				int num13 = num12 + num;
				array3[num11++] = num12;
				array3[num11++] = num13;
				array3[num11++] = num13 + 1;
				array3[num11++] = num12;
				array3[num11++] = num13 + 1;
				array3[num11++] = num12 + 1;
			}
		}
		Mesh val2 = new Mesh();
		val2.vertices = array;
		val2.uv = array2;
		val2.triangles = array3;
		val2.RecalculateNormals();
		val2.RecalculateBounds();
		val.AddComponent<MeshFilter>().mesh = val2;
		MeshRenderer val3 = val.AddComponent<MeshRenderer>();
		((Renderer)val3).sharedMaterial = mat;
		((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)val3).receiveShadows = false;
		return val2;
	}

	private static void BuildShatterTextures(out Texture2D scorch, out Texture2D glow)
	{
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Expected O, but got Unknown
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Expected O, but got Unknown
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		float[] array = new float[65536];
		float[] crack = new float[65536];
		Random rng = new Random(1337);
		float num = 128f;
		for (int i = 0; i < 256; i++)
		{
			for (int j = 0; j < 256; j++)
			{
				float num2 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num) * ((float)i - num)) / num;
				float num3 = (float)rng.NextDouble() * 0.15f;
				array[i * 256 + j] = Mathf.Clamp01(1f - Mathf.Pow(num2 / 0.55f, 2f) + num3 - 0.1f) * 0.75f;
			}
		}
		Action<float, float, float, float, float> walk = null;
		walk = delegate(float sx, float sy, float angle, float length, float width)
		{
			float num16 = sx;
			float num17 = sy;
			int num18 = (int)length;
			for (int k = 0; k < num18; k++)
			{
				angle = ((k % 7 != 0) ? (angle + ((float)rng.NextDouble() - 0.5f) * 0.06f) : (angle + ((float)rng.NextDouble() - 0.5f) * 0.9f));
				num16 += Mathf.Cos(angle);
				num17 += Mathf.Sin(angle);
				float num19 = width * (1f - (float)k / (float)num18) + 0.6f;
				int num20 = Mathf.CeilToInt(num19 + 1f);
				for (int l = -num20; l <= num20; l++)
				{
					for (int m = -num20; m <= num20; m++)
					{
						int num21 = (int)num16 + m;
						int num22 = (int)num17 + l;
						if (num21 >= 0 && num22 >= 0 && num21 < 256 && num22 < 256)
						{
							float num23 = Mathf.Sqrt((float)(m * m + l * l));
							float num24 = Mathf.Clamp01(1f - num23 / (num19 + 0.5f));
							int num25 = num22 * 256 + num21;
							if (num24 > crack[num25])
							{
								crack[num25] = num24;
							}
						}
					}
				}
				if (k > 10 && rng.NextDouble() < 0.025 && width > 1f)
				{
					walk(num16, num17, angle + ((!((double)(float)rng.NextDouble() < 0.5)) ? 1f : (-1f)) * (0.5f + (float)rng.NextDouble() * 0.6f), (float)(num18 - k) * 0.6f, width * 0.55f);
				}
			}
		};
		int num4 = 8;
		for (int num5 = 0; num5 < num4; num5++)
		{
			float arg = (float)num5 / (float)num4 * (float)Math.PI * 2f + (float)rng.NextDouble() * 0.5f;
			walk(num, num, arg, num * (0.7f + (float)rng.NextDouble() * 0.25f), 2.2f);
		}
		for (int num6 = 0; num6 < 7; num6++)
		{
			float num7 = num * (0.18f + (float)rng.NextDouble() * 0.3f);
			float num8 = (float)rng.NextDouble() * (float)Math.PI * 2f;
			walk(num + Mathf.Cos(num8) * num7, num + Mathf.Sin(num8) * num7, num8 + (float)Math.PI / 2f, num7 * (0.4f + (float)rng.NextDouble() * 0.4f), 1.2f);
		}
		scorch = new Texture2D(256, 256, (TextureFormat)4, false);
		glow = new Texture2D(256, 256, (TextureFormat)4, false);
		Texture2D obj = scorch;
		TextureWrapMode wrapMode = (TextureWrapMode)1;
		((Texture)glow).wrapMode = wrapMode;
		((Texture)obj).wrapMode = wrapMode;
		for (int num9 = 0; num9 < 256; num9++)
		{
			for (int num10 = 0; num10 < 256; num10++)
			{
				int num11 = num9 * 256 + num10;
				float num12 = Mathf.Clamp01((1f - Mathf.Sqrt(((float)num10 - num) * ((float)num10 - num) + ((float)num9 - num) * ((float)num9 - num)) / num) * 4f);
				float num13 = crack[num11] * num12;
				float num14 = Mathf.Clamp01(Mathf.Max(array[num11], num13 * 0.95f));
				scorch.SetPixel(num10, num9, new Color(0.04f, 0.03f, 0.03f, num14));
				float num15 = Mathf.Clamp01(num13 * 1.4f);
				glow.SetPixel(num10, num9, new Color(1f, 0.55f + 0.45f * num15 * num15, 0.55f + 0.45f * num15 * num15, num13));
			}
		}
		scorch.Apply();
		glow.Apply();
	}

	private static Vector3[] GroundArc(Vector3 center, float terrain)
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
		float num = Random.Range(0f, (float)Math.PI * 2f);
		float num2 = Random.Range(1.2f, 2.6999998f);
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num));
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(0f - val.z, 0f, val.x);
		Vector3[] array = (Vector3[])(object)new Vector3[8];
		float num3 = 0f;
		for (int i = 0; i < 8; i++)
		{
			float num4 = (float)i / 7f;
			num3 += Random.Range(-0.35f, 0.35f);
			Vector3 val3 = center + val * (num2 * num4) + val2 * (num3 * Mathf.Sin(num4 * (float)Math.PI));
			float num5 = SurfaceHeight(val3, center.y, terrain);
			val3.y = num5 + 0.15f;
			array[i] = val3;
		}
		return array;
	}

	private static Vector3[] BoltPath(Vector3 from, Vector3 to, int count, float jitter)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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_0063: 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_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: 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_0086: 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_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_00aa: 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)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[count];
		Vector3 val = Vector3.zero;
		for (int i = 0; i < count; i++)
		{
			float num = (float)i / (float)(count - 1);
			val += new Vector3(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f)) * jitter * 0.5f;
			val = Vector3.ClampMagnitude(val, jitter * 2f);
			float num2 = Mathf.Sin(num * (float)Math.PI);
			ref Vector3 reference = ref array[i];
			reference = Vector3.Lerp(from, to, num) + val * num2;
		}
		array[0] = from;
		array[count - 1] = to;
		return array;
	}

	private static void SetBoltAlpha(LineRenderer lr, float alpha)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		Color val = default(Color);
		((Color)(ref val))..ctor(EffectColor.r, EffectColor.g, EffectColor.b, Mathf.Clamp01(alpha));
		lr.startColor = val;
		lr.endColor = val;
	}

	private static Material GetParticleMaterial()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Expected O, but got Unknown
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_particleMaterial != (Object)null)
		{
			return _particleMaterial;
		}
		Material beamMaterial = GetBeamMaterial();
		if ((Object)(object)beamMaterial == (Object)null)
		{
			return null;
		}
		Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
		((Texture)val).wrapMode = (TextureWrapMode)1;
		float num = 15.5f;
		for (int i = 0; i < 32; i++)
		{
			for (int j = 0; j < 32; j++)
			{
				float num2 = ((float)j - num) / num;
				float num3 = ((float)i - num) / num;
				float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
				float num5 = Mathf.Clamp01(1f - num4);
				num5 = num5 * num5 * num5;
				val.SetPixel(j, i, new Color(1f, 1f, 1f, num5));
			}
		}
		val.Apply();
		_particleMaterial = new Material(beamMaterial.shader);
		_particleMaterial.mainTexture = (Texture)(object)val;
		return _particleMaterial;
	}

	private ParticleSystem MakeGlowParticles(Transform parent, Vector3 position)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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)
		//IL_0042: 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)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: 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_0104: 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_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Expected O, but got Unknown
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		Material particleMaterial = GetParticleMaterial();
		if ((Object)(object)particleMaterial == (Object)null)
		{
			return null;
		}
		GameObject val = new GameObject("DeathrattleGlowParticles");
		val.transform.SetParent(parent, false);
		val.transform.position = position + Vector3.up * 0.5f;
		ParticleSystem val2 = val.AddComponent<ParticleSystem>();
		val2.Stop(true, (ParticleSystemStopBehavior)0);
		MainModule main = val2.main;
		((MainModule)(ref main)).duration = Mathf.Max(0.1f, _beamDuration.Value);
		((MainModule)(ref main)).loop = false;
		((MainModule)(ref main)).startLifetime = new MinMaxCurve(1f, 2f);
		((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.02f, 0.12f);
		((MainModule)(ref main)).startSize = new MinMaxCurve(0.03f, 0.08f);
		((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(EffectColor);
		((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.02f);
		((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
		((MainModule)(ref main)).maxParticles = 300;
		EmissionModule emission = val2.emission;
		((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(Mathf.Max(0f, _particleRate.Value));
		ShapeModule shape = val2.shape;
		((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
		((ShapeModule)(ref shape)).radius = Mathf.Max(0.1f, _particleRadius.Value);
		ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime;
		((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
		Gradient val3 = new Gradient();
		val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
		{
			new GradientColorKey(EffectColor, 0f),
			new GradientColorKey(EffectColor, 1f)
		}, (GradientAlphaKey[])(object)new GradientAlphaKey[7]
		{
			new GradientAlphaKey(0f, 0f),
			new GradientAlphaKey(0.9f, 0.1f),
			new GradientAlphaKey(0.2f, 0.25f),
			new GradientAlphaKey(1f, 0.4f),
			new GradientAlphaKey(0.15f, 0.55f),
			new GradientAlphaKey(0.8f, 0.7f),
			new GradientAlphaKey(0f, 1f)
		});
		((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3);
		SizeOverLifetimeModule sizeOverLifetime = val2.sizeOverLifetime;
		((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
		((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, AnimationCurve.Linear(0f, 1f, 1f, 0.7f));
		ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
		((Renderer)component).material = particleMaterial;
		component.renderMode = (ParticleSystemRenderMode)0;
		((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)component).receiveShadows = false;
		val2.Play();
		return val2;
	}

	private static void SetLineAlpha(LineRenderer lr, float alpha)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: 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)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp01(alpha);
		Color val = default(Color);
		((Color)(ref val))..ctor(EffectColor.r, EffectColor.g, EffectColor.b, 1f);
		Gradient val2 = new Gradient();
		val2.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
		{
			new GradientColorKey(val, 0f),
			new GradientColorKey(val, 1f)
		}, (GradientAlphaKey[])(object)new GradientAlphaKey[5]
		{
			new GradientAlphaKey(num, 0f),
			new GradientAlphaKey(num * 0.85f, 0.02f),
			new GradientAlphaKey(num * 0.5f, 0.15f),
			new GradientAlphaKey(num * 0.2f, 0.5f),
			new GradientAlphaKey(num * 0.05f, 1f)
		});
		lr.colorGradient = val2;
	}

	private AudioSource Source()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		if ((Object)(object)_source == (Object)null)
		{
			GameObject val = new GameObject("DeathrattleAudio");
			Object.DontDestroyOnLoad((Object)(object)val);
			_source = val.AddComponent<AudioSource>();
			_source.playOnAwake = false;
			_source.spatialBlend = 0f;
		}
		return _source;
	}

	private void Play()
	{
		if ((Object)(object)_clip != (Object)null)
		{
			Source().PlayOneShot(_clip, 1f);
		}
		else
		{
			Log.LogWarning((object)"Death scream not loaded, skipping it.");
		}
		if (_layerEnabled.Value && (Object)(object)_layerClip != (Object)null)
		{
			Source().PlayOneShot(_layerClip, 1f);
		}
	}
}
[HarmonyPatch(typeof(Game), "Start")]
internal static class Game_Start_Patch
{
	private static void Postfix()
	{
		if (ZRoutedRpc.instance == null)
		{
			DeathrattlePlugin.Log.LogError((object)"ZRoutedRpc not ready, death RPC not registered.");
		}
		else
		{
			ZRoutedRpc.instance.Register<string, string, Vector3>("Deathrattle_PlayerDied", (Action<long, string, string, Vector3>)RPC_PlayerDied);
		}
	}

	private static void RPC_PlayerDied(long sender, string playerName, string message, Vector3 position)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer != (Object)null) || !(localPlayer.GetPlayerName() == playerName) || !(Time.time - DeathrattlePlugin.LocalDeathTime < 2f))
		{
			DeathrattlePlugin.Instance.OnPlayerDied(message, position);
		}
	}
}
[HarmonyPatch(typeof(MessageHud), "ShowMessage")]
internal static class MessageHud_ShowMessage_Patch
{
	private static string _youDiedLocalized;

	private static bool Prefix(MessageType type, ref string text)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		string pendingLocalMessage = DeathrattlePlugin.PendingLocalMessage;
		if (pendingLocalMessage == null || (int)type != 2 || text == null)
		{
			return true;
		}
		if (Time.time - DeathrattlePlugin.PendingLocalTime > 10f)
		{
			DeathrattlePlugin.PendingLocalMessage = null;
			return true;
		}
		if (_youDiedLocalized == null && Localization.instance != null)
		{
			_youDiedLocalized = Localization.instance.Localize("$msg_youdied");
		}
		if (!text.Contains("$msg_youdied") && (string.IsNullOrEmpty(_youDiedLocalized) || !(text == _youDiedLocalized)))
		{
			return true;
		}
		DeathrattlePlugin.PendingLocalMessage = null;
		return false;
	}
}
[HarmonyPatch(typeof(Character), "RPC_Damage")]
internal static class Character_RPC_Damage_Patch
{
	private static void Prefix(Character __instance, HitData hit)
	{
		if ((Object)(object)__instance != (Object)null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && hit != null)
		{
			DeathrattlePlugin.LastLocalHit = hit;
		}
	}
}
[HarmonyPatch(typeof(Player), "OnDeath")]
internal static class Player_OnDeath_Patch
{
	private static void Prefix(Player __instance)
	{
		//IL_005e: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			string text = DeathrattlePlugin.Instance.BuildDeathMessage(__instance);
			DeathrattlePlugin.LastLocalHit = null;
			if (DeathrattlePlugin.Instance.MessagesEnabled)
			{
				DeathrattlePlugin.PendingLocalMessage = text;
				DeathrattlePlugin.PendingLocalTime = Time.time;
			}
			DeathrattlePlugin.LocalDeathTime = Time.time;
			Vector3 position = ((Component)__instance).transform.position;
			DeathrattlePlugin.Instance.OnPlayerDied(text, position);
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "Deathrattle_PlayerDied", new object[3]
				{
					__instance.GetPlayerName(),
					text,
					position
				});
			}
		}
	}
}