Decompiled source of ArenMod v0.1.1
plugins\ArenMod.dll
Decompiled a month 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.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnboundLib.Cards; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("ArenMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ArenMod")] [assembly: AssemblyTitle("ArenMod")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 ArenMod { public class AirSupportBarrageProjectile : MonoBehaviour { private Player owner; private float damage; private bool dealDamage; private static Sprite cachedFlashSprite; public void Initialize(Player newOwner, float newDamage, bool shouldDealDamage) { owner = newOwner; damage = newDamage; dealDamage = shouldDealDamage; } private void OnTriggerEnter2D(Collider2D other) { //IL_0118: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00a6: 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_00ce: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)other == (Object)null) { return; } Player componentInParent = ((Component)other).GetComponentInParent<Player>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)owner != (Object)null) { if (dealDamage && (Object)(object)componentInParent.data != (Object)null && (Object)(object)componentInParent.data.healthHandler != (Object)null) { Vector2 val = Vector2.op_Implicit(((Component)componentInParent).transform.position - ((Component)this).transform.position); Vector2 normalized = ((Vector2)(ref val)).normalized; ((Damagable)componentInParent.data.healthHandler).CallTakeDamage(normalized * damage, Vector2.op_Implicit(((Component)this).transform.position), ((Component)owner).gameObject, owner, true); SpawnHitFlash(((Component)this).transform.position); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Air Support: barrage hit player {componentInParent.playerID}"); } } Object.Destroy((Object)(object)((Component)this).gameObject); } else if (!other.isTrigger) { SpawnHitFlash(((Component)this).transform.position); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void SpawnHitFlash(Vector3 pos) { //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_0010: 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_003d: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown GameObject val = new GameObject("AirSupport_HitFlash"); val.transform.position = pos; SpriteRenderer obj = val.AddComponent<SpriteRenderer>(); obj.sprite = CreateFlashSprite(); obj.color = new Color(1f, 0.85f, 0.35f, 0.9f); ((Renderer)obj).sortingOrder = 130; val.transform.localScale = new Vector3(0.5f, 0.5f, 1f); val.AddComponent<AirSupportHitFlash>(); Object.Destroy((Object)val, 0.2f); } private Sprite CreateFlashSprite() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) if ((Object)(object)cachedFlashSprite != (Object)null) { return cachedFlashSprite; } int num = 16; Texture2D val = new Texture2D(num, num, (TextureFormat)5, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2); float num3 = Mathf.Clamp01(1f - num2 / ((float)num * 0.5f)); val.SetPixel(j, i, new Color(1f, 1f, 1f, num3)); } } val.Apply(); cachedFlashSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num); return cachedFlashSprite; } } public class AirSupportCard : CustomCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.reloadTimeAdd += 0.75f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { AirSupportPlayerController airSupportPlayerController = ((Component)player).gameObject.GetComponent<AirSupportPlayerController>(); if ((Object)(object)airSupportPlayerController == (Object)null) { airSupportPlayerController = ((Component)player).gameObject.AddComponent<AirSupportPlayerController>(); } airSupportPlayerController.SetActive(value: true); AirSupportProjectileHook.EnsureAddedToGun(gun, player); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { AirSupportPlayerController component = ((Component)player).gameObject.GetComponent<AirSupportPlayerController>(); if ((Object)(object)component != (Object)null) { component.SetActive(value: false); } } protected override string GetTitle() { return "Air Support"; } protected override string GetDescription() { return "Your shots call in a delayed strafing run where they land."; } protected override CardInfoStat[] GetStats() { //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_0014: 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_002b: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[2] { new CardInfoStat { positive = true, stat = "Signal shot", amount = "Calls barrage" }, new CardInfoStat { positive = false, stat = "Reload time", amount = "+0.75s" } }; } protected override GameObject GetCardArt() { return null; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)0; } public override string GetModName() { return "Aren Mod"; } } public class AirSupportHitFlash : MonoBehaviour { private SpriteRenderer sr; private float age; private void Start() { sr = ((Component)this).GetComponent<SpriteRenderer>(); } private void Update() { //IL_003b: 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_005e: 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) age += Time.deltaTime; float num = Mathf.Lerp(0.5f, 1.1f, age / 0.2f); ((Component)this).transform.localScale = new Vector3(num, num, 1f); if ((Object)(object)sr != (Object)null) { Color color = sr.color; color.a = Mathf.Lerp(0.9f, 0f, age / 0.2f); sr.color = color; } } } public class AirSupportPlayerController : MonoBehaviour { private static readonly Dictionary<string, float> RecentAirSupportEvents = new Dictionary<string, float>(); private Player player; private bool active; private static Sprite cachedTracerSprite; private static Sprite cachedCircleSprite; private void Awake() { player = ((Component)this).GetComponent<Player>(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Air Support: player controller awake."); } } public void SetActive(bool value) { active = value; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Air Support: controller active set to {active}"); } } public bool IsActive() { return active; } public void CallAirSupport(Vector3 targetPoint) { //IL_0010: 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_00e2: 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) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Air Support: CallAirSupport received at {targetPoint}"); } if (!active || (Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.dead) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"Air Support: CallAirSupport aborted due to inactive/dead/null state."); } } else { if ((Object)(object)player.data.view == (Object)null || !player.data.view.IsMine) { return; } int num = Random.Range(int.MinValue, int.MaxValue); HandleNetworkedAirSupport(player.playerID, targetPoint, num); if (!Plugin.RaiseNetworkEvent("ArenMod_AirSupportCallEvent", player.playerID, targetPoint.x, targetPoint.y, num)) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)"Air Support: failed to raise networked air support event. Local barrage still succeeded."); } } } } public static void HandleNetworkedAirSupport(int ownerPlayerID, Vector3 targetPoint, int seed) { //IL_012e: Unknown result type (might be due to invalid IL or missing references) string key = $"{ownerPlayerID}:{seed}"; if (RecentAirSupportEvents.TryGetValue(key, out var value) && Time.time - value < 0.5f) { return; } RecentAirSupportEvents[key] = Time.time; CleanupRecentEvents(); Player[] array = Object.FindObjectsOfType<Player>(); Player val = null; for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && array[i].playerID == ownerPlayerID) { val = array[i]; break; } } if ((Object)(object)val == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"Air Support: could not resolve owner for networked barrage. playerID={ownerPlayerID}"); } return; } AirSupportPlayerController airSupportPlayerController = ((Component)val).GetComponent<AirSupportPlayerController>(); if ((Object)(object)airSupportPlayerController == (Object)null) { airSupportPlayerController = ((Component)val).gameObject.AddComponent<AirSupportPlayerController>(); } if (!airSupportPlayerController.IsActive()) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"Air Support: controller inactive for networked barrage. playerID={ownerPlayerID}"); } } else { bool dealDamage = (Object)(object)val.data != (Object)null && (Object)(object)val.data.view != (Object)null && val.data.view.IsMine; ((MonoBehaviour)airSupportPlayerController).StartCoroutine(airSupportPlayerController.AirSupportRoutine(targetPoint, seed, dealDamage)); } } private static void CleanupRecentEvents() { List<string> list = null; foreach (KeyValuePair<string, float> recentAirSupportEvent in RecentAirSupportEvents) { if (Time.time - recentAirSupportEvent.Value > 2f) { if (list == null) { list = new List<string>(); } list.Add(recentAirSupportEvent.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { RecentAirSupportEvents.Remove(list[i]); } } } private IEnumerator AirSupportRoutine(Vector3 targetPoint, int seed, bool dealDamage) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Air Support: barrage routine started."); } SpawnTargetMarker(targetPoint); yield return (object)new WaitForSeconds(0.8f); Camera main = Camera.main; if ((Object)(object)main == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)"Air Support: Camera.main was null."); } yield break; } Vector3 val = main.ViewportToWorldPoint(new Vector3(0f, 1f, 0f)); Vector3 val2 = main.ViewportToWorldPoint(new Vector3(1f, 1f, 0f)); float topY = Mathf.Max(val.y, val2.y) + 2.5f; float num = 5.5f; int bulletsToSpawn = 12; float timeBetweenBullets = 0.04f; Random random = new Random(seed); bool startFromLeft = random.NextDouble() > 0.5; float startX = (startFromLeft ? (targetPoint.x - num * 0.5f) : (targetPoint.x + num * 0.5f)); float endX = (startFromLeft ? (targetPoint.x + num * 0.5f) : (targetPoint.x - num * 0.5f)); ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)$"Air Support: barrage spawning. startFromLeft={startFromLeft}, startX={startX}, endX={endX}, topY={topY}"); } Vector3 spawnPos = default(Vector3); for (int i = 0; i < bulletsToSpawn; i++) { if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.dead) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)"Air Support: barrage cancelled because player died/null."); } break; } float num2 = ((bulletsToSpawn == 1) ? 0f : ((float)i / (float)(bulletsToSpawn - 1))); float num3 = Mathf.Lerp(startX, endX, num2); ((Vector3)(ref spawnPos))..ctor(num3, topY, 0f); Vector2 val3; Vector2 normalized; if (!startFromLeft) { val3 = new Vector2(-0.25f, -1f); normalized = ((Vector2)(ref val3)).normalized; } else { val3 = new Vector2(0.25f, -1f); normalized = ((Vector2)(ref val3)).normalized; } Vector2 direction = normalized; SpawnAirSupportProjectile(spawnPos, direction, dealDamage); yield return (object)new WaitForSeconds(timeBetweenBullets); } } private void SpawnTargetMarker(Vector3 targetPoint) { //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_0010: 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_003d: 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_0063: 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_007e: Expected O, but got Unknown GameObject val = new GameObject("AirSupport_TargetMarker"); val.transform.position = targetPoint; SpriteRenderer obj = val.AddComponent<SpriteRenderer>(); obj.sprite = CreateCircleSprite(); obj.color = new Color(1f, 0.3f, 0.15f, 0.65f); ((Renderer)obj).sortingOrder = 100; val.transform.localScale = new Vector3(0.7f, 0.7f, 1f); val.AddComponent<AirSupportTargetMarker>(); Object.Destroy((Object)val, 1.2f); } private void SpawnAirSupportProjectile(Vector3 spawnPos, Vector2 direction, bool dealDamage) { //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_0010: 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_001c: 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_003f: 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_0061: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown GameObject val = new GameObject("AirSupport_Bullet"); val.transform.position = spawnPos; float num = Mathf.Atan2(direction.y, direction.x) * 57.29578f; val.transform.rotation = Quaternion.Euler(0f, 0f, num); Rigidbody2D obj = val.AddComponent<Rigidbody2D>(); obj.gravityScale = 0f; obj.collisionDetectionMode = (CollisionDetectionMode2D)1; obj.velocity = direction * 35f; CircleCollider2D obj2 = val.AddComponent<CircleCollider2D>(); ((Collider2D)obj2).isTrigger = true; obj2.radius = 0.16f; SpriteRenderer val2 = val.AddComponent<SpriteRenderer>(); val2.sprite = CreateTracerSprite(); val2.color = new Color(1f, 0.95f, 0.65f, 1f); ((Renderer)val2).sortingOrder = 120; val.transform.localScale = new Vector3(0.9f, 0.2f, 1f); val.AddComponent<AirSupportTracerVisual>().SetRenderer(val2); val.AddComponent<AirSupportBarrageProjectile>().Initialize(player, 1.5f, dealDamage); Object.Destroy((Object)val, 4f); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Air Support: spawned custom barrage projectile."); } } private Sprite CreateTracerSprite() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cachedTracerSprite != (Object)null) { return cachedTracerSprite; } Texture2D val = new Texture2D(16, 4, (TextureFormat)5, false); Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < 4; i++) { for (int j = 0; j < 16; j++) { val.SetPixel(j, i, val2); } } for (int k = 1; k <= 2; k++) { for (int l = 0; l < 16; l++) { float num = (float)l / 15f; Color val3 = Color.Lerp(new Color(1f, 0.45f, 0.1f, 0.2f), new Color(1f, 1f, 0.9f, 1f), num); val.SetPixel(l, k, val3); } } val.Apply(); cachedTracerSprite = Sprite.Create(val, new Rect(0f, 0f, 16f, 4f), new Vector2(0.5f, 0.5f), 16f); return cachedTracerSprite; } private Sprite CreateCircleSprite() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_009d: 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) if ((Object)(object)cachedCircleSprite != (Object)null) { return cachedCircleSprite; } int num = 32; Texture2D val = new Texture2D(num, num, (TextureFormat)5, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2); float num3 = (float)num * 0.38f; float num4 = (float)num * 0.08f; if (num2 <= num3 && num2 >= num3 - num4) { val.SetPixel(j, i, Color.white); } else { val.SetPixel(j, i, new Color(0f, 0f, 0f, 0f)); } } } val.Apply(); cachedCircleSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num); return cachedCircleSprite; } } public static class AirSupportProjectileHook { public static void EnsureAddedToGun(Gun gun, Player owner) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //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_00d2: Expected O, but got Unknown if ((Object)(object)gun == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)"Air Support: gun was null in EnsureAddedToGun."); } return; } if ((Object)(object)owner == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)"Air Support: owner was null in EnsureAddedToGun."); } return; } if (gun.objectsToSpawn == null) { gun.objectsToSpawn = (ObjectsToSpawn[])(object)new ObjectsToSpawn[0]; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)"Air Support: initialized gun.objectsToSpawn."); } } if (gun.objectsToSpawn.Any((ObjectsToSpawn o) => o != null && (Object)(object)o.AddToProjectile != (Object)null && (Object)(object)o.AddToProjectile.GetComponent<AirSupportSignalProjectile>() != (Object)null)) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)"Air Support: signal hook already on gun."); } return; } GameObject val = new GameObject("AirSupportSignalHook"); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<AirSupportSignalProjectile>().SetOwner(owner); ObjectsToSpawn item = new ObjectsToSpawn { AddToProjectile = val }; List<ObjectsToSpawn> list = gun.objectsToSpawn.ToList(); list.Add(item); gun.objectsToSpawn = list.ToArray(); ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"Air Support: added signal hook to gun for player {owner.playerID}. objectsToSpawn count = {gun.objectsToSpawn.Length}"); } } } public class AirSupportSignalProjectile : MonoBehaviour { private bool triggered; [SerializeField] private int ownerPlayerID = -1; private Player owner; public void SetOwner(Player newOwner) { owner = newOwner; if ((Object)(object)newOwner != (Object)null) { ownerPlayerID = newOwner.playerID; } } private void Start() { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Air Support: signal projectile component started on projectile."); } ResolveOwner(); } private void OnCollisionEnter2D(Collision2D collision) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Air Support: projectile collision detected."); } TryTrigger(((Component)this).transform.position); } private void OnTriggerEnter2D(Collider2D other) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Air Support: projectile trigger detected."); } TryTrigger(((Component)this).transform.position); } private void OnDisable() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!triggered) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Air Support: projectile disabled before trigger, using fallback."); } TryTrigger(((Component)this).transform.position); } } private void TryTrigger(Vector3 point) { //IL_0020: 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) if (triggered) { return; } triggered = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Air Support: TryTrigger at {point}"); } ResolveOwner(); if ((Object)(object)owner == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"Air Support: TryTrigger failed because owner is null. ownerPlayerID={ownerPlayerID}"); } return; } AirSupportPlayerController component = ((Component)owner).GetComponent<AirSupportPlayerController>(); if ((Object)(object)component == (Object)null) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)"Air Support: owner had no AirSupportPlayerController."); } } else if (!component.IsActive()) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)"Air Support: controller exists but is not active."); } } else if (!((Object)(object)owner.data == (Object)null) && !((Object)(object)owner.data.view == (Object)null) && owner.data.view.IsMine) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"Air Support: calling air support for playerID={owner.playerID}"); } component.CallAirSupport(point); } } private void ResolveOwner() { //IL_0199: 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) if ((Object)(object)owner != (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Air Support: owner already assigned on projectile start. playerID={owner.playerID}"); } return; } if (ownerPlayerID != -1) { Player[] array = Object.FindObjectsOfType<Player>(); foreach (Player val in array) { if ((Object)(object)val != (Object)null && val.playerID == ownerPlayerID) { owner = val; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"Air Support: owner resolved by playerID. playerID={owner.playerID}"); } return; } } } AirSupportPlayerController[] array2 = Object.FindObjectsOfType<AirSupportPlayerController>(); AirSupportPlayerController airSupportPlayerController = null; int num = 0; AirSupportPlayerController[] array3 = array2; foreach (AirSupportPlayerController airSupportPlayerController2 in array3) { if ((Object)(object)airSupportPlayerController2 != (Object)null && airSupportPlayerController2.IsActive()) { airSupportPlayerController = airSupportPlayerController2; num++; } } if (num == 1 && (Object)(object)airSupportPlayerController != (Object)null) { owner = ((Component)airSupportPlayerController).GetComponent<Player>(); if ((Object)(object)owner != (Object)null) { ownerPlayerID = owner.playerID; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)$"Air Support: owner resolved by active controller fallback. playerID={owner.playerID}"); } return; } } if (num > 1) { float num2 = float.MaxValue; Player val2 = null; array3 = array2; foreach (AirSupportPlayerController airSupportPlayerController3 in array3) { if ((Object)(object)airSupportPlayerController3 == (Object)null || !airSupportPlayerController3.IsActive()) { continue; } Player component = ((Component)airSupportPlayerController3).GetComponent<Player>(); if (!((Object)(object)component == (Object)null)) { float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)component).transform.position); if (num3 < num2) { num2 = num3; val2 = component; } } } if ((Object)(object)val2 != (Object)null) { owner = val2; ownerPlayerID = owner.playerID; ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"Air Support: owner resolved by nearest active player fallback. playerID={owner.playerID}"); } return; } } ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)$"Air Support: owner unresolved. ownerPlayerID={ownerPlayerID}, activeControllers={num}"); } } } public class AirSupportTargetMarker : MonoBehaviour { private SpriteRenderer sr; private float age; private void Start() { sr = ((Component)this).GetComponent<SpriteRenderer>(); } private void Update() { //IL_0049: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) age += Time.deltaTime; float num = 1f + Mathf.Sin(age * 18f) * 0.12f; ((Component)this).transform.localScale = new Vector3(0.7f * num, 0.7f * num, 1f); if ((Object)(object)sr != (Object)null) { Color color = sr.color; color.a = Mathf.Lerp(0.75f, 0.15f, age / 1.2f); sr.color = color; } } } public class AirSupportTracerVisual : MonoBehaviour { private SpriteRenderer sr; private float age; private Vector3 baseScale; public void SetRenderer(SpriteRenderer rendererToUse) { sr = rendererToUse; } private void Start() { //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) baseScale = ((Component)this).transform.localScale; } private void Update() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) age += Time.deltaTime; float num = 1f + Mathf.Sin(age * 40f) * 0.08f; ((Component)this).transform.localScale = new Vector3(baseScale.x * num, baseScale.y, baseScale.z); if ((Object)(object)sr != (Object)null) { float a = Mathf.Clamp01(1f - age / 4f); Color color = sr.color; color.a = a; sr.color = color; } } } public class FountainBulletProjectile : MonoBehaviour { private Player owner; private float damage; public void Initialize(Player newOwner, float newDamage) { owner = newOwner; damage = newDamage; } private void OnTriggerEnter2D(Collider2D other) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_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_006f: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)other == (Object)null) { return; } Player componentInParent = ((Component)other).GetComponentInParent<Player>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)owner != (Object)null) { if ((Object)(object)componentInParent.data != (Object)null && (Object)(object)componentInParent.data.healthHandler != (Object)null) { Vector2 val = Vector2.op_Implicit(((Component)componentInParent).transform.position - ((Component)this).transform.position); Vector2 normalized = ((Vector2)(ref val)).normalized; ((Damagable)componentInParent.data.healthHandler).CallTakeDamage(normalized * damage, Vector2.op_Implicit(((Component)this).transform.position), ((Component)owner).gameObject, owner, true); } Object.Destroy((Object)(object)((Component)this).gameObject); } else if (!other.isTrigger) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public class FountainBulletVisual : MonoBehaviour { private SpriteRenderer sr; private float age; private Vector3 baseScale; public void SetRenderer(SpriteRenderer rendererToUse) { sr = rendererToUse; } private void Start() { //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) baseScale = ((Component)this).transform.localScale; } private void Update() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) age += Time.deltaTime; float num = 1f + Mathf.Sin(age * 30f) * 0.06f; ((Component)this).transform.localScale = new Vector3(baseScale.x * num, baseScale.y, baseScale.z); if ((Object)(object)sr != (Object)null) { Color color = sr.color; color.a = Mathf.Clamp01(1f - age / 3f); sr.color = color; } } } public class FountainCard : CustomCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.damage *= 0.7f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { FountainPlayerController fountainPlayerController = ((Component)player).gameObject.GetComponent<FountainPlayerController>(); if ((Object)(object)fountainPlayerController == (Object)null) { fountainPlayerController = ((Component)player).gameObject.AddComponent<FountainPlayerController>(); } fountainPlayerController.SetActive(value: true); FountainProjectileHook.EnsureAddedToGun(gun, player); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { FountainPlayerController component = ((Component)player).gameObject.GetComponent<FountainPlayerController>(); if ((Object)(object)component != (Object)null) { component.SetActive(value: false); } } protected override string GetTitle() { return "Fountain"; } protected override string GetDescription() { return "Each impact spawns a bullet fountain."; } protected override CardInfoStat[] GetStats() { //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_0014: 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_002b: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: Expected O, but got Unknown //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_005e: 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_0075: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[3] { new CardInfoStat { positive = true, stat = "On impact", amount = "Spawn fountain" }, new CardInfoStat { positive = true, stat = "Bounces", amount = "More fountains" }, new CardInfoStat { positive = false, stat = "Damage", amount = "-30%" } }; } protected override GameObject GetCardArt() { return null; } protected override Rarity GetRarity() { return (Rarity)1; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)3; } public override string GetModName() { return "Aren Mod"; } } public class FountainMarkerVisual : MonoBehaviour { private SpriteRenderer sr; private float age; private void Start() { sr = ((Component)this).GetComponent<SpriteRenderer>(); } private void Update() { //IL_003b: 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_005e: 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) age += Time.deltaTime; float num = Mathf.Lerp(0.45f, 0.8f, age / 0.6f); ((Component)this).transform.localScale = new Vector3(num, num, 1f); if ((Object)(object)sr != (Object)null) { Color color = sr.color; color.a = Mathf.Lerp(0.55f, 0f, age / 0.6f); sr.color = color; } } } public class FountainPlayerController : MonoBehaviour { private static readonly Dictionary<string, float> RecentFountainEvents = new Dictionary<string, float>(); private Player player; private bool active; private static Sprite cachedBulletSprite; private static Sprite cachedCircleSprite; private void Awake() { player = ((Component)this).GetComponent<Player>(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Fountain: player controller awake."); } } public void SetActive(bool value) { active = value; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Fountain: controller active set to {active}"); } } public bool IsActive() { return active; } public void SpawnFountain(Vector3 point) { //IL_009b: 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_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) if (!active || (Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.dead) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Fountain: SpawnFountain aborted due to inactive/dead/null state."); } } else { if ((Object)(object)player.data.view == (Object)null || !player.data.view.IsMine) { return; } int num = Random.Range(int.MinValue, int.MaxValue); HandleNetworkedFountain(player.playerID, point, num); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"Fountain: raising networked fountain event at {point} with seed {num}"); } if (!Plugin.RaiseNetworkEvent("ArenMod_FountainSpawnEvent", player.playerID, point.x, point.y, num)) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogError((object)"Fountain: failed to raise networked fountain event."); } } } } public static void HandleNetworkedFountain(int ownerPlayerID, Vector3 point, int seed) { //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) string text = $"{ownerPlayerID}:{seed}"; if (RecentFountainEvents.TryGetValue(text, out var value) && Time.time - value < 0.35f) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("Fountain: duplicate networked fountain ignored for key=" + text)); } return; } RecentFountainEvents[text] = Time.time; CleanupRecentEvents(); Player[] array = Object.FindObjectsOfType<Player>(); Player val = null; Player[] array2 = array; foreach (Player val2 in array2) { if ((Object)(object)val2 != (Object)null && val2.playerID == ownerPlayerID) { val = val2; break; } } if ((Object)(object)val == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"Fountain: could not resolve owner for networked fountain. playerID={ownerPlayerID}"); } return; } FountainPlayerController fountainPlayerController = ((Component)val).GetComponent<FountainPlayerController>(); if ((Object)(object)fountainPlayerController == (Object)null) { fountainPlayerController = ((Component)val).gameObject.AddComponent<FountainPlayerController>(); } if (!fountainPlayerController.IsActive()) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"Fountain: controller inactive for networked fountain. playerID={ownerPlayerID}"); } return; } bool flag = (Object)(object)val.data != (Object)null && (Object)(object)val.data.view != (Object)null && val.data.view.IsMine; ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"Fountain: received networked fountain at {point}, owner={ownerPlayerID}, damageAuthority={flag}"); } ((MonoBehaviour)fountainPlayerController).StartCoroutine(fountainPlayerController.FountainRoutine(point, seed, flag)); } private static void CleanupRecentEvents() { List<string> list = null; foreach (KeyValuePair<string, float> recentFountainEvent in RecentFountainEvents) { if (Time.time - recentFountainEvent.Value > 2f) { if (list == null) { list = new List<string>(); } list.Add(recentFountainEvent.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { RecentFountainEvents.Remove(list[i]); } } } private IEnumerator FountainRoutine(Vector3 point, int seed, bool dealDamage) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) SpawnMarker(point); int bulletCount = 10; float timeBetween = 0.06f; Gun val = (((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.weaponHandler != (Object)null) ? player.data.weaponHandler.gun : null); float bulletDamage = 0.8f; float bulletSpeed = 18f; if ((Object)(object)val != (Object)null) { bulletDamage = Mathf.Max(0.7f, val.damage * 0.85f); bulletSpeed = Mathf.Max(16f, val.projectileSpeed * 0.5f); } Random rng = new Random(seed); for (int i = 0; i < bulletCount; i++) { float num = Lerp(-0.38f, 0.38f, (float)rng.NextDouble()); float num2 = Lerp(1.15f, 1.55f, (float)rng.NextDouble()); Vector2 val2 = new Vector2(num, num2); Vector2 normalized = ((Vector2)(ref val2)).normalized; float speed = Lerp(bulletSpeed * 0.9f, bulletSpeed * 1.15f, (float)rng.NextDouble()); SpawnFountainBullet(point, normalized, speed, bulletDamage, dealDamage); yield return (object)new WaitForSeconds(timeBetween); } } private void SpawnMarker(Vector3 point) { //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_0010: 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_003d: 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_0063: 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_007e: Expected O, but got Unknown GameObject val = new GameObject("FountainMarker"); val.transform.position = point; SpriteRenderer obj = val.AddComponent<SpriteRenderer>(); obj.sprite = CreateCircleSprite(); obj.color = new Color(0.35f, 0.85f, 1f, 0.55f); ((Renderer)obj).sortingOrder = 110; val.transform.localScale = new Vector3(0.55f, 0.55f, 1f); val.AddComponent<FountainMarkerVisual>(); Object.Destroy((Object)val, 0.6f); } private void SpawnFountainBullet(Vector3 point, Vector2 dir, float speed, float damage, bool dealDamage) { //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_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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_005b: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("FountainBullet"); Vector3 position = point + new Vector3(0f, 0.38f, 0f); val.transform.position = position; float num = Mathf.Atan2(dir.y, dir.x) * 57.29578f; val.transform.rotation = Quaternion.Euler(0f, 0f, num); Rigidbody2D obj = val.AddComponent<Rigidbody2D>(); obj.gravityScale = 1.25f; obj.collisionDetectionMode = (CollisionDetectionMode2D)1; obj.drag = 0f; obj.angularDrag = 0f; obj.velocity = dir * speed; CircleCollider2D obj2 = val.AddComponent<CircleCollider2D>(); ((Collider2D)obj2).isTrigger = true; obj2.radius = 0.14f; SpriteRenderer val2 = val.AddComponent<SpriteRenderer>(); val2.sprite = CreateBulletSprite(); val2.color = new Color(0.55f, 0.95f, 1f, 1f); ((Renderer)val2).sortingOrder = 120; val.transform.localScale = new Vector3(0.5f, 0.16f, 1f); val.AddComponent<FountainBulletVisual>().SetRenderer(val2); if (dealDamage) { val.AddComponent<FountainBulletProjectile>().Initialize(player, damage); } Object.Destroy((Object)(object)val, 4f); } private static float Lerp(float a, float b, float t) { return a + (b - a) * t; } private Sprite CreateBulletSprite() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cachedBulletSprite != (Object)null) { return cachedBulletSprite; } Texture2D val = new Texture2D(16, 4, (TextureFormat)5, false); Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < 4; i++) { for (int j = 0; j < 16; j++) { val.SetPixel(j, i, val2); } } for (int k = 1; k <= 2; k++) { for (int l = 0; l < 16; l++) { float num = (float)l / 15f; Color val3 = Color.Lerp(new Color(0.2f, 0.7f, 1f, 0.15f), new Color(0.9f, 1f, 1f, 1f), num); val.SetPixel(l, k, val3); } } val.Apply(); cachedBulletSprite = Sprite.Create(val, new Rect(0f, 0f, 16f, 4f), new Vector2(0.5f, 0.5f), 16f); return cachedBulletSprite; } private Sprite CreateCircleSprite() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_009d: 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) if ((Object)(object)cachedCircleSprite != (Object)null) { return cachedCircleSprite; } int num = 32; Texture2D val = new Texture2D(num, num, (TextureFormat)5, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2); float num3 = (float)num * 0.36f; float num4 = (float)num * 0.1f; if (num2 <= num3 && num2 >= num3 - num4) { val.SetPixel(j, i, Color.white); } else { val.SetPixel(j, i, new Color(0f, 0f, 0f, 0f)); } } } val.Apply(); cachedCircleSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num); return cachedCircleSprite; } } public static class FountainProjectileHook { public static void EnsureAddedToGun(Gun gun, Player owner) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown if ((Object)(object)gun == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)"Fountain: gun was null in EnsureAddedToGun."); } return; } if ((Object)(object)owner == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)"Fountain: owner was null in EnsureAddedToGun."); } return; } if (gun.objectsToSpawn == null) { gun.objectsToSpawn = (ObjectsToSpawn[])(object)new ObjectsToSpawn[0]; } if (gun.objectsToSpawn.Any((ObjectsToSpawn o) => o != null && (Object)(object)o.AddToProjectile != (Object)null && (Object)(object)o.AddToProjectile.GetComponent<FountainSignalProjectile>() != (Object)null)) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)"Fountain: signal hook already on gun."); } return; } GameObject val = new GameObject("FountainSignalHook"); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<FountainSignalProjectile>().SetOwner(owner); ObjectsToSpawn item = new ObjectsToSpawn { AddToProjectile = val }; List<ObjectsToSpawn> list = gun.objectsToSpawn.ToList(); list.Add(item); gun.objectsToSpawn = list.ToArray(); ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"Fountain: added signal hook to gun for player {owner.playerID}. objectsToSpawn count = {gun.objectsToSpawn.Length}"); } } } public class FountainSignalProjectile : MonoBehaviour { [SerializeField] private int ownerPlayerID = -1; private Player owner; private float lastSpawnTime = -999f; private Vector3 lastSpawnPos = new Vector3(9999f, 9999f, 9999f); private Vector3 previousPosition; private Vector3 previousVelocityLike; private bool hasPreviousSample; public void SetOwner(Player newOwner) { owner = newOwner; if ((Object)(object)newOwner != (Object)null) { ownerPlayerID = newOwner.playerID; } } private void Start() { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Fountain: signal projectile started."); } ResolveOwner(); previousPosition = ((Component)this).transform.position; previousVelocityLike = Vector3.zero; hasPreviousSample = false; } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_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_0018: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; Vector3 val = position - previousPosition; if (hasPreviousSample) { float magnitude = ((Vector3)(ref val)).magnitude; float magnitude2 = ((Vector3)(ref previousVelocityLike)).magnitude; if (magnitude > 0.01f && magnitude2 > 0.01f) { Vector2 val2 = new Vector2(previousVelocityLike.x, previousVelocityLike.y); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(val.x, val.y); float num = Vector2.Angle(val2, val3); bool num2 = num > 28f; bool flag = Mathf.Sign(previousVelocityLike.y) != Mathf.Sign(val.y) && Mathf.Abs(previousVelocityLike.y) > 0.015f && Mathf.Abs(val.y) > 0.015f; bool flag2 = Mathf.Abs(magnitude2 - magnitude) > 0.08f && num > 16f; if (num2 || flag || flag2) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Fountain: bounce-like direction change detected at {position}, angle={num}"); } TrySpawnFountain(position, "direction-change"); } } } previousVelocityLike = val; previousPosition = position; hasPreviousSample = true; } private void OnCollisionEnter2D(Collision2D collision) { //IL_0016: 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) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Fountain: OnCollisionEnter2D at {((Component)this).transform.position}"); } TrySpawnFountain(((Component)this).transform.position, "collision"); } private void OnTriggerEnter2D(Collider2D other) { //IL_0016: 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) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Fountain: OnTriggerEnter2D at {((Component)this).transform.position}"); } TrySpawnFountain(((Component)this).transform.position, "trigger"); } private void OnDisable() { //IL_0016: 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) ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Fountain: OnDisable at {((Component)this).transform.position}"); } TrySpawnFountain(((Component)this).transform.position, "disable"); } private void TrySpawnFountain(Vector3 point, string source) { //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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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) ResolveOwner(); if ((Object)(object)owner == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"Fountain: owner unresolved during {source}. ownerPlayerID={ownerPlayerID}"); } return; } FountainPlayerController component = ((Component)owner).GetComponent<FountainPlayerController>(); if ((Object)(object)component == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("Fountain: no controller during " + source + ".")); } return; } if (!component.IsActive()) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("Fountain: controller inactive during " + source + ".")); } return; } float num = Time.time - lastSpawnTime; float num2 = Vector3.Distance(point, lastSpawnPos); if (num < 0.04f && num2 < 0.28f) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"Fountain: duplicate suppressed from {source}. dt={num:F3}, dist={num2:F3}"); } return; } lastSpawnTime = Time.time; lastSpawnPos = point; ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"Fountain: spawning fountain from {source} at {point} for playerID={owner.playerID}"); } component.SpawnFountain(point); } private void ResolveOwner() { if ((Object)(object)owner != (Object)null) { return; } if (ownerPlayerID != -1) { Player[] array = Object.FindObjectsOfType<Player>(); foreach (Player val in array) { if ((Object)(object)val != (Object)null && val.playerID == ownerPlayerID) { owner = val; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"Fountain: owner resolved by playerID={owner.playerID}"); } return; } } } FountainPlayerController[] array2 = Object.FindObjectsOfType<FountainPlayerController>(); FountainPlayerController fountainPlayerController = null; int num = 0; FountainPlayerController[] array3 = array2; foreach (FountainPlayerController fountainPlayerController2 in array3) { if ((Object)(object)fountainPlayerController2 != (Object)null && fountainPlayerController2.IsActive()) { fountainPlayerController = fountainPlayerController2; num++; } } if (num == 1 && (Object)(object)fountainPlayerController != (Object)null) { owner = ((Component)fountainPlayerController).GetComponent<Player>(); if ((Object)(object)owner != (Object)null) { ownerPlayerID = owner.playerID; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"Fountain: owner resolved by active controller fallback. playerID={owner.playerID}"); } return; } } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"Fountain: ResolveOwner failed. ownerPlayerID={ownerPlayerID}, activeControllers={num}"); } } } public class GlideCard : CustomCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.movementSpeed *= 0.95f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if ((Object)(object)((Component)player).gameObject.GetComponent<UtilityInputController>() == (Object)null) { ((Component)player).gameObject.AddComponent<UtilityInputController>(); } GlideUtility glideUtility = ((Component)player).gameObject.GetComponent<GlideUtility>(); if ((Object)(object)glideUtility == (Object)null) { glideUtility = ((Component)player).gameObject.AddComponent<GlideUtility>(); } glideUtility.SetUtilityActive(value: true); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { GlideUtility component = ((Component)player).gameObject.GetComponent<GlideUtility>(); if ((Object)(object)component != (Object)null) { component.SetUtilityActive(value: false); } } protected override string GetTitle() { return "Glide"; } protected override string GetDescription() { return "Hold Alt in the air to slow your fall."; } protected override CardInfoStat[] GetStats() { //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_0014: 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_002b: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: Expected O, but got Unknown //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_005e: 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_0075: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[3] { new CardInfoStat { positive = true, stat = "Utility", amount = "Alt to glide" }, new CardInfoStat { positive = true, stat = "Glide meter", amount = "Shown above health" }, new CardInfoStat { positive = false, stat = "Move speed", amount = "-5%" } }; } protected override GameObject GetCardArt() { return null; } protected override Rarity GetRarity() { return (Rarity)1; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)3; } public override string GetModName() { return "Aren Mod"; } } public class GlideMeterVisual : MonoBehaviour { private static readonly Vector3 MeterLocalPosition = new Vector3(0f, 1.22f, 0f); private static Sprite barSprite; private GameObject root; private Transform fillTransform; private Transform backgroundTransform; private SpriteRenderer backgroundRenderer; private SpriteRenderer fillRenderer; private void Awake() { EnsureVisuals(); SetMeter(1f, visible: false); } private void LateUpdate() { //IL_0019: 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) if ((Object)(object)root != (Object)null) { root.transform.localPosition = MeterLocalPosition; root.transform.localRotation = Quaternion.identity; } } public void SetMeter(float normalized, bool visible) { //IL_0055: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) EnsureVisuals(); normalized = Mathf.Clamp01(normalized); if ((Object)(object)root != (Object)null && root.activeSelf != visible) { root.SetActive(visible); } if ((Object)(object)fillTransform != (Object)null) { fillTransform.localScale = new Vector3(normalized, 1f, 1f); fillTransform.localPosition = Vector3.zero; } if ((Object)(object)fillRenderer != (Object)null) { fillRenderer.color = Color.Lerp(new Color(1f, 0.25f, 0.12f, 0.95f), new Color(0.25f, 0.9f, 1f, 0.95f), normalized); } } private void EnsureVisuals() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0041: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0097: 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_00f3: 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_0118: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)root != (Object)null)) { root = new GameObject("GlideMeter"); root.transform.SetParent(((Component)this).transform, false); root.transform.localPosition = MeterLocalPosition; root.transform.localScale = new Vector3(0.85f, 0.08f, 1f); GameObject val = new GameObject("Background"); val.transform.SetParent(root.transform, false); val.transform.localPosition = Vector3.zero; val.transform.localScale = Vector3.one; backgroundTransform = val.transform; backgroundRenderer = val.AddComponent<SpriteRenderer>(); backgroundRenderer.sprite = GetBarSprite(); backgroundRenderer.color = new Color(0.02f, 0.08f, 0.1f, 0.75f); ((Renderer)backgroundRenderer).sortingOrder = 151; GameObject val2 = new GameObject("Fill"); val2.transform.SetParent(root.transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localScale = Vector3.one; fillTransform = val2.transform; fillRenderer = val2.AddComponent<SpriteRenderer>(); fillRenderer.sprite = GetBarSprite(); fillRenderer.color = new Color(0.25f, 0.9f, 1f, 0.95f); ((Renderer)fillRenderer).sortingOrder = 152; } } private static Sprite GetBarSprite() { //IL_0017: 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_001f: 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_0043: 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_0061: Expected O, but got Unknown if ((Object)(object)barSprite != (Object)null) { return barSprite; } Texture2D val = new Texture2D(1, 1, (TextureFormat)5, false); val.SetPixel(0, 0, Color.white); val.Apply(); barSprite = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f); return barSprite; } } public class GlideUtility : UtilityAbility { private static readonly FieldInfo PlayerVelocityField = typeof(PlayerVelocity).GetField("velocity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo GravityForceField = typeof(Gravity).GetField("gravityForce", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private const float MaxGlideCharge = 2.75f; private const float GlideDrainPerSecond = 1f; private const float GlideRechargePerSecond = 1.35f; private const float GroundedRechargeDelay = 0.25f; private const float MaxFallSpeedWhileGliding = -3.15f; private const float MaxFallSpeedAfterGlide = -5.25f; private const float GlideReleaseClampTime = 0.55f; private const float GlideGravityMultiplier = 0.08f; private float glideCharge = 2.75f; private float lastAirborneTime; private GlideMeterVisual meterVisual; private Rigidbody2D cachedBody; private Gravity cachedGravity; private float originalGravityForce; private bool hasOriginalGravityForce; private bool wasGliding; private float releaseClampUntil; public override int Priority => 20; protected override void Awake() { base.Awake(); meterVisual = ((Component)this).GetComponent<GlideMeterVisual>(); if ((Object)(object)meterVisual == (Object)null) { meterVisual = ((Component)this).gameObject.AddComponent<GlideMeterVisual>(); } } private void Update() { if (!IsUtilityActive() || (Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null) { StopGlideGravity(); SetMeterVisible(visible: false); return; } UpdateCharge(); UpdateMeter(); if (!ShouldGlide()) { StopGlideGravity(); ApplyReleaseClamp(); } else { StartGlideGravity(); ApplyGlide(); glideCharge = Mathf.Max(0f, glideCharge - 1f * Time.deltaTime); } } private void FixedUpdate() { if (!ShouldGlide()) { ApplyReleaseClamp(); return; } StartGlideGravity(); ApplyGlide(); } private void LateUpdate() { if (!ShouldGlide()) { ApplyReleaseClamp(); } else { ApplyGlide(); } } private void OnDisable() { StopGlideGravity(); } private void OnDestroy() { StopGlideGravity(); } protected override void UseAbility() { } private void UpdateCharge() { if (player.data.isGrounded) { if (Time.time >= lastAirborneTime + 0.25f) { glideCharge = Mathf.Min(2.75f, glideCharge + 1.35f * Time.deltaTime); } } else { lastAirborneTime = Time.time; } } private void ApplyGlide() { ClampFallSpeed(-3.15f); } private void StartGlideGravity() { Gravity val = GetCachedGravity(); if ((Object)(object)val != (Object)null && GravityForceField != null) { if (!hasOriginalGravityForce) { originalGravityForce = (float)GravityForceField.GetValue(val); hasOriginalGravityForce = true; } GravityForceField.SetValue(val, originalGravityForce * 0.08f); } wasGliding = true; } private void StopGlideGravity() { Gravity val = GetCachedGravity(); if ((Object)(object)val != (Object)null && GravityForceField != null && hasOriginalGravityForce) { GravityForceField.SetValue(val, originalGravityForce); } if (wasGliding) { ApplyGlide(); releaseClampUntil = Time.time + 0.55f; wasGliding = false; } } private void ApplyReleaseClamp() { if (!(Time.time > releaseClampUntil)) { ClampFallSpeed(-5.25f); } } private bool ShouldGlide() { if (CanUse() && IsAltHeld() && glideCharge > 0f && (Object)(object)player.data != (Object)null) { return !player.data.isGrounded; } return false; } private void ClampFallSpeed(float maxFallSpeed) { //IL_00bb: 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_00d5: 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_004c: 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_0073: 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) if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.playerVel != (Object)null) { Vector2 val = (Vector2)((PlayerVelocityField != null) ? ((Vector2)PlayerVelocityField.GetValue(player.data.playerVel)) : Vector2.zero); if (val.y < maxFallSpeed) { val.y = maxFallSpeed; PlayerVelocityField?.SetValue(player.data.playerVel, val); } } Rigidbody2D val2 = GetCachedBody(); if ((Object)(object)val2 != (Object)null && val2.velocity.y < maxFallSpeed) { val2.velocity = new Vector2(val2.velocity.x, maxFallSpeed); } } private Rigidbody2D GetCachedBody() { if ((Object)(object)cachedBody == (Object)null) { if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && (Object)(object)player.data.playerVel != (Object)null) { cachedBody = ((Component)player.data.playerVel).GetComponent<Rigidbody2D>(); } if ((Object)(object)cachedBody == (Object)null) { cachedBody = ((Component)this).GetComponent<Rigidbody2D>(); } if ((Object)(object)cachedBody == (Object)null) { cachedBody = ((Component)this).GetComponentInChildren<Rigidbody2D>(); } } return cachedBody; } private Gravity GetCachedGravity() { if ((Object)(object)cachedGravity == (Object)null) { cachedGravity = ((Component)this).GetComponent<Gravity>(); if ((Object)(object)cachedGravity == (Object)null) { cachedGravity = ((Component)this).GetComponentInChildren<Gravity>(); } } return cachedGravity; } private void UpdateMeter() { if (!((Object)(object)meterVisual == (Object)null)) { float num = glideCharge / 2.75f; bool visible = IsUtilityActive() && num < 0.999f; meterVisual.SetMeter(num, visible); } } private void SetMeterVisible(bool visible) { if ((Object)(object)meterVisual != (Object)null) { meterVisual.SetMeter(glideCharge / 2.75f, visible); } } private static bool IsAltHeld() { if (!Input.GetKey((KeyCode)308)) { return Input.GetKey((KeyCode)307); } return true; } } public class GrenadeCard : CustomCard { public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.attackSpeed *= 0.95f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if ((Object)(object)((Component)player).gameObject.GetComponent<UtilityInputController>() == (Object)null) { ((Component)player).gameObject.AddComponent<UtilityInputController>(); } GrenadeUtility grenadeUtility = ((Component)player).gameObject.GetComponent<GrenadeUtility>(); if ((Object)(object)grenadeUtility == (Object)null) { grenadeUtility = ((Component)player).gameObject.AddComponent<GrenadeUtility>(); } grenadeUtility.SetUtilityActive(value: true); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { GrenadeUtility component = ((Component)player).gameObject.GetComponent<GrenadeUtility>(); if ((Object)(object)component != (Object)null) { component.SetUtilityActive(value: false); } } protected override string GetTitle() { return "Grenade"; } protected override string GetDescription() { return "Alt throws a grenade utility."; } protected override CardInfoStat[] GetStats() { //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_0014: 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_002b: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: Expected O, but got Unknown //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_005e: 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_0075: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[4] { new CardInfoStat { positive = true, stat = "Utility", amount = "Alt throws grenade" }, new CardInfoStat { positive = true, stat = "Explosion", amount = "Area damage" }, new CardInfoStat { positive = false, stat = "Utility cooldown", amount = "8s" }, new CardInfoStat { positive = false, stat = "Attack speed", amount = "-5%" } }; } protected override GameObject GetCardArt() { return null; } protected override Rarity GetRarity() { return (Rarity)2; } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)0; } public override string GetModName() { return "Aren Mod"; } } public class GrenadeProjectile : MonoBehaviour { private static readonly FieldInfo ExplosionSpawnedField = typeof(Explosion).GetField("spawned", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ExplosionSoundDamageField = typeof(Explosion).GetField("soundDamage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private const float FuseTime = 1.65f; private const float ExplosionRadius = 3.15f; private const float ExplosionDamage = 35f; private const float ExplosionForce = 115f; private const float ExplosionImmunity = 0.15f; private static Sprite cachedGrenadeSprite; private static GameObject cachedExplosionEffectTemplate; private static ObjectsToSpawn cachedExplosionObjectsToSpawn; private static object cachedExplosionSoundDamage; private Player owner; private bool dealDamage; private float spawnTime; private bool exploded; private SpriteRenderer bodyRenderer; private SpriteRenderer indicatorRenderer; private SpawnedAttack spawnedAttack; private Explosion builtInExplosion; public void Initialize(Player grenadeOwner, bool shouldDealDamage) { owner = grenadeOwner; dealDamage = shouldDealDamage; spawnTime = Time.time; bodyRenderer = ((Component)this).GetComponent<SpriteRenderer>(); Transform obj = ((Component)this).transform.Find("Indicator"); indicatorRenderer = ((obj != null) ? ((Component)obj).GetComponent<SpriteRenderer>() : null); ConfigureBuiltInExplosion(); } private void Update() { UpdateIndicatorFlash(); if (!exploded && Time.time >= spawnTime + 1.65f) { Explode(); } } private void OnCollisionEnter2D(Collision2D collision) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (exploded || Time.time < spawnTime + 0.12f) { return; } Rigidbody2D component = ((Component)this).GetComponent<Rigidbody2D>(); if ((Object)(object)component != (Object)null) { Vector2 velocity = component.velocity; if (((Vector2)(ref velocity)).magnitude < 1.2f) { component.velocity *= 0.65f; } } } private void Explode() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!exploded) { exploded = true; TriggerBuiltInExplosion(((Component)this).transform.position); Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f); } } private void UpdateIndicatorFlash() { //IL_008f: 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_00ae: 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_00f9: 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) if (!((Object)(object)indicatorRenderer == (Object)null)) { float num = Time.time - spawnTime; float num2 = Mathf.Max(0.01f, 1.65f - num); float num3 = Mathf.Lerp(5f, 14f, 1f - Mathf.Clamp01(num2 / 1.65f)); float num4 = 0.5f + 0.5f * Mathf.Sin(Time.time * num3 * MathF.PI * 2f); indicatorRenderer.color = Color.Lerp(new Color(0.4f, 0.05f, 0.05f, 0.65f), new Color(1f, 0.1f, 0.1f, 1f), num4); if ((Object)(object)bodyRenderer != (Object)null) { bodyRenderer.color = Color.Lerp(new Color(0.24f, 0.72f, 0.32f, 1f), new Color(0.32f, 0.9f, 0.42f, 1f), num4 * 0.18f); } } } private void TriggerBuiltInExplosion(Vector3 position) { //IL_0006: 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_0037: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.position = position; if ((Object)(object)builtInExplosion == (Object)null) { ConfigureBuiltInExplosion(); } SpawnBuiltInExplosionVisual(position); Explosion obj = builtInExplosion; if (obj != null) { obj.Explode(); } ApplyFallbackPhysicsPush(position); } private void ConfigureBuiltInExplosion() { if ((Object)(object)spawnedAttack == (Object)null) { spawnedAttack = ((Component)this).gameObject.GetComponent<SpawnedAttack>(); if ((Object)(object)spawnedAttack == (Object)null) { spawnedAttack = ((Component)this).gameObject.AddComponent<SpawnedAttack>(); } } spawnedAttack.spawner = owner; spawnedAttack.attackID = Random.Range(int.MinValue, int.MaxValue); spawnedAttack.attackLevel = 0; if ((Object)(object)builtInExplosion == (Object)null) { builtInExplosion = ((Component)this).gameObject.GetComponent<Explosion>(); if ((Object)(object)builtInExplosion == (Object)null) { builtInExplosion = ((Component)this).gameObject.AddComponent<Explosion>(); } } builtInExplosion.range = 3.15f; builtInExplosion.damage = (dealDamage ? 35f : 0f); builtInExplosion.force = (dealDamage ? 115f : 0f); builtInExplosion.objectForceMultiplier = (dealDamage ? 2f : 0f); builtInExplosion.forceIgnoreMass = true; builtInExplosion.ignoreWalls = false; builtInExplosion.ignoreTeam = false; builtInExplosion.staticRangeMultiplier = false; builtInExplosion.scaleDmg = false; builtInExplosion.scaleForce = false; builtInExplosion.scaleRadius = false; builtInExplosion.scaleSlow = false; builtInExplosion.scaleSilence = false; builtInExplosion.scaleStun = false; builtInExplosion.slow = 0f; builtInExplosion.silence = 0f; builtInExplosion.stun = 0f; builtInExplosion.fastSlow = false; builtInExplosion.immunity = 0.15f; builtInExplosion.flyingFor = 0f; builtInExplosion.auto = false; builtInExplosion.locallySimulated = true; ExplosionSpawnedField?.SetValue(builtInExplosion, spawnedAttack); CopyBuiltInExplosionSound(builtInExplosion); } private static void CopyBuiltInExplosionSound(Explosion target) { if (ExplosionSoundDamageField == null || (Object)(object)target == (Object)null) { return; } if (cachedExplosionSoundDamage == null) { Explosion[] array = Resources.FindObjectsOfTypeAll<Explosion>(); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null) && !((Object)(object)array[i] == (Object)(object)target)) { object value = ExplosionSoundDamageField.GetValue(array[i]); if (value != null) { cachedExplosionSoundDamage = value; break; } } } } if (cachedExplosionSoundDamage != null) { ExplosionSoundDamageField.SetValue(target, cachedExplosionSoundDamage); } } private static void SpawnBuiltInExplosionVisual(Vector3 position) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0028: Unknown result type (might be due to invalid IL or missing references) ObjectsToSpawn val = FindExplosiveShotObjectsToSpawn(); if (val != null) { ObjectsToSpawn.SpawnObject(val, position, Quaternion.identity); return; } GameObject val2 = FindBuiltInExplosionEffectTemplate(); if (!((Object)(object)val2 == (Object)null)) { GameObject val3 = Object.Instantiate<GameObject>(val2, position, Quaternion.identity); val3.SetActive(true); GeneralParticleSystem componentInChildren = val3.GetComponentInChildren<GeneralParticleSystem>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.Play(); } LineEffect componentInChildren2 = val3.GetComponentInChildren<LineEffect>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.Play(val3.transform); } Object.Destroy((Object)(object)val3, 3f); } } private static ObjectsToSpawn FindExplosiveShotObjectsToSpawn() { if (cachedExplosionObjectsToSpawn != null) { return cachedExplosionObjectsToSpawn; } CardInfo[] array = Resources.FindObjectsOfTypeAll<CardInfo>(); foreach (CardInfo val in array) { if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(val.cardName)) { continue; } string text = val.cardName.ToLowerInvariant(); if (!text.Contains("explosive") && !text.Contains("bomb")) { continue; } Gun componentInChildren = ((Component)val).GetComponentInChildren<Gun>(true); if ((Object)(object)componentInChildren == (Object)null || componentInChildren.objectsToSpawn == null) { continue; } for (int j = 0; j < componentInChildren.objectsToSpawn.Length; j++) { ObjectsToSpawn val2 = componentInChildren.objectsToSpawn[j]; if (val2 != null && !((Object)(object)val2.effect == (Object)null)) { cachedExplosionObjectsToSpawn = val2; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("Grenade: using built-in explosion effect from card '" + val.cardName + "' object '" + ((Object)val2.effect).name + "'.")); } return cachedExplosionObjectsToSpawn; } } } return null; } private static GameObject FindBuiltInExplosionEffectTemplate() { if ((Object)(object)cachedExplosionEffectTemplate != (Object)null) { return cachedExplosionEffectTemplate; } GeneralParticleSystem[] array = Resources.FindObjectsOfTypeAll<GeneralParticleSystem>(); foreach (GeneralParticleSystem val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant(); string text2 = (((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Object)((Component)val).transform.parent).name.ToLowerInvariant() : string.Empty); if (text.Contains("explosion") || text2.Contains("explosion")) { cachedExplosionEffectTemplate = (((Object)(object)((Component)val).transform.root != (Object)null) ? ((Component)((Component)val).transform.root).gameObject : ((Component)val).gameObject); return cachedExplosionEffectTemplate; } } } return null; } private static void ApplyFallbackPhysicsPush(Vector3 position) { //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_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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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) Collider2D[] array = Physics2D.OverlapCircleAll(Vector2.op_Implicit(position), 3.15f); HashSet<Rigidbody2D> hashSet = new HashSet<Rigidbody2D>(); foreach (Collider2D val in array) { if ((Object)(object)val == (Object)null || val.isTrigger) { continue; } Rigidbody2D attachedRigidbody = val.attachedRigidbody; if (!((Object)(object)attachedRigidbody == (Object)null) && !hashSet.Contains(attachedRigidbody) && !((Object)(object)((Component)attachedRigidbody).GetComponentInParent<CharacterData>() != (Object)null)) { Bounds bounds = val.bounds; Vector2 val2 = Vector2.op_Implicit(((Bounds)(ref bounds)).ClosestPoint(position)) - Vector2.op_Implicit(position); float num = Mathf.Max(0.1f, ((Vector2)(ref val2)).magnitude); float num2 = Mathf.Clamp01(1f - num / 3.15f); if (((Vector2)(ref val2)).sqrMagnitude < 0.001f) { val2 = Vector2.up; } attachedRigidbody.AddForce(((Vector2)(ref val2)).normalized * 115f * 0.75f * num2, (ForceMode2D)1); hashSet.Add(attachedRigidbody); } } } public static Sprite CreateGrenadeSprite() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_00af: 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_0045: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cachedGrenadeSprite != (Object)null) { return cachedGrenadeSprite; } int num = 16; Texture2D val = new Texture2D(num, num, (TextureFormat)5, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)num / 2f, (float)num / 2f); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val2); val.SetPixel(j, i, (Color)((num2 <= (float)num * 0.35f) ? Color.white : new Color(0f, 0f, 0f, 0f))); } } val.Apply(); cachedGrenadeSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), (float)num); return cachedGrenadeSprite; } } public class GrenadeUtility : UtilityAbility { private const float UtilityCooldown = 8f; private const float ThrowSpeed = 16f; private const float UpwardBoost = 2.5f; private static readonly Dictionary<string, float> RecentGrenadeEvents = new Dictionary<string, float>(); private float nextUseTime; public override int Priority => 10; public static void HandleNetworkedGrenade(int ownerPlayerID, Vector3 spawnPosition, Vector2 velocity, int throwId) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) string key = $"{ownerPlayerID}:{throwId}"; if (RecentGrenadeEvents.TryGetValue(key, out var value) && Time.time - value < 0.4f) { return; } RecentGrenadeEvents[key] = Time.time; CleanupRecentEvents(); Player[] array = Object.FindObjectsOfType<Player>(); Player val = null; for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && array[i].playerID == ownerPlayerID) { val = array[i]; break; } } if ((Object)(object)val == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"Grenade: could not resolve owner for throw. playerID={ownerPlayerID}"); } } else { bool dealDamage = (Object)(object)val.data != (Object)null && (Object)(object)val.data.view != (Object)null && val.data.view.IsMine; SpawnGrenadeObject(val, spawnPosition, velocity, dealDamage); } } protected override bool CanUse() { if (base.CanUse()) { return Time.time >= nextUseTime; } return false; } protected override void UseAbility() { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result typ