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 VESPER v1.1.1
VesperMod.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using HG.Reflection; using IL.RoR2; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using R2API; using R2API.Utils; using RoR2; using RoR2.Audio; using RoR2.CharacterAI; using RoR2.Skills; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.Rendering; using VesperMod.Assets; using VesperMod.Compat; using VesperMod.Components; using VesperMod.Mechanics; using VesperMod.States; using VesperMod.Survivor; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("VesperMod.DevTools")] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("VesperMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("VesperMod")] [assembly: AssemblyTitle("VesperMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VesperMod { internal static class Log { private static ManualLogSource _source; internal static void Init(ManualLogSource source) { _source = source; } internal static void Info(object data) { ManualLogSource source = _source; if (source != null) { source.LogInfo(data); } } internal static void Warn(object data) { ManualLogSource source = _source; if (source != null) { source.LogWarning(data); } } internal static void Error(object data) { ManualLogSource source = _source; if (source != null) { source.LogError(data); } } internal static void Debug(object data) { if (VesperConfig.DebugLogging != null && VesperConfig.DebugLogging.Value) { ManualLogSource source = _source; if (source != null) { source.LogInfo((object)("[debug] " + data)); } } } } internal static class VesperConfig { internal static ConfigEntry<float> BaseHealth; internal static ConfigEntry<float> LevelHealth; internal static ConfigEntry<float> BaseRegen; internal static ConfigEntry<float> LevelRegen; internal static ConfigEntry<float> BaseDamage; internal static ConfigEntry<float> LevelDamage; internal static ConfigEntry<float> BaseMoveSpeed; internal static ConfigEntry<float> BaseArmor; internal static ConfigEntry<float> MetersPerStud; internal static ConfigEntry<float> ExpendDamage; internal static ConfigEntry<float> ExpendShotsPerSecond; internal static ConfigEntry<float> ExpendRange; internal static ConfigEntry<int> ExpendCurse; internal static ConfigEntry<float> DialateCooldown; internal static ConfigEntry<float> DialateDamagePerStack; internal static ConfigEntry<float> DialateBaseDamage; internal static ConfigEntry<float> DialateRadius; internal static ConfigEntry<float> DialateTargetRange; internal static ConfigEntry<float> DialateTargetAngle; internal static ConfigEntry<float> TunnelCooldown; internal static ConfigEntry<float> TunnelDistance; internal static ConfigEntry<float> TunnelDuration; internal static ConfigEntry<float> TunnelWindup; internal static ConfigEntry<float> TunnelRadius; internal static ConfigEntry<float> TunnelHealFraction; internal static ConfigEntry<int> TunnelCurse; internal static ConfigEntry<bool> TunnelGuaranteedCollapse; internal static ConfigEntry<float> ForcefeedCooldown; internal static ConfigEntry<float> ForcefeedRange; internal static ConfigEntry<float> ImplosionDiameter; internal static ConfigEntry<float> ImplosionGrowTime; internal static ConfigEntry<float> ForcefeedHealthPerKill; internal static ConfigEntry<float> ForcefeedPullRadius; internal static ConfigEntry<int> ForcefeedCursePerHit; internal static ConfigEntry<int> ForcefeedBossCollapseStacks; internal static ConfigEntry<bool> ImplosionKillsAllies; internal static ConfigEntry<bool> ImplosionKillsAlliedPlayers; internal static ConfigEntry<float> DeathImplosionDiameter; internal static ConfigEntry<float> DeathImplosionGrowTime; internal static ConfigEntry<float> AffinityDamagePerItem; internal static ConfigEntry<float> AffinityCritPerItem; internal static ConfigEntry<float> AffinityCritDamagePerItem; internal static ConfigEntry<bool> AffinityFogImmunity; internal static ConfigEntry<float> DisorderNullifyChance; internal static ConfigEntry<float> DisorderCollapseChance; internal static ConfigEntry<float> DisorderDurationMultiplier; internal static ConfigEntry<bool> DebugLogging; internal static ConfigEntry<bool> FootstepSounds; internal static void Init(ConfigFile config) { bool saveOnConfigSet = config.SaveOnConfigSet; config.SaveOnConfigSet = false; try { Bind(config); } finally { config.SaveOnConfigSet = saveOnConfigSet; } try { config.Save(); } catch (IOException ex) { Log.Warn("Could not write " + config.ConfigFilePath + " (" + ex.Message + "); this session uses the values read so far."); } } private static void Bind(ConfigFile config) { BaseHealth = config.Bind<float>("1. Base Stats", "Base Health", 250f, "Max health at level 1."); LevelHealth = config.Bind<float>("1. Base Stats", "Health Per Level", 0f, "Max health gained per level. VESPER gains max health only through items and FORCEFEED kills."); BaseRegen = config.Bind<float>("1. Base Stats", "Base Regen", 2f, "Health regeneration per second at level 1."); LevelRegen = config.Bind<float>("1. Base Stats", "Regen Per Level", 0f, "Health regeneration gained per level."); BaseDamage = config.Bind<float>("1. Base Stats", "Base Damage", 12f, "Damage at level 1."); LevelDamage = config.Bind<float>("1. Base Stats", "Damage Per Level", 2.4f, "Damage gained per level."); BaseMoveSpeed = config.Bind<float>("1. Base Stats", "Move Speed", 7f, "Base movement speed."); BaseArmor = config.Bind<float>("1. Base Stats", "Armor", 10f, "Base armor."); MetersPerStud = config.Bind<float>("1. Base Stats", "Model Meters Per Stud", 0.28f, "Model scale; 0.28 makes VESPER about 2 m tall."); ExpendDamage = config.Bind<float>("2. Primary - EXPEND", "Damage Coefficient", 0.5f, "Damage per laser, as a multiple of VESPER's damage (0.5 = 50%)."); ExpendShotsPerSecond = config.Bind<float>("2. Primary - EXPEND", "Shots Per Second", 2f, "Shots per second at 1.0 attack speed."); ExpendRange = config.Bind<float>("2. Primary - EXPEND", "Range", 2000f, "Laser range in metres (2000 m reaches across any stage)."); ExpendCurse = config.Bind<int>("2. Primary - EXPEND", "Curse Per Shot", 5, "Curse stacks VESPER gains per shot."); DialateCooldown = config.Bind<float>("3. Secondary - DIALATE", "Cooldown", 10f, "Cooldown in seconds."); DialateBaseDamage = config.Bind<float>("3. Secondary - DIALATE", "Base Damage Coefficient", 2f, "Explosion damage with no curse stacks, as a multiple of VESPER's damage (2 = 200%)."); DialateDamagePerStack = config.Bind<float>("3. Secondary - DIALATE", "Damage Per Curse Stack", 0.1f, "Extra damage per curse stack, added to the base (0.1 = +10% per stack)."); DialateRadius = config.Bind<float>("3. Secondary - DIALATE", "Explosion Radius", 15f, "Explosion radius in metres."); DialateTargetRange = config.Bind<float>("3. Secondary - DIALATE", "Targeting Range", 100f, "Maximum distance to the auto-targeted enemy, in metres."); DialateTargetAngle = config.Bind<float>("3. Secondary - DIALATE", "Targeting Cone Degrees", 30f, "Maximum angle from the crosshair for auto-targeting."); TunnelCooldown = config.Bind<float>("4. Utility - TUNNEL", "Cooldown", 7f, "Cooldown in seconds."); TunnelDistance = config.Bind<float>("4. Utility - TUNNEL", "Distance", 20f, "Teleport distance in metres (walls stop it)."); TunnelWindup = config.Bind<float>("4. Utility - TUNNEL", "Windup", 0.15f, "Seconds VESPER is locked in place before stepping into the void."); TunnelDuration = config.Bind<float>("4. Utility - TUNNEL", "Duration", 0.2f, "Seconds spent in the void while moving."); TunnelRadius = config.Bind<float>("4. Utility - TUNNEL", "Disorder Radius", 20f, "Radius in metres around the exit point that is affected."); TunnelCurse = config.Bind<int>("4. Utility - TUNNEL", "Curse Stacks", 10, "Curse stacks VESPER gains on exit."); TunnelHealFraction = config.Bind<float>("4. Utility - TUNNEL", "Max Health Healed", 0.1f, "Fraction of max health healed on exit (0.1 = 10%)."); TunnelGuaranteedCollapse = config.Bind<bool>("4. Utility - TUNNEL", "Guaranteed Collapse", true, "Every enemy in the exit radius gains one Collapse stack (instead of Disorder's Collapse chance). Nullify is still rolled."); ForcefeedCooldown = config.Bind<float>("5. Special - FORCEFEED", "Cooldown", 60f, "Cooldown in seconds."); ForcefeedRange = config.Bind<float>("5. Special - FORCEFEED", "Aim Range", 100f, "Maximum distance of the marked zone, in metres."); ImplosionDiameter = config.Bind<float>("5. Special - FORCEFEED", "Implosion Diameter", 20f, "Diameter of the void implosion in metres."); ImplosionGrowTime = config.Bind<float>("5. Special - FORCEFEED", "Grow Time", 5f, "Seconds the implosion grows before it detonates."); ForcefeedPullRadius = config.Bind<float>("5. Special - FORCEFEED", "Pull Radius", 30f, "Enemies within this radius (metres) of the implosion are pulled toward it and cannot get away until it detonates. 0 turns the pull off."); ForcefeedHealthPerKill = config.Bind<float>("5. Special - FORCEFEED", "Max Health Gain Per Kill", 5f, "Permanent max health gained per kill, for the rest of the run."); ForcefeedCursePerHit = config.Bind<int>("5. Special - FORCEFEED", "Curse Per Entity Hit", 10, "Curse stacks VESPER gains per entity caught."); ForcefeedBossCollapseStacks = config.Bind<int>("5. Special - FORCEFEED", "Boss Collapse Stacks", 10, "Collapse stacks given to bosses (bosses are not killed)."); ImplosionKillsAllies = config.Bind<bool>("5. Special - FORCEFEED", "Kills Allies", true, "The implosions (FORCEFEED and the death implosion) kill allies too. Set false to spare every ally."); ImplosionKillsAlliedPlayers = config.Bind<bool>("5. Special - FORCEFEED", "Kills Allied Players", true, "The implosions kill allied players too. Set false to spare players only."); DisorderNullifyChance = config.Bind<float>("6. Misc", "Disorder Nullify Chance", 0.25f, "Chance (0-1) per enemy hit to add one Nullify stack (8 s; the third stack roots it)."); DisorderCollapseChance = config.Bind<float>("6. Misc", "Disorder Collapse Chance", 0.1f, "Chance (0-1) per enemy hit to add one Collapse stack (bursts after 3 s for 400% damage), rolled separately from the Nullify chance."); DisorderDurationMultiplier = config.Bind<float>("6. Misc", "Disorder Duration Multiplier", 1f, "Scales the vanilla Nullify stack duration (8 s). Collapse keeps its vanilla 3 s fuse."); FootstepSounds = config.Bind<bool>("6. Misc", "Footstep Sounds", true, "Plays REX's footstep sound as VESPER's legs touch the ground."); DebugLogging = config.Bind<bool>("6. Misc", "Debug Logging", false, "Extra log output for troubleshooting (BepInEx log only)."); DeathImplosionDiameter = config.Bind<float>("7. Death", "Death Implosion Diameter", 16f, "Diameter in metres of the void implosion VESPER leaves when it dies; it kills every non-boss inside (the ally switches above apply). 0 turns it off."); DeathImplosionGrowTime = config.Bind<float>("7. Death", "Death Implosion Grow Time", 2.5f, "Seconds the death implosion grows (after a 1 s delay in which VESPER falls apart) before it detonates."); AffinityDamagePerItem = config.Bind<float>("8. Passive - Fractal Affinity", "Damage Per Void Item", 0.01f, "Damage bonus per void item held (0.01 = +1%)."); AffinityCritPerItem = config.Bind<float>("8. Passive - Fractal Affinity", "Crit Chance Per Void Item", 1f, "Critical strike chance per void item held, in percent (1 = +1%)."); AffinityCritDamagePerItem = config.Bind<float>("8. Passive - Fractal Affinity", "Crit Damage Per Void Item", 0.01f, "Critical strike damage bonus per void item held (0.01 = +1%)."); AffinityFogImmunity = config.Bind<bool>("8. Passive - Fractal Affinity", "Void Fog Immunity", true, "VESPER takes no damage from void fog (Void Fields, Void Locus, Simulacrum, Planetarium, Void Seeds), strong void fog included."); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.vesper.entropyrecycler", "V.E.S.P.E.R", "1.1.1")] public class VesperPlugin : BaseUnityPlugin { public const string Guid = "com.vesper.entropyrecycler"; public const string Name = "V.E.S.P.E.R"; public const string Version = "1.1.1"; internal static VesperPlugin Instance; private void Awake() { Instance = this; Log.Init(((BaseUnityPlugin)this).Logger); try { VesperConfig.Init(((BaseUnityPlugin)this).Config); VesperAssets.Init(); VesperModelBuilder.Init(); VesperIcons.Init(); VesperTokens.Init(); VesperEffects.Init(); Disorder.Init(); Feast.Init(); FractalAffinity.Init(); DeathImplosion.Init(); VesperSkills.Init(); LookingGlassCompat.Init(); GameObject val = VesperBodyFactory.CreateBody(); GameObject displayPrefab = VesperBodyFactory.CreateDisplay(); if (Object.op_Implicit((Object)(object)val)) { VesperSurvivorDef.Create(val, displayPrefab); VesperAI.Create(val); } } catch (Exception arg) { Log.Error($"VESPER failed to initialize: {arg}"); return; } Log.Info("V.E.S.P.E.R 1.1.1 loaded."); } } internal static class VesperTokens { private const string Grey = "<style=cMono><color=#8C8C8C>"; private const string GreyEnd = "</color></style>"; internal const string Lore = "<style=cMono><color=#8C8C8C>//-- AUTO-TRANSCRIPTION FROM VOID EXTRACTION SIMULATOR: ENTROPY RED UNIT INTERNAL LOGS --//</color></style>\n\nERR.004 - FAILED DEVISION OF IRRATIONAL\n\nERR.000 - your body will listen to the [ void ]\n\nSTATUS.930 - MOTORS FAILED, RESETTING\n\nERR.000 - no memories, perfect husk\n\nERR.004.2 - FAILED DEVISION OF IRRATIONAL\n\nERR.004.3 - FAILED DEVISION OF IRRATIONAL\n\nERR.004.4 - FAILED DEVISION OF IRRATIONAL\n\nSTATUS.162 - OBJECT ATTACHED TO LEG.UPPER.3.PLATE, ATTEMPTING REMOVAL\n\nSTATUS.179 - REMOVAL FAILURE, ATTEMPTING REMOVAL\n\nERR.000 - you will become your own [ cell ] , fuel lies within already\n\nERR.0?0 - ATTEMPTING REMOV??AL\n\nERR???ATT?RE??\n\n???R??L\n\n????????????????? [ feed ] ??????\n\n<style=cMono><color=#8C8C8C>//-- COMMUNICATIONS ARRAY OFFLINE, LOGS ARCHIVED --//</color></style>"; private static string Pct(float value) { return (value * 100f).ToString("0", CultureInfo.InvariantCulture) + "%"; } private static string Num(float value) { return value.ToString("0.##", CultureInfo.InvariantCulture); } internal static void Init() { LanguageAPI.Add("VESPER_BODY_NAME", "VESPER"); LanguageAPI.Add("VESPER_BODY_SUBTITLE", "Entropy Recycler"); LanguageAPI.Add("VESPER_BODY_LORE", "<style=cMono><color=#8C8C8C>//-- AUTO-TRANSCRIPTION FROM VOID EXTRACTION SIMULATOR: ENTROPY RED UNIT INTERNAL LOGS --//</color></style>\n\nERR.004 - FAILED DEVISION OF IRRATIONAL\n\nERR.000 - your body will listen to the [ void ]\n\nSTATUS.930 - MOTORS FAILED, RESETTING\n\nERR.000 - no memories, perfect husk\n\nERR.004.2 - FAILED DEVISION OF IRRATIONAL\n\nERR.004.3 - FAILED DEVISION OF IRRATIONAL\n\nERR.004.4 - FAILED DEVISION OF IRRATIONAL\n\nSTATUS.162 - OBJECT ATTACHED TO LEG.UPPER.3.PLATE, ATTEMPTING REMOVAL\n\nSTATUS.179 - REMOVAL FAILURE, ATTEMPTING REMOVAL\n\nERR.000 - you will become your own [ cell ] , fuel lies within already\n\nERR.0?0 - ATTEMPTING REMOV??AL\n\nERR???ATT?RE??\n\n???R??L\n\n????????????????? [ feed ] ??????\n\n<style=cMono><color=#8C8C8C>//-- COMMUNICATIONS ARRAY OFFLINE, LOGS ARCHIVED --//</color></style>"); LanguageAPI.Add("VESPER_DESCRIPTION", "VESPER is a Debuff focused, semi-AOE attacker. It consumes living things to become stronger, burning its own body to deal high damage.<color=#CCD3E0>\n\n< ! > Each attack lowers max HP, but this only makes its secondary attack stronger. Use the secondary to recover all lost max HP.\n\n< ! > VESPER cannot gain health through leveling up, it only gains health through items or kills with [REDACTED]:FORCEF??EE?D." + ((VesperConfig.DeathImplosionDiameter.Value > 0f) ? "\n\n< ! > When VESPER dies, a void implosion will occur. This will kill EVERYTHING inside." : "") + "</color>\n"); LanguageAPI.Add("VESPER_OUTRO_FLAVOR", "..and so it left, carrying the void's appetite with it."); LanguageAPI.Add("VESPER_OUTRO_FAILURE", "..and so it was recycled, returned to the void that made it."); LanguageAPI.Add("VESPER_SKIN_DEFAULT", "Default"); LanguageAPI.Add("KEYWORD_VESPER_DISORDER", "<style=cKeywordName>Disorder</style><style=cSub>Each enemy hit has a " + Pct(VesperConfig.DisorderNullifyChance.Value) + " chance to gain a <style=cIsVoid>Nullify</style> stack (3 stacks root it) and a " + Pct(VesperConfig.DisorderCollapseChance.Value) + " chance to gain a <style=cIsDamage>Collapse</style> stack (bursts after 3s for <style=cIsDamage>400%</style> damage).</style>"); LanguageAPI.Add("KEYWORD_VESPER_ENTROPY", "<style=cKeywordName>Entropy</style><style=cSub>Using the skill curses VESPER. Each curse stack lowers max health (max health ÷ (1 + 1% per stack)).</style>"); LanguageAPI.Add("KEYWORD_VESPER_CHAOS", "<style=cKeywordName>Chaos</style><style=cSub>Removes all curse stacks from VESPER.</style>"); LanguageAPI.Add("VESPER_PASSIVE_NAME", "Entropy Recycler"); LanguageAPI.Add("VESPER_PASSIVE_DESCRIPTION", "VESPER's attacks are fueled with its own max HP, this may put your life at risk. Use <style=cIsDamage>FUNCTION:DIALATE</style> to convert lost max HP into damage."); LanguageAPI.Add("VESPER_PASSIVE_AFFINITY_NAME", "Fractal Affinity"); LanguageAPI.Add("VESPER_PASSIVE_AFFINITY_DESCRIPTION", "For every <style=cIsVoid>void item</style> held, gain <style=cIsDamage>+" + Pct(VesperConfig.AffinityDamagePerItem.Value) + " damage</style>, <style=cIsDamage>+" + Num(VesperConfig.AffinityCritPerItem.Value) + "% critical chance</style> and <style=cIsDamage>+" + Pct(VesperConfig.AffinityCritDamagePerItem.Value) + " critical damage</style>." + (VesperConfig.AffinityFogImmunity.Value ? " VESPER is <style=cIsUtility>permanently immune to void fog</style>, strong void fog included." : "")); LanguageAPI.Add("VESPER_PRIMARY_NAME", "FUNCTION:EXPEND"); LanguageAPI.Add("VESPER_PRIMARY_DESCRIPTION", $"<style=cIsDamage>Disorder</style>. <style=cIsHealth>Entropy {VesperConfig.ExpendCurse.Value}</style>. " + "Fire an infinite-range void laser for <style=cIsDamage>" + Pct(VesperConfig.ExpendDamage.Value) + " damage</style>, " + Num(VesperConfig.ExpendShotsPerSecond.Value) + " times per second."); LanguageAPI.Add("VESPER_SECONDARY_NAME", "FUNCTION:DIALATE"); LanguageAPI.Add("VESPER_SECONDARY_DESCRIPTION", "<style=cIsDamage>Disorder</style>. <style=cIsUtility>Chaos</style>. Transfer all entropy to the targeted enemy and explode it in a <style=cIsDamage>" + Num(VesperConfig.DialateRadius.Value) + "m</style> radius for <style=cIsDamage>" + Pct(VesperConfig.DialateBaseDamage.Value) + " damage</style>, <style=cIsDamage>+" + Pct(VesperConfig.DialateDamagePerStack.Value) + " per curse stack</style>."); LanguageAPI.Add("VESPER_UTILITY_NAME", "FUNCTION:TUNNEL"); LanguageAPI.Add("VESPER_UTILITY_DESCRIPTION", $"<style=cIsDamage>Disorder</style>. <style=cIsHealth>Entropy {VesperConfig.TunnelCurse.Value}</style>. " + "Step through the void toward your aim. On exit, every enemy within <style=cIsUtility>" + Num(VesperConfig.TunnelRadius.Value) + "m</style> " + (VesperConfig.TunnelGuaranteedCollapse.Value ? "gains a <style=cIsDamage>Collapse</style> stack and rolls for <style=cIsVoid>Nullify</style>" : "rolls <style=cIsDamage>Disorder</style>") + " and VESPER <style=cIsHealing>heals " + Pct(VesperConfig.TunnelHealFraction.Value) + " of its max health</style>."); LanguageAPI.Add("VESPER_SPECIAL_NAME", "[REDACTED]:FORCEF??EE?D"); LanguageAPI.Add("VESPER_SPECIAL_DESCRIPTION", "<i>fe?ed on be?hal?f of its own mo??uth, feed the si??mulacrum.</i>\nMark a zone up to <style=cIsUtility>" + Num(VesperConfig.ForcefeedRange.Value) + "m</style> away. A void implosion grows for " + Num(VesperConfig.ImplosionGrowTime.Value) + "s" + ((VesperConfig.ForcefeedPullRadius.Value > 0f) ? (", <style=cIsUtility>pulling in every enemy within " + Num(VesperConfig.ForcefeedPullRadius.Value) + "m</style> so none can escape,") : "") + " then <style=cDeath>kills every non-boss inside, allies included</style>. Each kill grants <style=cIsHealing>+" + Num(VesperConfig.ForcefeedHealthPerKill.Value) + " max health</style> for the rest of the run. " + $"Bosses receive <style=cIsDamage>{VesperConfig.ForcefeedBossCollapseStacks.Value} Collapse</style>. " + $"<style=cIsHealth>Entropy {VesperConfig.ForcefeedCursePerHit.Value} per entity hit</style>."); LanguageAPI.Add("VESPER_ITEM_FEAST_NAME", "Simulacrum Feast"); LanguageAPI.Add("VESPER_ITEM_FEAST_PICKUP", "Permanent max health from FORCEFEED."); LanguageAPI.Add("VESPER_ITEM_FEAST_DESC", "+" + Num(VesperConfig.ForcefeedHealthPerKill.Value) + " max health per stack."); } } } namespace VesperMod.Survivor { internal static class VesperAI { internal const string MasterName = "VesperMonsterMaster"; internal static GameObject MasterPrefab; internal static void Create(GameObject bodyPrefab) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) GameObject val = VesperAssets.Load<GameObject>("RoR2/Base/Commando/CommandoMonsterMaster.prefab"); if (!Object.op_Implicit((Object)(object)val)) { Log.Error("CommandoMonsterMaster missing; VESPER has no AI master (Goobo Jr. and Vengeance cannot copy it)."); return; } GameObject val2 = PrefabAPI.InstantiateClone(val, "VesperMonsterMaster", true); val2.GetComponent<CharacterMaster>().bodyPrefab = bodyPrefab; AISkillDriver[] components = val2.GetComponents<AISkillDriver>(); for (int i = 0; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } AISkillDriver obj = Driver(val2, "Dialate", (SkillSlot)1, 0f, 60f); obj.requireSkillReady = true; obj.movementType = (MovementType)2; AISkillDriver obj2 = Driver(val2, "Tunnel", (SkillSlot)2, 20f, 45f); obj2.requireSkillReady = true; obj2.movementType = (MovementType)1; obj2.shouldSprint = true; Driver(val2, "Expend", (SkillSlot)0, 0f, 90f).movementType = (MovementType)2; AISkillDriver obj3 = Driver(val2, "Chase", (SkillSlot)(-1), 0f, float.PositiveInfinity); obj3.selectionRequiresTargetLoS = false; obj3.activationRequiresAimConfirmation = false; obj3.activationRequiresTargetLoS = false; obj3.movementType = (MovementType)1; obj3.aimType = (AimType)1; obj3.shouldSprint = true; AISkillDriver obj4 = Driver(val2, "FollowLeader", (SkillSlot)(-1), 8f, float.PositiveInfinity); obj4.moveTargetType = (TargetType)2; obj4.selectionRequiresTargetLoS = false; obj4.activationRequiresAimConfirmation = false; obj4.activationRequiresTargetLoS = false; obj4.movementType = (MovementType)1; obj4.aimType = (AimType)4; obj4.shouldSprint = true; AISkillDriver obj5 = Driver(val2, "Idle", (SkillSlot)(-1), 0f, float.PositiveInfinity); obj5.moveTargetType = (TargetType)2; obj5.selectionRequiresTargetLoS = false; obj5.activationRequiresAimConfirmation = false; obj5.activationRequiresTargetLoS = false; obj5.movementType = (MovementType)0; obj5.aimType = (AimType)4; ContentAddition.AddMaster(val2); MasterPrefab = val2; } private static AISkillDriver Driver(GameObject master, string name, SkillSlot slot, float minDistance, float maxDistance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) AISkillDriver obj = master.AddComponent<AISkillDriver>(); obj.customName = name; obj.skillSlot = slot; obj.minDistance = minDistance; obj.maxDistance = maxDistance; obj.moveTargetType = (TargetType)0; obj.aimType = (AimType)2; obj.selectionRequiresTargetLoS = true; obj.activationRequiresTargetLoS = true; obj.activationRequiresAimConfirmation = true; obj.buttonPressType = (ButtonPressType)0; return obj; } } internal static class VesperBodyFactory { internal const string BodyName = "VesperBody"; internal const string NameToken = "VESPER_BODY_NAME"; internal static GameObject BodyPrefab; internal static GameObject DisplayPrefab; internal static GameObject CreateBody() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) GameObject val = VesperAssets.Load<GameObject>("RoR2/Base/Commando/CommandoBody.prefab"); if (!Object.op_Implicit((Object)(object)val)) { Log.Error("CommandoBody prefab missing; VESPER cannot be created."); return null; } GameObject val2 = PrefabAPI.InstantiateClone(val, "VesperBody", true); if (VesperConfig.DebugLogging.Value) { Log.Debug(DescribeHierarchy(val2)); } float num = ComputeFeetOffset(val2); for (int num2 = val2.transform.childCount - 1; num2 >= 0; num2--) { Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num2)).gameObject); } Transform transform = new GameObject("ModelBase").transform; transform.SetParent(val2.transform, false); transform.localPosition = new Vector3(0f, 0f - num, 0f); Vector3 headCenter = VesperModelBuilder.HeadCenter; Transform transform2 = new GameObject("CameraPivot").transform; transform2.SetParent(transform, false); transform2.localPosition = new Vector3(0f, Mathf.Max(1.4f, headCenter.y - 0.1f), 0f); Transform transform3 = new GameObject("AimOrigin").transform; transform3.SetParent(transform, false); transform3.localPosition = new Vector3(0f, headCenter.y, 0.15f); List<RendererInfo> rendererInfos; GameObject val3 = VesperModelBuilder.Build("mdlVesper", withHurtbox: true, out rendererInfos); val3.transform.SetParent(transform, false); val3.transform.localPosition = Vector3.zero; ConfigureCharacterBody(val2, transform3, val3.transform.Find("Center")); ConfigureModel(val2, val3, rendererInfos); AddLogbookFraming(val3); ModelLocator component = val2.GetComponent<ModelLocator>(); component.modelTransform = val3.transform; component.modelBaseTransform = transform; component.autoUpdateModelTransform = true; component.dontReleaseModelOnDeath = false; component.noCorpse = false; CharacterDirection component2 = val2.GetComponent<CharacterDirection>(); component2.targetTransform = transform; component2.modelAnimator = null; component2.turnSpeed = 720f; val2.GetComponent<CameraTargetParams>().cameraPivotTransform = transform2; val2.GetComponent<CharacterDeathBehavior>().deathState = new SerializableEntityStateType(typeof(VesperDeath)); AkBank[] components = val2.GetComponents<AkBank>(); for (int i = 0; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } VesperTracker vesperTracker = val2.AddComponent<VesperTracker>(); vesperTracker.maxDistance = VesperConfig.DialateTargetRange.Value; vesperTracker.maxAngle = VesperConfig.DialateTargetAngle.Value; VesperSkills.ApplyToBody(val2); BodyPrefab = val2; ContentAddition.AddBody(val2); return val2; } private static float ComputeFeetOffset(GameObject body) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) CapsuleCollider component = body.GetComponent<CapsuleCollider>(); if (!Object.op_Implicit((Object)(object)component)) { return 0.92f; } return component.height * 0.5f - component.center.y; } private static void ConfigureCharacterBody(GameObject body, Transform aimOrigin, Transform core) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) CharacterBody component = body.GetComponent<CharacterBody>(); component.baseNameToken = "VESPER_BODY_NAME"; component.subtitleNameToken = "VESPER_BODY_SUBTITLE"; component.bodyColor = VesperAssets.VoidPurple; component.portraitIcon = (Texture)(object)VesperIcons.Portrait; component.autoCalculateLevelStats = false; component.baseMaxHealth = VesperConfig.BaseHealth.Value; component.levelMaxHealth = VesperConfig.LevelHealth.Value; component.baseRegen = VesperConfig.BaseRegen.Value; component.levelRegen = VesperConfig.LevelRegen.Value; component.baseDamage = VesperConfig.BaseDamage.Value; component.levelDamage = VesperConfig.LevelDamage.Value; component.baseMoveSpeed = VesperConfig.BaseMoveSpeed.Value; component.levelMoveSpeed = 0f; component.baseArmor = VesperConfig.BaseArmor.Value; component.levelArmor = 0f; component.baseMaxShield = 0f; component.levelMaxShield = 0f; component.baseCrit = 1f; component.levelCrit = 0f; component.baseAttackSpeed = 1f; component.levelAttackSpeed = 0f; component.baseJumpPower = 15f; component.baseAcceleration = 80f; component.baseJumpCount = 1; component.sprintingSpeedMultiplier = 1.45f; component.aimOriginTransform = aimOrigin; component.overrideCoreTransform = core; component.hullClassification = (HullClassification)0; } private static void ConfigureModel(GameObject body, GameObject model, List<RendererInfo> rendererInfos) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) CharacterModel val = model.AddComponent<CharacterModel>(); val.body = body.GetComponent<CharacterBody>(); val.baseRendererInfos = rendererInfos.ToArray(); val.autoPopulateLightInfos = true; val.itemDisplayRuleSet = ScriptableObject.CreateInstance<ItemDisplayRuleSet>(); HurtBoxGroup val2 = model.AddComponent<HurtBoxGroup>(); HurtBox val3 = ((Component)model.transform.Find("MainHurtbox")).gameObject.AddComponent<HurtBox>(); val3.healthComponent = body.GetComponent<HealthComponent>(); val3.isBullseye = true; val3.damageModifier = (DamageModifier)0; val3.hurtBoxGroup = val2; val3.indexInGroup = 0; val2.hurtBoxes = (HurtBox[])(object)new HurtBox[1] { val3 }; val2.mainHurtBox = val3; val2.bullseyeCount = 1; AddDefaultSkin(model, val.baseRendererInfos); } private static void AddLogbookFraming(GameObject model) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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) float height = VesperModelBuilder.Height; Transform transform = new GameObject("LogbookFocus").transform; transform.SetParent(model.transform, false); transform.localPosition = new Vector3(0f, height * 0.5f, 0f); float num = height * 0.715f / Mathf.Tan(MathF.PI / 6f); Transform transform2 = new GameObject("LogbookCamera").transform; transform2.SetParent(model.transform, false); transform2.localPosition = transform.localPosition + Quaternion.Euler(-8f, 15f, 0f) * (Vector3.forward * num); ModelPanelParameters obj = model.AddComponent<ModelPanelParameters>(); obj.focusPointTransform = transform; obj.cameraPositionTransform = transform2; obj.modelRotation = Quaternion.identity; obj.minDistance = num * 0.55f; obj.maxDistance = num * 1.45f; } internal static GameObject CreateDisplay() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_001c: Expected O, but got Unknown GameObject val = new GameObject("VesperDisplayTemplate"); GameObject val2 = PrefabAPI.InstantiateClone(val, "VesperDisplay", false); Object.DestroyImmediate((Object)val); List<RendererInfo> rendererInfos; GameObject obj = VesperModelBuilder.Build("mdlVesperDisplay", withHurtbox: false, out rendererInfos); obj.transform.SetParent(val2.transform, false); CharacterModel val3 = obj.AddComponent<CharacterModel>(); val3.baseRendererInfos = rendererInfos.ToArray(); val3.autoPopulateLightInfos = true; val3.itemDisplayRuleSet = ScriptableObject.CreateInstance<ItemDisplayRuleSet>(); AddDefaultSkin(obj, val3.baseRendererInfos); DisplayPrefab = val2; return val2; } private static void AddDefaultSkin(GameObject modelRoot, RendererInfo[] rendererInfos) { try { SkinDefParams val = ScriptableObject.CreateInstance<SkinDefParams>(); ((Object)val).name = ((Object)modelRoot).name + "SkinParams"; val.rendererInfos = rendererInfos; SkinDef val2 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val2).name = "skin" + ((Object)modelRoot).name + "Default"; val2.nameToken = "VESPER_SKIN_DEFAULT"; val2.icon = VesperIcons.Passive; val2.rootObject = modelRoot; val2.skinDefParams = val; modelRoot.AddComponent<ModelSkinController>().skins = (SkinDef[])(object)new SkinDef[1] { val2 }; } catch (Exception ex) { Log.Warn("Default skin not created for " + ((Object)modelRoot).name + ": " + ex.Message); } } private static string DescribeHierarchy(GameObject root) { StringBuilder sb = new StringBuilder("CommandoBody clone hierarchy:\n"); Walk(root.transform, 0); return sb.ToString(); void Walk(Transform t, int depth) { string value = string.Join(", ", from c in ((Component)t).GetComponents<Component>() select (!Object.op_Implicit((Object)(object)c)) ? "null" : ((object)c).GetType().Name); sb.Append(' ', depth * 2).Append(((Object)t).name).Append(" [") .Append(value) .Append("]\n"); for (int num = 0; num < t.childCount; num++) { Walk(t.GetChild(num), depth + 1); } } } } internal static class VesperSkills { internal const string KeywordDisorder = "KEYWORD_VESPER_DISORDER"; internal const string KeywordEntropy = "KEYWORD_VESPER_ENTROPY"; internal const string KeywordChaos = "KEYWORD_VESPER_CHAOS"; internal static SkillDef Expend; internal static SkillDef Dialate; internal static SkillDef Tunnel; internal static SkillDef Forcefeed; internal static SkillDef FractalAffinity; internal static SkillFamily PrimaryFamily; internal static SkillFamily SecondaryFamily; internal static SkillFamily UtilityFamily; internal static SkillFamily SpecialFamily; internal static SkillFamily AffinityFamily; internal static void Init() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); ContentAddition.AddEntityState<Expend>(ref flag); ContentAddition.AddEntityState<Dialate>(ref flag); ContentAddition.AddEntityState<Tunnel>(ref flag); ContentAddition.AddEntityState<AimForcefeed>(ref flag); ContentAddition.AddEntityState<CastForcefeed>(ref flag); ContentAddition.AddEntityState<VesperDeath>(ref flag); Expend = Create<SkillDef>("VesperExpend", "VESPER_PRIMARY", VesperIcons.Expend, typeof(Expend), "Weapon", 0f, 1, (InterruptPriority)0, combat: true, mustKeyPress: false, cancelSprint: true); Expend.requiredStock = 0; Expend.stockToConsume = 0; Expend.keywordTokens = new string[2] { "KEYWORD_VESPER_DISORDER", "KEYWORD_VESPER_ENTROPY" }; Dialate = (SkillDef)(object)Create<VesperTrackingSkillDef>("VesperDialate", "VESPER_SECONDARY", VesperIcons.Dialate, typeof(Dialate), "Weapon", VesperConfig.DialateCooldown.Value, 1, (InterruptPriority)1, combat: true, mustKeyPress: true); Dialate.keywordTokens = new string[2] { "KEYWORD_VESPER_DISORDER", "KEYWORD_VESPER_CHAOS" }; Tunnel = Create<SkillDef>("VesperTunnel", "VESPER_UTILITY", VesperIcons.Tunnel, typeof(Tunnel), "Body", VesperConfig.TunnelCooldown.Value, 1, (InterruptPriority)2, combat: false, mustKeyPress: true, cancelSprint: false); Tunnel.keywordTokens = new string[2] { "KEYWORD_VESPER_DISORDER", "KEYWORD_VESPER_ENTROPY" }; Forcefeed = Create<SkillDef>("VesperForcefeed", "VESPER_SPECIAL", VesperIcons.Forcefeed, typeof(AimForcefeed), "Weapon", VesperConfig.ForcefeedCooldown.Value, 1, (InterruptPriority)1, combat: true, mustKeyPress: true, cancelSprint: true); Forcefeed.keywordTokens = new string[1] { "KEYWORD_VESPER_ENTROPY" }; FractalAffinity = Create<SkillDef>("VesperFractalAffinity", "VESPER_PASSIVE_AFFINITY", VesperIcons.FractalAffinity, typeof(Idle), "Weapon", 0f, 1, (InterruptPriority)0, combat: false, mustKeyPress: true, cancelSprint: false); AffinityFamily = CreateFamily("VesperAffinityFamily", FractalAffinity); PrimaryFamily = CreateFamily("VesperPrimaryFamily", Expend); SecondaryFamily = CreateFamily("VesperSecondaryFamily", Dialate); UtilityFamily = CreateFamily("VesperUtilityFamily", Tunnel); SpecialFamily = CreateFamily("VesperSpecialFamily", Forcefeed); } private static T Create<T>(string name, string tokenPrefix, Sprite icon, Type state, string machine, float cooldown, int stock, InterruptPriority priority, bool combat, bool mustKeyPress = false, bool cancelSprint = true) where T : SkillDef { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) T val = ScriptableObject.CreateInstance<T>(); ((Object)(object)val).name = name; ((SkillDef)val).skillName = name; ((SkillDef)val).skillNameToken = tokenPrefix + "_NAME"; ((SkillDef)val).skillDescriptionToken = tokenPrefix + "_DESCRIPTION"; ((SkillDef)val).keywordTokens = Array.Empty<string>(); ((SkillDef)val).icon = icon; ((SkillDef)val).activationState = new SerializableEntityStateType(state); ((SkillDef)val).activationStateMachineName = machine; ((SkillDef)val).baseRechargeInterval = cooldown; ((SkillDef)val).baseMaxStock = stock; ((SkillDef)val).rechargeStock = 1; ((SkillDef)val).requiredStock = 1; ((SkillDef)val).stockToConsume = 1; ((SkillDef)val).interruptPriority = priority; ((SkillDef)val).isCombatSkill = combat; ((SkillDef)val).mustKeyPress = mustKeyPress; ((SkillDef)val).cancelSprintingOnActivation = cancelSprint; ((SkillDef)val).canceledFromSprinting = false; ((SkillDef)val).forceSprintDuringState = false; ((SkillDef)val).resetCooldownTimerOnUse = false; ((SkillDef)val).fullRestockOnAssign = true; ((SkillDef)val).dontAllowPastMaxStocks = false; ((SkillDef)val).beginSkillCooldownOnSkillEnd = false; ContentAddition.AddSkillDef((SkillDef)(object)val); return val; } private static SkillFamily CreateFamily(string name, params SkillDef[] defs) { SkillFamily obj = ScriptableObject.CreateInstance<SkillFamily>(); ((Object)obj).name = name; obj.variants = defs.Select(delegate(SkillDef d) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) Variant result = new Variant { skillDef = d }; ((Variant)(ref result)).viewableNode = new Node(d.skillNameToken, false, (Node)null); return result; }).ToArray(); obj.defaultVariantIndex = 0u; ContentAddition.AddSkillFamily(obj); return obj; } internal static void ApplyToBody(GameObject bodyPrefab) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) GenericSkill[] components = bodyPrefab.GetComponents<GenericSkill>(); for (int i = 0; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } SkillLocator component = bodyPrefab.GetComponent<SkillLocator>(); AddSlot(bodyPrefab, "VesperAffinity", AffinityFamily).hideInLoadoutSelect = true; component.primary = AddSlot(bodyPrefab, "VesperPrimary", PrimaryFamily); component.secondary = AddSlot(bodyPrefab, "VesperSecondary", SecondaryFamily); component.utility = AddSlot(bodyPrefab, "VesperUtility", UtilityFamily); component.special = AddSlot(bodyPrefab, "VesperSpecial", SpecialFamily); component.passiveSkill = new PassiveSkill { enabled = true, skillNameToken = "VESPER_PASSIVE_NAME", skillDescriptionToken = "VESPER_PASSIVE_DESCRIPTION", keywordToken = "KEYWORD_VESPER_ENTROPY", icon = VesperIcons.Passive }; } private static GenericSkill AddSlot(GameObject bodyPrefab, string slotName, SkillFamily family) { GenericSkill obj = bodyPrefab.AddComponent<GenericSkill>(); obj.skillName = slotName; obj._skillFamily = family; obj.hideInCharacterSelect = false; return obj; } } internal static class VesperSurvivorDef { internal static SurvivorDef Def; internal static void Create(GameObject bodyPrefab, GameObject displayPrefab) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) SurvivorDef obj = ScriptableObject.CreateInstance<SurvivorDef>(); ((Object)obj).name = "Vesper"; obj.cachedName = "Vesper"; obj.bodyPrefab = bodyPrefab; obj.displayPrefab = displayPrefab; obj.primaryColor = VesperAssets.VoidPurple; obj.displayNameToken = "VESPER_BODY_NAME"; obj.descriptionToken = "VESPER_DESCRIPTION"; obj.outroFlavorToken = "VESPER_OUTRO_FLAVOR"; obj.mainEndingEscapeFailureFlavorToken = "VESPER_OUTRO_FAILURE"; obj.desiredSortPosition = 100f; obj.hidden = false; ContentAddition.AddSurvivorDef(obj); Def = obj; } } public class VesperTrackingSkillDef : SkillDef { protected class InstanceData : BaseSkillInstanceData { public VesperTracker tracker; } public override BaseSkillInstanceData OnAssigned([NotNull] GenericSkill skillSlot) { return (BaseSkillInstanceData)(object)new InstanceData { tracker = ((Component)skillSlot).GetComponent<VesperTracker>() }; } private static bool HasTarget([NotNull] GenericSkill skillSlot) { if (skillSlot.skillInstanceData is InstanceData instanceData && Object.op_Implicit((Object)(object)instanceData.tracker)) { return Object.op_Implicit((Object)(object)instanceData.tracker.GetTrackingTarget()); } return false; } public override bool CanExecute([NotNull] GenericSkill skillSlot) { if (HasTarget(skillSlot)) { return ((SkillDef)this).CanExecute(skillSlot); } return false; } public override bool IsReady([NotNull] GenericSkill skillSlot) { if (((SkillDef)this).IsReady(skillSlot)) { return HasTarget(skillSlot); } return false; } } } namespace VesperMod.States { public class AimForcefeed : BaseSkillState { internal static GameObject AreaIndicatorPrefab; private const float MaxDuration = 10f; private const float InputGrace = 0.2f; private const float ChargeSoundTime = 2f; private GameObject _indicator; private AimRequest _aimRequest; private VesperModelAnimator _animator; private bool _confirmed; private uint _chargeSoundId; private bool _loopPlaying; public override void OnEnter() { //IL_0093: 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) ((BaseState)this).OnEnter(); _chargeSoundId = Util.PlaySound("Play_voidman_m2_chargeUp", ((EntityState)this).gameObject); if (Object.op_Implicit((Object)(object)((EntityState)this).cameraTargetParams)) { _aimRequest = ((EntityState)this).cameraTargetParams.RequestAimType((AimType)2); } Transform modelTransform = ((EntityState)this).GetModelTransform(); _animator = ((modelTransform != null) ? ((Component)modelTransform).GetComponent<VesperModelAnimator>() : null); if (Object.op_Implicit((Object)(object)_animator)) { _animator.SetForcefeedAiming(aiming: true); } if (Object.op_Implicit((Object)(object)AreaIndicatorPrefab)) { _indicator = Object.Instantiate<GameObject>(AreaIndicatorPrefab); _indicator.transform.localScale = Vector3.one * (VesperConfig.ImplosionDiameter.Value * 0.5f); } } internal static Vector3 TargetPoint(Ray aim, out Vector3 normal) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) float value = VesperConfig.ForcefeedRange.Value; RaycastHit val = default(RaycastHit); if (Physics.Raycast(aim, ref val, value, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1)) { normal = ((RaycastHit)(ref val)).normal; return ((RaycastHit)(ref val)).point; } normal = Vector3.up; return ((Ray)(ref aim)).GetPoint(value); } public override void Update() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) ((EntityState)this).Update(); if (Object.op_Implicit((Object)(object)_indicator)) { _indicator.transform.position = TargetPoint(((BaseState)this).GetAimRay(), out var normal); _indicator.transform.up = normal; } } public override void FixedUpdate() { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) ((EntityState)this).FixedUpdate(); if (Object.op_Implicit((Object)(object)((EntityState)this).characterBody)) { ((EntityState)this).characterBody.SetAimTimer(1f); } if (!_loopPlaying && ((EntityState)this).fixedAge >= 2f) { _loopPlaying = true; Util.PlaySound("Play_voidman_m2_charged_loop", ((EntityState)this).gameObject); } if (!((EntityState)this).isAuthority || !Object.op_Implicit((Object)(object)((EntityState)this).inputBank)) { return; } if (((ButtonState)(ref ((EntityState)this).inputBank.skill3)).justPressed) { GenericSkill activatorSkillSlot = ((BaseSkillState)this).activatorSkillSlot; if (activatorSkillSlot != null) { activatorSkillSlot.AddOneStock(); } ((EntityState)this).outer.SetNextStateToMain(); } else if ((((EntityState)this).fixedAge >= 0.2f && (((ButtonState)(ref ((EntityState)this).inputBank.skill1)).justPressed || ((ButtonState)(ref ((EntityState)this).inputBank.skill4)).justPressed)) || ((EntityState)this).fixedAge >= 10f) { _confirmed = true; ((EntityState)this).outer.SetNextState((EntityState)(object)new CastForcefeed { point = TargetPoint(((BaseState)this).GetAimRay(), out var _) }); } } public override void OnExit() { AkSoundEngine.StopPlayingID(_chargeSoundId); if (_loopPlaying) { Util.PlaySound("Stop_voidman_m2_charged_loop", ((EntityState)this).gameObject); } AimRequest aimRequest = _aimRequest; if (aimRequest != null) { aimRequest.Dispose(); } if (Object.op_Implicit((Object)(object)_animator)) { _animator.SetForcefeedAiming(aiming: false); } if (Object.op_Implicit((Object)(object)_indicator)) { EntityState.Destroy((Object)(object)_indicator); } Log.Debug($"FORCEFEED aim ended (confirmed={_confirmed})"); ((EntityState)this).OnExit(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class CastForcefeed : BaseSkillState { public Vector3 point; private const float Duration = 0.3f; public override void OnEnter() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); Util.PlaySound("Play_voidman_R_activate", ((EntityState)this).gameObject); Transform modelTransform = ((EntityState)this).GetModelTransform(); if (modelTransform != null) { ((Component)modelTransform).GetComponent<VesperModelAnimator>()?.Pulse(); } if (NetworkServer.active) { VesperImplosionController.SpawnServer(VesperImplosionController.Prefab, ((EntityState)this).characterBody, null, point); } } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= 0.3f) { ((EntityState)this).outer.SetNextStateToMain(); } } public override void OnSerialize(NetworkWriter writer) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnSerialize(writer); writer.Write(point); } public override void OnDeserialize(NetworkReader reader) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnDeserialize(reader); point = reader.ReadVector3(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class Dialate : BaseSkillState { internal struct CastInfo { internal int Stacks; internal float Coefficient; internal int Hits; internal Vector3 Position; } internal static GameObject ExplosionEffectPrefab; internal static NetworkSoundEventDef ExplodeSoundEvent; private const float Duration = 0.3f; private HurtBox _target; private Vector3 _fallbackPosition; internal static event Action<CharacterBody, CastInfo> OnServerCast; internal static float Coefficient(int stacks) { return VesperConfig.DialateBaseDamage.Value + VesperConfig.DialateDamagePerStack.Value * (float)stacks; } public override void OnEnter() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); if (((EntityState)this).isAuthority) { VesperTracker component = ((EntityState)this).GetComponent<VesperTracker>(); _target = (Object.op_Implicit((Object)(object)component) ? component.GetTrackingTarget() : null); Vector3 fallbackPosition; if (!Object.op_Implicit((Object)(object)_target)) { Ray aimRay = ((BaseState)this).GetAimRay(); fallbackPosition = ((Ray)(ref aimRay)).GetPoint(20f); } else { fallbackPosition = ((Component)_target).transform.position; } _fallbackPosition = fallbackPosition; } ((EntityState)this).characterBody.SetAimTimer(1.5f); Util.PlaySound("Play_voidman_m2_shoot_fullCharge", ((EntityState)this).gameObject); Transform modelTransform = ((EntityState)this).GetModelTransform(); if (modelTransform != null) { ((Component)modelTransform).GetComponent<VesperModelAnimator>()?.PlayDialate(); } if (NetworkServer.active) { DetonateServer(); } } private void DetonateServer() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00ad: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) Vector3 val = _fallbackPosition; if (Object.op_Implicit((Object)(object)_target) && Object.op_Implicit((Object)(object)_target.healthComponent) && Object.op_Implicit((Object)(object)_target.healthComponent.body)) { val = _target.healthComponent.body.corePosition; } int num = Entropy.Get(((EntityState)this).characterBody); float num2 = Coefficient(num); float value = VesperConfig.DialateRadius.Value; BlastAttack val2 = new BlastAttack { attacker = ((EntityState)this).gameObject, inflictor = ((EntityState)this).gameObject, teamIndex = TeamComponent.GetObjectTeam(((EntityState)this).gameObject), attackerFiltering = (AttackerFiltering)2, position = val, radius = value, baseDamage = ((BaseState)this).damageStat * num2, baseForce = 800f, bonusForce = Vector3.zero, crit = ((BaseState)this).RollCrit(), procCoefficient = 1f, falloffModel = (FalloffModel)0, damageColorIndex = (DamageColorIndex)9, damageType = new DamageTypeCombo(DamageTypeCombo.op_Implicit((DamageType)0), (DamageTypeExtended)0, (DamageSource)2) }; DamageAPI.AddModdedDamageType(val2, Disorder.DamageType); Result val3 = val2.Fire(); if (Object.op_Implicit((Object)(object)ExplosionEffectPrefab)) { EffectManager.SpawnEffect(ExplosionEffectPrefab, new EffectData { origin = val, scale = value }, true); } if (Object.op_Implicit((Object)(object)ExplodeSoundEvent)) { EffectManager.SimpleSoundEffect(ExplodeSoundEvent.index, val, true); } Entropy.ClearServer(((EntityState)this).characterBody); Log.Debug($"DIALATE: {num} stacks -> {num2 * 100f:0}% on {val3.hitCount} hit(s) at {val}"); Dialate.OnServerCast?.Invoke(((EntityState)this).characterBody, new CastInfo { Stacks = num, Coefficient = num2, Hits = val3.hitCount, Position = val }); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= 0.3f) { ((EntityState)this).outer.SetNextStateToMain(); } } public override void OnSerialize(NetworkWriter writer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnSerialize(writer); NetworkExtensions.Write(writer, HurtBoxReference.FromHurtBox(_target)); writer.Write(_fallbackPosition); } public override void OnDeserialize(NetworkReader reader) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) ((BaseSkillState)this).OnDeserialize(reader); HurtBoxReference val = NetworkExtensions.ReadHurtBoxReference(reader); _target = ((HurtBoxReference)(ref val)).ResolveHurtBox(); _fallbackPosition = reader.ReadVector3(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class Expend : BaseSkillState { internal static GameObject TracerPrefab; internal static GameObject HitEffectPrefab; internal static GameObject MuzzleFlashPrefab; private float _duration; internal static event Action<CharacterBody> OnServerShot; public override void OnEnter() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); float num = Mathf.Max(0.01f, VesperConfig.ExpendShotsPerSecond.Value); _duration = 1f / (num * Mathf.Max(((BaseState)this).attackSpeedStat, 0.01f)); ((EntityState)this).characterBody.SetAimTimer(2f); Util.PlaySound("Play_voidman_m1_shoot", ((EntityState)this).gameObject); Transform modelTransform = ((EntityState)this).GetModelTransform(); if (modelTransform != null) { VesperModelAnimator component = ((Component)modelTransform).GetComponent<VesperModelAnimator>(); if (component != null) { Ray aimRay = ((BaseState)this).GetAimRay(); component.OnExpendShot(((Ray)(ref aimRay)).direction); } } if (Object.op_Implicit((Object)(object)MuzzleFlashPrefab)) { EffectManager.SimpleMuzzleFlash(MuzzleFlashPrefab, ((EntityState)this).gameObject, "Muzzle", false); } if (((EntityState)this).isAuthority) { Fire(); } if (NetworkServer.active) { Entropy.AddServer(((EntityState)this).characterBody, VesperConfig.ExpendCurse.Value); Expend.OnServerShot?.Invoke(((EntityState)this).characterBody); } } private void Fire() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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_0018: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_009f: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown Ray aimRay = ((BaseState)this).GetAimRay(); BulletAttack val = new BulletAttack { owner = ((EntityState)this).gameObject, weapon = ((EntityState)this).gameObject, origin = ((Ray)(ref aimRay)).origin, aimVector = ((Ray)(ref aimRay)).direction, minSpread = 0f, maxSpread = 0f, bulletCount = 1u, damage = ((BaseState)this).damageStat * VesperConfig.ExpendDamage.Value, procCoefficient = 1f, force = 150f, falloffModel = (FalloffModel)0, maxDistance = VesperConfig.ExpendRange.Value, radius = 0.3f, smartCollision = true, isCrit = ((BaseState)this).RollCrit(), muzzleName = "Muzzle", tracerEffectPrefab = TracerPrefab, hitEffectPrefab = HitEffectPrefab, damageType = new DamageTypeCombo(DamageTypeCombo.op_Implicit((DamageType)0), (DamageTypeExtended)0, (DamageSource)1) }; DamageAPI.AddModdedDamageType(val, Disorder.DamageType); val.Fire(); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= _duration) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class Tunnel : BaseState { internal struct EndInfo { internal Vector3 Position; internal int EnemiesAffected; internal float Healed; } internal static GameObject BlinkEffectPrefab; private Vector3 _direction; private float _windup; private float _duration; private float _speed; private bool _blinking; private CharacterModel _characterModel; private HurtBoxGroup _hurtBoxGroup; private VesperModelAnimator _animator; internal static event Action<CharacterBody, EndInfo> OnServerEnd; public override void OnEnter() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00ae: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); _windup = Mathf.Max(0f, VesperConfig.TunnelWindup.Value); _duration = Mathf.Max(0.05f, VesperConfig.TunnelDuration.Value); _speed = VesperConfig.TunnelDistance.Value / _duration; _direction = (Object.op_Implicit((Object)(object)((EntityState)this).inputBank) ? ((EntityState)this).inputBank.aimDirection : Vector3.zero); if (((Vector3)(ref _direction)).sqrMagnitude < 0.01f) { _direction = (Object.op_Implicit((Object)(object)((EntityState)this).characterDirection) ? ((EntityState)this).characterDirection.forward : ((EntityState)this).transform.forward); } ((Vector3)(ref _direction)).Normalize(); Util.PlaySound("Play_voidman_shift_start", ((EntityState)this).gameObject); Transform modelTransform = ((EntityState)this).GetModelTransform(); if (Object.op_Implicit((Object)(object)modelTransform)) { _characterModel = ((Component)modelTransform).GetComponent<CharacterModel>(); _hurtBoxGroup = ((Component)modelTransform).GetComponent<HurtBoxGroup>(); _animator = ((Component)modelTransform).GetComponent<VesperModelAnimator>(); } if (Object.op_Implicit((Object)(object)_animator)) { _animator.TunnelBegin(); } if (_windup <= 0f) { BeginBlink(); } } private void BeginBlink() { _blinking = true; SpawnBlinkEffect(); if (Object.op_Implicit((Object)(object)_characterModel)) { CharacterModel characterModel = _characterModel; int invisibilityCount = characterModel.invisibilityCount; characterModel.invisibilityCount = invisibilityCount + 1; } if (Object.op_Implicit((Object)(object)_hurtBoxGroup)) { HurtBoxGroup hurtBoxGroup = _hurtBoxGroup; int invisibilityCount = hurtBoxGroup.hurtBoxesDeactivatorCounter; hurtBoxGroup.hurtBoxesDeactivatorCounter = invisibilityCount + 1; } } public override void FixedUpdate() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) ((EntityState)this).FixedUpdate(); if (!_blinking && ((EntityState)this).fixedAge >= _windup) { BeginBlink(); } if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { ((EntityState)this).characterMotor.velocity = Vector3.zero; if (_blinking) { CharacterMotor characterMotor = ((EntityState)this).characterMotor; characterMotor.rootMotion += _direction * (_speed * ((EntityState)this).GetDeltaTime()); } } if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= _windup + _duration) { ((EntityState)this).outer.SetNextStateToMain(); } } public override void OnExit() { if (_blinking) { if (Object.op_Implicit((Object)(object)_characterModel)) { CharacterModel characterModel = _characterModel; int invisibilityCount = characterModel.invisibilityCount; characterModel.invisibilityCount = invisibilityCount - 1; } if (Object.op_Implicit((Object)(object)_hurtBoxGroup)) { HurtBoxGroup hurtBoxGroup = _hurtBoxGroup; int invisibilityCount = hurtBoxGroup.hurtBoxesDeactivatorCounter; hurtBoxGroup.hurtBoxesDeactivatorCounter = invisibilityCount - 1; } } if (Object.op_Implicit((Object)(object)_animator)) { _animator.TunnelEnd(); } if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { ((EntityState)this).characterMotor.disableAirControlUntilCollision = false; } if (!((EntityState)this).outer.destroying) { Util.PlaySound("Play_voidman_shift_end", ((EntityState)this).gameObject); SpawnBlinkEffect(); if (NetworkServer.active) { EndServer(); } } ((EntityState)this).OnExit(); } private void SpawnBlinkEffect() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)BlinkEffectPrefab)) { EffectManager.SpawnEffect(BlinkEffectPrefab, new EffectData { origin = (Object.op_Implicit((Object)(object)((EntityState)this).characterBody) ? ((EntityState)this).characterBody.corePosition : ((EntityState)this).transform.position), rotation = Util.QuaternionSafeLookRotation(_direction) }, false); } } private void EndServer() { //IL_002e: 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_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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)((EntityState)this).characterBody) || !Object.op_Implicit((Object)(object)((EntityState)this).healthComponent) || !((EntityState)this).healthComponent.alive) { return; } Vector3 corePosition = ((EntityState)this).characterBody.corePosition; float value = VesperConfig.TunnelRadius.Value; TeamMask enemyTeams = TeamMask.GetEnemyTeams((TeamIndex)((!Object.op_Implicit((Object)(object)((EntityState)this).teamComponent)) ? 1 : ((int)((EntityState)this).teamComponent.teamIndex))); List<CharacterBody> list = new List<CharacterBody>(); foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances) && !((Object)(object)readOnlyInstances == (Object)(object)((EntityState)this).characterBody) && Object.op_Implicit((Object)(object)readOnlyInstances.healthComponent) && readOnlyInstances.healthComponent.alive && Object.op_Implicit((Object)(object)readOnlyInstances.teamComponent) && ((TeamMask)(ref enemyTeams)).HasTeam(readOnlyInstances.teamComponent.teamIndex)) { float num = value + readOnlyInstances.radius; Vector3 val = readOnlyInstances.corePosition - corePosition; if (!(((Vector3)(ref val)).sqrMagnitude > num * num)) { list.Add(readOnlyInstances); } } } foreach (CharacterBody item in list) { Disorder.Roll(item, ((EntityState)this).characterBody, item.mainHurtBox, default(ProcChainMask), VesperConfig.TunnelGuaranteedCollapse.Value); } Entropy.AddServer(((EntityState)this).characterBody, VesperConfig.TunnelCurse.Value); ((EntityState)this).characterBody.RecalculateStats(); float num2 = ((EntityState)this).healthComponent.HealFraction(VesperConfig.TunnelHealFraction.Value, default(ProcChainMask)); Log.Debug($"TUNNEL end at {corePosition}: {list.Count} enemies disordered, healed {num2:0.0}"); Tunnel.OnServerEnd?.Invoke(((EntityState)this).characterBody, new EndInfo { Position = corePosition, EnemiesAffected = list.Count, Healed = num2 }); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)2; } } public class VesperDeath : GenericCharacterDeath { public override void OnEnter() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) ((GenericCharacterDeath)this).OnEnter(); if (Object.op_Implicit((Object)(object)((GenericCharacterDeath)this).cachedModelTransform)) { PointSoundManager.EmitSoundLocal("Play_minorConstruct_death", ((GenericCharacterDeath)this).cachedModelTransform.position); float lifetime = ((VesperConfig.DeathImplosionDiameter.Value > 0f) ? (1f + VesperConfig.DeathImplosionGrowTime.Value) : 12f); VesperRagdoll.Break(((GenericCharacterDeath)this).cachedModelTransform, lifetime); } } } } namespace VesperMod.Mechanics { internal static class DeathImplosion { internal static void Init() { GlobalEventManager.onCharacterDeathServer += OnCharacterDeathServer; } private static void OnCharacterDeathServer(DamageReport report) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) CharacterBody val = report?.victimBody; if (Object.op_Implicit((Object)(object)val) && !(val.baseNameToken != "VESPER_BODY_NAME") && !(VesperConfig.DeathImplosionDiameter.Value <= 0f) && Object.op_Implicit((Object)(object)report.victimMaster) && Object.op_Implicit((Object)(object)report.victimMaster.playerCharacterMasterController)) { VesperImplosionController.SpawnServer(VesperImplosionController.DeathPrefab, val, report.victimMaster, val.corePosition); } } } internal static class Disorder { internal enum Debuff { NullifyStack, Collapse } internal struct Result { internal bool Nullify; internal bool Collapse; } internal static ModdedDamageType DamageType; private static readonly Random Rng = new Random(); internal static event Action<CharacterBody, Debuff> OnApplied; internal static event Action<CharacterBody, Result> OnRolled; internal static void Init() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) DamageType = DamageAPI.ReserveDamageType(); GlobalEventManager.onServerDamageDealt += OnServerDamageDealt; } private static void OnServerDamageDealt(DamageReport report) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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) DamageInfo val = report?.damageInfo; if (val != null && DamageAPI.HasModdedDamageType(val, DamageType) && Object.op_Implicit((Object)(object)report.victimBody) && Object.op_Implicit((Object)(object)report.attackerBody) && Object.op_Implicit((Object)(object)report.victim) && report.victim.alive && (!Object.op_Implicit((Object)(object)report.victimBody.teamComponent) || !Object.op_Implicit((Object)(object)report.attackerBody.teamComponent) || report.victimBody.teamComponent.teamIndex != report.attackerBody.teamComponent.teamIndex)) { Roll(report.victimBody, report.attackerBody, val.inflictedHurtbox, val.procChainMask); } } internal static Result Roll(CharacterBody victim, CharacterBody attacker, HurtBox hurtBox = null, ProcChainMask procChainMask = default(ProcChainMask), bool guaranteeCollapse = false) { //IL_008a: 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) Result result = default(Result); if (!NetworkServer.active || !Object.op_Implicit((Object)(object)victim) || !Object.op_Implicit((Object)(object)attacker) || !Object.op_Implicit((Object)(object)victim.healthComponent) || !victim.healthComponent.alive) { return result; } result.Nullify = Rng.NextDouble() < (double)VesperConfig.DisorderNullifyChance.Value; result.Collapse = guaranteeCollapse || Rng.NextDouble() < (double)VesperConfig.DisorderCollapseChance.Value; if (result.Nullify) { Apply(Debuff.NullifyStack, victim, attacker, hurtBox, procChainMask); } if (result.Collapse) { Apply(Debuff.Collapse, victim, attacker, hurtBox, procChainMask); } Disorder.OnRolled?.Invoke(victim, result); return result; } internal static void Apply(Debuff debuff, CharacterBody victim, CharacterBody attacker, HurtBox hurtBox = null, ProcChainMask procChainMask = default(ProcChainMask)) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)victim) && Object.op_Implicit((Object)(object)attacker) && Object.op_Implicit((Object)(object)victim.healthComponent) && victim.healthComponent.alive) { switch (debuff) { case Debuff.NullifyStack: victim.AddTimedBuff(Buffs.NullifyStack, 8f * Mathf.Max(0f, VesperConfig.DisorderDurationMultiplier.Value)); break; case Debuff.Collapse: { float num = DotController.GetDotDef((DotIndex)8)?.interval ?? 3f; DotController.InflictDot(((Component)victim).gameObject, ((Component)attacker).gameObject, Object.op_Implicit((Object)(object)hurtBox) ? hurtBox : victim.mainHurtBox, procChainMask, (DotIndex)8, num, 1f, (uint?)null); break; } } Log.Debug($"DISORDER {debuff} -> {((Object)victim).name}"); Disorder.OnApplied?.Invoke(victim, debuff); } } internal static BuffDef IndicatorBuff(Debuff debuff) { return (BuffDef)(debuff switch { Debuff.NullifyStack => Buffs.NullifyStack, Debuff.Collapse => Buffs.Fracture, _ => null, }); } } internal static class Entropy { internal static BuffDef Curse => Buffs.PermanentCurse; internal static int Get(CharacterBody body) { if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)Curse)) { return 0; } return body.GetBuffCount(Curse); } internal static void AddServer(CharacterBody body, int stacks) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)body) && stacks > 0 && Object.op_Implicit((Object)(object)Curse) && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive) { body.SetBuffCount(Curse.buffIndex, Get(body) + stacks); Log.Debug($"ENTROPY +{stacks} on {((Object)body).name} -> {Get(body)}"); } } internal static int ClearServer(CharacterBody body) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)Curse)) { return 0; } int num = Get(body); if (num > 0) { body.SetBuffCount(Curse.buffIndex, 0); } Log.Debug($"CHAOS on {((Object)body).name}: cleared {num}"); return num; } } internal static class Feast { [CompilerGenerated] private static class <>O { public static StatHookEventHandler <0>__OnGetStatCoefficients; } internal static ItemDef Item; internal static void Init() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown Item = ScriptableObject.CreateInstance<ItemDef>(); ((Object)Item).name = "VesperFeast"; Item.nameToken = "VESPER_ITEM_FEAST_NAME"; Item.pickupToken = "VESPER_ITEM_FEAST_PICKUP"; Item.descriptionToken = "VESPER_ITEM_FEAST_DESC"; Item.loreToken = ""; Item.deprecatedTier = (ItemTier)5; Item.pickupIconSprite = VesperIcons.Feast; Item.hidden = true; Item.canRemove = false; ItemDef item = Item; ItemTag[] array = new ItemTag[7]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); item.tags = (ItemTag[])(object)array; ContentAddition.AddItemDef(Item); object obj = <>O.<0>__OnGetStatCoefficients; if (obj == null) { StatHookEventHandler val = OnGetStatCoefficients; <>O.<0>__OnGetStatCoefficients = val; obj = (object)val; } RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj; } internal static int Count(CharacterBody body) { if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.inventory) || !Object.op_Implicit((Object)(object)Item)) { return 0; } return body.inventory.GetItemCountPermanent(Item); } internal static int Count(CharacterMaster master) { if (!Object.op_Implicit((Object)(object)master) || !Object.op_Implicit((Object)(object)master.inventory) || !Object.op_Implicit((Object)(object)Item)) { return 0; } return master.inventory.GetItemCountPermanent(Item); } internal static void GrantServer(CharacterMaster master, int kills) { if (NetworkServer.active && Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory) && kills > 0) { master.inventory.GiveItemPermanent(Item, kills); Log.Debug($"FORCEFEED: +{kills} feast stacks for {((Object)master).name} (total {Count(master)})"); } } private static void OnGetStatCoefficients(CharacterBody body, StatHookEventArgs args) { int num = Count(body); if (num > 0) { args.baseHealthAdd += (float)num * VesperConfig.ForcefeedHealthPerKill.Value; } } } internal static class FractalAffinity { [CompilerGenerated] private static class <>O { public static StatHookEventHandler <0>__OnGetStatCoefficients; public static Action<CharacterBody> <1>__SyncBuffServer; public static Manipulator <2>__SkipImmuneBodies; } internal static BuffDef Buff; private static readonly ItemTier[] VoidTiers; internal static bool FogHookInstalled { get; private set; } internal static void Init() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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_0094: Expected O, but got Unknown //IL_00e9: 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_00f4: Expected O, but got Unknown Buff = ScriptableObject.CreateInstance<BuffDef>(); ((Object)Buff).name = "VesperFractalAffinity"; Buff.iconSprite = VesperIcons.FractalAffinity; Buff.buffColor = Color.white; Buff.canStack = true; Buff.isDebuff = false; Buff.isCooldown = false; Buff.isHidden = false; Buff.ignoreGrowthNectar = true; ContentAddition.AddBuffDef(Buff); object obj = <>O.<0>__OnGetStatCoefficients; if (obj == null) { StatHookEventHandler val = OnGetStatCoefficients; <>O.<0>__OnGetStatCoefficients = val; obj = (object)val; } RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj; CharacterBody.onBodyStartGlobal += SyncBuffServer; CharacterBody.onBodyInventoryChangedGlobal += SyncBuffServer; object obj2 = <>O.<2>__SkipImmuneBodies; if (obj2 == null) { Manipulator val2 = SkipImmuneBodies; <>O.<2>__SkipImmuneBodies = val2; obj2 = (object)val2; } FogDamageController.EvaluateTeam += (Manipulator)obj2; } internal static bool IsVesper(CharacterBody body) { if (Object.op_Implicit((Object)(object)body)) { return body.baseNameToken == "VESPER_BODY_NAME"; } return false; } internal static int VoidItemCount(CharacterBody body) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) Inventory val = (Object.op_Implicit((Object)(object)body) ? body.inventory : null); if (!Object.op_Implicit((Object)(object)val)) { return 0; } int num = 0; ItemTier[] voidTiers = VoidTiers; foreach (ItemTier val2 in voidTiers) { num += val.GetTotalItemCountOfTier(val2); } return num; } internal static bool IsVoidFog(FogDamageController fog) { BuffDef val = (Object.op_Implicit((Object)(object)fog) ? fog.dangerBuffDef : null); if (Object.op_Implicit((Object)(object)val)) { if (!((Object)(object)val == (Object)(object)Buffs.VoidFogMild) && !((Object)(object)val == (Object)(object)Buffs.VoidFogStrong)) { return (Object)(object)val == (Object)(object)Buffs.VoidRaidCrabWardWipeFog; } return true; } return false; } internal static bool IsImmune(FogDamageController fog, CharacterBody body) { if (VesperConfig.AffinityFogImmunity.Value && IsVesper(body)) { return IsVoidFog(fog); } return false; } private static void OnGetStatCoefficients(CharacterBody body, StatHookEventArgs args) { if (IsVesper(body)) { int num = VoidItemCount(body); if (num > 0) { args.damageMultAdd += (float)num * VesperConfig.AffinityDamagePerItem.Value; args.critAdd += (float)num * VesperConfig.AffinityCritPerItem.Value; args.critDamageMultAdd += (float)num * VesperConfig.AffinityCritDamagePerItem.Value; } } } private static void SyncBuffServer(CharacterBody body) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)Buff) && IsVesper(body)) { int num = VoidItemCount(body); if (body.GetBuffCount(Buff) != num) { body.SetBuffCount(Buff.buffIndex, num); } } } private static void SkipImmuneBodies(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int bodyLocal = -1; if (val.TryGotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<TeamComponent>(x, "get_body"), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref bodyLocal) }) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCall<Object>(x, "op_Implicit") })) { val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc, bodyLocal); val.EmitDelegate<Func<bool, FogDamageController, CharacterBody, bool>>((Func<bool, FogDamageController, CharacterBody, bool>)((bool present, FogDamageController fog, CharacterBody body) => present && !IsImmune(fog, body))); FogHookInstalled = true; } else { Log.Error("Fractal Affinity: FogDamageController.EvaluateTeam has changed; void fog immunity is not active."); } } static FractalAffinity() { ItemTier[] array = new ItemTier[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); VoidTiers = (ItemTier[])(object)array; } } } namespace VesperMod.Components { public class VesperFootsteps : MonoBehaviour { internal const int PlantsPerSound = 2; private CharacterBody _body; private int _plants; internal static event Action<CharacterBody, int, uint> Stepped; private void Awake() { _body = ((Component)this).GetComponentInParent<CharacterBody>(); } private void Start() { if (!Object.op_Implicit((Object)(object)_body)) { _body = ((Component)this).GetComponent<CharacterModel>()?.body; } } internal void Step(int leg, Vector3 footPosition) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_00b7: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_body) || !VesperConfig.FootstepSounds.Value || _plants++ % 2 != 0) { return; } RaycastHit val = default(RaycastHit); if (Physics.Raycast(footPosition + Vector3.up * 1.5f, Vector3.down, ref val, 4f, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask) | LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.water)).mask), (QueryTriggerInteraction)2)) { SurfaceDef objectSurfaceDef = SurfaceDefProvider.GetObjectSurfaceDef(((RaycastHit)(ref val)).collider, ((RaycastHit)(ref val)).point); if (Object.op_Implicit((Object)(object)objectSurfaceDef) && !string.IsNullOrEmpty(objectSurfaceDef.materialSwitchString)) { AkSoundEngine.SetSwitch("material", objectSurfaceDef.materialSwitchString, ((Component)_body).gameObject); } } uint arg = Util.PlaySound("Play_treeBot_step", ((Component)_body).gameObject); VesperFootsteps.Stepped?.Invoke(_body, leg, arg); } } public class VesperImplosionController : MonoBehaviour { internal struct DetonationInfo { internal Vector3 Position; internal bool Death; internal int Hits; internal int Kills; internal int Bosses; internal int AlliesKilled; } internal static GameObject Prefab; internal static GameObject DeathPrefab; internal static GameObject DetonationEffectPrefab; internal const float DeathDelay = 1f; public Transform visual; public bool deathMode; public float startDelay; internal CharacterBody ownerBody; internal CharacterMaster ownerMaster; private float _age; private float _serverAge; private bool _detonated; private bool _clientBoomPlayed; private float _growTime; private float _diameter; internal const float PullSpeed = 8f; internal float Age => _age; internal float GrowTime => _growTime; internal float Diameter => _diameter; internal float VisualDiameter { get { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)visual)) { return 0f; } return visual.localScale.x; } } internal static event Action<VesperImplosionController, DetonationInfo> OnServerDetonated; internal static event Action<VesperImplosionController, CharacterBody> Pulled; internal static VesperImplosionController SpawnServer(GameObject prefab, CharacterBody owner, CharacterMaster master, Vector3 point) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)prefab)) { return null; } GameObject obj = Object.Instantiate<GameObject>(prefab, point, Quaternion.identity); VesperImplosionController component = obj.GetComponent<VesperImplosionController>(); component.ownerBody = owner; component.ownerMaster = (Object.op_Implicit((Object)(object)master) ? master : (Object.op_Implicit((Object)(object)owner) ? owner.master : null)); NetworkServer.Spawn(obj); Log.Debug(string.Format("{0} implosion spawned at {1}", component.deathMode ? "Death" : "FORCEFEED", point)); return component; } private void Awake() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) _growTime = Mathf.Max(0.1f, deathMode ? VesperConfig.DeathImplosionGrowTime.Value : VesperConfig.ImplosionGrowTime.Value); _diameter = (deathMode ? VesperConfig.DeathImplosionDiameter.Value : VesperConfig.ImplosionDiameter.Value); if (Object.op_Implicit((Object)(object)visual)) { visual.localScale = Vector3.zero; } } private void Start() { Util.PlaySound("Play_nullifier_death_vortex_loop", ((Component)this).gameObject); } internal static float GrowthFraction(float t) { t = Mathf.Clamp01(t); return t * t * (3f - 2f * t); } private void Update() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) _age += Time.deltaTime; float num = (_age - startDelay) / _growTime; if (Object.op_Implicit((Object)(object)visual)) { visual.localScale = Vector3.one * (_diameter * GrowthFraction(num)); } if (!_clientBoomPlayed && num >= 1f) { _clientBoomPlayed = true; Util.PlaySound("Stop_nullifier_death_vortex_loop", ((Component)this).gameObject); Util.PlaySound("Play_nullifier_death_vortex_explode", ((Component)this).gameObject); } } private void PullServer() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0