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 VoidFiendAlternates v0.1.0
BepInEx/plugins/VoidFiendAlternates/VoidFiendAlternates.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using EntityStates; using EntityStates.VoidSurvivor; using EntityStates.VoidSurvivor.CorruptMode; using EntityStates.VoidSurvivor.Weapon; using Newtonsoft.Json; using On.EntityStates.VoidSurvivor.CorruptMode; using ProperSave; using R2API; using R2API.Utils; using RoR2; using RoR2.ContentManagement; using RoR2.Networking; using RoR2.Projectile; using RoR2.Skills; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace VoidFiendAlternates; public enum Skill { Impale, Lash, Undertow, Condense, Displace, Breach, Quarantine, Unleash } public static class Balance { public const string Revision = "spec-1.0-r1"; public static readonly float[] Cooldowns = new float[8] { 0f, 0f, 7f, 6f, 7f, 8f, 10f, 12f }; public static readonly float[] ControlledDamage = new float[8] { 4.2f, 2.8f, 1.2f, 9f, 0f, 4f, 0f, 0f }; public static readonly float[] CorruptedDamage = new float[8] { 2.2f, 7f, 10f, 6f, 2f, 8f, 6f, 24f }; public static readonly float[] ControlledProc = new float[8] { 1f, 1f, 0.2f, 1f, 0f, 1f, 0f, 0f }; public static readonly float[] CorruptedProc = new float[8] { 0.55f, 0.6f, 1f, 0.5f, 0.5f, 1f, 0.5f, 1f }; public static int Slot(Skill s) { return (int)s / 2; } public static float Damage(Skill s, bool c) { return (c ? CorruptedDamage : ControlledDamage)[(int)s]; } public static float Proc(Skill s, bool c) { return (c ? CorruptedProc : ControlledProc)[(int)s]; } public static float Cycle(Skill s, bool c) { switch (s) { default: return 0.25f; case Skill.Displace: return 0.18f; case Skill.Unleash: if (!c) { return 0.6f; } return 0.5f; case Skill.Lash: if (!c) { return 0.5f; } return 0.4f; case Skill.Impale: if (!c) { return 0.8f; } return 0.5f; } } public static float Scaled(float time, float speed) { return time / Math.Max(0.01f, speed); } public static float Pierce(int hit) { return (float)Math.Pow(0.7, hit); } public static float Meter(float current, float delta, float min, float max) { return Math.Max(min, Math.Min(max, current + delta)); } public static int ClampStock(int stock, int max) { return Math.Max(0, Math.Min(stock, max)); } public static float LaunchScale(float speed, float baseSpeed) { return Math.Max(0.75f, Math.Min(1.5f, speed / Math.Max(0.01f, baseSpeed))); } public static bool InArc(float dot, float distance) { if (distance <= 8f) { return dot >= (float)Math.Cos(Math.PI * 5.0 / 18.0); } return false; } public static float PulseTime(Skill s, bool c, int index) { if (s != Skill.Undertow) { return 0.25f * (float)index; } if (!c) { return 0.15f + 0.5f * (float)(index + 1); } return 0.35f; } public static int Pulses(Skill s, bool c) { if (s != Skill.Undertow) { return 3; } if (!c) { return 6; } return 1; } } internal static class Combat { internal static readonly Stack<Collider[]> Colliders = new Stack<Collider[]>(); internal static readonly Stack<HashSet<HealthComponent>> Sets = new Stack<HashSet<HealthComponent>>(); internal static Collider[] Rent() { if (Colliders.Count <= 0) { return (Collider[])(object)new Collider[256]; } return Colliders.Pop(); } internal static HashSet<HealthComponent> RentSet() { if (Sets.Count <= 0) { return new HashSet<HealthComponent>(); } return Sets.Pop(); } internal static void Return(Collider[] b, HashSet<HealthComponent> h) { Array.Clear(b, 0, b.Length); h.Clear(); if (Colliders.Count < 32) { Colliders.Push(b); } if (Sets.Count < 32) { Sets.Push(h); } } internal static DamageTypeCombo Type(Skill s, bool c) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) DamageTypeCombo result = DamageTypeCombo.op_Implicit((DamageType)0); result.damageSource = (DamageSource)(byte)(1 << Balance.Slot(s)); DamageAPI.AddModdedDamageType(ref result, Registry.Tags[(int)s, c ? 1u : 0u]); return result; } internal static bool Hostile(CharacterBody owner, HealthComponent hc) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)hc) && hc.alive && Object.op_Implicit((Object)(object)hc.body) && Object.op_Implicit((Object)(object)hc.body.teamComponent) && hc.body.teamComponent.teamIndex != owner.teamComponent.teamIndex) { return (Object)(object)((Component)hc).gameObject != (Object)(object)((Component)owner).gameObject; } return false; } internal static bool Visible(Vector3 origin, Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) LayerIndex world = LayerIndex.world; return !Physics.Linecast(origin, point, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1); } internal static void Hit(CharacterBody owner, HealthComponent hc, Vector3 point, float damage, float proc, Skill s, bool c, bool crit, GameObject inflictor, ProcChainMask mask = default(ProcChainMask)) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Hostile(owner, hc)) { DamageInfo val = new DamageInfo { attacker = ((Component)owner).gameObject, inflictor = inflictor, damage = damage, crit = crit, position = point, procCoefficient = proc, procChainMask = mask, damageType = Type(s, c), damageColorIndex = (DamageColorIndex)0 }; hc.TakeDamage(val); GlobalEventManager.instance.OnHitEnemy(val, ((Component)hc).gameObject); GlobalEventManager.instance.OnHitAll(val, ((Component)hc).gameObject); Telemetry.Hit(s, c, val); Visuals.Emit(point, point, 0.25f, VisualKind.Puncture, 0.12f, c); } } internal static int Area(CharacterBody owner, Vector3 origin, float radius, float damage, float proc, Skill s, bool c, Vector3? forward = null) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)owner)) { return 0; } Collider[] array = Rent(); HashSet<HealthComponent> hashSet = RentSet(); Collider[] array2 = array; LayerIndex entityPrecise = LayerIndex.entityPrecise; int num = Physics.OverlapSphereNonAlloc(origin, radius, array2, LayerMask.op_Implicit(((LayerIndex)(ref entityPrecise)).mask), (QueryTriggerInteraction)2); if (num == array.Length) { entityPrecise = LayerIndex.entityPrecise; array = Physics.OverlapSphere(origin, radius, LayerMask.op_Implicit(((LayerIndex)(ref entityPrecise)).mask), (QueryTriggerInteraction)2); num = array.Length; } int num2 = 0; for (int i = 0; i < num; i++) { HurtBox val = (Object.op_Implicit((Object)(object)array[i]) ? ((Component)array[i]).GetComponent<HurtBox>() : null); HealthComponent val2 = (Object.op_Implicit((Object)(object)val) ? val.healthComponent : null); if (Hostile(owner, val2) && !hashSet.Contains(val2)) { Vector3 val3 = array[i].ClosestPoint(origin); Vector3 val4 = val3 - origin; if ((!forward.HasValue || Balance.InArc(Vector3.Dot(forward.Value, ((Vector3)(ref val4)).normalized), ((Vector3)(ref val4)).magnitude)) && Visible(origin, val3)) { hashSet.Add(val2); Hit(owner, val2, val3, damage, proc, s, c, owner.RollCrit(), ((Component)owner).gameObject); num2++; } } } Return(array, hashSet); Telemetry.Event(s, c, "pulse", num2); return num2; } internal static Vector3 AimPoint(Ray aim, float range) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Ray val = aim; LayerIndex world = LayerIndex.world; RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(val, ref val2, range, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { return ((Ray)(ref aim)).GetPoint(range); } return ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.1f; } internal static void Pull(CharacterBody owner, Vector3 center, float radius, float dt) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Rent(); HashSet<HealthComponent> hashSet = RentSet(); LayerIndex entityPrecise = LayerIndex.entityPrecise; int num = Physics.OverlapSphereNonAlloc(center, radius, array, LayerMask.op_Implicit(((LayerIndex)(ref entityPrecise)).mask), (QueryTriggerInteraction)2); for (int i = 0; i < num; i++) { HurtBox val = (Object.op_Implicit((Object)(object)array[i]) ? ((Component)array[i]).GetComponent<HurtBox>() : null); HealthComponent val2 = (Object.op_Implicit((Object)(object)val) ? val.healthComponent : null); if (!Hostile(owner, val2) || hashSet.Contains(val2)) { continue; } hashSet.Add(val2); CharacterBody body = val2.body; if (!body.isBoss && !body.isChampion && Object.op_Implicit((Object)(object)body.characterMotor) && Object.op_Implicit((Object)(object)body.rigidbody) && !(body.rigidbody.mass > 300f) && Visible(center, body.corePosition)) { Vector3 val3 = center - body.corePosition; float magnitude = ((Vector3)(ref val3)).magnitude; if (!(magnitude < 1f)) { float num2 = Vector3.Dot(body.characterMotor.velocity, ((Vector3)(ref val3)).normalized); float num3 = 4f * Mathf.Clamp01((magnitude - 1f) / 2f); float num4 = Mathf.Min(Mathf.Max(0f, num3 - num2), 12f * dt) * Mathf.Clamp01(100f / body.rigidbody.mass); val2.TakeDamageForce(((Vector3)(ref val3)).normalized * num4 * body.rigidbody.mass, true, false); } } } Return(array, hashSet); } internal static Vector3 BlinkEndpoint(CharacterBody body, Vector3 direction, float range) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: 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_023c: Unknown result type (might be due to invalid IL or missing references) //IL_023f: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Invalid comparison between Unknown and I4 //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) CapsuleCollider component = ((Component)body).GetComponent<CapsuleCollider>(); if (!Object.op_Implicit((Object)(object)component)) { return ((Component)body).transform.position; } Vector3 val = ((Component)component).transform.TransformPoint(component.center); float num = component.radius * Mathf.Max(Mathf.Abs(((Component)component).transform.lossyScale.x), Mathf.Abs(((Component)component).transform.lossyScale.z)); float num2 = Mathf.Max(0f, component.height * Mathf.Abs(((Component)component).transform.lossyScale.y) * 0.5f - num); Vector3 val2 = val + Vector3.up * num2; Vector3 val3 = val - Vector3.up * num2; float num3 = range; LayerIndex world = LayerIndex.world; RaycastHit val4 = default(RaycastHit); if (Physics.CapsuleCast(val2, val3, num, direction, ref val4, range, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { num3 = Mathf.Max(0f, ((RaycastHit)(ref val4)).distance - 0.08f); } while (num3 > 0.01f) { Vector3 val5 = val2 + direction * num3; Vector3 val6 = val3 + direction * num3; world = LayerIndex.world; if (!Physics.CheckCapsule(val5, val6, num, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { break; } num3 = Mathf.Max(0f, num3 - 0.1f); } Collider[] array = Physics.OverlapCapsule(val, val + direction * num3, num + num2, -1, (QueryTriggerInteraction)2); for (int i = 1; i <= Mathf.CeilToInt(num3 / 0.1f); i++) { float num4 = Mathf.Min(num3, (float)i * 0.1f); Vector3 val7 = val + direction * num4; bool flag = false; Collider[] array2 = array; for (int j = 0; j < array2.Length; j++) { MapZone component2 = ((Component)array2[j]).GetComponent<MapZone>(); if (Object.op_Implicit((Object)(object)component2)) { bool flag2 = component2.IsPointInsideMapZone(val7); if ((int)component2.triggerType == 1 && flag2) { flag = true; } if ((int)component2.triggerType == 0 && component2.IsPointInsideMapZone(val) && !flag2) { flag = true; } } } if (flag) { num3 = Mathf.Max(0f, num4 - 0.1f); break; } } return ((Component)body).transform.position + direction * num3; } internal static void Path(CharacterBody owner, Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) Vector3 val = b - a; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return; } Collider[] array = Rent(); HashSet<HealthComponent> hashSet = RentSet(); LayerIndex entityPrecise = LayerIndex.entityPrecise; int num = Physics.OverlapCapsuleNonAlloc(a, b, 0.65f, array, LayerMask.op_Implicit(((LayerIndex)(ref entityPrecise)).mask), (QueryTriggerInteraction)2); for (int i = 0; i < num; i++) { HurtBox val2 = (Object.op_Implicit((Object)(object)array[i]) ? ((Component)array[i]).GetComponent<HurtBox>() : null); HealthComponent val3 = (Object.op_Implicit((Object)(object)val2) ? val2.healthComponent : null); if (Hostile(owner, val3) && !hashSet.Contains(val3)) { Vector3 point = array[i].ClosestPoint(a + val * Mathf.Clamp01(Vector3.Dot(((Component)val2).transform.position - a, val) / ((Vector3)(ref val)).sqrMagnitude)); if (Visible(a, point)) { hashSet.Add(val3); Hit(owner, val3, point, owner.damage * 2f, 0.5f, Skill.Displace, c: true, owner.RollCrit(), ((Component)owner).gameObject); } } } Return(array, hashSet); } } internal static class Pairing { private struct StockSnapshot { private readonly GenericSkill slot; private readonly AlternateSkillDef before; private readonly int stock; private readonly float clock; internal StockSnapshot(GenericSkill slot) { this.slot = slot; before = (Object.op_Implicit((Object)(object)slot) ? (slot.skillDef as AlternateSkillDef) : null); stock = (Object.op_Implicit((Object)(object)slot) ? slot.stock : 0); clock = (Object.op_Implicit((Object)(object)slot) ? slot.rechargeStopwatch : 0f); } internal void Restore() { if (Object.op_Implicit((Object)(object)slot) && Object.op_Implicit((Object)(object)before) && before.choice >= Skill.Quarantine) { AlternateSkillDef alternateSkillDef = slot.skillDef as AlternateSkillDef; if (Object.op_Implicit((Object)(object)alternateSkillDef) && alternateSkillDef.choice == before.choice) { slot.stock = Balance.ClampStock(stock, slot.maxStock); slot.rechargeStopwatch = clock; Telemetry.Event(before.choice, alternateSkillDef.corrupted, "transform-stock", stock); } } } } internal static void Install() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown CorruptMode.OnEnter += new hook_OnEnter(Enter); CorruptMode.OnExit += new hook_OnExit(Exit); } internal static void Uninstall() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown CorruptMode.OnEnter -= new hook_OnEnter(Enter); CorruptMode.OnExit -= new hook_OnExit(Exit); } private static SkillDef Pair(GenericSkill slot, SkillDef vanilla) { AlternateSkillDef alternateSkillDef = ((slot != null) ? slot.baseSkill : null) as AlternateSkillDef; if (!Object.op_Implicit((Object)(object)alternateSkillDef)) { return vanilla; } return (SkillDef)(object)Registry.Defs[(int)alternateSkillDef.choice, 1]; } private static void Enter(orig_OnEnter orig, CorruptMode self) { SkillLocator component = ((Component)((EntityState)self).outer).GetComponent<SkillLocator>(); StockSnapshot stockSnapshot = new StockSnapshot(Object.op_Implicit((Object)(object)component) ? component.special : null); if (Object.op_Implicit((Object)(object)component)) { self.primaryOverrideSkillDef = Pair(component.primary, self.primaryOverrideSkillDef); self.secondaryOverrideSkillDef = Pair(component.secondary, self.secondaryOverrideSkillDef); self.utilityOverrideSkillDef = Pair(component.utility, self.utilityOverrideSkillDef); self.specialOverrideSkillDef = Pair(component.special, self.specialOverrideSkillDef); } orig.Invoke(self); stockSnapshot.Restore(); } private static void Exit(orig_OnExit orig, CorruptMode self) { SkillLocator component = ((Component)((EntityState)self).outer).GetComponent<SkillLocator>(); StockSnapshot stockSnapshot = new StockSnapshot(Object.op_Implicit((Object)(object)component) ? component.special : null); orig.Invoke(self); stockSnapshot.Restore(); } } [BepInPlugin("com.rodanius.voidfiendalternates", "Void Fiend Alternates", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "com.rodanius.voidfiendalternates"; public const string Version = "0.1.0"; internal static Plugin Instance; private bool saveEnabled; internal static ConfigEntry<bool> ReducedFlash; internal static ConfigEntry<bool> LowDensity; internal static ConfigEntry<bool> Diagnostics; private void Awake() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown Instance = this; ReducedFlash = ((BaseUnityPlugin)this).Config.Bind<bool>("Accessibility", "ReducedFlashing", true, "Dim short hit flashes. No screen shake is added."); LowDensity = ((BaseUnityPlugin)this).Config.Bind<bool>("Accessibility", "LowEffectDensity", false, "Reduce decorative segments; preserve attack boundaries."); Diagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "Telemetry", false, "Write aggregate combat samples every 30 seconds; no player names or inventory changes."); ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(Collect); Pairing.Install(); SaveWire.Install(); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(Audit)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Void Fiend Alternates 0.1.0; immutable balance spec-1.0-r1; Windows runtime acceptance pending."); } private void Collect(AddContentPackProviderDelegate add) { add.Invoke((IContentPackProvider)(object)new Content()); } private void Audit() { Content.Audit(); if (Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.ProperSave")) { SaveBridge.Install(); saveEnabled = true; } } private void OnDestroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ContentManager.collectContentPackProviders -= new CollectContentPackProvidersDelegate(Collect); RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(Audit)); Pairing.Uninstall(); SaveWire.Uninstall(); if (saveEnabled) { SaveBridge.Uninstall(); } } internal static void Log(string s) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)s); } internal static void Warn(string s) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)s); } } public sealed class Content : IContentPackProvider { private readonly ContentPack pack = new ContentPack(); public string identifier => "com.rodanius.voidfiendalternates"; public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args) { typeof(ContentPack).GetProperty("identifier").SetValue(pack, identifier, null); AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC1/VoidSurvivor/VoidSurvivorBody.prefab"); yield return handle; if (!Object.op_Implicit((Object)(object)handle.Result)) { throw new InvalidOperationException("VoidSurvivorBody missing: unsupported game content."); } Registry.Build(pack, handle.Result); 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; } internal static void Audit() { Registry.Audit(); } } internal static class Projectiles { internal static readonly GameObject[] Prefabs = (GameObject[])(object)new GameObject[9]; internal static void Build(ContentPack pack) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown GameObject val = new GameObject("VFA Prefabs"); val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); for (int i = 0; i < Prefabs.Length; i++) { GameObject val2 = new GameObject("VoidFiendAltProjectile" + i); val2.transform.SetParent(val.transform); val2.AddComponent<NetworkIdentity>(); Rigidbody obj = val2.AddComponent<Rigidbody>(); obj.isKinematic = true; obj.useGravity = false; val2.AddComponent<TeamFilter>(); ProjectileController obj2 = val2.AddComponent<ProjectileController>(); obj2.allowPrediction = false; obj2.doNotPerformImpactOnCollision = true; obj2.procCoefficient = i switch { 3 => 0.5f, 1 => 0.55f, _ => 1f, }; val2.AddComponent<ProjectileDamage>(); ProjectileNetworkTransform obj3 = val2.AddComponent<ProjectileNetworkTransform>(); obj3.allowClientsideCollision = false; obj3.positionTransmitInterval = 0.033f; val2.AddComponent<VoidProjectile>().mode = i; Visuals.ProjectileShape(val2, i); PrefabAPI.RegisterNetworkPrefab(val2); Prefabs[i] = val2; } pack.projectilePrefabs.Add(Prefabs); } internal static void Fire(CharacterBody body, int mode, Ray aim, float damage, bool crit, ProcChainMask mask = default(ProcChainMask)) { //IL_003a: 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_0057: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } if (mode < 6) { Vector3 origin = ((Ray)(ref aim)).origin; LayerIndex world = LayerIndex.world; if (Physics.CheckSphere(origin, 0.05f, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { return; } } ProjectileManager.instance.FireProjectile(new FireProjectileInfo { projectilePrefab = Prefabs[mode], position = ((Ray)(ref aim)).origin, rotation = Util.QuaternionSafeLookRotation(((Ray)(ref aim)).direction), owner = ((Component)body).gameObject, damage = damage, crit = crit, force = 0f, procChainMask = mask }); } } public sealed class VoidProjectile : MonoBehaviour { public int mode; internal static readonly HashSet<VoidProjectile> Active = new HashSet<VoidProjectile>(); private ProjectileController controller; private ProjectileDamage damage; private CharacterBody owner; private float age; private float traveled; private int pulse; private bool ended; private readonly HashSet<HealthComponent> hit = new HashSet<HealthComponent>(); private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[128]; private static readonly float[] Speeds = new float[9] { 110f, 130f, 120f, 95f, 95f, 95f, 0f, 0f, 0f }; private static readonly float[] Ranges = new float[9] { 100f, 65f, 70f, 35f, 40f, 35f, 0f, 0f, 0f }; private static readonly IComparer<RaycastHit> ByDistance = Comparer<RaycastHit>.Create((RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); private void OnEnable() { Active.Add(this); } private void OnDisable() { Active.Remove(this); } internal SaveBridge.FieldRecord Save() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (mode < 6 || !Object.op_Implicit((Object)(object)owner) || ended) { return null; } return new SaveBridge.FieldRecord { Owner = SaveBridge.OwnerId(owner), Mode = mode, X = ((Component)this).transform.position.x, Y = ((Component)this).transform.position.y, Z = ((Component)this).transform.position.z, Damage = damage.damage, Age = age, Pulse = pulse, Crit = damage.crit }; } internal void RestoreClock(float savedAge, int savedPulse) { age = savedAge; pulse = savedPulse; } private void Start() { controller = ((Component)this).GetComponent<ProjectileController>(); damage = ((Component)this).GetComponent<ProjectileDamage>(); owner = (Object.op_Implicit((Object)(object)controller.owner) ? controller.owner.GetComponent<CharacterBody>() : null); } private void FixedUpdate() { //IL_009b: 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) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || ended) { return; } if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)owner.healthComponent) || !owner.healthComponent.alive) { End(); return; } age += Time.fixedDeltaTime; if (mode >= 6) { Field(); return; } float num = Mathf.Min(Speeds[mode] * Time.fixedDeltaTime, Ranges[mode] - traveled); Vector3 position = ((Component)this).transform.position; Vector3 forward = ((Component)this).transform.forward; LayerIndex val = LayerIndex.world; int num2 = LayerMask.op_Implicit(((LayerIndex)(ref val)).mask); int num3; if (mode >= 4) { num3 = 0; } else { val = LayerIndex.entityPrecise; num3 = LayerMask.op_Implicit(((LayerIndex)(ref val)).mask); } int num4 = num2 | num3; int num5 = Physics.SphereCastNonAlloc(position, 0.225f, forward, hits, num, num4, (QueryTriggerInteraction)2); RaycastHit[] array = hits; if (num5 == hits.Length) { array = Physics.SphereCastAll(position, 0.225f, forward, num, num4, (QueryTriggerInteraction)2); num5 = array.Length; } Array.Sort(array, 0, num5, ByDistance); for (int i = 0; i < num5; i++) { RaycastHit val2 = array[i]; HurtBox component = ((Component)((RaycastHit)(ref val2)).collider).GetComponent<HurtBox>(); if (Object.op_Implicit((Object)(object)component)) { HealthComponent healthComponent = component.healthComponent; if (Combat.Hostile(owner, healthComponent) && !hit.Contains(healthComponent)) { if (mode == 3) { Impact(position + forward * ((RaycastHit)(ref val2)).distance); return; } Combat.Hit(owner, healthComponent, ((RaycastHit)(ref val2)).point, damage.damage * ((mode < 2) ? Balance.Pierce(hit.Count) : 1f), (mode == 1) ? 0.55f : 1f, (mode >= 2) ? Skill.Condense : Skill.Impale, mode == 1, damage.crit, ((Component)this).gameObject, controller.procChainMask); hit.Add(healthComponent); if (mode == 2 || hit.Count >= 3) { End(); return; } } } else { val = LayerIndex.world; if ((LayerMask.op_Implicit(((LayerIndex)(ref val)).mask) & (1 << ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer)) != 0) { Impact(position + forward * Mathf.Max(0f, ((RaycastHit)(ref val2)).distance - 0.02f)); return; } } } traveled += num; ((Component)this).transform.position = position + forward * num; if (traveled >= Ranges[mode] - 0.001f) { Impact(((Component)this).transform.position); } } private void Impact(Vector3 p) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!ended) { if (mode >= 3 && mode <= 5) { Projectiles.Fire(owner, (mode == 3) ? 8 : ((mode == 4) ? 6 : 7), new Ray(p, Vector3.forward), damage.damage, damage.crit, controller.procChainMask); } Visuals.Emit(p, p, 0.3f, VisualKind.Puncture, 0.12f, mode % 2 == 1); End(); } } private void Field() { //IL_0065: 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) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) bool num = mode != 8; bool c = mode == 7; Skill s = (num ? Skill.Undertow : Skill.Condense); float radius = ((mode == 6) ? 8 : ((mode == 7) ? 10 : 3)); if (num && age >= ((mode == 6) ? 0.15f : 0f)) { Combat.Pull(owner, ((Component)this).transform.position, radius, Time.fixedDeltaTime); } int num2 = ((mode == 6) ? 6 : ((mode == 7) ? 1 : 3)); while (pulse < num2 && age + 1E-05f >= Balance.PulseTime(s, c, pulse)) { Combat.Area(owner, ((Component)this).transform.position, radius, damage.damage, (mode == 6) ? 0.2f : ((mode == 7) ? 1f : 0.5f), s, mode != 6); Visuals.Emit(((Component)this).transform.position, ((Component)this).transform.position, radius, VisualKind.Ring, 0.15f, mode != 6); pulse++; } if (pulse >= num2) { End(); } } private void End() { if (!ended) { ended = true; NetworkServer.Destroy(((Component)this).gameObject); } } } public sealed class AlternateSkillDef : SkillDef { public Skill choice; public bool corrupted; } internal static class Registry { internal static readonly AlternateSkillDef[,] Defs = new AlternateSkillDef[8, 2]; internal static readonly ModdedDamageType[,] Tags = new ModdedDamageType[8, 2]; private static SkillFamily[] families; private static SkillDef[][] originals; private static readonly Type[,] States = new Type[8, 2] { { typeof(Impale), typeof(CorruptedImpale) }, { typeof(Lash), typeof(CorruptedLash) }, { typeof(Undertow), typeof(CorruptedUndertow) }, { typeof(Condense), typeof(CorruptedCondense) }, { typeof(Displace), typeof(CorruptedDisplace) }, { typeof(Breach), typeof(CorruptedBreach) }, { typeof(Quarantine), typeof(CorruptedQuarantine) }, { typeof(Unleash), typeof(CorruptedUnleash) } }; private static readonly string[] Descriptions = new string[8] { "Pierce three enemies for <style=cIsDamage>420% / 294% / 205.8%</style> damage. 1.0 proc per target; 100m range; 0.8s cycle. <style=cIsVoid>CORRUPTED:</style> Three 220% spikes, 70% retained per pierce; 0.55 proc per hit; 65m range; 0.5s burst; 85% walking speed.", "Whip one enemy for <style=cIsDamage>280%</style> damage. 18m reach; 1.0 proc; 0.5s cycle. <style=cIsVoid>CORRUPTED:</style> Sweep a 100° arc to 8m for 700% per enemy; 0.60 proc; 0.4s cycle.", "Create an 8m pulling field: six <style=cIsDamage>120%</style> pulses over 3 seconds; 0.20 proc per pulse. 7s recharge. <style=cIsVoid>CORRUPTED:</style> Pull for 0.35s then implode once for 1000% in 10m; 1.0 proc. Bosses resist the pull.", "Fire one precise <style=cIsDamage>900%</style> bolt; 70m range; 1.0 proc. 6s recharge. <style=cIsVoid>CORRUPTED:</style> Anchor three 600% pulses at the impact point, 0.25s apart; 3m radius; 0.50 proc each. Moving targets can escape.", "<style=cIsUtility>Agile.</style> Store two collision-safe 12m blinks. 7s recharge per stock. Protection only during traversal, at most 0.12s; no cleanse. <style=cIsVoid>CORRUPTED:</style> Blink 16m, dealing 200% along the actual path once per enemy; 0.50 proc.", "<style=cIsUtility>Agile.</style> Blast enemies at departure for <style=cIsDamage>400%</style> in 6m and leap backward/upward. <style=cIsVoid>CORRUPTED:</style> Leap forward and impact for 800% in 8m. 1.0 proc; 8s recharge; at most 0.35s opening protection. Momentum scales 0.75–1.5× with movement speed.", "<style=cIsUtility>Agile.</style> Gain barrier equal to <style=cIsHealing>25% maximum health + shield</style>; vent 25 corruption, respecting its floor. <style=cIsVoid>CORRUPTED:</style> Also blast for 600% in 8m; 0.50 proc. 10s recharge. <style=cIsUtility>Shared stock and recharge do not reset on transformation.</style>", "<style=cIsUtility>Agile.</style> Channel for 0.6s, then gain <style=cIsVoid>35 corruption</style>. <style=cIsVoid>CORRUPTED:</style> Wind up 0.5s, blast for 2400% in 12m with 1.0 proc, then vent 35 corruption. 12s recharge. Stock is spent on activation, including canceled channels. <style=cIsUtility>Shared stock and recharge do not reset on transformation.</style>" }; internal static void Build(ContentPack pack, GameObject prefab) { //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Expected O, but got Unknown //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) SkillLocator component = prefab.GetComponent<SkillLocator>(); GenericSkill[] array = (GenericSkill[])(object)new GenericSkill[4] { component.primary, component.secondary, component.utility, component.special }; families = array.Select((GenericSkill x) => x.skillFamily).ToArray(); originals = families.Select((SkillFamily f) => f.variants.Select((Variant v) => v.skillDef).ToArray()).ToArray(); for (int num = 0; num < 8; num++) { for (int num2 = 0; num2 < 2; num2++) { AlternateSkillDef alternateSkillDef = ScriptableObject.CreateInstance<AlternateSkillDef>(); alternateSkillDef.choice = (Skill)num; alternateSkillDef.corrupted = num2 == 1; string[] obj = new string[5] { "VoidFiendAlt.", (new string[4] { "Primary", "Secondary", "Utility", "Special" })[num / 2], ".", null, null }; Skill skill = (Skill)num; obj[3] = skill.ToString(); obj[4] = ((num2 == 1) ? ".Corrupted" : ""); ((Object)alternateSkillDef).name = string.Concat(obj); ((SkillDef)alternateSkillDef).skillName = ((Object)alternateSkillDef).name; ((SkillDef)alternateSkillDef).skillNameToken = ((SkillDef)alternateSkillDef).skillName + ".NAME"; ((SkillDef)alternateSkillDef).skillDescriptionToken = ((SkillDef)alternateSkillDef).skillName + ".DESC"; string skillNameToken = ((SkillDef)alternateSkillDef).skillNameToken; string obj2 = ((num2 == 1) ? "Corrupted " : ""); skill = (Skill)num; LanguageAPI.Add(skillNameToken, obj2 + skill); LanguageAPI.Add(((SkillDef)alternateSkillDef).skillDescriptionToken, Descriptions[num]); ((SkillDef)alternateSkillDef).activationStateMachineName = array[num / 2].skillFamily.variants[0].skillDef.activationStateMachineName; ((SkillDef)alternateSkillDef).activationState = new SerializableEntityStateType(States[num, num2]); ((SkillDef)alternateSkillDef).baseMaxStock = ((num != 4) ? 1 : 2); ((SkillDef)alternateSkillDef).baseRechargeInterval = Balance.Cooldowns[num]; ((SkillDef)alternateSkillDef).rechargeStock = 1; ((SkillDef)alternateSkillDef).requiredStock = ((num >= 2) ? 1 : 0); ((SkillDef)alternateSkillDef).stockToConsume = ((num >= 2) ? 1 : 0); ((SkillDef)alternateSkillDef).fullRestockOnAssign = num < 6; ((SkillDef)alternateSkillDef).dontAllowPastMaxStocks = true; ((SkillDef)alternateSkillDef).resetCooldownTimerOnUse = false; ((SkillDef)alternateSkillDef).beginSkillCooldownOnSkillEnd = false; ((SkillDef)alternateSkillDef).isCombatSkill = num != 4; ((SkillDef)alternateSkillDef).cancelSprintingOnActivation = num < 4; ((SkillDef)alternateSkillDef).canceledFromSprinting = num < 2; ((SkillDef)alternateSkillDef).mustKeyPress = num >= 2; ((SkillDef)alternateSkillDef).interruptPriority = (InterruptPriority)0; ((SkillDef)alternateSkillDef).icon = Visuals.Icon((Skill)num, num2 == 1); ((SkillDef)alternateSkillDef).autoHandleLuminousShot = num / 2 == 1; Defs[num, num2] = alternateSkillDef; Tags[num, num2] = DamageAPI.ReserveDamageType(); } } for (int num3 = 0; num3 < 4; num3++) { List<Variant> list = new List<Variant>(families[num3].variants); for (int num4 = 0; num4 < 2; num4++) { AlternateSkillDef alternateSkillDef2 = Defs[num3 * 2 + num4, 0]; Variant item = new Variant { skillDef = (SkillDef)(object)alternateSkillDef2 }; ((Variant)(ref item)).viewableNode = new Node(((SkillDef)alternateSkillDef2).skillNameToken, false, (Node)null); list.Add(item); } families[num3].variants = list.ToArray(); } pack.skillDefs.Add(Defs.Cast<AlternateSkillDef>().Cast<SkillDef>().ToArray()); pack.entityStateTypes.Add(States.Cast<Type>().ToArray()); Visuals.Build(pack); Projectiles.Build(pack); } internal static void Audit() { int i; for (i = 0; i < 4; i++) { if (originals[i].Any((SkillDef x) => !families[i].variants.Any((Variant v) => (Object)(object)v.skillDef == (Object)(object)x))) { throw new InvalidOperationException("Vanilla family entry removed"); } } Plugin.Log("Catalog audit: 8 alternate choices, 16 states; original family entries preserved. Game " + RoR2Application.GetBuildId()); } } internal static class SaveBridge { [Serializable] public sealed class FieldRecord { public string Owner; public int Mode; public int Pulse; public float X; public float Y; public float Z; public float Damage; public float Age; public bool Crit; } [Serializable] public sealed class Fields { public string Scene; public List<FieldRecord> Entries = new List<FieldRecord>(); } [Serializable] public sealed class Record { public string User; public int Choice; public int Stock; public float Clock; } private const string Key = "com.rodanius.voidfiendalternates.special.v1"; private const string FieldsKey = "com.rodanius.voidfiendalternates.fields.v1"; private static bool installed; internal static string OwnerId(CharacterBody b) { foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances.master) && (Object)(object)readOnlyInstances.master.GetBody() == (Object)(object)b) { return Id(readOnlyInstances); } } return null; } [MethodImpl(MethodImplOptions.NoInlining)] internal static void Install() { if (!installed) { installed = true; SaveFile.OnGatherSaveData += Gather; Loading.OnLoadingEnded += Loaded; } } [MethodImpl(MethodImplOptions.NoInlining)] internal static void Uninstall() { if (installed) { installed = false; SaveFile.OnGatherSaveData -= Gather; Loading.OnLoadingEnded -= Loaded; } } private static string Id(NetworkUser u) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) return u.id.value + ":" + u.id.strValue + ":" + u.id.subId; } private static void Gather(Dictionary<string, object> data) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } List<Record> list = new List<Record>(); foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { CharacterBody val = (Object.op_Implicit((Object)(object)readOnlyInstances.master) ? readOnlyInstances.master.GetBody() : null); GenericSkill val2 = (Object.op_Implicit((Object)(object)val) ? val.skillLocator.special : null); AlternateSkillDef alternateSkillDef = (Object.op_Implicit((Object)(object)val2) ? (val2.skillDef as AlternateSkillDef) : null); if (Object.op_Implicit((Object)(object)alternateSkillDef) && alternateSkillDef.choice >= Skill.Quarantine) { list.Add(new Record { User = Id(readOnlyInstances), Choice = (int)alternateSkillDef.choice, Stock = val2.stock, Clock = val2.rechargeStopwatch }); } } data["com.rodanius.voidfiendalternates.special.v1"] = JsonConvert.SerializeObject((object)list); Fields fields = new Fields(); Scene activeScene = SceneManager.GetActiveScene(); fields.Scene = ((Scene)(ref activeScene)).name; Fields fields2 = fields; foreach (VoidProjectile item in VoidProjectile.Active) { FieldRecord fieldRecord = (Object.op_Implicit((Object)(object)item) ? item.Save() : null); if (fieldRecord != null && fieldRecord.Owner != null) { fields2.Entries.Add(fieldRecord); } } data["com.rodanius.voidfiendalternates.fields.v1"] = JsonConvert.SerializeObject((object)fields2); } private static void Loaded(SaveFile file) { if (!NetworkServer.active) { return; } try { string text = file.TryGetModdedData<string>("com.rodanius.voidfiendalternates.special.v1"); if (!string.IsNullOrEmpty(text)) { List<Record> list = JsonConvert.DeserializeObject<List<Record>>(text); if (list == null || list.Count > 64) { throw new InvalidOperationException("Invalid saved player count"); } ((MonoBehaviour)Plugin.Instance).StartCoroutine(Restore(list)); string text2 = file.TryGetModdedData<string>("com.rodanius.voidfiendalternates.fields.v1"); if (!string.IsNullOrEmpty(text2)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(RestoreFields(JsonConvert.DeserializeObject<Fields>(text2))); } } } catch (Exception ex) { Plugin.Warn("Alternate special checkpoint rejected: " + ex.Message); } } private static IEnumerator Restore(List<Record> records) { for (int attempt = 0; attempt < 100; attempt++) { if (records.Count <= 0) { break; } for (int num = records.Count - 1; num >= 0; num--) { Record record = records[num]; if (record.Choice < 6 || record.Choice > 7 || record.Stock < 0 || record.Clock < 0f || float.IsNaN(record.Clock) || float.IsInfinity(record.Clock)) { records.RemoveAt(num); } else { foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { if (Id(readOnlyInstances) != record.User) { continue; } CharacterBody val = (Object.op_Implicit((Object)(object)readOnlyInstances.master) ? readOnlyInstances.master.GetBody() : null); GenericSkill val2 = (Object.op_Implicit((Object)(object)val) ? val.skillLocator.special : null); AlternateSkillDef alternateSkillDef = (Object.op_Implicit((Object)(object)val2) ? (val2.skillDef as AlternateSkillDef) : null); if (Object.op_Implicit((Object)(object)alternateSkillDef)) { if (alternateSkillDef.choice == (Skill)record.Choice) { val2.stock = Balance.ClampStock(record.Stock, val2.maxStock); val2.rechargeStopwatch = Mathf.Min(record.Clock, val2.GetFinalRechargeInterval()); SaveWire.Send(readOnlyInstances, record.Choice, val2.stock, val2.rechargeStopwatch); } records.RemoveAt(num); break; } } } } yield return (object)new WaitForSeconds(0.1f); } if (records.Count > 0) { Plugin.Warn("Some saved alternate stocks could not be matched to a spawned body."); } } private static IEnumerator RestoreFields(Fields fields) { if (fields == null || fields.Entries == null) { yield break; } string scene = fields.Scene; Scene activeScene = SceneManager.GetActiveScene(); if (scene != ((Scene)(ref activeScene)).name) { yield break; } for (int attempt = 0; attempt < 100; attempt++) { if (fields.Entries.Count <= 0) { break; } for (int num = fields.Entries.Count - 1; num >= 0; num--) { FieldRecord fieldRecord = fields.Entries[num]; if (fieldRecord.Mode < 6 || fieldRecord.Mode > 8 || fieldRecord.Pulse < 0 || fieldRecord.Pulse > 6 || fieldRecord.Age < 0f || fieldRecord.Age > 4f || fieldRecord.Damage < 0f || float.IsNaN(fieldRecord.Damage) || float.IsInfinity(fieldRecord.Damage) || float.IsNaN(fieldRecord.X + fieldRecord.Y + fieldRecord.Z + fieldRecord.Age) || float.IsInfinity(fieldRecord.X + fieldRecord.Y + fieldRecord.Z + fieldRecord.Age)) { fields.Entries.RemoveAt(num); } else { foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { if (!(Id(readOnlyInstances) != fieldRecord.Owner) && Object.op_Implicit((Object)(object)readOnlyInstances.master)) { CharacterBody body = readOnlyInstances.master.GetBody(); if (Object.op_Implicit((Object)(object)body)) { GameObject obj = Object.Instantiate<GameObject>(Projectiles.Prefabs[fieldRecord.Mode], new Vector3(fieldRecord.X, fieldRecord.Y, fieldRecord.Z), Quaternion.identity); ProjectileController component = obj.GetComponent<ProjectileController>(); component.SetOwner(((Component)body).gameObject); component.Networkowner = ((Component)body).gameObject; obj.GetComponent<TeamFilter>().teamIndex = body.teamComponent.teamIndex; ProjectileDamage component2 = obj.GetComponent<ProjectileDamage>(); component2.damage = fieldRecord.Damage; component2.crit = fieldRecord.Crit; obj.GetComponent<VoidProjectile>().RestoreClock(fieldRecord.Age, fieldRecord.Pulse); NetworkServer.Spawn(obj); fields.Entries.RemoveAt(num); break; } } } } } yield return (object)new WaitForSeconds(0.1f); } } } internal static class SaveWire { public sealed class Packet : MessageBase { public uint User; public int Choice; public int Stock; public float Clock; public override void Serialize(NetworkWriter w) { w.Write(User); w.Write(Choice); w.Write(Stock); w.Write(Clock); } public override void Deserialize(NetworkReader r) { User = r.ReadUInt32(); Choice = r.ReadInt32(); Stock = r.ReadInt32(); Clock = r.ReadSingle(); } } private const short Channel = 28291; private static readonly HashSet<NetworkClient> clients = new HashSet<NetworkClient>(); internal static void Install() { NetworkManagerSystem.onStartClientGlobal += Client; } internal static void Uninstall() { NetworkManagerSystem.onStartClientGlobal -= Client; foreach (NetworkClient client in clients) { if (client != null) { client.UnregisterHandler((short)28291); } } clients.Clear(); } private static void Client(NetworkClient c) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (c.handlers.ContainsKey(28291)) { Plugin.Warn("Save restore channel is occupied; remote special restore unavailable."); return; } c.RegisterHandler((short)28291, new NetworkMessageDelegate(Read)); clients.Add(c); } private static void Read(NetworkMessage m) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { return; } bool flag = false; foreach (NetworkClient client in clients) { if (client.connection == m.conn) { flag = true; } } if (!flag) { return; } Packet packet = m.ReadMessage<Packet>(); if (packet.Choice < 6 || packet.Choice > 7 || packet.Stock < 0 || packet.Clock < 0f || float.IsNaN(packet.Clock) || float.IsInfinity(packet.Clock)) { return; } foreach (LocalUser readOnlyLocalUsers in LocalUserManager.readOnlyLocalUsersList) { NetworkUser currentNetworkUser = readOnlyLocalUsers.currentNetworkUser; if (!Object.op_Implicit((Object)(object)currentNetworkUser)) { continue; } NetworkInstanceId netId = ((NetworkBehaviour)currentNetworkUser).netId; if (((NetworkInstanceId)(ref netId)).Value != packet.User || !Object.op_Implicit((Object)(object)currentNetworkUser.master)) { continue; } CharacterBody body = currentNetworkUser.master.GetBody(); if (Object.op_Implicit((Object)(object)body)) { GenericSkill special = body.skillLocator.special; AlternateSkillDef alternateSkillDef = special.skillDef as AlternateSkillDef; if (Object.op_Implicit((Object)(object)alternateSkillDef) && alternateSkillDef.choice == (Skill)packet.Choice) { special.stock = Balance.ClampStock(packet.Stock, special.maxStock); special.rechargeStopwatch = Mathf.Min(packet.Clock, special.GetFinalRechargeInterval()); } } } } internal static void Send(NetworkUser user, int choice, int stock, float clock) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && ((NetworkBehaviour)user).connectionToClient != null) { NetworkConnection connectionToClient = ((NetworkBehaviour)user).connectionToClient; Packet packet = new Packet(); NetworkInstanceId netId = ((NetworkBehaviour)user).netId; packet.User = ((NetworkInstanceId)(ref netId)).Value; packet.Choice = choice; packet.Stock = stock; packet.Clock = clock; connectionToClient.Send((short)28291, (MessageBase)(object)packet); } } } public abstract class AlternateState : BaseSkillState { protected float duration; protected bool committed; private int shots; private static readonly float[] BurstTimes = new float[3] { 0.05f, 0.17f, 0.29f }; private WalkSpeedPenaltyModifier walkPenalty; protected Ray aim; private Transform muzzle; protected abstract Skill Choice { get; } protected virtual bool Corrupted => false; protected virtual float CommitTime { get { if (Choice != Skill.Impale) { if (Choice != Skill.Lash) { return duration; } return duration * 0.35f; } return Balance.Scaled(0.2f, ((BaseState)this).attackSpeedStat); } } public override void OnEnter() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); aim = ((BaseState)this).GetAimRay(); duration = Balance.Scaled(Balance.Cycle(Choice, Corrupted), ((BaseState)this).attackSpeedStat); ((BaseState)this).StartAimMode(2f, false); EntityState obj = EntityStateCatalog.InstantiateState(typeof(FireHandBeam)); FireHandBeam val = (FireHandBeam)(object)((obj is FireHandBeam) ? obj : null); if (val != null && !string.IsNullOrEmpty(val.muzzle)) { muzzle = ((BaseState)this).FindModelChild(val.muzzle); } if (val != null && !string.IsNullOrEmpty(val.animationStateName)) { ((EntityState)this).PlayAnimation(val.animationLayerName, val.animationStateName, val.animationPlaybackRateParam, duration, 0f); } if (Choice == Skill.Impale && Corrupted && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { walkPenalty = ((EntityState)this).characterMotor.AddWalkSpeedPenalty(0.15f); } if (NetworkServer.active) { Telemetry.Event(Choice, Corrupted, "activation", ((BaseState)this).attackSpeedStat); } } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (Choice < Skill.Undertow && !committed && ((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).inputBank) && !((EntityState)this).inputBank.skill1.down) { ((EntityState)this).outer.SetNextStateToMain(); return; } if (Choice == Skill.Impale && Corrupted) { while (shots < 3 && ((EntityState)this).fixedAge >= Balance.Scaled(BurstTimes[shots], ((BaseState)this).attackSpeedStat)) { Commit(); shots++; committed = true; } } else if (!committed && ((EntityState)this).fixedAge >= CommitTime) { committed = true; Commit(); } if (((EntityState)this).fixedAge >= duration && ((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); } } protected virtual void Commit() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) Visuals.CastSound(((EntityState)this).gameObject, Choice, Corrupted); if (!NetworkServer.active) { return; } aim = ((BaseState)this).GetAimRay(); if (Object.op_Implicit((Object)(object)muzzle)) { Vector3 val = Combat.AimPoint(aim, 100f); Vector3 position = muzzle.position; Vector3 val2 = val - muzzle.position; aim = new Ray(position, ((Vector3)(ref val2)).normalized); } float damage = ((EntityState)this).characterBody.damage * Balance.Damage(Choice, Corrupted); float proc = Balance.Proc(Choice, Corrupted); switch (Choice) { case Skill.Impale: Projectiles.Fire(((EntityState)this).characterBody, Corrupted ? 1 : 0, aim, damage, ((BaseState)this).RollCrit()); break; case Skill.Condense: Projectiles.Fire(((EntityState)this).characterBody, Corrupted ? 3 : 2, aim, damage, ((BaseState)this).RollCrit()); break; case Skill.Undertow: Projectiles.Fire(((EntityState)this).characterBody, Corrupted ? 5 : 4, aim, damage, ((BaseState)this).RollCrit()); break; case Skill.Lash: { if (Corrupted) { Combat.Area(((EntityState)this).characterBody, ((Ray)(ref aim)).origin, 8f, damage, proc, Choice, c: true, ((Ray)(ref aim)).direction); Visuals.Emit(((Ray)(ref aim)).origin, ((Ray)(ref aim)).GetPoint(8f), 8f, VisualKind.Sweep, 0.18f, c: true); break; } Vector3 point = ((Ray)(ref aim)).GetPoint(18f); BulletAttack val3 = new BulletAttack { owner = ((EntityState)this).gameObject, weapon = ((EntityState)this).gameObject, origin = ((Ray)(ref aim)).origin, aimVector = ((Ray)(ref aim)).direction, bulletCount = 1u, damage = damage, procCoefficient = 1f, isCrit = ((BaseState)this).RollCrit(), maxDistance = 18f, radius = 0.6f, smartCollision = true, falloffModel = (FalloffModel)0, damageType = Combat.Type(Choice, c: false) }; LayerIndex val4 = LayerIndex.world; int num = LayerMask.op_Implicit(((LayerIndex)(ref val4)).mask); val4 = LayerIndex.entityPrecise; val3.stopperMask = LayerMask.op_Implicit(num | LayerMask.op_Implicit(((LayerIndex)(ref val4)).mask)); val3.Fire(); point = Combat.AimPoint(aim, 18f); Visuals.Emit(((Ray)(ref aim)).origin, point, 1f, VisualKind.Tendril, 0.15f, c: false); break; } case Skill.Quarantine: { float barrier = ((EntityState)this).healthComponent.barrier; ((EntityState)this).healthComponent.AddBarrier(0.25f * ((EntityState)this).healthComponent.fullCombinedHealth); Telemetry.Event(Choice, Corrupted, "barrier", ((EntityState)this).healthComponent.barrier - barrier); if (Corrupted) { Combat.Area(((EntityState)this).characterBody, ((EntityState)this).characterBody.corePosition, 8f, damage, proc, Choice, c: true); } Meter(-25f); Visuals.Emit(((EntityState)this).characterBody.corePosition, ((EntityState)this).characterBody.corePosition, Corrupted ? 8f : 1.5f, VisualKind.Shell, 0.25f, Corrupted); break; } case Skill.Unleash: if (Corrupted) { Combat.Area(((EntityState)this).characterBody, ((EntityState)this).characterBody.corePosition, 12f, damage, proc, Choice, c: true); } Meter(Corrupted ? (-35) : 35); Visuals.Emit(((EntityState)this).characterBody.corePosition, ((EntityState)this).characterBody.corePosition, Corrupted ? 12f : 1.5f, VisualKind.Ring, 0.25f, Corrupted); break; case Skill.Displace: case Skill.Breach: break; } } private void Meter(float delta) { VoidSurvivorController component = ((EntityState)this).GetComponent<VoidSurvivorController>(); if (Object.op_Implicit((Object)(object)component)) { float corruption = component.corruption; component.AddCorruption(Balance.Meter(corruption, delta, component.minimumCorruption, component.maxCorruption) - corruption); Telemetry.Event(Choice, Corrupted, "corruption", component.corruption - corruption); } } public override void OnExit() { if (walkPenalty != null && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { ((EntityState)this).characterMotor.RemoveWalkSpeedPenalty(walkPenalty); } ((EntityState)this).OnExit(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class Impale : AlternateState { protected override Skill Choice => Skill.Impale; } public sealed class CorruptedImpale : Impale { protected override bool Corrupted => true; } public class Lash : AlternateState { protected override Skill Choice => Skill.Lash; } public sealed class CorruptedLash : Lash { protected override bool Corrupted => true; } public class Undertow : AlternateState { protected override Skill Choice => Skill.Undertow; } public sealed class CorruptedUndertow : Undertow { protected override bool Corrupted => true; } public class Condense : AlternateState { protected override Skill Choice => Skill.Condense; } public sealed class CorruptedCondense : Condense { protected override bool Corrupted => true; } public class Quarantine : AlternateState { protected override Skill Choice => Skill.Quarantine; } public sealed class CorruptedQuarantine : Quarantine { protected override bool Corrupted => true; } public class Unleash : AlternateState { protected override Skill Choice => Skill.Unleash; } public sealed class CorruptedUnleash : Unleash { protected override bool Corrupted => true; } public class Displace : AlternateState { protected override Skill Choice => Skill.Displace; protected override float CommitTime => 0f; protected override void Commit() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_003c: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } Vector3 position = ((EntityState)this).transform.position; CharacterBody characterBody = ((EntityState)this).characterBody; Ray aimRay = ((BaseState)this).GetAimRay(); Vector3 val = Combat.BlinkEndpoint(characterBody, ((Ray)(ref aimRay)).direction, Corrupted ? 16 : 12); Vector3 val2 = val - position; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { TeleportHelper.TeleportGameObject(((EntityState)this).gameObject, val); if (Corrupted) { Combat.Path(((EntityState)this).characterBody, position, val); } } Visuals.Emit(position, val, 1f, VisualKind.Tear, 0.18f, Corrupted); Visuals.CastSound(((EntityState)this).gameObject, Choice, Corrupted); } } public sealed class CorruptedDisplace : Displace { protected override bool Corrupted => true; } public class Breach : BaseSkillState { private float flight; private float maxFlight; private bool impacted; private bool protectedTravel; private Vector3 previous; protected virtual bool Corrupted => false; public override void OnEnter() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_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_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); previous = ((EntityState)this).characterBody.corePosition; Ray aimRay = ((BaseState)this).GetAimRay(); Vector3 val = ((Ray)(ref aimRay)).direction; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = ((EntityState)this).characterDirection.forward; } ((Vector3)(ref val)).Normalize(); float num = Balance.LaunchScale(((BaseState)this).moveSpeedStat, ((EntityState)this).characterBody.baseMoveSpeed); float num2 = Mathf.Sqrt(2f * Mathf.Abs(Physics.gravity.y) * 8f); maxFlight = 2f * num2 / Mathf.Abs(Physics.gravity.y); if (NetworkServer.active && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { PhysForceInfo val2 = PhysForceInfo.Create(); val2.force = val * (float)(Corrupted ? 22 : (-10)) / maxFlight * num + Vector3.up * num2; ((PhysForceInfo)(ref val2)).massIsOne = true; ((PhysForceInfo)(ref val2)).resetVelocity = true; ((PhysForceInfo)(ref val2)).ignoreGroundStick = true; ((EntityState)this).healthComponent.TakeDamageForce(val2); } if (NetworkServer.active) { ((EntityState)this).characterBody.AddBuff(Buffs.HiddenInvincibility); protectedTravel = true; if (!Corrupted) { Combat.Area(((EntityState)this).characterBody, previous, 6f, ((BaseState)this).damageStat * 4f, 1f, Skill.Breach, c: false); } Telemetry.Event(Skill.Breach, Corrupted, "activation", num); } Visuals.Emit(previous, previous, Corrupted ? 1 : 6, VisualKind.Ring, 0.2f, Corrupted); } public override void FixedUpdate() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0097: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) ((EntityState)this).FixedUpdate(); flight += Time.fixedDeltaTime; if (flight >= 0.35f) { EndProtection(); } if (Corrupted && !impacted && NetworkServer.active) { Vector3 corePosition = ((EntityState)this).characterBody.corePosition; Vector3 val = previous; LayerIndex val2 = LayerIndex.world; bool flag = Physics.Linecast(val, corePosition, LayerMask.op_Implicit(((LayerIndex)(ref val2)).mask), (QueryTriggerInteraction)1); bool flag2 = false; Collider[] array = Combat.Rent(); HashSet<HealthComponent> h = Combat.RentSet(); val2 = LayerIndex.entityPrecise; int num = Physics.OverlapSphereNonAlloc(corePosition, 1f, array, LayerMask.op_Implicit(((LayerIndex)(ref val2)).mask), (QueryTriggerInteraction)2); for (int i = 0; i < num; i++) { HurtBox val3 = (Object.op_Implicit((Object)(object)array[i]) ? ((Component)array[i]).GetComponent<HurtBox>() : null); if (Object.op_Implicit((Object)(object)val3) && Combat.Hostile(((EntityState)this).characterBody, val3.healthComponent)) { flag2 = true; break; } } Combat.Return(array, h); if (flag || flag2 || (flight > 0.15f && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor) && ((EntityState)this).characterMotor.isGrounded) || flight >= maxFlight) { impacted = true; EndProtection(); PhysForceInfo val4 = PhysForceInfo.Create(); val4.force = Vector3.up * ((EntityState)this).characterMotor.velocity.y; ((PhysForceInfo)(ref val4)).massIsOne = true; ((PhysForceInfo)(ref val4)).resetVelocity = true; ((EntityState)this).healthComponent.TakeDamageForce(val4); Combat.Area(((EntityState)this).characterBody, corePosition, 8f, ((EntityState)this).characterBody.damage * 8f, 1f, Skill.Breach, c: true); Visuals.Emit(corePosition, corePosition, 8f, VisualKind.Ring, 0.2f, c: true); } previous = corePosition; } if (((EntityState)this).isAuthority && (flight >= maxFlight || (flight > 0.15f && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor) && ((EntityState)this).characterMotor.isGrounded))) { ((EntityState)this).outer.SetNextStateToMain(); } } private void EndProtection() { if (protectedTravel && NetworkServer.active && Object.op_Implicit((Object)(object)((EntityState)this).characterBody)) { ((EntityState)this).characterBody.RemoveBuff(Buffs.HiddenInvincibility); protectedTravel = false; } } public override void OnExit() { EndProtection(); ((EntityState)this).OnExit(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public sealed class CorruptedBreach : Breach { protected override bool Corrupted => true; } public static class Telemetry { private static readonly string[] Slots = new string[4] { "Primary", "Secondary", "Utility", "Special" }; private static readonly Dictionary<string, double> totals = new Dictionary<string, double>(); private static float last; public static event Action<string, string, float> Sample; public static void Event(Skill skill, bool corrupted, string metric, float value) { string text = "VoidFiendAlt." + Slots[Balance.Slot(skill)] + "." + skill.ToString() + "." + (corrupted ? "Corrupted" : "Controlled"); if (Telemetry.Sample != null) { Delegate[] invocationList = Telemetry.Sample.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<string, string, float> action = (Action<string, string, float>)invocationList[i]; try { action(text, metric, value); } catch (Exception ex) { Plugin.Warn("Telemetry listener failed: " + ex.GetType().Name); } } } if (!Plugin.Diagnostics.Value) { return; } string key = text + "/" + metric; totals.TryGetValue(key, out var value2); totals[key] = value2 + (double)value; if (Time.unscaledTime - last < 30f) { return; } last = Time.unscaledTime; foreach (KeyValuePair<string, double> total in totals) { Plugin.Log("VFA_METRIC " + total.Key + "=" + total.Value.ToString(CultureInfo.InvariantCulture)); } totals.Clear(); } internal static void Hit(Skill s, bool c, DamageInfo d) { Event(s, c, "raw-direct-damage", d.damage); Event(s, c, "hit", 1f); Event(s, c, "proc-weight", d.procCoefficient); if (d.crit) { Event(s, c, "crit", 1f); } } } public enum VisualKind { Puncture, Ring, Tendril, Sweep, Tear, Shell } internal static class Visuals { internal static Material Material; private static GameObject effect; internal static Sprite Icon(Skill s, bool c) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "icons", s.ToString() + (c ? "-Corrupted" : "") + ".png"); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text))) { throw new InvalidDataException(text); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } internal static void Build(ContentPack pack) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //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_00a5: Expected O, but got Unknown Material = new Material(Shader.Find("Sprites/Default")); ((Object)Material).name = "VFA Original Void Lines"; GameObject val = new GameObject("VFA Effect Templates"); val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); effect = new GameObject("VoidFiendAltEvent"); effect.transform.SetParent(val.transform); effect.AddComponent<EffectComponent>().applyScale = false; effect.AddComponent<VFXAttributes>(); effect.AddComponent<VoidEffect>(); pack.effectDefs.Add((EffectDef[])(object)new EffectDef[1] { new EffectDef(effect) { shouldPool = true } }); } internal static LineRenderer Line(GameObject go, int count, float width, bool world = true) { LineRenderer obj = go.AddComponent<LineRenderer>(); ((Renderer)obj).sharedMaterial = Material; obj.positionCount = count; obj.startWidth = width; obj.endWidth = width * 0.4f; obj.useWorldSpace = world; obj.numCapVertices = 0; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } internal static Color Color(bool c, float alpha = 1f) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) return new Color(c ? 1f : 0.7f, c ? 0.18f : 0.35f, c ? 0.65f : 1f, alpha); } internal static void Emit(Vector3 a, Vector3 b, float radius, VisualKind kind, float lifetime, bool c) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown if (NetworkServer.active && Object.op_Implicit((Object)(object)effect)) { EffectManager.SpawnEffect(effect, new EffectData { origin = a, start = b, scale = radius, genericUInt = (uint)(kind + (c ? 16 : 0)), genericFloat = lifetime }, true); } } internal static void CastSound(GameObject body, Skill s, bool c) { EntityState val = EntityStateCatalog.InstantiateState((s == Skill.Displace) ? typeof(VoidBlinkUp) : typeof(FireHandBeam)); string text = ((FireHandBeam)(((val is FireHandBeam) ? val : null)?)).attackSoundString; if (string.IsNullOrEmpty(text)) { text = ((VoidBlinkBase)(((val is VoidBlinkBase) ? val : null)?)).beginSoundString; } if (!string.IsNullOrEmpty(text)) { Util.PlaySound(text, body); } } internal static void ProjectileShape(GameObject p, int mode) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0054: 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_005a: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_00af: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("OriginalVoidGeometry"); val.transform.SetParent(p.transform, false); LineRenderer val2 = Line(val, (mode >= 6) ? 49 : 5, (mode >= 6) ? 0.035f : 0.08f, world: false); Color startColor = (val2.endColor = Color(mode % 2 == 1, (mode >= 6) ? 0.28f : 0.9f)); val2.startColor = startColor; if (mode >= 6) { float num = mode switch { 7 => 10, 6 => 8, _ => 3, }; for (int i = 0; i < 49; i++) { float num2 = (float)i * (float)Math.PI * 2f / 48f; val2.SetPosition(i, new Vector3(Mathf.Cos(num2) * num, 0f, Mathf.Sin(num2) * num)); } } else { val2.SetPositions((Vector3[])(object)new Vector3[5] { new Vector3(0f, 0f, 1f), new Vector3(0.12f, 0f, -0.4f), new Vector3(0f, 0f, -0.8f), new Vector3(-0.12f, 0f, -0.4f), new Vector3(0f, 0f, 1f) }); } } } public sealed class VoidEffect : MonoBehaviour { private LineRenderer line; private EffectComponent component; private float age; private bool initialized; private void Awake() { component = ((Component)this).GetComponent<EffectComponent>(); line = Visuals.Line(((Component)this).gameObject, 49, 0.07f); } private void OnEnable() { age = 0f; initialized = false; } private void Update() { //IL_009e: 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) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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) //IL_0157: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing r