Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Deathrattle v2.0.1
plugins/Deathrattle/Deathrattle.dll
Decompiled 5 days agousing 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 }); } } } }