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 Risk of Deadlock v1.0.0
plugins/DeadlockOfRain.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; 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.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DeadlockOfRain.Sheets; using DeadlockOfRain.States; using EntityStates; using HarmonyLib; using KinematicCharacterController; using Rewired; using RoR2; using RoR2.CameraModes; using RoR2.CharacterAI; using RoR2.ConVar; using RoR2.ContentManagement; using RoR2.ExpansionManagement; using RoR2.Navigation; using RoR2.Networking; using RoR2.Projectile; using RoR2.Skills; using RoR2.UI; using RoR2.UI.MainMenu; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DeadlockOfRain")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f360653062c6271fc0f998add72022b2dfdb78ea")] [assembly: AssemblyProduct("DeadlockOfRain")] [assembly: AssemblyTitle("DeadlockOfRain")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace DeadlockOfRain { public static class Buffs { public static readonly Dictionary<string, BuffDef> Defs = new Dictionary<string, BuffDef>(); private static readonly Dictionary<string, Dictionary<CharacterBody, CharacterBody>> owners = new Dictionary<string, Dictionary<CharacterBody, CharacterBody>>(); public static BuffDef Get(string id) { if (id == null || !Defs.TryGetValue(id, out var value)) { return null; } return value; } public static void Create() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) BuffRow[] all = BuffRow.All; foreach (BuffRow buffRow in all) { BuffDef val = ScriptableObject.CreateInstance<BuffDef>(); ((Object)val).name = "bdDeadlock" + buffRow.Id; val.buffColor = Sheet.Color(buffRow.Color); val.canStack = buffRow.CanStack; val.isDebuff = buffRow.IsDebuff; val.isHidden = buffRow.IsHidden; if (buffRow.Icon == "none" || File.Exists(DeadlockCache.ImageFile(buffRow.Icon))) { val.iconSprite = DeadlockCache.Sprite(buffRow.Icon); } Defs[buffRow.Id] = val; } } public static void InitHooks() { GlobalEventManager.onServerDamageDealt += HealBack.OnDamage; } public static int Count(CharacterBody b, string id) { BuffDef val = Get(id); if (!Object.op_Implicit((Object)(object)b) || !Object.op_Implicit((Object)(object)val)) { return 0; } return b.GetBuffCount(val); } public static CharacterBody OwnerOf(CharacterBody victim, string id) { if (!Object.op_Implicit((Object)(object)victim) || !owners.TryGetValue(id, out var value) || !value.TryGetValue(victim, out var value2)) { return null; } return value2; } public static void AddTimed(CharacterBody b, string id, float duration, int max = 0) { BuffDef val = Get(id); if (!Object.op_Implicit((Object)(object)b) || !Object.op_Implicit((Object)(object)val) || !NetworkServer.active) { return; } if (duration <= 0f) { if (max <= 0 || b.GetBuffCount(val) < max) { b.AddBuff(val); } } else if (max > 0 && b.GetBuffCount(val) >= max) { b.ClearTimedBuffs(val); for (int i = 0; i < max; i++) { b.AddTimedBuff(val, duration); } } else { b.AddTimedBuff(val, duration); } } public static void Apply(CharacterBody owner, CharacterBody victim, string id, float bossMult = 1f) { BuffRow buffRow = Sheet.Buff(id); if (buffRow == null || !Object.op_Implicit((Object)(object)victim) || !NetworkServer.active) { return; } float num = buffRow.Duration * (victim.isChampion ? bossMult : 1f); if (!(num <= 0f)) { Clear(victim, id); AddTimed(victim, id, num); SetOwner(owner, victim, id); if (buffRow.Disarm && Object.op_Implicit((Object)(object)Buffs.DisableAllSkills)) { victim.ClearTimedBuffs(Buffs.DisableAllSkills); victim.AddTimedBuff(Buffs.DisableAllSkills, num); } if (buffRow.WithBuff != "none" && buffRow.WithBuff != id) { Apply(owner, victim, buffRow.WithBuff, bossMult); } } } public static void AddStacks(CharacterBody owner, CharacterBody victim, string id, int n) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) BuffRow buffRow = Sheet.Buff(id); BuffDef val = Get(id); if (buffRow != null && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)victim) && n > 0 && NetworkServer.active) { int buffCount = victim.GetBuffCount(val); int num = Mathf.Min((!buffRow.CanStack) ? 1 : Mathf.Max(1, (int)buffRow.MaxStacks), buffCount + n); victim.ClearTimedBuffs(val); while (victim.GetBuffCount(val) > 0) { victim.RemoveBuff(val); } for (int i = 0; i < num; i++) { victim.AddTimedBuff(val, buffRow.Duration); } if (Object.op_Implicit((Object)(object)owner)) { SetOwner(owner, victim, id); } if (buffCount == 0 && buffRow.Vfx != "none") { Relay.Vfx(buffRow.Vfx, "hit", victim.corePosition, 1f, ((Component)victim).gameObject); } } } public static bool Stack(CharacterBody owner, CharacterBody victim, string id, bool crit) { BuffRow buffRow = Sheet.Buff(id); if (buffRow == null || !Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)victim) || !NetworkServer.active) { return false; } int num = ((!buffRow.CanStack) ? 1 : ((int)buffRow.MaxStacks)); int num2 = Count(victim, id); int num3 = ((!crit || !(buffRow.CritStacks > 0f)) ? 1 : ((int)buffRow.CritStacks)); for (int i = 0; i < num3; i++) { AddTimed(victim, id, buffRow.Duration, num); } SetOwner(owner, victim, id); if (buffRow.WithBuff != "none") { Apply(owner, victim, buffRow.WithBuff); } int num4 = (int)buffRow.TriggerStacks; if (num4 <= 0) { return false; } int num5 = Mathf.Min(num, num2 + num3); if (!(buffRow.TriggerClears ? (num5 >= num4) : (num2 / num4 < num5 / num4))) { return false; } if (buffRow.TriggerClears) { Clear(victim, id); } Trigger(owner, victim, buffRow); return true; } private static void Trigger(CharacterBody owner, CharacterBody victim, BuffRow row) { //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_002e: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0107: Unknown result type (might be due to invalid IL or missing references) List<HurtBox> list = new List<HurtBox>(); if (Object.op_Implicit((Object)(object)victim.mainHurtBox)) { list.Add(victim.mainHurtBox); } if (row.TriggerTargets > 0f) { foreach (HurtBox item in Fx.Enemies(owner, victim.corePosition, row.TriggerRadius)) { if ((float)list.Count > row.TriggerTargets) { break; } if ((Object)(object)item.healthComponent.body != (Object)(object)victim) { list.Add(item); } } } Color c = Sheet.Color(row.Color); Relay.Flash(victim.corePosition, c, 6f, 0.25f); foreach (HurtBox item2 in list) { CharacterBody body = item2.healthComponent.body; if ((Object)(object)body != (Object)(object)victim) { Relay.Bolt(victim.corePosition, Object.op_Implicit((Object)(object)body) ? body.corePosition : ((Component)item2).transform.position, c, 0.35f, 0.25f); } if (row.TriggerDamagePct > 0f) { Fx.Hit(owner, item2, row.TriggerDamagePct / 100f, 0.5f, ((Component)item2).transform.position, default(DamageTypeCombo), (DamageColorIndex)5); } if (row.TriggerStun > 0f) { Fx.Stun(item2.healthComponent, row.TriggerStun); } if (row.TriggerBuff != "none" && Object.op_Implicit((Object)(object)body)) { Apply(owner, body, row.TriggerBuff); } if (row.DotDamagePct > 0f && Object.op_Implicit((Object)(object)body)) { Burn(owner, body, row.DotDamagePct); } } MeltyTest.Report("trigger:" + row.Id, ok: true, owner.baseNameToken); } public static void Burn(CharacterBody owner, CharacterBody victim, float pct) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)victim) && NetworkServer.active) { InflictDotInfo val = new InflictDotInfo { attackerObject = ((Component)owner).gameObject, victimObject = ((Component)victim).gameObject, dotIndex = (DotIndex)1, duration = 3f, damageMultiplier = pct / 100f * 2f }; DotController.InflictDot(ref val); Relay.Sound("infernus_gun", "hit", victim.corePosition); } } public static void Dot(CharacterBody owner, CharacterBody victim, DotIndex index, float seconds, int stacks) { //IL_001e: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)victim) && NetworkServer.active) { for (int i = 0; i < stacks; i++) { InflictDotInfo val = new InflictDotInfo { attackerObject = ((Component)owner).gameObject, victimObject = ((Component)victim).gameObject, dotIndex = index, duration = seconds, damageMultiplier = 1f }; DotController.InflictDot(ref val); } } } public static void Clear(CharacterBody b, string id) { BuffDef val = Get(id); if (Object.op_Implicit((Object)(object)b) && Object.op_Implicit((Object)(object)val) && NetworkServer.active) { b.ClearTimedBuffs(val); while (b.HasBuff(val)) { b.RemoveBuff(val); } } } private static void SetOwner(CharacterBody owner, CharacterBody victim, string id) { if (!owners.TryGetValue(id, out var value)) { value = (owners[id] = new Dictionary<CharacterBody, CharacterBody>()); } value[victim] = owner; } } public sealed class HealBack : MonoBehaviour { private struct Part { public float Rate; public float Until; } private readonly List<Part> parts = new List<Part>(); private HealthComponent hc; private float next; public static void OnDamage(DamageReport r) { if (r == null || !Object.op_Implicit((Object)(object)r.victimBody) || r.damageDealt <= 0f) { return; } HeroRow heroRow = Sheet.Hero(Survivors.HeroOf(r.victimBody)); if (heroRow != null && !(heroRow.DamageHealBack <= 0f) && !(heroRow.DamageHealBackTime <= 0f)) { HealBack healBack = ((Component)r.victimBody).GetComponent<HealBack>(); if (!Object.op_Implicit((Object)(object)healBack)) { healBack = ((Component)r.victimBody).gameObject.AddComponent<HealBack>(); } healBack.parts.Add(new Part { Rate = r.damageDealt * heroRow.DamageHealBack / heroRow.DamageHealBackTime, Until = Time.fixedTime + heroRow.DamageHealBackTime }); } } private void Awake() { hc = ((Component)this).GetComponent<HealthComponent>(); } private void FixedUpdate() { //IL_00ba: 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) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)hc) || !hc.alive || parts.Count == 0 || Time.fixedTime < next) { return; } next = Time.fixedTime + 0.25f; float num = 0f; for (int num2 = parts.Count - 1; num2 >= 0; num2--) { num += parts[num2].Rate * 0.25f; if (Time.fixedTime >= parts[num2].Until) { parts.RemoveAt(num2); } } if (num > 0f) { hc.Heal(num, default(ProcChainMask), true); } } } [HarmonyPatch(typeof(CharacterBody), "RecalculateStats")] internal static class StatsPatch { private static readonly ConditionalWeakTable<CharacterBody, float[]> lastHealthAdd = new ConditionalWeakTable<CharacterBody, float[]>(); private static readonly Dictionary<string, MethodInfo> setters = new Dictionary<string, MethodInfo>(); private static void Prefix(CharacterBody __instance, out float[] __state) { __state = null; if (NetworkServer.active && Object.op_Implicit((Object)(object)__instance.healthComponent) && lastHealthAdd.TryGetValue(__instance, out var value) && value[0] != 0f) { __state = new float[2] { __instance.healthComponent.health, __instance.maxHealth - value[0] }; } } private static void Postfix(CharacterBody __instance, float[] __state) { float maxHealth = __instance.maxHealth; float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = 0f; float num5 = 0f; float num6 = 0f; float num7 = 0f; float num8 = 0f; float num9 = 0f; float num10 = 0f; BuffRow[] all = BuffRow.All; foreach (BuffRow buffRow in all) { if (buffRow.MoveSpeedAdd == 0f && buffRow.AttackSpeedAdd == 0f && buffRow.ArmorAdd == 0f && buffRow.RegenAdd == 0f && buffRow.SlowResist == 0f && buffRow.MaxHealthAdd == 0f && buffRow.AccelerationAdd == 0f && buffRow.JumpPowerAdd == 0f && buffRow.JumpCountAdd == 0f) { continue; } BuffDef val = Buffs.Get(buffRow.Id); if (!Object.op_Implicit((Object)(object)val)) { continue; } int buffCount = __instance.GetBuffCount(val); if (buffCount > 0) { int num11 = ((!buffRow.CanStack) ? 1 : buffCount); float num12 = (float)num11 * (__instance.isChampion ? (1f - buffRow.BossStatCut) : 1f); if (buffRow.LinearSlow) { num7 += buffRow.MoveSpeedAdd * num12; } else { num += buffRow.MoveSpeedAdd * num12; } num2 += buffRow.AttackSpeedAdd * num12; num3 += buffRow.ArmorAdd * (float)num11; num4 += buffRow.RegenAdd * (float)num11; num6 += buffRow.MaxHealthAdd * (float)num11; num8 += buffRow.AccelerationAdd * (float)num11; num9 += buffRow.JumpPowerAdd * (float)num11; num10 += buffRow.JumpCountAdd * (float)num11; num5 = Mathf.Max(num5, buffRow.SlowResist); } } if (num6 != 0f || lastHealthAdd.TryGetValue(__instance, out var _)) { lastHealthAdd.GetValue(__instance, (CharacterBody _) => new float[1])[0] = num6; } if (num6 != 0f) { Set(__instance, "maxHealth", __instance.maxHealth + num6); } if (__state != null && NetworkServer.active && Object.op_Implicit((Object)(object)__instance.healthComponent) && __instance.healthComponent.alive) { float num13 = __state[0] + Mathf.Max(0f, maxHealth - __state[1]); __instance.healthComponent.Networkhealth = Mathf.Clamp(num13, 1f, __instance.maxHealth); } if (num8 != 0f) { Set(__instance, "acceleration", __instance.acceleration * Mathf.Max(0.02f, 1f + num8)); } if (num9 != 0f) { Set(__instance, "jumpPower", __instance.jumpPower * Mathf.Max(0.1f, 1f + num9)); } if (num10 != 0f) { SetInt(__instance, "maxJumpCount", Mathf.Max(0, __instance.maxJumpCount + (int)num10)); } if (num == 0f && num2 == 0f && num3 == 0f && num4 == 0f && num5 == 0f && num7 == 0f) { return; } float num14 = __instance.moveSpeed; if (num > 0f) { num14 *= 1f + num; } else if (num < 0f) { num14 /= 1f - num; } if (num7 < 0f) { num14 *= Mathf.Max(0.1f, 1f + num7); } if (num5 > 0f) { float num15 = (__instance.baseMoveSpeed + __instance.levelMoveSpeed * (__instance.level - 1f)) * (__instance.isSprinting ? __instance.sprintingSpeedMultiplier : 1f); if (num14 < num15) { num14 += (num15 - num14) * num5; } } Set(__instance, "moveSpeed", num14); Set(__instance, "attackSpeed", __instance.attackSpeed * Mathf.Max(0.1f, 1f + num2)); Set(__instance, "armor", __instance.armor + num3); Set(__instance, "regen", __instance.regen + num4 * (1f + 0.2f * (__instance.level - 1f))); } private static void Set(CharacterBody b, string prop, float v) { if (!setters.TryGetValue(prop, out var value)) { value = (setters[prop] = AccessTools.PropertySetter(typeof(CharacterBody), prop)); } value.Invoke(b, new object[1] { v }); } private static void SetInt(CharacterBody b, string prop, int v) { if (!setters.TryGetValue(prop, out var value)) { value = (setters[prop] = AccessTools.PropertySetter(typeof(CharacterBody), prop)); } value.Invoke(b, new object[1] { v }); } } [HarmonyPatch(typeof(CharacterBody), "AddTimedBuffInternal")] internal static class DebuffResistPatch { private static void Prefix(CharacterBody __instance, BuffDef buffDef, ref float duration) { if (Object.op_Implicit((Object)(object)buffDef) && buffDef.isDebuff) { HeroRow heroRow = Sheet.Hero(Survivors.HeroOf(__instance)); if (heroRow != null && heroRow.DebuffResist > 0f) { duration *= 1f - heroRow.DebuffResist; } } } } [HarmonyPatch(typeof(HealthComponent), "TakeDamage")] internal static class DamagePatch { private static readonly Random rng = new Random(); private static void Prefix(HealthComponent __instance, DamageInfo damageInfo) { if (damageInfo == null || !Object.op_Implicit((Object)(object)__instance)) { return; } CharacterBody body = __instance.body; if (!Object.op_Implicit((Object)(object)body)) { return; } CharacterBody val = (Object.op_Implicit((Object)(object)damageInfo.attacker) ? damageInfo.attacker.GetComponent<CharacterBody>() : null); BuffRow buffRow = Sheet.Buff("bullet_dance"); if (buffRow != null && Buffs.Count(body, "bullet_dance") > 0 && Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)body && rng.NextDouble() < (double)buffRow.EvasionChance) { damageInfo.rejected = true; } else { if (!Object.op_Implicit((Object)(object)val)) { return; } BuffRow[] all = BuffRow.All; foreach (BuffRow buffRow2 in all) { if (!(buffRow2.DamageTakenFromOwnerPerStack <= 0f)) { int num = Buffs.Count(body, buffRow2.Id); if (num > 0 && !((Object)(object)Buffs.OwnerOf(body, buffRow2.Id) != (Object)(object)val)) { damageInfo.damage *= 1f + (float)((!buffRow2.CanStack) ? 1 : num) * buffRow2.DamageTakenFromOwnerPerStack; } } } } } } public static class Equipment { [HarmonyPatch(typeof(EquipmentSlot), "PerformEquipmentAction")] private static class FirePatch { private static bool Prefix(EquipmentSlot __instance, EquipmentDef equipmentDef, ref bool __result) { SkillRow skillRow = RowOf(equipmentDef); if (skillRow == null) { return true; } CharacterBody characterBody = __instance.characterBody; __result = Object.op_Implicit((Object)(object)characterBody) && (!characterBody.hasEffectiveAuthority || Fire(characterBody, skillRow)); if (__result) { MeltyTest.Report("equipment-fires", ok: true, characterBody.baseNameToken); } return false; } } [HarmonyPatch(typeof(EquipmentSlot), "RpcOnClientEquipmentActivationRecieved")] private static class ClientFirePatch { private static void Postfix(EquipmentSlot __instance) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { return; } CharacterBody characterBody = __instance.characterBody; if (Object.op_Implicit((Object)(object)characterBody) && characterBody.hasEffectiveAuthority) { SkillRow skillRow = RowOf(EquipmentCatalog.GetEquipmentDef(__instance.equipmentIndex)); if (skillRow != null) { Fire(characterBody, skillRow); } } } } public static readonly Dictionary<string, EquipmentDef> Defs = new Dictionary<string, EquipmentDef>(); private static readonly Dictionary<EquipmentDef, SkillRow> rowOf = new Dictionary<EquipmentDef, SkillRow>(); private static readonly HashSet<CharacterMaster> given = new HashSet<CharacterMaster>(); internal const float FigurePadding = 2.2f; public static GameObject FigureFor(string vfx) { foreach (KeyValuePair<EquipmentDef, SkillRow> item in rowOf) { if (item.Value.Vfx == vfx && Object.op_Implicit((Object)(object)item.Key.pickupModelPrefab)) { return item.Key.pickupModelPrefab; } } return null; } public static SkillRow RowOf(EquipmentDef def) { if (!Object.op_Implicit((Object)(object)def) || !rowOf.TryGetValue(def, out var value)) { return null; } return value; } public static EquipmentDef OfHero(string hero) { if (hero == null) { return null; } EquipmentRow[] all = EquipmentRow.All; foreach (EquipmentRow equipmentRow in all) { if (equipmentRow.Hero == hero && Defs.TryGetValue(equipmentRow.Id, out var value)) { return value; } } return null; } public static void Init() { CharacterBody.onBodyStartGlobal += GiveStartingEquipment; Run.onRunStartGlobal += delegate { given.Clear(); }; } public static void Build(Transform holder) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) EquipmentRow[] all = EquipmentRow.All; foreach (EquipmentRow equipmentRow in all) { SkillRow skillRow = Sheet.Skill(equipmentRow.Skill); HeroRow heroRow = Sheet.Hero(equipmentRow.Hero); if (skillRow != null && heroRow != null && Survivors.Bodies.ContainsKey(heroRow.Id)) { EquipmentDef val = ScriptableObject.CreateInstance<EquipmentDef>(); ((Object)val).name = "edDeadlock_" + skillRow.Id; val.nameToken = Sheet.Token("equip", equipmentRow.Id); val.pickupToken = Sheet.Token("equippickup", equipmentRow.Id); val.descriptionToken = Sheet.Token("equipdesc", equipmentRow.Id); val.loreToken = Sheet.Token("equiplore", equipmentRow.Id); val.cooldown = skillRow.Cooldown; val.canDrop = equipmentRow.CanDrop; val.enigmaCompatible = equipmentRow.EnigmaCompatible; val.canBeRandomlyTriggered = equipmentRow.RandomTrigger; val.appearsInSinglePlayer = true; val.appearsInMultiPlayer = true; val.colorIndex = (ColorIndex)5; val.pickupIconSprite = DeadlockCache.Sprite(skillRow.Icon); val.pickupModelPrefab = PickupModel(heroRow, holder, equipmentRow.Figure); Defs[equipmentRow.Id] = val; rowOf[val] = skillRow; Survivors.Tokens[val.nameToken] = heroRow.DisplayName + "'s " + skillRow.Name; Survivors.Tokens[val.pickupToken] = equipmentRow.PickupText; Survivors.Tokens[val.descriptionToken] = skillRow.Description; Survivors.Tokens[val.loreToken] = equipmentRow.Lore; Log.Info($"Built equipment {skillRow.Name} ({skillRow.Cooldown:F0}s)"); } } } private static GameObject PickupModel(HeroRow hero, Transform holder, string figure) { //IL_00a6: 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_00d8: Expected O, but got Unknown //IL_00ef: 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_0112: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Expected O, but got Unknown GameObject val = ModelBuilder.Build(hero, forDisplay: true, (figure == "all") ? null : figure); if (!Object.op_Implicit((Object)(object)val)) { return null; } try { Animation component = val.GetComponent<Animation>(); string idle = Sheet.Anims(hero.Id).Idle; if (Object.op_Implicit((Object)(object)component) && idle != "none" && (TrackedReference)(object)component[idle] != (TrackedReference)null) { AnimationState obj = component[idle]; obj.enabled = true; obj.weight = 1f; obj.time = 0f; component.Sample(); obj.enabled = false; } SkinnedMeshRenderer[] componentsInChildren = val.GetComponentsInChildren<SkinnedMeshRenderer>(true); List<Mesh> list = new List<Mesh>(); List<Material> list2 = new List<Material>(); Bounds val2 = default(Bounds); bool flag = true; SkinnedMeshRenderer[] array = componentsInChildren; foreach (SkinnedMeshRenderer val3 in array) { if (Object.op_Implicit((Object)(object)val3.sharedMesh)) { Mesh val4 = new Mesh(); val3.BakeMesh(val4); val4.RecalculateBounds(); Material val5 = new Material(((Renderer)val3).sharedMaterial) { name = ((Object)((Renderer)val3).sharedMaterial).name + "_Figure" }; if (val5.HasProperty("_Fade")) { val5.SetFloat("_Fade", 1f); } val5.DisableKeyword("DITHER"); list.Add(val4); list2.Add(val5); if (flag) { val2 = val4.bounds; flag = false; } else { ((Bounds)(ref val2)).Encapsulate(val4.bounds); } } } if (list.Count == 0) { return null; } CombineInstance[] array2 = (CombineInstance[])(object)new CombineInstance[list.Count]; Matrix4x4 transform = Matrix4x4.Translate(-((Bounds)(ref val2)).center); for (int j = 0; j < list.Count; j++) { int num = j; CombineInstance val6 = default(CombineInstance); ((CombineInstance)(ref val6)).mesh = list[j]; ((CombineInstance)(ref val6)).transform = transform; array2[num] = val6; } Mesh val7 = new Mesh { name = "mshDeadlock" + hero.DisplayName + "Figure", indexFormat = (IndexFormat)1 }; val7.CombineMeshes(array2, false, true); val7.RecalculateBounds(); Bounds bounds = val7.bounds; Vector3 center = ((Bounds)(ref bounds)).center; bounds = val7.bounds; val7.bounds = new Bounds(center, ((Bounds)(ref bounds)).size * 2.2f); foreach (Mesh item in list) { Object.Destroy((Object)(object)item); } GameObject val8 = new GameObject("PickupDeadlock" + hero.DisplayName); val8.transform.SetParent(holder, false); val8.AddComponent<MeshFilter>().sharedMesh = val7; ((Renderer)val8.AddComponent<MeshRenderer>()).sharedMaterials = list2.ToArray(); return val8; } finally { Object.DestroyImmediate((Object)(object)val); } } private static void GiveStartingEquipment(CharacterBody body) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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)Run.instance)) { return; } EquipmentDef val = OfHero(Survivors.HeroOf(body)); CharacterMaster master = body.master; if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory) && Object.op_Implicit((Object)(object)master.playerCharacterMasterController) && !given.Contains(master) && Run.instance.stageClearCount <= 0) { given.Add(master); if ((int)master.inventory.currentEquipmentIndex == -1) { EquipmentLocation activeEquipmentLocation = master.inventory.activeEquipmentLocation; master.inventory.SetEquipmentIndex(val.equipmentIndex, ref activeEquipmentLocation); MeltyTest.Report("starting-equipment", ok: true, body.baseNameToken); } } } public static bool Fire(CharacterBody body, SkillRow row) { if (!Object.op_Implicit((Object)(object)body) || row == null) { return false; } Type type = Survivors.StateFor(row.Kind); if (type == null) { return false; } EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)body).gameObject, Survivors.MachineFor(row.Kind)); if (!Object.op_Implicit((Object)(object)val)) { val = EntityStateMachine.FindByCustomName(((Component)body).gameObject, "Weapon"); } if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)body).GetComponent<EntityStateMachine>(); } if (!Object.op_Implicit((Object)(object)val)) { return false; } DlrState dlrState = (DlrState)Activator.CreateInstance(type); dlrState.RowOverride = row; bool flag; if (val.state is Burrow && dlrState is UltDevil ultDevil) { ultDevil.FromBurrow = true; val.SetNextState((EntityState)(object)dlrState); flag = true; } else { flag = val.SetInterruptState((EntityState)(object)dlrState, (InterruptPriority)2); } if (flag && body.isPlayerControlled && body.hasEffectiveAuthority) { Voice.SkillLine(row); } return flag; } } [HarmonyPatch] internal static class LoadoutSkinRowPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__2_0; internal void <Postfix>b__2_0() { } } private static Type rowType = AccessTools.Inner(typeof(LoadoutPanelController), "Row"); private static MethodBase TargetMethod() { return AccessTools.Method(rowType, "FromSkin", (Type[])null, (Type[])null); } private static void Postfix(object __result, LoadoutPanelController owner, BodyIndex bodyIndex) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown if (__result == null) { return; } IList list = (IList)AccessTools.Field(rowType, "rowData").GetValue(__result); if (list == null || list.Count > 0) { return; } CharacterBody bodyPrefabBodyComponent = BodyCatalog.GetBodyPrefabBodyComponent(bodyIndex); DeadlockHero deadlockHero = (Object.op_Implicit((Object)(object)bodyPrefabBodyComponent) ? ((Component)bodyPrefabBodyComponent).GetComponent<DeadlockHero>() : null); if (Object.op_Implicit((Object)(object)deadlockHero)) { HeroRow heroRow = Sheet.Hero(deadlockHero.HeroId); Sprite val = DeadlockCache.Sprite(heroRow.ImageSmall); Survivors.Tokens["DLR_SKIN_DEFAULT"] = "Default"; MethodInfo methodInfo = AccessTools.Method(rowType, "AddButton", (Type[])null, (Type[])null); object[] obj = new object[10] { owner, val, "DLR_SKIN_DEFAULT", "", Sheet.Color(heroRow.PrimaryColor), null, null, null, null, null }; object obj2 = <>c.<>9__2_0; if (obj2 == null) { UnityAction val2 = delegate { }; <>c.<>9__2_0 = val2; obj2 = (object)val2; } obj[5] = obj2; obj[6] = ""; obj[8] = false; obj[9] = 0; methodInfo.Invoke(__result, obj); } } } public static class MissingHeroes { [HarmonyPatch(typeof(UserProfile), "HasSurvivorUnlocked")] private static class LockPatch { private static bool Prefix(SurvivorIndex survivorIndex, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (!Is(SurvivorCatalog.GetSurvivorDef(survivorIndex))) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(SurvivorIconController), "Rebuild")] private static class IconPatch { private static void Postfix(SurvivorIconController __instance) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) SurvivorDef survivorDef = __instance.survivorDef; if (Is(survivorDef)) { if (Object.op_Implicit((Object)(object)__instance.survivorIcon)) { ((Graphic)__instance.survivorIcon).color = Color.white; } bool flag = soon.Contains(survivorDef); string text = Language.GetString(survivorDef.displayNameToken) + (flag ? ": coming soon" : ": not available"); string text2 = (Object.op_Implicit((Object)(object)survivorDef.unlockableDef) ? survivorDef.unlockableDef.getHowToUnlockString() : ""); Color val = (flag ? new Color(0.6f, 0.6f, 0.6f, 1f) : new Color(0.9f, 0.2f, 0.2f, 1f)); if (Object.op_Implicit((Object)(object)__instance.tooltipProvider)) { ((Behaviour)__instance.tooltipProvider).enabled = true; __instance.tooltipProvider.overrideTitleText = text; __instance.tooltipProvider.titleColor = val; __instance.tooltipProvider.overrideBodyText = text2; } HGButton component = ((Component)__instance).GetComponent<HGButton>(); if (Object.op_Implicit((Object)(object)component)) { val.a = 0.2f; component.hoverToken = Language.GetStringFormatted("LOGBOOK_HOVER_DESCRIPTION_FORMAT", new object[3] { text, text2, ColorUtility.ToHtmlStringRGBA(val) }); } } } } public static readonly Dictionary<string, GameObject> Bodies = new Dictionary<string, GameObject>(); public static readonly Dictionary<string, SurvivorDef> Defs = new Dictionary<string, SurvivorDef>(); public static readonly Dictionary<string, UnlockableDef> Unlockables = new Dictionary<string, UnlockableDef>(); private static readonly HashSet<SurvivorDef> placeholders = new HashSet<SurvivorDef>(); private static readonly HashSet<SurvivorDef> soon = new HashSet<SurvivorDef>(); private static Texture2D icon; public static bool Is(SurvivorDef def) { if (Object.op_Implicit((Object)(object)def)) { return placeholders.Contains(def); } return false; } public static void Add(GameObject commando, Transform holder, HeroRow hero, string why) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) string text = Survivors.CodeName(hero); GameObject val = Object.Instantiate<GameObject>(commando, holder); ((Object)val).name = "Deadlock" + text + "MissingBody"; NetworkIdentity component = val.GetComponent<NetworkIdentity>(); if (Object.op_Implicit((Object)(object)component)) { byte[] array = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("DeadlockOfRain." + ((Object)val).name)); AccessTools.Field(typeof(NetworkIdentity), "m_AssetId").SetValue(component, NetworkHash128.Parse(BitConverter.ToString(array).Replace("-", "").ToLowerInvariant())); } CharacterBody component2 = val.GetComponent<CharacterBody>(); component2.baseNameToken = "DLR_MISSING_NAME_" + hero.Id.ToUpperInvariant(); component2.subtitleNameToken = component2.baseNameToken; component2.portraitIcon = (Texture)(object)((why == null) ? (Silhouette(DeadlockCache.Image(hero.ImageSmall)) ?? Icon()) : Icon()); Survivors.Tokens[component2.baseNameToken] = hero.DisplayName; string text2 = ((why == null) ? (hero.DisplayName + " is coming in a later update.") : (hero.DisplayName + " couldn't be read from your Deadlock (" + why + "). The other heroes are ready to play.\n\n" + BuiltWith.Versions())); UnlockableDef val2 = ScriptableObject.CreateInstance<UnlockableDef>(); val2.cachedName = "DeadlockOfRain.Missing." + hero.Id; val2.nameToken = component2.baseNameToken; val2.hidden = true; val2.getHowToUnlockString = () => text2; val2.getUnlockedString = () => text2; GameObject val3 = new GameObject("Deadlock" + text + "MissingDisplay"); val3.transform.SetParent(holder, false); SurvivorDef val4 = ScriptableObject.CreateInstance<SurvivorDef>(); ((Object)val4).name = "Deadlock" + text + "Missing"; val4.cachedName = "Deadlock" + text + "Missing"; val4.bodyPrefab = val; val4.displayPrefab = val3; val4.displayNameToken = component2.baseNameToken; val4.descriptionToken = component2.baseNameToken; val4.primaryColor = ((why == null) ? Color.black : Color.red); val4.desiredSortPosition = hero.SortPosition; val4.unlockableDef = val2; Bodies[hero.Id] = val; Defs[hero.Id] = val4; Unlockables[hero.Id] = val2; placeholders.Add(val4); if (why == null) { soon.Add(val4); Log.Info(hero.DisplayName + ": shown as a blacked-out \"coming soon\" tile in character select"); } else { Log.Warn(hero.DisplayName + ": shown as a locked red ! tile in character select (" + why + ")"); } } private static Texture2D Silhouette(Texture2D src) { //IL_0018: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)src)) { return null; } Texture2D val = new Texture2D(((Texture)src).width, ((Texture)src).height, (TextureFormat)4, false) { name = ((Object)src).name + "_soon", wrapMode = (TextureWrapMode)1 }; Color32[] pixels = src.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { pixels[i] = new Color32((byte)0, (byte)0, (byte)0, pixels[i].a); } val.SetPixels32(pixels); val.Apply(); return val; } private static Texture2D Icon() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)icon)) { return icon; } icon = new Texture2D(128, 128, (TextureFormat)4, false) { name = "DeadlockOfRainMissing", wrapMode = (TextureWrapMode)1 }; Color32[] array = (Color32[])(object)new Color32[16384]; Color32 val = default(Color32); ((Color32)(ref val))..ctor((byte)70, (byte)8, (byte)8, byte.MaxValue); Color32 val2 = default(Color32); ((Color32)(ref val2))..ctor((byte)235, (byte)40, (byte)40, byte.MaxValue); for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num = (float)j - 64f + 0.5f; float num2 = (float)i - 64f + 0.5f; bool flag = num * num + num2 * num2 <= 3844f; bool flag2 = Mathf.Abs(num) <= 9f && i >= 46 && i <= 108; bool flag3 = num * num + ((float)i - 28f) * ((float)i - 28f) <= 110f; array[i * 128 + j] = (Color32)((!flag) ? new Color32((byte)0, (byte)0, (byte)0, (byte)0) : ((flag2 || flag3) ? val2 : val)); } } icon.SetPixels32(array); icon.Apply(); return icon; } } public sealed class DeadlockHero : MonoBehaviour { public string HeroId; } [AttributeUsage(AttributeTargets.Class)] public sealed class KindAttribute : Attribute { public readonly string Kind; public KindAttribute(string kind) { Kind = kind; } } public static class Survivors { public static readonly Dictionary<string, GameObject> Bodies = new Dictionary<string, GameObject>(); public static readonly Dictionary<string, SurvivorDef> Defs = new Dictionary<string, SurvivorDef>(); public static readonly Dictionary<string, SkillDef> SkillDefs = new Dictionary<string, SkillDef>(); public static readonly Dictionary<SkillDef, SkillRow> RowOfSkill = new Dictionary<SkillDef, SkillRow>(); public static readonly List<SkillFamily> Families = new List<SkillFamily>(); public static readonly List<Type> StateTypes = new List<Type>(); public static readonly Dictionary<string, string> Tokens = new Dictionary<string, string>(); public static float CommandoHeight; private static GameObject holder; private static HeroRow[] released; private static HeroRow[] comingSoon; private static Dictionary<string, Type> kindTypes; public static HeroRow[] Released { get { if (released != null) { return released; } string path = Path.Combine(Plugin.PluginDir ?? "", "heroes.txt"); if (!File.Exists(path)) { return released = HeroRow.All; } HashSet<string> ids = new HashSet<string>(from l in File.ReadAllLines(path) select l.Trim() into l where l.Length > 0 select l); HeroRow[] all = HeroRow.All; foreach (HeroRow heroRow in all) { if (!ids.Contains(heroRow.Id)) { Log.Info(heroRow.DisplayName + ": not in this release (heroes.txt)"); } } return released = HeroRow.All.Where((HeroRow h) => ids.Contains(h.Id)).ToArray(); } } public static HeroRow[] ComingSoon { get { if (comingSoon != null) { return comingSoon; } string path = Path.Combine(Plugin.PluginDir ?? "", "coming-soon.txt"); if (!File.Exists(path)) { return comingSoon = new HeroRow[0]; } HashSet<string> ids = new HashSet<string>(from l in File.ReadAllLines(path) select l.Trim() into l where l.Length > 0 select l); return comingSoon = HeroRow.All.Where((HeroRow h) => ids.Contains(h.Id) && !Released.Contains(h)).ToArray(); } } public static string CodeName(HeroRow hero) { return Regex.Replace(hero.DisplayName, "[^A-Za-z0-9]", ""); } public static void LimitTo(ICollection<string> ids) { List<string> list = (from h in Released where !ids.Contains(h.Id) select h.DisplayName).ToList(); if (list.Count > 0) { Log.Info("Not chosen in the hero picker (not read from Deadlock yet): " + string.Join(", ", list)); } released = Released.Where((HeroRow h) => ids.Contains(h.Id)).ToArray(); } public static bool IsHero(CharacterBody b, string id) { DeadlockHero deadlockHero = (Object.op_Implicit((Object)(object)b) ? ((Component)b).GetComponent<DeadlockHero>() : null); if (Object.op_Implicit((Object)(object)deadlockHero)) { return deadlockHero.HeroId == id; } return false; } public static string HeroOf(CharacterBody b) { DeadlockHero deadlockHero = (Object.op_Implicit((Object)(object)b) ? ((Component)b).GetComponent<DeadlockHero>() : null); if (!Object.op_Implicit((Object)(object)deadlockHero)) { return null; } return deadlockHero.HeroId; } private static Dictionary<string, Type> KindTypes() { Dictionary<string, Type> dictionary = new Dictionary<string, Type>(); Type[] types = typeof(Survivors).Assembly.GetTypes(); foreach (Type type in types) { KindAttribute kindAttribute = (KindAttribute)Attribute.GetCustomAttribute(type, typeof(KindAttribute)); if (kindAttribute != null) { dictionary[kindAttribute.Kind] = type; } if (typeof(EntityState).IsAssignableFrom(type) && !type.IsAbstract) { StateTypes.Add(type); } } return dictionary; } public static string MachineFor(string kind) { switch (kind) { default: return "Weapon"; case "dash_charge": case "dash_trail": case "ult_leap": case "phantom_strike": case "heavy_melee": case "burrow": case "ult_devil": case "goo_cube": case "banner_leap": case "storm_flight": case "bashdown": case "rising_ram": case "ult_chains": return "Body"; } } public static bool NoFallDamage(CharacterBody b) { return Sheet.Hero(HeroOf(b))?.NoFallDamage ?? false; } public static Type StateFor(string kind) { if (kindTypes == null || !kindTypes.TryGetValue(kind, out var value)) { return null; } return value; } public static IEnumerator Build() { holder = new GameObject("DeadlockOfRainPrefabs"); holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)holder); GameObject commando = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Commando/CommandoBody.prefab").WaitForCompletion(); SkinnedMeshRenderer componentInChildren = ((Component)commando.GetComponent<ModelLocator>().modelTransform).GetComponentInChildren<SkinnedMeshRenderer>(true); ModelBuilder.Template = Addressables.LoadAssetAsync<Material>((object)"RoR2/Base/Commando/matCommandoDualies.mat").WaitForCompletion(); Log.Info("hero material template: " + (Object.op_Implicit((Object)(object)ModelBuilder.Template) ? ((Object)ModelBuilder.Template.shader).name : "none")); CapsuleCollider component = commando.GetComponent<CapsuleCollider>(); float num = 0f; if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren.sharedMesh)) { Bounds bounds = componentInChildren.sharedMesh.bounds; num = ((Bounds)(ref bounds)).size.y * ((Component)componentInChildren).transform.lossyScale.y; } CommandoHeight = ((num > 1f && num < 3f) ? num : component.height); HeroRow heroRow = Sheet.Hero("haze"); ModelBuilder.GlobalScale = CommandoHeight / heroRow.SourceHeight; Log.Info($"Commando height {CommandoHeight:F3} m (mesh {num:F3}, capsule {component.height:F3}); Deadlock->RoR2 scale {ModelBuilder.GlobalScale:F4}"); Dictionary<string, Type> kinds = (kindTypes = KindTypes()); Buffs.Create(); Fx.Preload(); yield return null; HeroRow[] array = ComingSoon; foreach (HeroRow hero in array) { MissingHeroes.Add(commando, holder.transform, hero, null); } FirstRun.BuildBegin(Released.Length); HeroRow[] array2 = Released; foreach (HeroRow hero2 in array2) { FirstRun.BuildHero(hero2.DisplayName); int frame = Time.frameCount; while (Time.frameCount == frame) { yield return null; } if (DeadlockCache.Failed.ContainsKey(hero2.Id) || DeadlockCache.LoadHero(hero2.Id) == null) { string value; string text = (DeadlockCache.Failed.TryGetValue(hero2.Id, out value) ? value : "no Deadlock content for it"); Log.Error("hero " + hero2.Id + " skipped: Deadlock could not be read for it (" + text + ")"); MissingHeroes.Add(commando, holder.transform, hero2, text); FirstRun.BuildHeroDone(hero2.DisplayName, text); continue; } GameObject val = BuildBody(commando, hero2, kinds); Bodies[hero2.Id] = val; GameObject val2 = ModelBuilder.Build(hero2, forDisplay: true); val2.transform.SetParent(holder.transform, false); ((Object)val2).name = "Deadlock" + CodeName(hero2) + "Display"; SurvivorDef val3 = ScriptableObject.CreateInstance<SurvivorDef>(); ((Object)val3).name = "Deadlock" + CodeName(hero2); val3.cachedName = "Deadlock" + CodeName(hero2); val3.bodyPrefab = val; val3.displayPrefab = val2; val3.displayNameToken = Sheet.Token("name", hero2.Id); val3.descriptionToken = Sheet.Token("desc", hero2.Id); val3.outroFlavorToken = Sheet.Token("outro", hero2.Id); val3.mainEndingEscapeFailureFlavorToken = Sheet.Token("fail", hero2.Id); val3.primaryColor = Sheet.Color(hero2.PrimaryColor); val3.desiredSortPosition = hero2.SortPosition; Defs[hero2.Id] = val3; AddTokens(hero2); Log.Info($"Built survivor {hero2.DisplayName} ({FirstRun.HeroSeconds:F1} s)"); FirstRun.BuildHeroDone(hero2.DisplayName, null); } Equipment.Build(holder.transform); Net.Build(holder.transform); } private static GameObject BuildBody(GameObject commando, HeroRow hero, Dictionary<string, Type> kinds) { //IL_0091: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0574: Unknown result type (might be due to invalid IL or missing references) //IL_06c8: Unknown result type (might be due to invalid IL or missing references) //IL_06e2: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Expected O, but got Unknown //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_06ee: Unknown result type (might be due to invalid IL or missing references) //IL_07be: Unknown result type (might be due to invalid IL or missing references) //IL_07c3: Unknown result type (might be due to invalid IL or missing references) //IL_07dc: Unknown result type (might be due to invalid IL or missing references) //IL_05d0: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_0601: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Unknown result type (might be due to invalid IL or missing references) //IL_060a: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_085d: Unknown result type (might be due to invalid IL or missing references) //IL_085f: Unknown result type (might be due to invalid IL or missing references) //IL_0832: Unknown result type (might be due to invalid IL or missing references) //IL_0849: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(commando, holder.transform); ((Object)val).name = "Deadlock" + CodeName(hero) + "Body"; NetworkIdentity component = val.GetComponent<NetworkIdentity>(); if (Object.op_Implicit((Object)(object)component)) { string text = BitConverter.ToString(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("DeadlockOfRain." + ((Object)val).name))).Replace("-", "").ToLowerInvariant(); AccessTools.Field(typeof(NetworkIdentity), "m_AssetId").SetValue(component, NetworkHash128.Parse(text)); } ModelLocator component2 = val.GetComponent<ModelLocator>(); Transform modelTransform = component2.modelTransform; Transform val2 = (Object.op_Implicit((Object)(object)component2.modelBaseTransform) ? component2.modelBaseTransform : modelTransform.parent); GameObject val3 = ModelBuilder.Build(hero, forDisplay: false); val3.transform.SetParent(val2, false); val3.transform.localPosition = modelTransform.localPosition; val3.transform.localRotation = Quaternion.identity; Object.DestroyImmediate((Object)(object)((Component)modelTransform).gameObject); AccessTools.Field(typeof(ModelLocator), "_modelTransform").SetValue(component2, val3.transform); CharacterBody component3 = val.GetComponent<CharacterBody>(); HealthComponent component4 = val.GetComponent<HealthComponent>(); val3.GetComponent<CharacterModel>().body = component3; HurtBox[] componentsInChildren = val3.GetComponentsInChildren<HurtBox>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].healthComponent = component4; } CharacterDirection component5 = val.GetComponent<CharacterDirection>(); if (Object.op_Implicit((Object)(object)component5)) { component5.modelAnimator = null; } AimAnimator[] componentsInChildren2 = val.GetComponentsInChildren<AimAnimator>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } StatRow statRow = Sheet.Stats(hero.Id); component3.baseNameToken = Sheet.Token("name", hero.Id); component3.subtitleNameToken = Sheet.Token("subtitle", hero.Id); component3.portraitIcon = (Texture)(object)DeadlockCache.Image(hero.ImageSmall); component3.bodyColor = Sheet.Color(hero.PrimaryColor); component3.baseMaxHealth = statRow.BaseMaxHealth; component3.levelMaxHealth = statRow.LevelMaxHealth; component3.baseRegen = statRow.BaseRegen; component3.levelRegen = statRow.LevelRegen; component3.baseDamage = statRow.BaseDamage; component3.levelDamage = statRow.LevelDamage; component3.baseArmor = statRow.BaseArmor; component3.levelArmor = statRow.LevelArmor; component3.baseAttackSpeed = statRow.BaseAttackSpeed; component3.levelAttackSpeed = statRow.LevelAttackSpeed; component3.baseCrit = statRow.BaseCrit; component3.levelCrit = statRow.LevelCrit; component3.baseMoveSpeed = statRow.BaseMoveSpeed; component3.levelMoveSpeed = 0f; component3.baseJumpPower = statRow.BaseJumpPower; component3.levelJumpPower = 0f; component3.baseJumpCount = (int)statRow.BaseJumpCount; component3.baseAcceleration = statRow.BaseAcceleration; component3.baseMaxShield = statRow.BaseMaxShield; component3.levelMaxShield = 0f; component3.sprintingSpeedMultiplier = statRow.SprintingSpeedMultiplier; if (hero.NoFallDamage) { component3.bodyFlags = (BodyFlags)(component3.bodyFlags | 1); } CapsuleCollider component6 = val.GetComponent<CapsuleCollider>(); float num = component6.height * hero.HeightScale; float num2 = component6.radius * hero.WidthScale; float num3 = component6.center.y * hero.HeightScale; GameObject val4 = VanillaBody(hero.CapsuleFrom); CapsuleCollider val5 = (Object.op_Implicit((Object)(object)val4) ? val4.GetComponent<CapsuleCollider>() : null); if (Object.op_Implicit((Object)(object)val5)) { num = val5.height; num2 = val5.radius; num3 = val5.center.y; } component6.height = num; component6.radius = Mathf.Min(num2, num * 0.5f); component6.center = new Vector3(0f, num3, 0f); KinematicCharacterMotor component7 = val.GetComponent<KinematicCharacterMotor>(); if (Object.op_Implicit((Object)(object)component7)) { AccessTools.Field(typeof(KinematicCharacterMotor), "CapsuleHeight").SetValue(component7, num); AccessTools.Field(typeof(KinematicCharacterMotor), "CapsuleRadius").SetValue(component7, Mathf.Min(num2, num * 0.5f)); AccessTools.Field(typeof(KinematicCharacterMotor), "CapsuleYOffset").SetValue(component7, num3); } if (Object.op_Implicit((Object)(object)component3.aimOriginTransform)) { component3.aimOriginTransform.localPosition = Vector3.Scale(component3.aimOriginTransform.localPosition, new Vector3(1f, hero.HeightScale, 1f)); } CameraTargetParams component8 = val.GetComponent<CameraTargetParams>(); GameObject val6 = VanillaBody(hero.CameraFrom); CameraTargetParams val7 = (Object.op_Implicit((Object)(object)val6) ? val6.GetComponent<CameraTargetParams>() : null); if (Object.op_Implicit((Object)(object)component8) && ((Object.op_Implicit((Object)(object)val7) && Object.op_Implicit((Object)(object)val7.cameraParams)) || Object.op_Implicit((Object)(object)component8.cameraParams))) { CharacterCameraParams val8 = Object.Instantiate<CharacterCameraParams>((Object.op_Implicit((Object)(object)val7) && Object.op_Implicit((Object)(object)val7.cameraParams)) ? val7.cameraParams : component8.cameraParams); ((Object)val8).name = "ccpDeadlock" + hero.DisplayName; CharacterCameraParamsData data = val8.data; if (!Object.op_Implicit((Object)(object)val7)) { data.idealLocalCameraPos.value = data.idealLocalCameraPos.value * Mathf.Lerp(1f, hero.HeightScale, 0.8f); data.pivotVerticalOffset.value = data.pivotVerticalOffset.value * hero.HeightScale; } Vector3 value = data.idealLocalCameraPos.value * hero.CameraScale; value.x += hero.CameraRight; data.idealLocalCameraPos.value = value; val8.data = data; component8.cameraParams = val8; } Interactor component9 = val.GetComponent<Interactor>(); if (Object.op_Implicit((Object)(object)component9)) { component9.maxInteractionDistance *= hero.InteractRange; } SkillLocator component10 = val.GetComponent<SkillLocator>(); FieldInfo fieldInfo = AccessTools.Field(typeof(GenericSkill), "_skillFamily"); foreach (SkillRow item in Sheet.SkillsOf(hero.Id)) { if (!(item.Slot == "equipment")) { SkillDef val9 = MakeSkillDef(item, kinds); SkillFamily val10 = ScriptableObject.CreateInstance<SkillFamily>(); ((Object)val10).name = "sfDeadlock_" + item.Id; Variant[] array = new Variant[1]; Variant val11 = new Variant { skillDef = val9 }; ((Variant)(ref val11)).viewableNode = new Node(val9.skillNameToken, false, (Node)null); array[0] = val11; val10.variants = (Variant[])(object)array; Families.Add(val10); GenericSkill obj; switch (item.Slot) { case "primary": obj = component10.primary; break; case "secondary": obj = component10.secondary; break; case "utility": obj = component10.utility; break; case "special": obj = component10.special; break; default: Log.Error("skill " + item.Id + ": unknown slot " + item.Slot); continue; } fieldInfo.SetValue(obj, val10); } } PassiveSkill passiveSkill = component10.passiveSkill; passiveSkill.enabled = hero.PassiveName != "none"; if (passiveSkill.enabled) { passiveSkill.skillNameToken = Sheet.Token("passive", hero.Id); passiveSkill.skillDescriptionToken = Sheet.Token("passivedesc", hero.Id); passiveSkill.icon = DeadlockCache.Sprite(hero.PassiveIcon); passiveSkill.keywordToken = null; Tokens[passiveSkill.skillNameToken] = hero.PassiveName; Tokens[passiveSkill.skillDescriptionToken] = hero.PassiveDescription; } component10.passiveSkill = passiveSkill; val.AddComponent<DeadlockHero>().HeroId = hero.Id; val.AddComponent<HeroRuntime>(); return val; } private static SkillDef MakeSkillDef(SkillRow row, Dictionary<string, Type> kinds) { //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_00ec: Unknown result type (might be due to invalid IL or missing references) SkillDef val = ScriptableObject.CreateInstance<SkillDef>(); ((Object)val).name = "sdDeadlock_" + row.Id; val.skillName = "Deadlock_" + row.Id; val.skillNameToken = Sheet.Token("skill", row.Id); val.skillDescriptionToken = Sheet.Token("skilldesc", row.Id); val.icon = DeadlockCache.Sprite(row.Icon); if (!kinds.TryGetValue(row.Kind, out var value)) { Log.Error("no state for kind " + row.Kind); value = typeof(Idle); } val.activationState = new SerializableEntityStateType(value); val.activationStateMachineName = MachineFor(row.Kind); bool flag = row.Slot == "primary"; bool flag2 = row.Slot == "special"; val.interruptPriority = (InterruptPriority)((!flag) ? ((!flag2) ? 1 : 2) : 0); val.baseRechargeInterval = (flag ? 0f : row.Cooldown); val.baseMaxStock = (int)Mathf.Max(1f, row.Stocks); val.rechargeStock = 1; val.requiredStock = 1; val.stockToConsume = ((!flag) ? 1 : 0); val.fullRestockOnAssign = true; val.isCombatSkill = true; val.mustKeyPress = !flag; bool flag3 = row.Kind.StartsWith("dash") || row.Kind == "burrow" || (row.Kind == "self_buff" && row.Buff == "smoke"); val.cancelSprintingOnActivation = !flag3; val.canceledFromSprinting = false; val.hideCooldown = false; val.hideStockCount = flag; val.beginSkillCooldownOnSkillEnd = row.CooldownOnEnd; SkillDefs[row.Id] = val; RowOfSkill[val] = row; Tokens[val.skillNameToken] = row.Name; Tokens[val.skillDescriptionToken] = row.Description; return val; } private static void AddTokens(HeroRow hero) { Tokens[Sheet.Token("name", hero.Id)] = hero.DisplayName; Tokens[Sheet.Token("subtitle", hero.Id)] = hero.Subtitle; Tokens[Sheet.Token("outro", hero.Id)] = "..and so " + hero.DisplayName + " left, the contract fulfilled."; Tokens[Sheet.Token("fail", hero.Id)] = "..and so " + hero.DisplayName + " vanished into the storm."; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(hero.Lore).Append("\n\n"); foreach (SkillRow item in Sheet.SkillsOf(hero.Id)) { string value = ((item.Slot == "primary") ? "M1" : ((item.Slot == "secondary") ? "M2" : ((item.Slot == "utility") ? "Shift" : ((item.Slot == "special") ? "R" : "Q (Ultimate equipment)")))); stringBuilder.Append("< ! > <style=cIsUtility>").Append(value).Append(" - ") .Append(item.Name) .Append("</style>\n"); } stringBuilder.Append("\n<style=cIsUtility>You start every run holding your Deadlock ultimate as equipment (Q, 120s). Swap it for another and it stays on the ground for anyone to take.</style>"); Tokens[Sheet.Token("desc", hero.Id)] = stringBuilder.ToString(); BuffRow[] all = BuffRow.All; foreach (BuffRow buffRow in all) { Tokens[Sheet.Token("buff", buffRow.Id)] = buffRow.Name; } } private static GameObject VanillaBody(string name) { //IL_0052: 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) if (string.IsNullOrEmpty(name) || name == "none") { return null; } try { return Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/" + name.Replace("Body", "") + "/" + name + ".prefab")).WaitForCompletion(); } catch (Exception ex) { Log.Warn("vanilla body " + name + ": " + ex.Message); return null; } } public static SkillRow RowFor(GenericSkill gs) { if (!Object.op_Implicit((Object)(object)gs) || !Object.op_Implicit((Object)(object)gs.skillDef) || !RowOfSkill.TryGetValue(gs.skillDef, out var value)) { return null; } return value; } } public sealed class HeroRuntime : MonoBehaviour { public int Ammo = -1; public bool Reloading; public bool AltMuzzle; public float SmokeUntil; private float reloadEnd; private int clip; private CharacterBody body; private HeroRow hero; private SoundRow steps; private SoundRow lands; private Transform rider; private Vector3 riderScale = Vector3.one; private bool riderHidden; private GameObject frenzy; private float nextStep; private float airTime; private bool wasGrounded = true; private float reloadTime; private int dodgesUsed; public float ComboUntil; public int Combo; public float LastSwingEnd = -99f; public float GunBlockedUntil; public int Octagon; private float hangUntil; private float hangUsed; private bool hanging; private bool jumpPressed; private float airSince; private float nextUntarget; private int lastJumps; public float ReloadFraction { get { if (!Reloading || !(reloadTime > 0f)) { return 1f; } return Mathf.Clamp01(1f - (reloadEnd - Time.time) / reloadTime); } } public int Extra => DlrPuddle.Supply(body); public bool CanFire { get { if (Extra <= 0) { if (!Reloading) { return Ammo > 0; } return false; } return true; } } public int Rounds => Extra + ((!Reloading) ? Mathf.Max(0, Ammo) : 0); public int Dodges { get { if (hero == null) { return 0; } return (int)hero.AirDodges; } } public int DodgesLeft => Dodges - dodgesUsed; public float HangLeft => Mathf.Max(0f, hangUntil - Time.fixedTime); private void Awake() { body = ((Component)this).GetComponent<CharacterBody>(); } private void Start() { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) hero = Sheet.Hero(Survivors.HeroOf(body)); if (hero == null) { return; } if (hero.ImmuneToForce && NetworkServer.active && !body.HasBuff(Buffs.ImmuneToPhysicsForces)) { body.AddBuff(Buffs.ImmuneToPhysicsForces); } SkillRow skillRow = Sheet.SkillsOf(hero.Id).FirstOrDefault((SkillRow s) => s.Slot == "primary"); steps = ((skillRow != null) ? Sheet.Sound(skillRow.Id + "/step") : null); lands = ((skillRow != null) ? (Sheet.Sound(skillRow.Id + "/land") ?? steps) : null); Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); if (!Object.op_Implicit((Object)(object)val) || !(hero.RiderBone != "none")) { return; } Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if (((Object)val2).name == hero.RiderBone) { rider = val2; riderScale = val2.localScale; break; } } } public static bool Melee(CharacterBody b) { if (!Object.op_Implicit((Object)(object)b)) { return false; } BuffRow[] all = BuffRow.All; foreach (BuffRow buffRow in all) { if (buffRow.Melee && Buffs.Count(b, buffRow.Id) > 0) { return true; } } return false; } public static bool NoGun(CharacterBody b) { if (!Object.op_Implicit((Object)(object)b)) { return false; } BuffRow[] all = BuffRow.All; foreach (BuffRow buffRow in all) { if (buffRow.NoGun && Buffs.Count(b, buffRow.Id) > 0) { return true; } } GenericSkill val = (Object.op_Implicit((Object)(object)b.skillLocator) ? b.skillLocator.primary : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.skillDef)) { return (Object)(object)val.skillDef == (Object)(object)CommonAssets.disabledSkill; } return false; } private void LateUpdate() { //IL_00ba: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)rider)) { bool flag = Melee(body); if (flag != riderHidden) { riderHidden = flag; rider.localScale = (flag ? Vector3.zero : riderScale); if (flag) { frenzy = Vfx.Play("mokrill_punch", "frenzy", body.footPosition, body.radius, ((Component)body).transform); } else { Vfx.Stop(frenzy, 0.6f); frenzy = null; } } else if (flag) { rider.localScale = Vector3.zero; } } if (steps == null || !Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.characterMotor) || !Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive) { return; } CharacterMotor characterMotor = body.characterMotor; bool isGrounded = characterMotor.isGrounded; if (!isGrounded) { airTime += Time.deltaTime; } else { if (!wasGrounded && airTime > 0.6f) { Fx.Sound(lands.Skill, "hit", body.footPosition); if (hero.LandShake > 0f) { ShakeEmitter.CreateSimpleShakeEmitter(body.footPosition, new Wave { amplitude = hero.LandShake, frequency = 25f }, 0.3f, 12f, true); } } airTime = 0f; Vector3 velocity = characterMotor.velocity; velocity.y = 0f; if (((Vector3)(ref velocity)).magnitude > 1f && Time.time >= nextStep) { nextStep = Time.time + 2.75f / Mathf.Max(2f, ((Vector3)(ref velocity)).magnitude); Fx.Sound(steps.Skill, "cast", body.footPosition); } } wasGrounded = isGrounded; } public void BeginReload(SkillRow gun, float attackSpeed) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!Reloading) { Reloading = true; clip = (int)gun.ClipSize; reloadTime = gun.ReloadTime / Mathf.Max(0.1f, attackSpeed); reloadEnd = Time.time + reloadTime; Fx.Sound(gun.Id, "reload", ((Component)this).transform.position); } } public void Spend(int n) { n -= DlrPuddle.Draw(body, n); if (n > 0 && !Reloading) { Ammo = Mathf.Max(0, Ammo - n); } } private void Update() { if (hero != null && hero.AirDodges > 0f && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inputBank) && ((ButtonState)(ref body.inputBank.jump)).justPressed) { jumpPressed = true; } if (Reloading && Time.time >= reloadEnd) { Reloading = false; Ammo = clip; MeltyTest.Report("gun-reloads", ok: true, Object.op_Implicit((Object)(object)body) ? body.baseNameToken : ""); } } public void UseDodge() { dodgesUsed++; } public void RefreshDodges() { dodgesUsed = 0; hangUsed = 0f; } public void HangFor(float seconds, float budget) { if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.characterMotor) && !body.characterMotor.isGrounded && !(hangUsed >= budget)) { float fixedTime = Time.fixedTime; float num = Mathf.Max(0f, hangUntil - fixedTime); float num2 = Mathf.Min(seconds - num, budget - hangUsed); if (!(num2 <= 0f)) { hangUsed += num2; hangUntil = fixedTime + num + num2; } } } public void EndHang() { hangUntil = 0f; hangUsed = float.MaxValue; } public void Refill(SkillRow gun, float pct) { if (gun != null && !(pct <= 0f) && !(gun.ClipSize <= 0f)) { int num = Mathf.Max(1, Mathf.RoundToInt(gun.ClipSize * pct / 100f)); if (Reloading) { Reloading = false; Ammo = 0; } if (Ammo < 0) { Ammo = (int)gun.ClipSize; } Ammo = Mathf.Min((int)gun.ClipSize, Ammo + num); } } private void BillyFixedUpdate() { //IL_00a5: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00be: Unknown result type (might be due to invalid IL or missing references) CharacterMotor characterMotor = body.characterMotor; if (characterMotor.isGrounded) { dodgesUsed = 0; hangUsed = 0f; airSince = Time.fixedTime; } if (jumpPressed) { jumpPressed = false; if (!characterMotor.isGrounded && Time.fixedTime - airSince > 0.1f && characterMotor.jumpCount >= body.maxJumpCount) { BillyAir.TryDodge(body); } } bool flag = Time.fixedTime < hangUntil && !characterMotor.isGrounded; if (flag != hanging) { hanging = flag; CharacterGravityParameters gravityParameters = characterMotor.gravityParameters; gravityParameters.channeledAntiGravityGranterCount += (flag ? 1 : (-1)); characterMotor.gravityParameters = gravityParameters; } if (flag && characterMotor.velocity.y < 0f) { Vector3 velocity = characterMotor.velocity; velocity.y = 0f; characterMotor.velocity = velocity; } } private void FixedUpdate() { //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if (hero != null && hero.AirDodges > 0f && Object.op_Implicit((Object)(object)body) && body.hasEffectiveAuthority && Object.op_Implicit((Object)(object)body.characterMotor)) { BillyFixedUpdate(); } if (hero != null && hero.AirJumpMult != 1f && Object.op_Implicit((Object)(object)body) && body.hasEffectiveAuthority && Object.op_Implicit((Object)(object)body.characterMotor)) { CharacterMotor characterMotor = body.characterMotor; if (characterMotor.jumpCount > lastJumps && lastJumps >= 1 && !characterMotor.isGrounded && characterMotor.velocity.y > 0f) { Vector3 velocity = characterMotor.velocity; velocity.y *= hero.AirJumpMult; characterMotor.velocity = velocity; MeltyTest.Report("air-jump", ok: true, body.baseNameToken); } lastJumps = characterMotor.jumpCount; } if (!NetworkServer.active || !Object.op_Implicit((Object)(object)body) || !body.hasCloakBuff || Time.fixedTime < nextUntarget) { return; } nextUntarget = Time.fixedTime + 0.2f; foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { if (!Object.op_Implicit((Object)(object)readOnlyInstances) || readOnlyInstances.teamIndex == body.teamComponent.teamIndex || readOnlyInstances.AiComponents == null) { continue; } BaseAI[] aiComponents = readOnlyInstances.AiComponents; foreach (BaseAI val in aiComponents) { if (Object.op_Implicit((Object)(object)val) && val.currentEnemy != null && (Object)(object)val.currentEnemy.gameObject == (Object)(object)((Component)body).gameObject) { val.currentEnemy.Reset(); } } } } } internal sealed class DeadlockContentProvider : IContentPackProvider { private readonly ContentPack pack = new ContentPack(); public string identifier => "melty.deadlockofrain"; public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args) { if (FirstRun.Started) { while (FirstRun.Choosing || (FirstRun.Running && !FirstRun.StopIfStalled())) { args.ReportProgress(0.45f * FirstRun.Progress); yield return null; } FirstRun.Finish(DeadlockCache.DefaultDir()); Plugin.OpenCache(); if (FirstRun.Wanted != null) { Survivors.LimitTo(FirstRun.Wanted); } DeadlockAudio.Init(); } if (DeadlockCache.Ready) { IEnumerator e = Survivors.Build(); while (e.MoveNext()) { args.ReportProgress(0.5f); yield return e.Current; } } FirstRun.BuildEnd(); pack.bodyPrefabs.Add(Survivors.Bodies.Values.ToArray()); pack.survivorDefs.Add(Survivors.Defs.Values.ToArray()); pack.bodyPrefabs.Add(MissingHeroes.Bodies.Values.ToArray()); pack.survivorDefs.Add(MissingHeroes.Defs.Values.ToArray()); pack.unlockableDefs.Add(MissingHeroes.Unlockables.Values.ToArray()); pack.skillDefs.Add(Survivors.SkillDefs.Values.ToArray()); pack.skillFamilies.Add(Survivors.Families.ToArray()); pack.entityStateTypes.Add(Survivors.StateTypes.ToArray()); pack.buffDefs.Add(Buffs.Defs.Values.ToArray()); pack.equipmentDefs.Add(Equipment.Defs.Values.ToArray()); if (Net.RelayDef != null) { pack.effectDefs.Add((EffectDef[])(object)new EffectDef[1] { Net.RelayDef }); } pack.effectDefs.Add(Fx.TintedDefs.ToArray()); Net.RegisterModList(); args.ReportProgress(1f); } public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args) { ContentPack.Copy(pack, args.output); args.ReportProgress(1f); yield break; } public IEnumerator FinalizeAsync(FinalizeAsyncArgs args) { args.ReportProgress(1f); yield break; } } [HarmonyPatch(typeof(Language), "GetLocalizedStringByToken")] internal static class LanguagePatch { private static bool Prefix(string token, ref string __result) { if (token != null && token.StartsWith("DLR_", StringComparison.Ordinal) && Survivors.Tokens.TryGetValue(token, out var value)) { __result = value; return false; } return true; } } [BepInPlugin("melty.deadlockofrain", "Deadlock of Rain", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static CollectContentPackProvidersDelegate <>9__6_0; internal void <Awake>b__6_0(AddContentPackProviderDelegate add) { add.Invoke((IContentPackProvider)(object)new DeadlockContentProvider()); } } public const string Guid = "melty.deadlockofrain"; public const string Version = "1.0.0"; public static Plugin Instance; public static ConfigEntry<float> Volume; public static ConfigEntry<string> DeadlockFolder; public static string PluginDir; private void Awake() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown Instance = this; Log.Source = ((BaseUnityPlugin)this).Logger; PluginDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); Volume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Deadlock sound volume", 1f, "Volume of the Deadlock sounds (0-1), on top of the game's master and SFX volume."); DeadlockFolder = ((BaseUnityPlugin)this).Config.Bind<string>("Deadlock", "Deadlock folder", "", "Only needed if Deadlock is not found by itself: your Deadlock folder, e.g. D:\\SteamLibrary\\steamapps\\common\\Deadlock (Steam: Deadlock > Manage > Browse local files). Its game or game\\citadel folder works too."); QuitSafety.Init(); if (MeltyTest.Off("mod")) { MeltyTest.Init(); return; } BuiltWith.Read(); FirstRunOverlay.Show(); if (!FirstRun.Start(DeadlockCache.DefaultDir(), DeadlockFolder.Value)) { OpenCache(); } if (!MeltyTest.Off("harmony")) { new Harmony("melty.deadlockofrain").PatchAll(typeof(Plugin).Assembly); } object obj = <>c.<>9__6_0; if (obj == null) { CollectContentPackProvidersDelegate val = delegate(AddContentPackProviderDelegate add) { add.Invoke((IContentPackProvider)(object)new DeadlockContentProvider()); }; <>c.<>9__6_0 = val; obj = (object)val; } ContentManager.collectContentPackProviders += (CollectContentPackProvidersDelegate)obj; Equipment.Init(); Buffs.InitHooks(); GunHits.Init(); Net.Init(); if (!FirstRun.Started && !MeltyTest.Off("audio")) { DeadlockAudio.Init(); } Voice.Init(); DlrHopper.InitTrophies(); FirstRun.Init(); CommunityButton.Init(); MeltyTest.Init(); DpsBench.Init(); } public static void OpenCache() { DeadlockCache.Open(DeadlockCache.DefaultDir()); Log.Info("Deadlock of Rain 1.0.0: Deadlock content from build " + DeadlockCache.DeadlockBuild + " at " + DeadlockCache.Dir); if (!DeadlockCache.Ready && FirstRun.Problem == null) { FirstRun.Problem = "The Deadlock heroes are missing. Install Deadlock (free on Steam) and restart Risk of Rain 2.\n\n" + BuiltWith.Versions(); } } private void OnDestroy() { DeadlockAudio.Shutdown(); } private void OnApplicationQuit() { DeadlockAudio.Shutdown(); } } public static class Log { public static ManualLogSource Source; public static void Info(string s) { ManualLogSource source = Source; if (source != null) { source.LogInfo((object)s); } } public static void Warn(string s) { ManualLogSource source = Source; if (source != null) { source.LogWarning((object)s); } } public static void Error(string s) { ManualLogSource source = Source; if (source != null) { source.LogError((object)s); } } } [HarmonyPatch(typeof(SkillIcon), "LateUpdate")] internal static class AmmoCounter { private static void Postfix(SkillIcon __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)__instance.targetSkillSlot == 0) { AmmoLabel ammoLabel = ((Component)__instance).GetComponent<AmmoLabel>(); if (!Object.op_Implicit((Object)(object)ammoLabel)) { ammoLabel = ((Component)__instance).gameObject.AddComponent<AmmoLabel>(); } ammoLabel.Show(__instance); } } } internal sealed class AmmoLabel : MonoBehaviour { private static readonly Color Full = Color.white; private static readonly Color Reload = new Color(0.6f, 0.6f, 0.6f); public static string Shown; public static CharacterBody ShownFor; public static float LastShow = -1f; private TextMeshProUGUI text; private int shownAmmo = int.MinValue; private int shownClip = -1; private int shownExtra = -1; private bool shownReload; public void Show(SkillIcon icon) { //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) GenericSkill targetSkill = icon.targetSkill; CharacterBody val = (Object.op_Implicit((Object)(object)targetSkill) ? targetSkill.characterBody : null); SkillRow skillRow = Survivors.RowFor(targetSkill); HeroRuntime heroRuntime = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<HeroRuntime>() : null); if (skillRow == null || !(skillRow.ClipSize > 0f) || !Object.op_Implicit((Object)(object)heroRuntime) || !val.hasEffectiveAuthority) { if (Object.op_Implicit((Object)(object)text)) { ((Component)text).gameObject.SetActive(false); } return; } LastShow = Time.unscaledTime; if (!Object.op_Implicit((Object)(object)text)) { Build(icon); } if (Object.op_Implicit((Object)(object)text)) { int num = (int)skillRow.ClipSize; int num2 = ((heroRuntime.Ammo < 0) ? num : heroRuntime.Ammo); int extra = heroRuntime.Extra; if (!((Component)text).gameObject.activeSelf) { ((Component)text).gameObject.SetActive(true); } if (num2 != shownAmmo || num != shownClip || extra != shownExtra || heroRuntime.Reloading != shownReload) { shownAmmo = num2; shownClip = num; shownExtra = extra; shownReload = heroRuntime.Reloading; string arg = ((extra > 0) ? $"{extra}+" : ""); ((TMP_Text)text).SetText((extra > 0) ? $"<color=#8CFF5A>{arg}</color>{num2}/{num}" : $"{num2}/{num}", true); Shown = $"{arg}{num2}/{num}"; ShownFor = val; ((Graphic)text).color = (heroRuntime.Reloading ? Reload : Full); } } } private void Build(SkillIcon icon) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_004f: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) GameObject val = new GameObject("DlrAmmo", new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(((Component)icon).transform, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0f); val2.anchoredPosition = new Vector2(0f, 4f); val2.sizeDelta = new Vector2(160f, 28f); text = (TextMeshProUGUI)(object)val.AddComponent<HGTextMeshProUGUI>(); TextMeshProUGUI val4 = (Object.op_Implicit((Object)(object)icon.stockText) ? icon.stockText : icon.cooldownText); if (Object.op_Implicit((Object)(object)val4)) { ((TMP_Text)text).font = ((TMP_Text)val4).font; ((TMP_Text)text).fontSharedMaterial = ((TMP_Text)val4).fontSharedMaterial; } ((TMP_Text)text).fontSize = 22f; ((TMP_Text)text).alignment = (TextAlignmentOptions)1026; ((TMP_Text)text).enableWordWrapping = false; ((Graphic)text).raycastTarget = false; } } public static class BillyAir { public static HurtBox Nearest(CharacterBody body, float range, bool onScreen = false) { //IL_000c: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)body)) { return null; } foreach (HurtBox item in Fx.Enemies(body, body.corePosition, range)) { CharacterBody body2 = item.healthComponent.body; if (!Object.op_Implicit((Object)(object)body2) || (onScreen && !OnScreen(body, body2.corePosition))) { continue; } Vector3 corePosition = body.corePosition; Vector3 corePosition2 = body2.corePosition; LayerIndex world = LayerIndex.world; if (Physics.Linecast(corePosition, corePosition2, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { Vector3 corePosition3 = body.corePosition; Vector3 val = body2.corePosition + Vector3.up * body2.radius; world = LayerIndex.world; if (Physics.Linecast(corePosition3, val, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { continue; } } return item; } return null; } public static bool OnScreen(CharacterBody body, Vector3 point) { //IL_00cd: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) foreach (CameraRigController readOnlyInstances in CameraRigController.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances) && !((Object)(object)readOnlyInstances.target != (Object)(object)((Component)body).gameObject) && Object.op_Implicit((Object)(object)readOnlyInstances.sceneCam)) { Vector3 val = readOnlyInstances.sceneCam.WorldToViewportPoint(point); return val.z > 0f && val.x >= 0f && val.x <= 1f && val.y >= 0f && val.y <= 1f; } } return Vector3.Dot(Object.op_Implicit((Object)(object)body.inputBank) ? body.inputBank.aimDirection : ((Component)body).transform.forward, point - body.corePosition) > 0f; } public static void SlamDown(HealthComponent hc, float speed) { if (Object.op_Implicit((Object)(object)hc) && Object.op_Implicit((Object)(object)hc.body) && NetworkServer.active) { DlrLift dlrLift = ((Component)hc.body).GetComponent<DlrLift>(); if (!Object.op_Implicit((Object)(object)dlrLift)) { dlrLift = ((Component)hc.body).gameObject.AddComponent<DlrLift>(); } dlrLift.Slam(speed); } } public static void DragDown(HealthComponent hc, CharacterBody by, float speed) { if (Object.op_Implicit((Object)(object)hc) && Object.op_Implicit((Object)(object)hc.body) && Object.op_Implicit((Object)(object)by) && NetworkServer.active) { DlrLift dlrLift = ((Component)hc.body).GetComponent<DlrLift>(); if (!Object.op_Implicit((Object)(object)dlrLift)) { dlrLift = ((Component)hc.body).gameObject.AddComponent<DlrLift>(); } dlrLift.Drag(by, speed); } } public static void LetGo(CharacterBody by, float speed) { if (Object.op_Implicit((Object)(object)by) && NetworkServer.active) { DlrLift[] array = Object.FindObjectsOfType<DlrLift>(); for (int i = 0; i < array.Length; i++) { array[i].Release(by, speed); } } } public static bool InAir(CharacterBody body) { CharacterMotor val = (Object.op_Implicit((Object)(object)body) ? body.characterMotor : null); if (Object.op_Implicit((Object)(object)val)) { if (val.isGrounded) { return val.velocity.y > 1f; } return true; } return false; } public static bool InCombo(CharacterBody body) { HeroRuntime heroRuntime = (Object.op_Implicit((Object)(object)body) ? ((Component)body).GetComponent<HeroRuntime>() : null); if (Object.op_Implicit((Object)(object)heroRuntime) && heroRuntime.Dodges > 0) { if (!Object.op_Implicit((Object)(object)body.characterMotor) || body.characterMotor.isGrounded) { return Time.time < heroRuntime.ComboUntil; } return true; } return false; } public static bool TryDodge(CharacterBody body) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) HeroRuntime heroRuntime = (Object.op_Implicit((Object)(object)body) ? ((Component)body).GetComponent<HeroRuntime>() : null); if (!Object.op_Implicit((Object)(object)heroRuntime) || !body.hasEffectiveAuthority || heroRuntime.DodgesLeft <= 0) { return false; } EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)body).gameObject, "Body"); if (!Object.op_Implicit((Object)(object)val) || !(val.state is GenericCharacterMain)) { return false; } InputBankTest inputBank = body.inputBank; Vector3 val2 = (Object.op_Implicit((Object)(object)inputBank) ? inputBank.aimDirection : ((Component)body).transform.forward); if (Object.op_Implicit((Object)(object)inputBank) && ((Vector3)(ref inputBank.moveVector)).sqrMagnitude > 0.1f) { val2 = inputBank.moveVector; val2.y = 0f; } val.SetNextState((EntityState)(object)new BillyDodge { Dir = ((Vector3)(ref val2)).normalized }); return true; } } public sealed class DlrLift : MonoBehaviour { private enum Phase { Rise, Drift, Hold, Slam, Drag } private Phase phase; private CharacterBody body; private float riseSpeed; private float riseEnd; private float until; private float cap; private float driftSpeed; private float slamSpeed; private float start; private float slamUntil; private bool antiGravity; private bool flyer; private bool hold; private bool lifted; private CharacterBody dragBy; public static DlrLift Float(CharacterBody victim, float height, float riseTime, float floatTime) { if (!Object.op_Implicit((Object)(object)victim) || !NetworkServer.active) { return null; } DlrLift obj = ((Component)victim).GetComponent<DlrLift>() ?? ((Component)victim).gameObject.AddComponent<DlrLift>(); obj.Begin(height, riseTime, floatTime, holdOnly: false); return obj; } public static DlrLift Haul(CharacterBody victim, float height, float riseTime, float holdTime) { if (!Object.op_Implicit((Object)(object)victim) || !NetworkServer.active) { return null; } DlrLift obj = ((Component)victim).GetComponent<DlrLift>() ?? ((Component)victim).gameObject.AddComponent<DlrLift>(); obj.Begin(height, riseTime, riseTime + holdTime, holdOnly: true); return obj; } public static bool Floating(CharacterBody b) { DlrLift dlrLift = (Object.op_Implicit((Object)(object)b) ? ((Component)b).GetComponent<DlrLift>() : null); if (Object.op_Implicit((Object)(object)dlrLift) && dlrLift.phase != Phase.Slam) { return dlrLift.phase != Phase.Drag; } return false; } public static bool Dragged(CharacterBody b, CharacterBody by) { DlrLift dlrLift = (Object.op_Implicit((Object)(object)b) ? ((Component)b).GetComponent<DlrLift>() : null); if (Object.op_Implicit((Object)(object)dlrLift) && dlrLift.phase == Phase.Drag