using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using BoplFixedMath; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SiphonBeam")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A Bopl Battle ability: no cooldown, only a circle. Stand near other players to charge, then fire a piercing beam.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+03cd6db5d3874468aefed4c8ac2503a8f168bcbd")] [assembly: AssemblyProduct("SiphonBeam")] [assembly: AssemblyTitle("SiphonBeam")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SiphonBeam { internal static class PlayerBodies { private static bool warnedEmpty; private static readonly HashSet alreadyKilled = new HashSet(); public static void ForgetAll() { alreadyKilled.Clear(); } public static bool IsProtected(int playerId) { PlayerHandler val = PlayerHandler.Get(); Player val2 = ((val == null) ? null : val.GetPlayer(playerId)); if (val2 != null && val2.InPlatformTransform) { return true; } ControlPlatform[] array = Object.FindObjectsOfType(); foreach (ControlPlatform val3 in array) { if (!((Object)(object)val3 == (Object)null) && ((Behaviour)val3).isActiveAndEnabled) { IPlayerIdHolder component = ((Component)val3).GetComponent(); if (component != null && component.GetPlayerId() == playerId) { return true; } } } return false; } public static int KillWhere(int victimId, int killerId, CauseOfDeath causeOfDeath, Func isInside, out int bodiesSeen, bool respectProtection = true) { //IL_0075: 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) bodiesSeen = 0; int num = 0; if (respectProtection && IsProtected(victimId)) { return 0; } PlayerCollision[] array = Object.FindObjectsOfType(); foreach (PlayerCollision val in array) { if ((Object)(object)val == (Object)null || ((MonoUpdatable)val).IsDestroyed || !((Component)val).gameObject.activeInHierarchy || val.GetPlayerId() != victimId) { continue; } FixTransform component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null) && !component.IsDestroyed) { bodiesSeen++; if (isInside(component.position) && !alreadyKilled.Contains(((Object)val).GetInstanceID()) && val.killPlayer(killerId, true, !respectProtection, causeOfDeath)) { alreadyKilled.Add(((Object)val).GetInstanceID()); num++; } } } return num; } public static int KillAll(int victimId, int killerId, CauseOfDeath causeOfDeath, out int bodiesSeen, bool respectProtection = true) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return KillWhere(victimId, killerId, causeOfDeath, (Vec2 position) => true, out bodiesSeen, respectProtection); } public static void WarnIfBlind(int bodiesSeen, string what) { if (bodiesSeen <= 0 && !warnedEmpty) { warnedEmpty = true; Plugin.Log.LogWarning((object)(what + ": no live PlayerCollision was found for the target, so nothing can be killed. Every kill in this mod goes through that lookup, so this is not a near miss -- the scan itself is blind and the ability will appear to do nothing. Falling back to the old single-body lookup for this hit.")); } } } [BepInPlugin("com.maha.boplbattle.siphonbeam", "Siphon Beam", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.maha.boplbattle.siphonbeam"; public const string PluginName = "Siphon Beam"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; private void Awake() { //IL_001f: 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) Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Siphon Beam: loading..."); new Harmony("com.maha.boplbattle.siphonbeam").PatchAll(); Log.LogInfo((object)($"Siphon Beam: loaded (charge {180} ticks per " + $"player in the circle, radius {(float)SiphonAbility.CircleRadius}, " + $"beam lasts {10} ticks).")); } } public static class SiphonAbility { public const string AbilityName = "siphonbeam"; public const string TemplateNameFragment = "invis"; public const int ChargeTicksNeeded = 180; public static readonly Fix CircleRadius = (Fix)8.5; public const int RingDashes = 16; public static readonly Fix DisplayCooldown = (Fix)10L; public const int LockedDirectionCount = 32; public const int MaxAimTicks = 270; public const float PreviewAlpha = 0.28f; public const float PreviewThickness = 0.3f; public const int BeamTicks = 10; public static readonly Fix BeamHalfWidth = (Fix)3.15; public static readonly Fix FallbackBeamLength = (Fix)40L; public static readonly Fix BeamStartOffset = (Fix)1L; public const float BeamDrawThickness = 9.9f; public const float LaserSpriteHeightUnits = 0.125f; public const int PoseFrameTicks = 3; public static readonly Color DashEmpty = new Color(0.35f, 0.4f, 0.5f, 0.55f); public static readonly Color DashCharging = new Color(0.35f, 0.7f, 1f, 1f); public static readonly Color DashFull = new Color(0.75f, 0.95f, 1f, 1f); public static bool IsSiphonBeam(GameObject go) { if ((Object)(object)go != (Object)null) { return ((Object)go).name.ToLower().Contains("siphonbeam"); } return false; } public static Sprite LoadIcon(Sprite template) { //IL_0064: 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_002b: 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_004d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = LoadTexture("SiphonBeam.AbilityIcon.png"); if ((Object)(object)val == (Object)null) { return null; } float pixelsPerUnit = 100f; if ((Object)(object)template != (Object)null) { Rect rect = template.rect; if (((Rect)(ref rect)).width > 0f) { float pixelsPerUnit2 = template.pixelsPerUnit; float num = ((Texture)val).width; rect = template.rect; pixelsPerUnit = pixelsPerUnit2 * (num / ((Rect)(ref rect)).width); } } return Build(val, pixelsPerUnit, new Vector2(0.5f, 0.5f)); } public static Sprite LoadDash() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Texture2D val = LoadTexture("SiphonBeam.Dash.png"); if (!((Object)(object)val == (Object)null)) { return Build(val, ((Texture)val).width, new Vector2(0.5f, 0.5f)); } return null; } public static Sprite LoadLaser() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Texture2D val = LoadTexture("SiphonBeam.Laser.png"); if (!((Object)(object)val == (Object)null)) { return Build(val, ((Texture)val).width, new Vector2(0f, 0.5f)); } return null; } private static Sprite Build(Texture2D texture, float pixelsPerUnit, Vector2 pivot) { //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) return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), pivot, pixelsPerUnit); } private static Texture2D LoadTexture(string resourceName) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { Plugin.Log.LogError((object)("Siphon Beam: embedded resource '" + resourceName + "' not found.")); return null; } byte[] array; using (MemoryStream memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Texture2D val = new Texture2D(1, 1); if (!ImageConversion.LoadImage(val, array)) { Plugin.Log.LogError((object)("Siphon Beam: '" + resourceName + "' failed to decode as a PNG.")); return null; } return val; } } [HarmonyPatch(typeof(AbilityGrid), "Awake")] public static class SiphonInjectionPatch { private static bool hasInjected; public static void Prefix(AbilityGrid __instance) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_012d: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0172: 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) if (hasInjected) { return; } NamedSpriteList abilityIcons = __instance.abilityIcons; if ((Object)(object)abilityIcons == (Object)null || abilityIcons.sprites == null) { Plugin.Log.LogWarning((object)"Siphon Beam: AbilityGrid.abilityIcons was empty this Awake; not injecting yet (will retry on the next grid build)."); return; } SlimePose.CaptureFrom(abilityIcons); NamedSprite val = default(NamedSprite); bool flag = false; foreach (NamedSprite sprite in abilityIcons.sprites) { if (sprite.name != null && sprite.name.ToLower().Contains("invis")) { val = sprite; flag = true; break; } } if (!flag || (Object)(object)val.associatedGameObject == (Object)null) { Plugin.Log.LogError((object)"Siphon Beam: could not find a native instant ability to clone, so the beam was not added. (Looked for an ability whose name contains 'invis'.)"); return; } GameObject val2 = Object.Instantiate(val.associatedGameObject); Object.DontDestroyOnLoad((Object)(object)val2); ((Object)val2).name = "siphonbeam"; StripTemplateEffect(val2); InstantAbility component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogError((object)("Siphon Beam: '" + val.name + "' has no InstantAbility component, so it cannot be cast and the beam was not added.")); Object.Destroy((Object)(object)val2); return; } component.SetCoolDown(SiphonAbility.DisplayCooldown); component.AudioOnCast = string.Empty; Sprite val3 = SiphonAbility.LoadIcon(val.sprite) ?? val.sprite; abilityIcons.sprites.Add(new NamedSprite("siphonbeam", val3, val2, true)); hasInjected = true; Plugin.Log.LogInfo((object)("Siphon Beam: ability injected into the select grid (cloned " + $"'{val.name}', charge {180} ticks " + "per player in the circle).")); } private static void StripTemplateEffect(GameObject clone) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown InstantAbility component = clone.GetComponent(); if ((Object)(object)component != (Object)null) { component.funcOnEnter = new UnityEvent(); component.EffectOnEnter = null; component.isInvisibilty = false; } Invisibility[] componentsInChildren = clone.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } } } [HarmonyPatch(typeof(InstantAbility), "EnterAbility")] public static class SiphonCastPatch { public static void Postfix(InstantAbility __instance) { if (SiphonAbility.IsSiphonBeam(((Component)__instance).gameObject)) { SiphonState.BeginAim(__instance.playerInfo.playerId, __instance.playerInfo.AbilityButtonUsedIndex012); } } } [HarmonyPatch(typeof(PlayerPhysics), "Move")] public static class SiphonAimRootPatch { public static bool Prefix(PlayerPhysics __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) IPlayerIdHolder component = ((Component)__instance).GetComponent(); if (component == null || !SiphonState.IsPlayerAiming(component.GetPlayerId())) { return true; } __instance.groundedSpeed = Fix.Zero; return false; } } [HarmonyPatch(typeof(Updater), "TickSimulation")] public static class SiphonTickPatch { public static void Postfix() { SiphonState.Tick(); SiphonVisuals.Sync(); } } [HarmonyPatch(typeof(Player), "Kill")] public static class SiphonClearOnDeathPatch { public static void Prefix(Player __instance) { SiphonState.DropPlayer(__instance.Id); } } [HarmonyPatch(typeof(PlayerHandler), "ResetForNextStage")] public static class SiphonResetPatch { public static void Prefix() { PlayerBodies.ForgetAll(); SiphonState.ResetForNextStage(); SiphonVisuals.DestroyAll(); } } [HarmonyPatch(typeof(Updater), "PreLevelLoad")] public static class SiphonLevelLoadPatch { public static void Prefix() { SiphonState.ResetForNextStage(); SiphonVisuals.DestroyAll(); } } public static class SiphonState { private struct Beam { public int Ticks; public Vec2 Origin; public Vec2 Dir; public Fix Length; } private struct Aim { public int Ticks; public int Slot; public Vec2 Dir; } public struct Carrier { public int OthersInside; public float RingProgress; public bool AnyFull; } private static readonly Vec2[] LockedDirections = BuildLockedDirections(); private static readonly Dictionary charge = new Dictionary(); private static readonly Dictionary beams = new Dictionary(); private static readonly Dictionary aiming = new Dictionary(); private static readonly HashSet justFilled = new HashSet(); private static readonly Dictionary carriers = new Dictionary(); private static readonly Dictionary controllers = new Dictionary(); private static bool warnedAboutBeamLength; private static Vec2[] BuildLockedDirections() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0145: Unknown result type (might be due to invalid IL or missing references) int[][] array = new int[8][] { new int[2] { 1, 0 }, new int[2] { 3, 1 }, new int[2] { 2, 1 }, new int[2] { 3, 2 }, new int[2] { 1, 1 }, new int[2] { 2, 3 }, new int[2] { 1, 2 }, new int[2] { 1, 3 } }; int[][] array2 = new int[array.Length * 4][]; for (int i = 0; i < array.Length; i++) { int num = array[i][0]; int num2 = array[i][1]; array2[i] = new int[2] { num, num2 }; array2[i + array.Length] = new int[2] { -num2, num }; array2[i + array.Length * 2] = new int[2] { -num, -num2 }; array2[i + array.Length * 3] = new int[2] { num2, -num }; } Vec2[] array3 = (Vec2[])(object)new Vec2[array2.Length]; for (int j = 0; j < array2.Length; j++) { array3[j] = Vec2.NormalizedSafe(new Vec2((Fix)(long)array2[j][0], (Fix)(long)array2[j][1])); } return array3; } public static long KeyFor(int playerId, int slot) { return (long)playerId * 16L + slot; } public static int PlayerOfKey(long key) { return (int)(key / 16); } public static bool TryGetCarrier(int playerId, out Carrier carrier) { return carriers.TryGetValue(playerId, out carrier); } public static List CarrierIds() { return new List(carriers.Keys); } public static List BeamKeys() { return new List(beams.Keys); } public static bool IsBeaming(long key) { return beams.ContainsKey(key); } public static bool IsPlayerBeaming(int playerId) { foreach (long key in beams.Keys) { if (PlayerOfKey(key) == playerId) { return true; } } return false; } public static List AimKeys() { return new List(aiming.Keys); } public static bool IsAiming(long key) { return aiming.ContainsKey(key); } public static Vec2 AimDirection(long key) { //IL_0016: 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) if (!aiming.TryGetValue(key, out var value)) { return Vec2.right; } return value.Dir; } public static bool IsPlayerAiming(int playerId) { foreach (long key in aiming.Keys) { if (PlayerOfKey(key) == playerId) { return true; } } return false; } public static int BeamTicksElapsed(long key) { if (!beams.TryGetValue(key, out var value)) { return 0; } return value.Ticks; } public static Vec2 BeamOrigin(long key) { //IL_0016: 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) if (!beams.TryGetValue(key, out var value)) { return Vec2.zero; } return value.Origin; } public static Vec2 BeamDirection(long key) { //IL_0016: 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) if (!beams.TryGetValue(key, out var value)) { return Vec2.right; } return value.Dir; } public static float BeamLengthOf(long key) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!beams.TryGetValue(key, out var value)) { return 0f; } return (float)value.Length; } public static void Tick() { ChargeFromNeighbours(); PushChargeToCooldownTimers(); TickAiming(); TickBeams(); } private static void ChargeFromNeighbours() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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) //IL_0096: 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_009c: 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_00d8: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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) carriers.Clear(); justFilled.Clear(); PlayerHandler val = PlayerHandler.Get(); if (val == null) { return; } List list = val.PlayerList(); if (list == null) { Plugin.Log.LogWarning((object)"Siphon Beam: PlayerHandler returned no player list this tick; skipping charging."); return; } foreach (Player item in list) { if (item == null || !item.IsAlive || GameTime.IsTimeStoppedFor(item.Id)) { continue; } List list2 = SlotsHolding(item.Id); if (list2.Count == 0) { continue; } Fix val2 = SiphonAbility.CircleRadius * item.Scale; Fix val3 = val2 * val2; int num = 0; foreach (Player item2 in list) { if (item2 != null && item2.IsAlive && item2.Id != item.Id) { Vec2 val4 = item2.Position - item.Position; if (Vec2.Dot(val4, val4) <= val3) { num++; } } } float num2 = 0f; bool flag = false; foreach (int item3 in list2) { long num3 = KeyFor(item.Id, item3); int num4 = ChargeOf(num3); if (num4 < 180 && num > 0) { num4 = Mathf.Min(num4 + num, 180); charge[num3] = num4; if (num4 >= 180) { justFilled.Add(num3); AudioManager val5 = AudioManager.Get(); if ((Object)(object)val5 != (Object)null) { val5.PlayRandomWithPrefix("beamSparks", 0f); } Plugin.Log.LogInfo((object)$"Siphon Beam: player {item.Id} slot {item3} is charged."); } } num2 = Mathf.Max(num2, (float)num4 / 180f); flag = flag || num4 >= 180; } carriers[item.Id] = new Carrier { OthersInside = num, RingProgress = num2, AnyFull = flag }; } } private static void PushChargeToCooldownTimers() { //IL_00ca: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) foreach (int item in CarrierIds()) { SlimeController val = ControllerFor(item); if ((Object)(object)val == (Object)null) { continue; } Fix[] value = Traverse.Create((object)val).Field("abilityCooldownTimers").GetValue(); if (value == null) { continue; } foreach (int item2 in SlotsHolding(item)) { if (item2 >= 0 && item2 < value.Length) { long num = KeyFor(item, item2); int num2 = ChargeOf(num); if (num2 >= 180) { value[item2] = (justFilled.Contains(num) ? (SiphonAbility.DisplayCooldown - (Fix)0.01) : SiphonAbility.DisplayCooldown); continue; } Fix val2 = (Fix)(long)num2 / (Fix)180L; Fix val3 = SiphonAbility.DisplayCooldown - (Fix)0.1; value[item2] = Fix.Min(SiphonAbility.DisplayCooldown * val2, val3); } } } } public static void BeginAim(int playerId, int slot) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_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) long key = KeyFor(playerId, slot); charge[key] = 0; aiming[key] = new Aim { Ticks = 0, Slot = slot, Dir = SnapToLockedDirection(CurrentAim(playerId), Vec2.right) }; Plugin.Log.LogInfo((object)$"Siphon Beam: player {playerId} slot {slot} is aiming."); } private static void TickAiming() { //IL_00a2: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if (aiming.Count == 0) { return; } PlayerHandler val = PlayerHandler.Get(); foreach (long item in AimKeys()) { Aim value = aiming[item]; int num = PlayerOfKey(item); if (GameTime.IsTimeStoppedFor(num)) { continue; } Player val2 = ((val == null) ? null : val.GetPlayer(num)); if (val2 == null || !val2.IsAlive) { aiming.Remove(item); Plugin.Log.LogInfo((object)($"Siphon Beam: player {num} died while aiming, so the shot " + "was lost.")); continue; } value.Dir = SnapToLockedDirection(RawAim(num), value.Dir); value.Ticks++; if (!val2.AbilityButtonIsDown(value.Slot)) { aiming.Remove(item); Fire(item, val2, value.Dir); } else if (value.Ticks >= 270) { aiming.Remove(item); Plugin.Log.LogInfo((object)($"Siphon Beam: player {num} held the aim to the limit, so " + "the shot went off by itself.")); Fire(item, val2, value.Dir); } else { aiming[item] = value; } } } private static Vec2 RawAim(int playerId) { //IL_001e: 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) PlayerHandler val = PlayerHandler.Get(); Player val2 = ((val == null) ? null : val.GetPlayer(playerId)); if (val2 != null) { return val2.AimVector(); } return Vec2.zero; } private static Vec2 CurrentAim(int playerId) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0017: 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_0043: 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_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_005b: 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) PlayerHandler val = PlayerHandler.Get(); Player val2 = ((val == null) ? null : val.GetPlayer(playerId)); if (val2 == null) { return Vec2.zero; } Vec2 val3 = val2.AimVector(); if (val3 != Vec2.zero) { return val3; } SlimeController val4 = ControllerFor(playerId); if ((Object)(object)val4 == (Object)null) { return Vec2.zero; } if (!val4.isFacingRight()) { return new Vec2(-Fix.One, Fix.Zero); } return Vec2.right; } private static Vec2 SnapToLockedDirection(Vec2 aim, Vec2 fallback) { //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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_005e: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (aim == Vec2.zero) { return fallback; } Vec2 val = LockedDirections[0]; Fix val2 = Vec2.Dot(aim, val); for (int i = 1; i < LockedDirections.Length; i++) { Fix val3 = Vec2.Dot(aim, LockedDirections[i]); if (val3 > val2) { val2 = val3; val = LockedDirections[i]; } } return val; } private static void Fire(long key, Player player, Vec2 dir) { //IL_0013: 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_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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_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) Beam value = new Beam { Ticks = 0, Origin = player.Position + dir * SiphonAbility.BeamStartOffset, Dir = dir, Length = BeamLength() }; beams[key] = value; AudioManager val = AudioManager.Get(); if ((Object)(object)val != (Object)null) { val.Play("beamFire"); } Plugin.Log.LogInfo((object)($"Siphon Beam: player {player.Id} fired along ({(float)dir.x:0.##}, " + $"{(float)dir.y:0.##}).")); } private static Fix BeamLength() { //IL_0032: 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) DetPhysics val = DetPhysics.Get(); if ((Object)(object)val == (Object)null) { if (!warnedAboutBeamLength) { warnedAboutBeamLength = true; Plugin.Log.LogWarning((object)"Siphon Beam: DetPhysics was not available, so the beam used its fallback length instead of the game's own beam range."); } return SiphonAbility.FallbackBeamLength; } return val.maxBeamDistance; } public static float PreviewLength() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return (float)BeamLength(); } private static void TickBeams() { if (beams.Count == 0) { return; } foreach (long item in BeamKeys()) { if (GameTime.IsTimeStoppedFor(PlayerOfKey(item))) { continue; } Beam beam = beams[item]; KillAlongBeam(PlayerOfKey(item), beam); DetonateAlongBeam(beam); beam.Ticks++; if (beam.Ticks >= 10) { beams.Remove(item); AudioManager val = AudioManager.Get(); if ((Object)(object)val != (Object)null) { val.Play("beamEnd"); } } else { beams[item] = beam; } } } private static void KillAlongBeam(int casterId, Beam beam) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) PlayerHandler val = PlayerHandler.Get(); if (val == null) { return; } foreach (Player item in val.PlayerList()) { if (item == null || !item.IsAlive || item.Id == casterId) { continue; } Beam onBeam = beam; int bodiesSeen; int num = PlayerBodies.KillWhere(item.Id, casterId, (CauseOfDeath)4, (Vec2 position) => OnBeam(position, onBeam), out bodiesSeen); if (num > 0) { Plugin.Log.LogInfo((object)($"Siphon Beam: player {casterId}'s beam caught player " + $"{item.Id} ({num} of {bodiesSeen} bodies).")); } else { if (bodiesSeen != 0) { continue; } PlayerBodies.WarnIfBlind(bodiesSeen, "Siphon Beam"); if (OnBeam(item.Position, beam)) { SlimeController val2 = ControllerFor(item.Id); PlayerCollision val3 = (((Object)(object)val2 == (Object)null) ? null : val2.GetActivePlayerCollision()); if ((Object)(object)val3 != (Object)null) { val3.killPlayer(casterId, true, false, (CauseOfDeath)4); } } } } } private static void DetonateAlongBeam(Beam beam) { FlammableSmoke[] array = Object.FindObjectsOfType(); foreach (FlammableSmoke gas in array) { DPhysicsCircle component = ((Component)gas).GetComponent(); if ((!((Object)(object)component != (Object)null) || ((Behaviour)component).enabled) && OnBeam((Component)(object)gas, beam)) { TryDetonate(delegate { gas.Ignite(); }, "gas cloud"); } } GrenadeExplode[] array2 = Object.FindObjectsOfType(); foreach (GrenadeExplode grenade in array2) { if (OnBeam((Component)(object)grenade, beam)) { TryDetonate(delegate { grenade.Detonate(); }, "grenade"); } } SmokeGrenadeExplode2[] array3 = Object.FindObjectsOfType(); foreach (SmokeGrenadeExplode2 smoke in array3) { if (OnBeam((Component)(object)smoke, beam)) { TryDetonate(delegate { smoke.Detonate(); }, "smoke grenade"); } } Mine[] array4 = Object.FindObjectsOfType(); foreach (Mine mine in array4) { if (OnBeam((Component)(object)mine, beam)) { TryDetonate(delegate { mine.Detonate(); }, "mine"); } } } private static bool OnBeam(Component component, Beam beam) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)component == (Object)null) { return false; } FixTransform component2 = component.GetComponent(); if ((Object)(object)component2 == (Object)null || component2.IsDestroyed) { return false; } DPhysicsCircle component3 = component.GetComponent(); Fix radius = (((Object)(object)component3 == (Object)null) ? Fix.Zero : component3.radius); return OnBeam(component2.position, beam, radius); } private static bool OnBeam(Vec2 position, Beam beam) { //IL_0000: 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) return OnBeam(position, beam, Fix.Zero); } private static bool OnBeam(Vec2 position, Beam beam, Fix radius) { //IL_0000: 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_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references) return OnSegment(position, beam.Origin, beam.Dir, beam.Length, radius); } private static bool OnSegment(Vec2 position, Vec2 origin, Vec2 dir, Fix length, Fix radius) { //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_0008: 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_000a: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) Vec2 val = position - origin; Fix val2 = Vec2.Dot(val, dir); if (val2 < -radius || val2 > length + radius) { return false; } return Fix.Abs(Vec2.Cross(dir, val)) <= SiphonAbility.BeamHalfWidth + radius; } private static void TryDetonate(Action detonate, string what) { try { detonate(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Siphon Beam: setting off a " + what + " threw, so it was left alone: " + ex.Message)); } } public static int ChargeOf(long key) { if (!charge.TryGetValue(key, out var value)) { return 0; } return value; } public static List SlotsHolding(int playerId) { List list = new List(); SlimeController val = ControllerFor(playerId); if ((Object)(object)val == (Object)null || val.abilities == null) { return list; } for (int i = 0; i < val.abilities.Count; i++) { AbilityMonoBehaviour val2 = val.abilities[i]; if ((Object)(object)val2 != (Object)null && SiphonAbility.IsSiphonBeam(((Component)val2).gameObject)) { list.Add(i); } } return list; } private static SlimeController ControllerFor(int playerId) { if (controllers.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null) { return value; } SlimeController[] array = Object.FindObjectsOfType(); foreach (SlimeController val in array) { if (val.GetPlayerId() == playerId) { controllers[playerId] = val; return val; } } return null; } public static void ResetForNextStage() { charge.Clear(); beams.Clear(); aiming.Clear(); carriers.Clear(); controllers.Clear(); justFilled.Clear(); } public static void DropPlayer(int playerId) { foreach (long item in new List(charge.Keys)) { if (PlayerOfKey(item) == playerId) { charge.Remove(item); } } foreach (long item2 in new List(beams.Keys)) { if (PlayerOfKey(item2) == playerId) { beams.Remove(item2); } } foreach (long item3 in new List(aiming.Keys)) { if (PlayerOfKey(item3) == playerId) { aiming.Remove(item3); } } carriers.Remove(playerId); } } public static class SiphonVisuals { private const float DashFill = 0.55f; private const float DashThickness = 0.22f; private static Sprite dashSprite; private static Sprite laserSprite; private static float dashSpriteHeightUnits = 1f; private static bool loadAttempted; private static bool loadFailed; private static readonly Dictionary rings = new Dictionary(); private static readonly Dictionary lasers = new Dictionary(); private static readonly Dictionary previews = new Dictionary(); private static readonly Dictionary playerSprites = new Dictionary(); public static void Sync() { if (!loadFailed && (loadAttempted || Load())) { SyncRings(); SyncPreviews(); SyncLasers(); SyncPose(); } } private static void SyncPreviews() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown foreach (long item in SiphonState.AimKeys()) { if (!previews.TryGetValue(item, out var value) || (Object)(object)value == (Object)null) { value = new GameObject("SiphonBeamAimLine"); value.AddComponent().sprite = laserSprite; previews[item] = value; } PositionPreview(item, value); } Sweep(previews, (long k) => SiphonState.IsAiming(k)); } private static void PositionPreview(long key, GameObject preview) { //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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) int num = SiphonState.PlayerOfKey(key); PlayerHandler val = PlayerHandler.Get(); Player val2 = ((val == null) ? null : val.GetPlayer(num)); if (val2 == null) { preview.SetActive(false); return; } Vec2 val3 = SiphonState.AimDirection(key); Vec2 origin = val2.Position + val3 * SiphonAbility.BeamStartOffset; preview.SetActive(true); ShapeSegment(preview, origin, val3, SiphonState.PreviewLength(), 0.3f, 0.28f, 1999); } private static void ShapeSegment(GameObject go, Vec2 origin, Vec2 dir, float length, float thicknessScale, float alpha, int sortingOrder) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0028: 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_0039: 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_007f: Unknown result type (might be due to invalid IL or missing references) go.transform.position = Vector2.op_Implicit((Vector2)origin); go.transform.right = new Vector3((float)dir.x, (float)dir.y, 0f); go.transform.localScale = new Vector3(length, 9.9f * thicknessScale / 0.125f, 1f); SpriteRenderer component = go.GetComponent(); component.color = new Color(1f, 1f, 1f, alpha); ((Renderer)component).sortingOrder = sortingOrder; } private static void SyncRings() { foreach (int item in SiphonState.CarrierIds()) { if (!rings.TryGetValue(item, out var value) || (Object)(object)value == (Object)null) { value = BuildRing(); rings[item] = value; } PositionRing(item, value); } Sweep(rings, (int id) => SiphonState.TryGetCarrier(id, out var _)); } private static GameObject BuildRing() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00b1: 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_00d2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("SiphonBeamRing"); float num = (float)SiphonAbility.CircleRadius; float num2 = 22.5f; float num3 = MathF.PI * 2f * num / 16f * 0.55f; for (int i = 0; i < 16; i++) { float num4 = num2 * (float)i; float num5 = num4 * (MathF.PI / 180f); GameObject val2 = new GameObject("Dash" + i); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = new Vector3(Mathf.Cos(num5) * num, Mathf.Sin(num5) * num, 0f); val2.transform.localRotation = Quaternion.Euler(0f, 0f, num4 + 90f); val2.transform.localScale = new Vector3(num3, 0.22f / dashSpriteHeightUnits, 1f); val2.AddComponent().sprite = dashSprite; } return val; } private static void PositionRing(int playerId, GameObject ring) { //IL_007a: 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_004c: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer val = FindPlayerSprite(playerId); PlayerHandler val2 = PlayerHandler.Get(); Player val3 = ((val2 == null) ? null : val2.GetPlayer(playerId)); if (val3 == null || !SiphonState.TryGetCarrier(playerId, out var carrier)) { ring.SetActive(false); return; } ring.SetActive(true); ring.transform.position = (Vector3)(((Object)(object)val != (Object)null) ? ((Component)val).transform.position : new Vector3((float)val3.Position.x, (float)val3.Position.y, 0f)); float num = Mathf.Max(0.01f, (float)val3.Scale); ring.transform.localScale = new Vector3(num, num, 1f); float num2 = (float)(Updater.SimulationTicks * carrier.OthersInside) * 0.6f; ring.transform.rotation = Quaternion.Euler(0f, 0f, num2); int num3 = Mathf.RoundToInt(carrier.RingProgress * 16f); Color val4 = (carrier.AnyFull ? SiphonAbility.DashFull : SiphonAbility.DashCharging); for (int i = 0; i < ring.transform.childCount; i++) { SpriteRenderer component = ((Component)ring.transform.GetChild(i)).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.color = ((i < num3) ? val4 : SiphonAbility.DashEmpty); if ((Object)(object)val != (Object)null) { ((Renderer)component).sortingLayerID = ((Renderer)val).sortingLayerID; ((Renderer)component).sortingOrder = ((Renderer)val).sortingOrder - 3; } } } } private static void SyncLasers() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown foreach (long item in SiphonState.BeamKeys()) { if (!lasers.TryGetValue(item, out var value) || (Object)(object)value == (Object)null) { value = new GameObject("SiphonBeamLaser"); value.AddComponent().sprite = laserSprite; lasers[item] = value; } PositionLaser(item, value); } Sweep(lasers, (long k) => SiphonState.IsBeaming(k)); } private static float FadeRemaining(long key) { int num = SiphonState.BeamTicksElapsed(key); return 1f - (float)num / 10f; } private static float FadeThickness(long key) { return Mathf.Max(0.08f, FadeRemaining(key)); } private static float FadeAlpha(long key) { return Mathf.Clamp01(FadeRemaining(key) * 1.6f); } private static void PositionLaser(long key, GameObject laser) { //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_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) //IL_0022: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0045: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) Vec2 val = SiphonState.BeamOrigin(key); Vec2 val2 = SiphonState.BeamDirection(key); float num = SiphonState.BeamLengthOf(key); laser.SetActive(true); laser.transform.position = Vector2.op_Implicit((Vector2)val); laser.transform.right = new Vector3((float)val2.x, (float)val2.y, 0f); int num2 = SiphonState.BeamTicksElapsed(key); float num3 = 1f - (float)num2 / 10f; float num4 = 9.9f * Mathf.Max(0.08f, num3); laser.transform.localScale = new Vector3(num, num4 / 0.125f, 1f); SpriteRenderer component = laser.GetComponent(); component.color = new Color(1f, 1f, 1f, Mathf.Clamp01(num3 * 1.6f)); ((Renderer)component).sortingOrder = 2000; } private static void SyncPose() { Sprite[] frames = SlimePose.Frames; if (frames == null || frames.Length == 0) { return; } foreach (long item in SiphonState.AimKeys()) { Apply(SiphonState.PlayerOfKey(item), frames, 0); } foreach (long item2 in SiphonState.BeamKeys()) { Apply(frame: SiphonState.BeamTicksElapsed(item2) / 3, playerId: SiphonState.PlayerOfKey(item2), frames: frames); } } private static void Apply(int playerId, Sprite[] frames, int frame) { SpriteRenderer val = FindPlayerSprite(playerId); if (!((Object)(object)val == (Object)null)) { Sprite val2 = frames[Mathf.Clamp(frame, 0, frames.Length - 1)]; if ((Object)(object)val2 != (Object)null) { val.sprite = val2; } } } private static void Sweep(Dictionary objects, Func stillWanted) { List list = null; foreach (KeyValuePair @object in objects) { if (!stillWanted(@object.Key)) { (list ?? (list = new List())).Add(@object.Key); } } if (list == null) { return; } foreach (TKey item in list) { if ((Object)(object)objects[item] != (Object)null) { Object.Destroy((Object)(object)objects[item]); } objects.Remove(item); } } public static void DestroyAll() { foreach (KeyValuePair ring in rings) { if ((Object)(object)ring.Value != (Object)null) { Object.Destroy((Object)(object)ring.Value); } } rings.Clear(); foreach (KeyValuePair laser in lasers) { if ((Object)(object)laser.Value != (Object)null) { Object.Destroy((Object)(object)laser.Value); } } lasers.Clear(); foreach (KeyValuePair preview in previews) { if ((Object)(object)preview.Value != (Object)null) { Object.Destroy((Object)(object)preview.Value); } } previews.Clear(); playerSprites.Clear(); } private static SpriteRenderer FindPlayerSprite(int playerId) { if (playerSprites.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null && ((Component)value).gameObject.activeInHierarchy) { return value; } SlimeController[] array = Object.FindObjectsOfType(); foreach (SlimeController val in array) { if (val.GetPlayerId() == playerId) { SpriteRenderer playerSprite = val.GetPlayerSprite(); if ((Object)(object)playerSprite != (Object)null && ((Component)playerSprite).gameObject.activeInHierarchy) { playerSprites[playerId] = playerSprite; return playerSprite; } } } return null; } private static bool Load() { //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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) loadAttempted = true; dashSprite = SiphonAbility.LoadDash(); laserSprite = SiphonAbility.LoadLaser(); if ((Object)(object)dashSprite == (Object)null || (Object)(object)laserSprite == (Object)null) { loadFailed = true; Plugin.Log.LogError((object)"Siphon Beam: art failed to load, so the circle and the beam will be invisible. The ability itself still works."); return false; } Rect rect = dashSprite.rect; float height = ((Rect)(ref rect)).height; rect = dashSprite.rect; dashSpriteHeightUnits = height / ((Rect)(ref rect)).width; Plugin.Log.LogInfo((object)"Siphon Beam: art ready."); return true; } } public static class SlimePose { private static readonly string[] WantedAnimations = new string[4] { "loop", "loopUp", "loopAir", "enter" }; public static Sprite[] Frames { get; private set; } public static void CaptureFrom(NamedSpriteList icons) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) if (Frames != null || (Object)(object)icons == (Object)null || icons.sprites == null) { return; } Beam val = null; foreach (NamedSprite sprite in icons.sprites) { if (!((Object)(object)sprite.associatedGameObject == (Object)null)) { Beam component = sprite.associatedGameObject.GetComponent(); if ((Object)(object)component != (Object)null) { val = component; break; } } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Siphon Beam: the game's own beam ability was not in the ability grid, so the slime will keep its normal sprite while firing. Everything else works."); return; } AnimationData value = Traverse.Create((object)val).Field("animData").GetValue(); if ((Object)(object)value == (Object)null) { Plugin.Log.LogWarning((object)"Siphon Beam: the beam ability had no animation data, so the slime will keep its normal sprite while firing."); return; } string[] wantedAnimations = WantedAnimations; foreach (string text in wantedAnimations) { List list = Extract(value, text); if (list != null && list.Count != 0) { Frames = list.ToArray(); Plugin.Log.LogInfo((object)("Siphon Beam: borrowed the game's '" + text + "' beam pose " + $"({Frames.Length} frames) for the firing animation.")); return; } } Plugin.Log.LogWarning((object)("Siphon Beam: none of the expected beam animations were present (" + string.Join(", ", WantedAnimations) + "), so the slime will keep its normal sprite while firing.")); } private static List Extract(AnimationData data, string name) { //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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) SpriteFrame[] animation; try { animation = data.GetAnimation(name); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Siphon Beam: beam animation '" + name + "' is not present (" + ex.Message + "); trying the next one.")); return null; } if (animation == null) { return null; } List list = new List(); SpriteFrame[] array = animation; foreach (SpriteFrame val in array) { if ((Object)(object)val.sprite != (Object)null) { list.Add(val.sprite); } } return list; } } }