Decompiled source of Hugos Cards v0.10.12
plugins/CustomCards.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using CustomCards.Cards; using CustomCards.Effects; using CustomCards.Patches; using CustomCards.Testing; using HarmonyLib; using InControl; using Microsoft.CodeAnalysis; using ModdingUtils.Extensions; using ModdingUtils.MonoBehaviours; using ModdingUtils.Utils; using Photon.Pun; using Sonigon; using Sonigon.Internal; using TMPro; using UnboundLib; using UnboundLib.Cards; using UnboundLib.Extensions; using UnboundLib.GameModes; using UnboundLib.Networking; using UnboundLib.Utils; using UnboundLib.Utils.UI; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyCompany("CustomCards")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CustomCards")] [assembly: AssemblyTitle("CustomCards")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CustomCards { internal static class CardUtils { private static readonly FieldRef<PlayerVelocity, Vector2> PlayerVelocityField = AccessTools.FieldRefAccess<PlayerVelocity, Vector2>("velocity"); public static int CountCard(Player player, string cardName) { if ((Object)(object)player == (Object)null || (Object)(object)player.data == (Object)null || player.data.currentCards == null) { return 0; } return player.data.currentCards.Count((CardInfo c) => (Object)(object)c != (Object)null && c.cardName == cardName); } public static bool Alive(Player p) { if ((Object)(object)p != (Object)null && (Object)(object)p.data != (Object)null && !p.data.dead) { return p.data.isPlaying; } return false; } public static IEnumerable<Player> Enemies(Player player) { return PlayerManager.instance.players.Where((Player p) => (Object)(object)p != (Object)(object)player && p.teamID != player.teamID && Alive(p)); } public static Player ClosestEnemy(Player player) { return (from p in Enemies(player) orderby Vector2.Distance(Vector2.op_Implicit(((Component)p).transform.position), Vector2.op_Implicit(((Component)player).transform.position)) select p).FirstOrDefault(); } public static Vector2 Velocity(Player player) { //IL_001c: 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) if (!((Object)(object)player != (Object)null) || !((Object)(object)player.data.playerVel != (Object)null)) { return Vector2.zero; } return PlayerVelocityField.Invoke(player.data.playerVel); } public static T Ensure<T>(Player player) where T : Component { T component = ((Component)player).GetComponent<T>(); if (!((Object)(object)component != (Object)null)) { return ((Component)player).gameObject.AddComponent<T>(); } return component; } } public abstract class CardBehaviour : MonoBehaviour { protected Player player; protected CharacterData data; protected abstract string CardName { get; } protected int Stacks => CardUtils.CountCard(player, CardName); protected virtual void Awake() { player = ((Component)this).GetComponent<Player>(); data = ((Component)this).GetComponent<CharacterData>(); } protected virtual void Update() { if (Stacks <= 0) { Object.Destroy((Object)(object)this); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.custom.rounds.customcards", "Hugo's Cards", "0.10.12")] [BepInProcess("Rounds.exe")] public class CustomCardsPlugin : BaseUnityPlugin { public const string ModId = "com.custom.rounds.customcards"; public const string ModName = "Hugo's Cards"; public const string Version = "0.10.12"; public const string ModInitials = "HC"; internal static ManualLogSource Log; internal static CustomCardsPlugin Instance; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; new Harmony("com.custom.rounds.customcards").PatchAll(); Log.LogInfo((object)"Patches applied."); } private void Start() { CustomCard.BuildCard<DemoCard>(); CustomCard.BuildCard<NeoCard>(); CustomCard.BuildCard<BalloonCard>((Action<CardInfo>)delegate(CardInfo card) { BalloonCard.Card = card; }); CustomCard.BuildCard<PiercerCard>(); CustomCard.BuildCard<NormalizeCard>(); CustomCard.BuildCard<GreedCard>(); GreedPicks.RegisterHooks(); CustomCard.BuildCard<TopsyTurvyCard>(); TopsyTurvy.RegisterHooks(); CustomCard.BuildCard<PlatingCard>(); CustomCard.BuildCard<MossCard>(); CustomCard.BuildCard<TreasureMapCard>(); CustomCard.BuildCard<BloodthirstyCard>(); CustomCard.BuildCard<FragileCard>(); CustomCard.BuildCard<OneManArmyCard>(); CustomCard.BuildCard<DetonaterCard>(); CustomCard.BuildCard<RocketBootsCard>(); CustomCard.BuildCard<TeslaCard>(); CustomCard.BuildCard<ChickenCard>(); CustomCard.BuildCard<WoundedCard>(); CustomCard.BuildCard<SlipperyCard>(); CustomCard.BuildCard<ForcePushCard>(); CustomCard.BuildCard<FlameOnCard>(); CustomCard.BuildCard<RouletteCard>(); CustomCard.BuildCard<TranscendenceCard>(); CustomCard.BuildCard<DoublingCherryCard>(); DoublingCherry.RegisterHooks(); TreasureMap.RegisterHooks(); PerPointResets.RegisterHooks(); CardManager.AddAllCardsCallback((Action<CardInfo[]>)BalloonCard.CopyGrowEffect); CardManager.AddAllCardsCallback((Action<CardInfo[]>)DetonaterCard.FindExplosion); TestMap.Init(); } } } namespace CustomCards.Testing { internal class DamageRecord { public float time = Time.time; public Player victim; public Player attacker; public string source; public readonly List<string> steps = new List<string>(); public float current; public float applied = -1f; public float hpBefore; public float hpAfter; public float maxHp; public bool blocked; public bool refilled; public bool delayed; public bool logged; public void Step(string text) { steps.Add(text); } } internal class BulletNotes : MonoBehaviour { public float fired; public float finalAtFire = float.NaN; public readonly List<string> mods = new List<string>(); } internal static class DamageLog { public struct FloatingNumber { public Vector3 pos; public string text; public Color color; public float born; } public const int MaxRecords = 40; public static readonly List<DamageRecord> Records = new List<DamageRecord>(); public static readonly List<FloatingNumber> Numbers = new List<FloatingNumber>(); internal static string SourceOverride; internal static ProjectileHit CurrentBullet; private static readonly Stack<DamageRecord> sending = new Stack<DamageRecord>(); public static bool Enabled => TestMap.Active; internal static DamageRecord Top { get { if (sending.Count <= 0) { return null; } return sending.Peek(); } } public static void Step(string label, float before, float after) { if (Enabled && sending.Count != 0 && !Mathf.Approximately(before, after)) { DamageRecord damageRecord = sending.Peek(); damageRecord.Step($"{label}: {before:0.#} → {after:0.#}"); damageRecord.current = after; } } public static void Clear() { Records.Clear(); Numbers.Clear(); sending.Clear(); SourceOverride = null; CurrentBullet = null; } internal static DamageRecord Begin(HealthHandler victim, Vector2 damage, Player attacker) { DamageRecord damageRecord = new DamageRecord { victim = ((Component)victim).GetComponent<Player>(), attacker = attacker, source = Classify(), current = ((Vector2)(ref damage)).magnitude }; ProjectileHit currentBullet = CurrentBullet; if (SourceOverride == null && (Object)(object)currentBullet != (Object)null) { BulletNotes component = ((Component)currentBullet).GetComponent<BulletNotes>(); if ((Object)(object)component != (Object)null) { damageRecord.Step($"Bullet fired with {component.fired:0.#} damage"); foreach (string mod in component.mods) { damageRecord.Step(mod); } } float num = (((Object)(object)component != (Object)null) ? component.finalAtFire : float.NaN); if (!float.IsNaN(num) && Mathf.Abs(num - currentBullet.damage) > 0.05f) { damageRecord.Step($"Changed in flight (Grow/Balloon etc.): {num:0.#} → {currentBullet.damage:0.#}"); } if (currentBullet.percentageDamage != 0f) { damageRecord.Step($"+{currentBullet.percentageDamage * 100f:0.#}% of max HP (vanilla percentage damage)"); } if (!Mathf.Approximately(currentBullet.dealDamageMultiplierr, 1f)) { damageRecord.Step($"Damage multiplier ×{currentBullet.dealDamageMultiplierr:0.##}"); } } damageRecord.Step($"Hit for {damageRecord.current:0.#}"); return damageRecord; } internal static void Push(DamageRecord rec) { sending.Push(rec); } internal static void Pop() { if (sending.Count > 0) { sending.Pop(); } } internal static void Finish(DamageRecord rec, Vector3 pos) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (!rec.logged) { rec.logged = true; Records.Insert(0, rec); if (Records.Count > 40) { Records.RemoveAt(Records.Count - 1); } string text; Color color = default(Color); if (rec.blocked) { text = "BLOCKED"; ((Color)(ref color))..ctor(0.4f, 0.8f, 1f); } else if (rec.delayed && rec.applied < 0f) { text = $"{rec.current:0.#} over time"; ((Color)(ref color))..ctor(0.7f, 1f, 0.4f); } else { text = $"-{rec.applied:0.#}" + (rec.refilled ? " (lethal)" : ""); color = (rec.refilled ? new Color(1f, 0.85f, 0.2f) : new Color(1f, 0.35f, 0.3f)); } Numbers.Add(new FloatingNumber { pos = pos + Vector3.up * 2f + Vector2.op_Implicit(Random.insideUnitCircle * 0.5f), text = text, color = color, born = Time.time }); if (Numbers.Count > 60) { Numbers.RemoveAt(0); } TestDummy testDummy = (((Object)(object)rec.victim != (Object)null) ? ((Component)rec.victim).GetComponent<TestDummy>() : null); if ((Object)(object)testDummy != (Object)null && rec.applied > 0f) { testDummy.OnDamaged(rec.applied); } } } private static string Classify() { if (SourceOverride != null) { return SourceOverride; } if ((Object)(object)CurrentBullet != (Object)null) { return "Bullet"; } try { StackFrame[] array = new StackTrace(2, fNeedFileInfo: false).GetFrames() ?? new StackFrame[0]; for (int i = 0; i < array.Length; i++) { string text = FrameType(array[i]); if (text != null && !text.StartsWith("HealthHandler") && !text.StartsWith("Damagable") && !text.StartsWith("System") && !text.StartsWith("HarmonyLib") && !text.StartsWith("MonoMod") && !text.StartsWith("Photon") && !text.StartsWith("CustomCards.Testing") && !text.Contains("PhotonView") && !text.Contains("NetworkingPeer")) { if (text.Contains("ProjectileHit")) { return "Bullet"; } if (text.Contains("Explosion")) { return "Explosion"; } if (text.Contains("DamageOverTime")) { return "Damage over time"; } if (text.Contains("FlameOn")) { return "Flame on! fire"; } if (text.Contains("Tesla")) { return "Tesla arc"; } if (text.Contains("OutOfBounds")) { return "Out of bounds"; } int num = text.LastIndexOf('.'); return (num >= 0) ? text.Substring(num + 1) : text; } } } catch (Exception) { } return "Unknown"; } private static string FrameType(StackFrame frame) { MethodBase method = frame.GetMethod(); if (method == null) { return null; } if (method.DeclaringType != null) { return method.DeclaringType.FullName; } string name = method.Name; int num = name.IndexOf('<'); int num2 = name.IndexOf("::", StringComparison.Ordinal); if (num < 0 || num2 <= num) { return null; } return name.Substring(num + 1, num2 - num - 1); } } [HarmonyPatch(typeof(ProjectileHit), "RPCA_DoHit")] internal static class DamageLogBulletContext { [HarmonyPriority(800)] private static void Prefix(ProjectileHit __instance, out ProjectileHit __state) { __state = DamageLog.CurrentBullet; if (DamageLog.Enabled) { DamageLog.CurrentBullet = __instance; } } private static Exception Finalizer(Exception __exception, ProjectileHit __state) { DamageLog.CurrentBullet = __state; return __exception; } } [HarmonyPatch(typeof(HealthHandler), "CallTakeDamage")] internal static class DamageLogSendStart { [HarmonyPriority(800)] private static void Prefix(HealthHandler __instance, Vector2 damage, Player damagingPlayer, out DamageRecord __state) { //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_0032: Unknown result type (might be due to invalid IL or missing references) __state = null; if (DamageLog.Enabled && !(damage == Vector2.zero) && !((Object)(object)((Component)__instance).GetComponent<Player>() == (Object)null) && !DoublingCherry.SameGroup(__instance, damagingPlayer)) { __state = DamageLog.Begin(__instance, damage, damagingPlayer); DamageLog.Push(__state); } } private static Exception Finalizer(Exception __exception, HealthHandler __instance, DamageRecord __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (__state != null) { DamageLog.Pop(); if (__state.applied < 0f) { if (!__state.blocked) { __state.delayed = true; } DamageLog.Finish(__state, ((Component)__instance).transform.position); } } return __exception; } } [HarmonyPatch(typeof(HealthHandler), "CallTakeDamage")] internal static class DamageLogSendEnd { [HarmonyPriority(0)] private static void Prefix(HealthHandler __instance, Vector2 damage) { DamageRecord top = DamageLog.Top; if (top != null && DamageLog.Enabled) { float magnitude = ((Vector2)(ref damage)).magnitude; if (Mathf.Abs(magnitude - top.current) > 0.05f) { top.Step($"Other mods: {top.current:0.#} → {magnitude:0.#}"); top.current = magnitude; } CharacterData component = ((Component)__instance).GetComponent<CharacterData>(); if ((Object)(object)component != (Object)null && component.block.IsBlocking()) { top.blocked = true; } } } } [HarmonyPatch(typeof(HealthHandler), "DoDamage")] internal static class DamageLogApply { [HarmonyPriority(800)] private static void Prefix(HealthHandler __instance, Vector2 damage, Player damagingPlayer, bool ignoreBlock, out DamageRecord __state) { //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_007c: Unknown result type (might be due to invalid IL or missing references) __state = null; if (!DamageLog.Enabled || damage == Vector2.zero) { return; } CharacterData component = ((Component)__instance).GetComponent<CharacterData>(); if (!((Object)(object)component == (Object)null) && component.isPlaying && !component.dead && !__instance.isRespawning && (!component.block.IsBlocking() || ignoreBlock)) { DamageRecord damageRecord = DamageLog.Top; if (damageRecord == null || (Object)(object)damageRecord.victim != (Object)(object)component.player || damageRecord.applied >= 0f) { damageRecord = DamageLog.Begin(__instance, damage, damagingPlayer); } else if (Mathf.Abs(((Vector2)(ref damage)).magnitude - damageRecord.current) > 0.05f) { damageRecord.Step($"Changed on arrival: {damageRecord.current:0.#} → {((Vector2)(ref damage)).magnitude:0.#}"); damageRecord.current = ((Vector2)(ref damage)).magnitude; } damageRecord.hpBefore = component.health; damageRecord.maxHp = component.maxHealth; if (((Vector2)(ref damage)).magnitude >= component.health && TestMap.IsImmortal(component.player)) { damageRecord.refilled = true; component.health = ((Vector2)(ref damage)).magnitude + component.maxHealth; } __state = damageRecord; } } private static void Postfix(HealthHandler __instance, Vector2 damage, DamageRecord __state) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (__state != null) { CharacterData component = ((Component)__instance).GetComponent<CharacterData>(); __state.hpAfter = component.health; __state.applied = (__state.refilled ? ((Vector2)(ref damage)).magnitude : (__state.hpBefore - component.health)); DamageLog.Finish(__state, ((Component)__instance).transform.position); if (__state.refilled && (Object)(object)((Component)component.player).GetComponent<TestDummy>() != (Object)null && DamageLog.SourceOverride != "Detonater explosion") { __state.Step("Counts as a kill (Detonater, Bloodthirsty)"); Detonater.OnPlayerDied(component.player); Bloodthirsty.OnPlayerDied(component.player); } } } } public enum DummyKind { Target, Shooter } public class TestDummy : MonoBehaviour { public DummyKind Kind; public Vector3 Home; public bool Disabled; private const float DpsWindow = 3f; private const float AutoHealDelay = 2.5f; private readonly Queue<KeyValuePair<float, float>> recent = new Queue<KeyValuePair<float, float>>(); private Player player; private CharacterData data; private float nextShot; public float TotalDamage { get; private set; } public int Hits { get; private set; } public float BiggestHit { get; private set; } public float LastDamaged { get; private set; } = -100f; public string Name { get { if (Kind != DummyKind.Target) { return "Shooter dummy"; } return "Target dummy"; } } public float Dps { get { while (recent.Count > 0 && Time.time - recent.Peek().Key > 3f) { recent.Dequeue(); } float num = 0f; foreach (KeyValuePair<float, float> item in recent) { num += item.Value; } return num / 3f; } } private void Awake() { player = ((Component)this).GetComponent<Player>(); data = ((Component)this).GetComponent<CharacterData>(); } public void OnDamaged(float amount) { TotalDamage += amount; Hits++; BiggestHit = Mathf.Max(BiggestHit, amount); LastDamaged = Time.time; recent.Enqueue(new KeyValuePair<float, float>(Time.time, amount)); } public void ResetStats() { TotalDamage = 0f; Hits = 0; BiggestHit = 0f; recent.Clear(); } private void Update() { //IL_00a3: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if (!TestMap.Active || (Object)(object)data == (Object)null) { return; } GeneralInput input = data.input; input.ResetInput(); if (!CardUtils.Alive(player)) { return; } if (TestMap.DummiesAutoHeal && Time.time - LastDamaged > 2.5f && data.health < data.maxHealth) { data.health = data.maxHealth; } if (TestMap.DummiesWalkBack && data.isGrounded) { float num = Home.x - ((Component)this).transform.position.x; if (Mathf.Abs(num) > 0.8f) { input.direction = new Vector3(Mathf.Sign(num), 0f, 0f); } } Player human = TestMap.Human; if (!((Object)(object)human == (Object)null) && CardUtils.Alive(human)) { Vector3 val = ((Component)human).transform.position - ((Component)this).transform.position; val.z = 0f; ((Vector3)(ref val)).Normalize(); Gun val2 = (((Object)(object)data.weaponHandler != (Object)null) ? data.weaponHandler.gun : null); if ((Object)(object)val2 != (Object)null) { val += Vector3.up * 0.13f / Mathf.Clamp(val2.projectileSpeed, 1f, 100f); } input.aimDirection = val; input.lastAimDirection = val; if (Kind == DummyKind.Shooter && TestMap.ShooterFiring && Time.time >= nextShot) { nextShot = Time.time + TestMap.ShooterInterval; input.shootWasPressed = true; input.shootIsPressed = true; } } } } internal static class TestMap { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Open; public static Action <1>__SpawnProps; } public const float FloorTop = -9f; public static readonly Vector3 PlayerSpawn = new Vector3(0f, -7f, 0f); public static readonly Vector3 TargetSpawn = new Vector3(14f, -7f, 0f); public static readonly Vector3 ShooterSpawn = new Vector3(-14f, -7f, 0f); private const float PropStartX = -31f; private const float PropSpacing = 3.2f; private static readonly string[] PropNames = new string[6] { "box", "box_medium", "box_destructible", "box_destructible_small", "box_big", "ball_big" }; public static bool DummiesImmortal = true; public static bool DummiesAutoHeal = true; public static bool DummiesWalkBack = true; public static bool ShooterFiring = true; public static float ShooterInterval = 1f; public static bool GodMode; public static float TimeScale = 1f; private static Map map; private static GameObject floor; private static readonly List<GameObject> props = new List<GameObject>(); private static bool dummiesRequested; private static float defaultBaseTimeScale = -1f; private static readonly Dictionary<string, bool> propEnabled = PropNames.ToDictionary((string n) => n, (string n) => true); private static readonly Dictionary<string, GameObject> propByName = new Dictionary<string, GameObject>(); private static float lastJoinAt = -10f; private static readonly FieldRef<PlayerVelocity, Vector2> Velocity = AccessTools.FieldRefAccess<PlayerVelocity, Vector2>("velocity"); public static bool Active { get; private set; } public static Player Human { get { if (!((Object)(object)PlayerManager.instance == (Object)null)) { return ((IEnumerable<Player>)PlayerManager.instance.players).FirstOrDefault((Func<Player, bool>)((Player p) => (Object)(object)p != (Object)null && (Object)(object)((Component)p).GetComponent<TestDummy>() == (Object)null && !p.data.input.controlledElseWhere)); } return null; } } public static IEnumerable<string> PropList => PropNames; public static Player Dummy(DummyKind kind) { if (!((Object)(object)PlayerManager.instance == (Object)null)) { return ((IEnumerable<Player>)PlayerManager.instance.players).FirstOrDefault((Func<Player, bool>)delegate(Player p) { if ((Object)(object)p != (Object)null) { TestDummy component = ((Component)p).GetComponent<TestDummy>(); if (component != null) { return component.Kind == kind; } } return false; }); } return null; } public static bool IsImmortal(Player p) { if (!Active || (Object)(object)p == (Object)null) { return false; } if ((Object)(object)((Component)p).GetComponent<TestDummy>() != (Object)null) { return DummiesImmortal; } if (GodMode) { return (Object)(object)p == (Object)(object)Human; } return false; } public static void Init() { SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name == "Main") { Leave(); } }; ((MonoBehaviour)CustomCardsPlugin.Instance).StartCoroutine(KeepMenuButton()); ((Component)CustomCardsPlugin.Instance).gameObject.AddComponent<TestMapUI>(); } private static IEnumerator KeepMenuButton() { while (true) { yield return (object)new WaitForSecondsRealtime(1f); if (Active) { continue; } GameObject val = GameObject.Find("/Game/UI/UI_MainMenu/Canvas/ListSelector/LOCAL"); Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.Find("Group/Grid/Scroll View/Viewport/Content") : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.Find("CC Test Map") != (Object)null) { continue; } try { object obj = <>O.<0>__Open; if (obj == null) { UnityAction val3 = Open; <>O.<0>__Open = val3; obj = (object)val3; } GameObject val4 = MenuHandler.CreateButton("TEST MAP", val, (UnityAction)obj, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null); ((Object)val4).name = "CC Test Map"; Transform val5 = val2.Find("Test"); if ((Object)(object)val5 != (Object)null) { val4.transform.SetSiblingIndex(val5.GetSiblingIndex() + 1); } } catch (Exception ex) { CustomCardsPlugin.Log.LogWarning((object)("Test map: couldn't add menu button: " + ex)); } } } private static void Open() { Active = true; dummiesRequested = false; DamageLog.Clear(); MainMenuHandler.instance.Close(); GameModeManager.SetGameMode("Sandbox"); GameModeManager.CurrentHandler.StartGame(); CustomCardsPlugin.Log.LogInfo((object)"Test map: opened. Press jump/any button to join."); } private static void Leave() { if (Active) { Active = false; SetTimeScale(1f); map = null; floor = null; props.Clear(); propByName.Clear(); DamageLog.Clear(); Unbound.lockInputBools.Remove("CustomCards_TestMap"); } } internal static void BuildFrom(Scene scene) { //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) Map val = (from g in ((Scene)(ref scene)).GetRootGameObjects() select g.GetComponent<Map>()).FirstOrDefault((Func<Map, bool>)((Map x) => (Object)(object)x != (Object)null)); if ((Object)(object)val == (Object)null) { CustomCardsPlugin.Log.LogWarning((object)"Test map: loaded scene has no Map."); return; } val.size = 20f; Collider2D val2 = FindGroundTemplate(val); GameObject val3 = (((Object)(object)val2 != (Object)null) ? CloneAsFloor(((Component)val2).gameObject, ((Component)val).transform) : FloorFromBoxPrefab(((Component)val).transform)); if ((Object)(object)val3 == (Object)null) { CustomCardsPlugin.Log.LogWarning((object)"Test map: couldn't build a floor; using the normal map."); return; } foreach (Transform item in ((IEnumerable)((Component)val).transform).Cast<Transform>().ToList()) { if ((Object)(object)((Component)item).gameObject != (Object)(object)val3) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } } GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val4 in rootGameObjects) { if ((Object)(object)val4 != (Object)(object)((Component)val).gameObject && (Object)(object)val4.GetComponentInChildren<Collider2D>(true) != (Object)null) { Object.DestroyImmediate((Object)(object)val4); } } val3.transform.SetAsFirstSibling(); AddSpawnPoint(val, PlayerSpawn, 0); AddSpawnPoint(val, TargetSpawn, 1); AddSpawnPoint(val, ShooterSpawn, 1); map = val; floor = val3; props.Clear(); propByName.Clear(); val.mapIsReadyAction = (Action)Delegate.Combine(val.mapIsReadyAction, new Action(SpawnProps)); CustomCardsPlugin.Log.LogInfo((object)("Test map: built from '" + ((Scene)(ref scene)).name + "' using floor template '" + (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "box prefab") + "'.")); } private static Collider2D FindGroundTemplate(Map m) { List<BoxCollider2D> list = ((Component)m).GetComponentsInChildren<BoxCollider2D>(true).Where(delegate(BoxCollider2D c) { //IL_0009: 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_003f: 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_0069: Invalid comparison between Unknown and I4 if (((Collider2D)c).isTrigger || c.size.x <= 0f || c.size.y <= 0f) { return false; } SpriteRenderer component = ((Component)c).GetComponent<SpriteRenderer>(); if ((Object)(object)component == (Object)null || component.color.a < 0.5f) { return false; } Rigidbody2D componentInParent = ((Component)c).GetComponentInParent<Rigidbody2D>(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.bodyType != 2) { return false; } return (Object)(object)((Component)c).GetComponentInParent<PhotonMapObject>() == (Object)null && (Object)(object)((Component)c).GetComponentInParent<NetworkPhysicsObject>() == (Object)null; }).ToList(); List<BoxCollider2D> list2 = list.Where((BoxCollider2D c) => ((Component)c).GetComponents<MonoBehaviour>().All((MonoBehaviour b) => (Object)(object)b == (Object)null || b is SFPolygon)).ToList(); return (Collider2D)(object)((list2.Count > 0) ? list2 : list).OrderByDescending((BoxCollider2D c) => c.size.x * ((Component)c).transform.lossyScale.x * c.size.y * ((Component)c).transform.lossyScale.y).FirstOrDefault(); } private static GameObject CloneAsFloor(GameObject template, Transform parent) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(template, parent); ((Object)val).name = "Test floor"; foreach (Transform item in ((IEnumerable)val.transform).Cast<Transform>().ToList()) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } ShapeFloor(val, template.transform.position.z); return val; } private static GameObject FloorFromBoxPrefab(Transform parent) { GameObject val = ((IEnumerable<GameObject>)Resources.LoadAll<GameObject>("4 Map Objects")).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => ((Object)p).name.ToLower() == "box")); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate<GameObject>(val, parent); ((Object)val2).name = "Test floor"; MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val3 in componentsInChildren) { if (!(val3 is SFPolygon) && !(val3 is PhotonView)) { Object.DestroyImmediate((Object)(object)val3); } } PhotonView[] componentsInChildren2 = val2.GetComponentsInChildren<PhotonView>(true); for (int num = 0; num < componentsInChildren2.Length; num++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[num]); } Rigidbody2D[] componentsInChildren3 = val2.GetComponentsInChildren<Rigidbody2D>(true); for (int num = 0; num < componentsInChildren3.Length; num++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[num]); } if ((Object)(object)val2.GetComponent<BoxCollider2D>() == (Object)null) { Object.DestroyImmediate((Object)(object)val2); return null; } ShapeFloor(val2, 0f); return val2; } private static void ShapeFloor(GameObject g, float z) { //IL_000d: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) BoxCollider2D component = g.GetComponent<BoxCollider2D>(); g.transform.localRotation = Quaternion.identity; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(100f / component.size.x, 14f / component.size.y, 1f); g.transform.localScale = val; g.transform.localPosition = new Vector3((0f - ((Collider2D)component).offset.x) * val.x, -16f - ((Collider2D)component).offset.y * val.y, z); SFPolygon component2 = g.GetComponent<SFPolygon>(); if ((Object)(object)component2 != (Object)null) { component2.CopyFromCollider((Collider2D)(object)component); } } private static void AddSpawnPoint(Map m, Vector3 pos, int team) { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Test spawn"); val.transform.SetParent(((Component)m).transform, false); val.transform.localPosition = pos; val.AddComponent<SpawnPoint>().TEAMID = team; } public static bool IsPropEnabled(string name) { bool value; return propEnabled.TryGetValue(name, out value) && value; } public static string PropLabel(string name) { return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(name.Replace('_', ' ')); } public static void SetPropEnabled(string name, bool on) { if (!propEnabled.ContainsKey(name) || propEnabled[name] == on) { return; } propEnabled[name] = on; if (Active && !((Object)(object)map == (Object)null)) { GameObject value; if (on) { SpawnProp(name); } else if (propByName.TryGetValue(name, out value)) { DestroyProp(value); props.Remove(value); propByName.Remove(name); } } } private static void SpawnProps() { if (!Active || (Object)(object)map == (Object)null) { return; } string[] propNames = PropNames; foreach (string name in propNames) { if (IsPropEnabled(name)) { SpawnProp(name); } } } private static void SpawnProp(string name) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (propByName.TryGetValue(name, out var value) && (Object)(object)value != (Object)null) { return; } GameObject val = ((IEnumerable<GameObject>)Resources.LoadAll<GameObject>("4 Map Objects")).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => ((Object)p).name.ToLower() == name)); if ((Object)(object)val == (Object)null) { return; } float num = -31f + 3.2f * (float)Array.IndexOf(PropNames, name); try { GameObject val2 = PhotonNetwork.Instantiate("4 Map Objects/" + ((Object)val).name, new Vector3(num, -5f, 0f), Quaternion.identity, (byte)0, (object[])null); props.Add(val2); propByName[name] = val2; ((MonoBehaviour)CustomCardsPlugin.Instance).StartCoroutine(WakeProp(val2)); } catch (Exception ex) { CustomCardsPlugin.Log.LogWarning((object)("Test map: couldn't spawn " + ((Object)val).name + ": " + ex.Message)); } } public static bool IsDummyEnabled(DummyKind kind) { Player val = Dummy(kind); if ((Object)(object)val != (Object)null) { return !((Component)val).GetComponent<TestDummy>().Disabled; } return false; } public static void SetDummyEnabled(DummyKind kind, bool on) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) Player val = Dummy(kind); if ((Object)(object)val == (Object)null) { return; } TestDummy component = ((Component)val).GetComponent<TestDummy>(); if (component.Disabled != !on) { component.Disabled = !on; if (on) { ((Component)val).gameObject.SetActive(true); val.data.isPlaying = true; val.data.health = val.data.maxHealth; Teleport(val, component.Home); } else { val.data.isPlaying = false; ((Component)val).gameObject.SetActive(false); } } } private static IEnumerator WakeProp(GameObject go) { for (int i = 0; i < 5; i++) { yield return null; } if ((Object)(object)go == (Object)null) { yield break; } Rigidbody2D[] componentsInChildren = go.GetComponentsInChildren<Rigidbody2D>(); foreach (Rigidbody2D val in componentsInChildren) { if ((int)val.bodyType != 2) { val.isKinematic = false; val.simulated = true; val.gravityScale = 1f; } } } public static void ResetProps() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Invalid comparison between Unknown and I4 if (!Active || (Object)(object)map == (Object)null) { return; } foreach (GameObject prop in props) { DestroyProp(prop); } props.Clear(); propByName.Clear(); Rigidbody2D[] componentsInChildren = ((Component)map).GetComponentsInChildren<Rigidbody2D>(true); foreach (Rigidbody2D val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)(object)floor && (Object)(object)((Component)val).GetComponentInParent<Player>() == (Object)null && (int)val.bodyType != 2) { DestroyProp(((Component)val).gameObject); } } SpawnProps(); } private static void DestroyProp(GameObject go) { if (!((Object)(object)go == (Object)null)) { PhotonView component = go.GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null && component.IsMine) { PhotonNetwork.Destroy(go); } else { Object.Destroy((Object)(object)go); } } } public static void ClearBullets() { ProjectileHit[] array = Object.FindObjectsOfType<ProjectileHit>(); foreach (ProjectileHit val in array) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } MapTransition instance = MapTransition.instance; if (instance != null) { instance.ClearObjects(); } } public static void ResetEverything() { //IL_007b: 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) ClearBullets(); ResetProps(); foreach (Player item in PlayerManager.instance.players.ToList()) { if (!((Object)(object)item == (Object)null) && !item.data.dead && ((Component)item).gameObject.activeSelf) { item.data.health = item.data.maxHealth; TestDummy component = ((Component)item).GetComponent<TestDummy>(); Teleport(item, ((Object)(object)component != (Object)null) ? component.Home : PlayerSpawn); if ((Object)(object)component != (Object)null) { component.ResetStats(); } } } DamageLog.Clear(); } public static void SetTimeScale(float scale) { TimeScale = scale; if (!((Object)(object)TimeHandler.instance == (Object)null)) { if (defaultBaseTimeScale < 0f) { defaultBaseTimeScale = TimeHandler.instance.baseTimeScale; } TimeHandler.instance.baseTimeScale = defaultBaseTimeScale * scale; } } internal static void OnPlayerAdded(Player player) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!Active || (Object)(object)player == (Object)null) { return; } TestDummy component = ((Component)player).GetComponent<TestDummy>(); Teleport(player, ((Object)(object)component != (Object)null) ? component.Home : PlayerSpawn); int num; if ((Object)(object)component == (Object)null) { num = ((!player.data.input.controlledElseWhere) ? 1 : 0); if (num != 0 && player.teamID != 0) { player.AssignTeamID(0); PlayerExtensions.AssignColorID(player, 0); } } else { num = 0; } if (num != 0 && !dummiesRequested) { dummiesRequested = true; ((MonoBehaviour)CustomCardsPlugin.Instance).StartCoroutine(SpawnDummies()); } } private static IEnumerator SpawnDummies() { yield return (object)new WaitForSecondsRealtime(0.5f); if ((Object)(object)Dummy(DummyKind.Target) == (Object)null) { yield return SpawnDummy(DummyKind.Target); } if ((Object)(object)Dummy(DummyKind.Shooter) == (Object)null) { yield return SpawnDummy(DummyKind.Shooter); } } internal static void HandleJoining() { PlayerAssigner instance = PlayerAssigner.instance; if ((Object)(object)instance == (Object)null || DevConsole.isTyping || GameManager.lockInput || Time.unscaledTime - lastJoinAt < 0.5f || PlayerManager.instance.players.Count >= instance.maxPlayers) { return; } List<Player> source = PlayerManager.instance.players.Where((Player p) => (Object)(object)p != (Object)null && p.data.playerActions != null && !p.data.input.controlledElseWhere).ToList(); if (Input.GetKey((KeyCode)32) && !source.Any((Player p) => ((PlayerActionSet)p.data.playerActions).Device == null)) { lastJoinAt = Time.unscaledTime; ((MonoBehaviour)instance).StartCoroutine(instance.CreatePlayer((InputDevice)null, false)); return; } foreach (InputDevice device in InputManager.ActiveDevices) { if ((((OneAxisInputControl)device.Action1).WasPressed || ((OneAxisInputControl)device.Action2).WasPressed || ((OneAxisInputControl)device.Action3).WasPressed || ((OneAxisInputControl)device.Action4).WasPressed) && !source.Any((Player p) => ((PlayerActionSet)p.data.playerActions).Device == device)) { lastJoinAt = Time.unscaledTime; ((MonoBehaviour)instance).StartCoroutine(instance.CreatePlayer(device, false)); break; } } } public static void RespawnMissingDummies() { if (Active) { ((MonoBehaviour)CustomCardsPlugin.Instance).StartCoroutine(SpawnDummies()); } } private static IEnumerator SpawnDummy(DummyKind kind) { if (!Active) { yield break; } int before = PlayerManager.instance.players.Count; yield return PlayerAssigner.instance.CreatePlayer((InputDevice)null, true); if (PlayerManager.instance.players.Count <= before) { CustomCardsPlugin.Log.LogWarning((object)"Test map: couldn't create a dummy (player limit?)."); yield break; } Player p = PlayerManager.instance.players.Last(); StripAI(p); PlayerAPI component = ((Component)p).GetComponent<PlayerAPI>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } p.AssignTeamID(1); PlayerExtensions.AssignColorID(p, (kind == DummyKind.Target) ? 1 : 3); TestDummy d = ((Component)p).gameObject.AddComponent<TestDummy>(); d.Kind = kind; d.Home = ((kind == DummyKind.Target) ? TargetSpawn : ShooterSpawn); yield return null; Teleport(p, d.Home); } private static void StripAI(Player p) { MonoBehaviour[] componentsInChildren = ((Component)p).GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Type type = ((object)val).GetType(); if (!(type == typeof(PlayerAPI)) && (type.Name.Contains("AI") || (type.Namespace != null && type.Namespace.Contains("AI")))) { Object.Destroy((Object)(object)val); } } } } public static void Teleport(Player p, Vector3 pos) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)p == (Object)null)) { ((Component)p).transform.position = pos; if ((Object)(object)p.data.playerVel != (Object)null) { Velocity.Invoke(p.data.playerVel) = Vector2.zero; } PlayerCollision component = ((Component)p).GetComponent<PlayerCollision>(); if ((Object)(object)component != (Object)null) { component.IgnoreWallForFrames(2); } } } } [HarmonyPatch(typeof(MapManager), "GetRandomMap")] internal static class TestMapPickLevel { private static bool Prefix(MapManager __instance, ref string __result) { if (!TestMap.Active || __instance.levels == null || __instance.levels.Length == 0) { return true; } __result = __instance.levels[0]; return false; } } [HarmonyPatch(typeof(MapManager), "OnLevelFinishedLoading")] internal static class TestMapBuildPatch { private static void Prefix(Scene scene) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (TestMap.Active) { TestMap.BuildFrom(scene); } } } [HarmonyPatch(typeof(GM_Test), "PlayerWasAdded")] internal static class TestMapPlayerAddedPatch { private static void Postfix(Player player) { TestMap.OnPlayerAdded(player); } } [HarmonyPatch(typeof(HealthHandler), "RPCA_Die")] internal static class TestMapNoDeathPatch { [HarmonyPriority(800)] private static bool Prefix(HealthHandler __instance) { Player component = ((Component)__instance).GetComponent<Player>(); if (!TestMap.IsImmortal(component)) { return true; } component.data.health = component.data.maxHealth; return false; } } [HarmonyPatch(typeof(PlayerAssigner), "LateUpdate")] internal static class TestMapJoinPatch { private static bool Prefix() { if (!TestMap.Active) { return true; } TestMap.HandleJoining(); return false; } } public class TestMapUI : MonoBehaviour { public const string LockKey = "CustomCards_TestMap"; private bool visible = true; private Rect mainRect = new Rect(15f, 110f, 450f, 820f); private Rect logRect = new Rect(-1f, 110f, 500f, 600f); private int tab; private int targetIndex; private string search = ""; private Vector2 cardScroll; private Vector2 loadoutScroll; private Vector2 logScroll; private Vector2 statsScroll; private float busyUntil; private bool mouseOver; private bool logOnlyDummies; private float scale = 1f; private List<CardInfo> cards; private Dictionary<CardInfo, string> categories; private float cardsRefreshedAt = -100f; private GUIStyle small; private GUIStyle smallDim; private GUIStyle bold; private GUIStyle richButton; private GUIStyle worldNumber; private GUIStyle worldLabel; private GUIStyle shadow; private static readonly string[] Tabs = new string[4] { "Cards", "Dummies", "Objects", "Tools" }; private const string AllMods = "All mods"; private string modFilter = "All mods"; private string[] modNames = new string[1] { "All mods" }; private static readonly string[] Targets = new string[3] { "You", "Target dummy", "Shooter dummy" }; private static readonly float[] Speeds = new float[4] { 0.25f, 0.5f, 1f, 1.5f }; private static readonly string[] SpeedNames = new string[4] { "0.25×", "0.5×", "1×", "1.5×" }; private const float NumberLifetime = 1.2f; private void Update() { if (!TestMap.Active) { mouseOver = false; return; } if (Input.GetKeyDown((KeyCode)283)) { visible = !visible; } Unbound.lockInputBools["CustomCards_TestMap"] = visible && (mouseOver || GUIUtility.keyboardControl != 0); } private void OnGUI() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Invalid comparison between Unknown and I4 //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Invalid comparison between Unknown and I4 if (!TestMap.Active) { return; } InitStyles(); scale = Mathf.Max(0.5f, (float)Screen.height / 1080f); GUI.matrix = Matrix4x4.Scale(new Vector3(scale, scale, 1f)); float num = (float)Screen.width / scale; DrawWorldText(); if (!visible) { GUI.Label(new Rect(10f, 8f, 400f, 24f), "F2: show test map panel", small); mouseOver = false; return; } if (((Rect)(ref logRect)).x < 0f) { ((Rect)(ref logRect)).x = num - ((Rect)(ref logRect)).width - 15f; } mainRect = GUI.Window(73001, mainRect, new WindowFunction(DrawMain), "TEST MAP (F2 hides)"); logRect = GUI.Window(73002, logRect, new WindowFunction(DrawLog), "DAMAGE LOG"); Vector2 mousePosition = Event.current.mousePosition; mouseOver = ((Rect)(ref mainRect)).Contains(mousePosition) || ((Rect)(ref logRect)).Contains(mousePosition); if ((int)Event.current.type == 0 && !mouseOver) { GUIUtility.keyboardControl = 0; } if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 27) { GUIUtility.keyboardControl = 0; } } private void InitStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown if (small == null) { small = new GUIStyle(GUI.skin.label) { fontSize = 13, wordWrap = true, richText = true }; GUIStyle val = new GUIStyle(small); val.normal.textColor = new Color(0.7f, 0.75f, 0.8f); smallDim = val; bold = new GUIStyle(small) { fontStyle = (FontStyle)1, fontSize = 14 }; richButton = new GUIStyle(GUI.skin.button) { richText = true, alignment = (TextAnchor)3, fontSize = 13 }; worldNumber = new GUIStyle(GUI.skin.label) { fontSize = 24, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, richText = false }; worldLabel = new GUIStyle(GUI.skin.label) { fontSize = 14, alignment = (TextAnchor)1, richText = true }; GUIStyle val2 = new GUIStyle(worldNumber); val2.normal.textColor = Color.black; shadow = val2; } } private void DrawMain(int id) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) tab = GUILayout.Toolbar(tab, Tabs, Array.Empty<GUILayoutOption>()); GUILayout.Space(4f); switch (tab) { case 0: DrawCardsTab(); break; case 1: DrawDummiesTab(); break; case 2: DrawObjectsTab(); break; default: DrawToolsTab(); break; } GUI.DragWindow(new Rect(0f, 0f, 10000f, 22f)); } private Player SelectedPlayer() { if (targetIndex != 0) { return TestMap.Dummy((targetIndex != 1) ? DummyKind.Shooter : DummyKind.Target); } return TestMap.Human; } private void DrawCardsTab() { //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("Give cards to:", small, Array.Empty<GUILayoutOption>()); targetIndex = GUILayout.Toolbar(targetIndex, Targets, Array.Empty<GUILayoutOption>()); Player val = SelectedPlayer(); if ((Object)(object)val == (Object)null) { GUILayout.Label((targetIndex == 0) ? "<color=#ffcc66>Press jump (or any controller button) to join first.</color>" : "<color=#ffcc66>That dummy isn't here. Dummies tab → Respawn missing dummies.</color>", small, Array.Empty<GUILayoutOption>()); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Search", small, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty<GUILayoutOption>()); if (GUILayout.Button("×", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) })) { search = ""; GUIUtility.keyboardControl = 0; } GUILayout.EndHorizontal(); RefreshCards(); int num = Array.IndexOf(modNames, modFilter); if (num < 0) { num = 0; modFilter = "All mods"; } int num2 = GUILayout.SelectionGrid(num, modNames, Mathf.Min(3, modNames.Length), Array.Empty<GUILayoutOption>()); modFilter = modNames[num2]; string text = search.Trim().ToLower(); cardScroll = GUILayout.BeginScrollView(cardScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height((modNames.Length > 3) ? 290f : 310f) }); foreach (CardInfo card in cards) { if (text.Length > 0 && !card.cardName.ToLower().Contains(text)) { continue; } string value; string text2 = (categories.TryGetValue(card, out value) ? value : ""); if (!(modFilter != "All mods") || !(text2 != modFilter)) { string text3 = $"{card.cardName} <size=11><color=#8fa0b0>{card.rarity} · {text2}</color></size>"; GUI.enabled = (Object)(object)val != (Object)null && Time.time >= busyUntil; if (GUILayout.Button(text3, richButton, Array.Empty<GUILayoutOption>())) { AddCard(val, card); } GUI.enabled = true; } } GUILayout.EndScrollView(); GUILayout.Space(6f); List<CardInfo> list = (((Object)(object)val != (Object)null) ? val.data.currentCards : new List<CardInfo>()); GUILayout.Label($"Loadout ({list.Count} cards)" + ((Time.time < busyUntil) ? " <color=#8fa0b0>updating…</color>" : ""), bold, Array.Empty<GUILayoutOption>()); loadoutScroll = GUILayout.BeginScrollView(loadoutScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(230f) }); for (int i = 0; i < list.Count; i++) { if (!((Object)(object)list[i] == (Object)null)) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"{i + 1}. {list[i].cardName}", small, Array.Empty<GUILayoutOption>()); GUI.enabled = Time.time >= busyUntil; if (GUILayout.Button("Remove", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { RemoveCard(val, i); } GUI.enabled = true; GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); GUI.enabled = (Object)(object)val != (Object)null && list.Count > 0 && Time.time >= busyUntil; if (GUILayout.Button("Remove all cards", Array.Empty<GUILayoutOption>())) { RemoveAll(val); } GUI.enabled = true; GUILayout.Label("<color=#8fa0b0>Sandbox chat still works too: press Enter, type a card name, then shoot the card.</color>", small, Array.Empty<GUILayoutOption>()); } private void RefreshCards() { if (cards != null && Time.time - cardsRefreshedAt < 5f) { return; } cardsRefreshedAt = Time.time; categories = new Dictionary<CardInfo, string>(); foreach (KeyValuePair<string, Card> card in CardManager.cards) { if ((Object)(object)card.Value?.cardInfo != (Object)null && !categories.ContainsKey(card.Value.cardInfo)) { categories[card.Value.cardInfo] = card.Value.category; } } cards = (from c in categories.Keys where (Object)(object)c != (Object)null orderby c.cardName select c).ToList(); modNames = new string[1] { "All mods" }.Concat(from v in categories.Values.Where((string v) => !string.IsNullOrEmpty(v)).Distinct() orderby (!(v == "Vanilla")) ? v : "" select v).ToArray(); } private void DrawObjectsTab() { GUILayout.Label("Physics objects", bold, Array.Empty<GUILayoutOption>()); foreach (string prop in TestMap.PropList) { bool flag = TestMap.IsPropEnabled(prop); bool flag2 = GUILayout.Toggle(flag, " " + TestMap.PropLabel(prop), Array.Empty<GUILayoutOption>()); if (flag2 != flag) { TestMap.SetPropEnabled(prop, flag2); } } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Enable all", Array.Empty<GUILayoutOption>())) { foreach (string item in TestMap.PropList.ToList()) { TestMap.SetPropEnabled(item, on: true); } } if (GUILayout.Button("Disable all", Array.Empty<GUILayoutOption>())) { foreach (string item2 in TestMap.PropList.ToList()) { TestMap.SetPropEnabled(item2, on: false); } } GUILayout.EndHorizontal(); GUILayout.Label("<color=#8fa0b0>Turning one back on spawns a fresh copy in its spot. Leftover debris goes away with Tools → Reset physics objects.</color>", small, Array.Empty<GUILayoutOption>()); GUILayout.Space(10f); GUILayout.Label("Dummies", bold, Array.Empty<GUILayoutOption>()); DummyKind[] array = new DummyKind[2] { DummyKind.Target, DummyKind.Shooter }; foreach (DummyKind dummyKind in array) { Player val = TestMap.Dummy(dummyKind); string text = ((dummyKind == DummyKind.Target) ? " Target dummy" : " Shooter dummy"); if ((Object)(object)val == (Object)null) { GUILayout.Label("<color=#ffcc66>" + text.Trim() + " missing (Dummies tab → Respawn)</color>", small, Array.Empty<GUILayoutOption>()); continue; } bool flag3 = TestMap.IsDummyEnabled(dummyKind); bool flag4 = GUILayout.Toggle(flag3, text, Array.Empty<GUILayoutOption>()); if (flag4 != flag3) { TestMap.SetDummyEnabled(dummyKind, flag4); } } GUILayout.Label("<color=#8fa0b0>A disabled dummy is hidden and out of play: bullets pass through and cards like One Man Army don't count it.</color>", small, Array.Empty<GUILayoutOption>()); } private void AddCard(Player target, CardInfo card) { if (!((Object)(object)target == (Object)null) && !((Object)(object)card == (Object)null)) { Cards.instance.AddCardToPlayer(target, card, false, "", 0f, 0f, true); } } private void RemoveCard(Player target, int index) { if (!((Object)(object)target == (Object)null)) { CustomEffects.ClearAllReversibleEffects(((Component)target).gameObject); Cards.instance.RemoveCardFromPlayer(target, index, true); busyUntil = Time.time + 0.5f; } } private void RemoveAll(Player target) { CustomEffects.ClearAllReversibleEffects(((Component)target).gameObject); Cards.instance.RemoveAllCardsFromPlayer(target, true); busyUntil = Time.time + 0.3f; } private void DrawDummiesTab() { //IL_02e3: Unknown result type (might be due to invalid IL or missing references) TestMap.DummiesImmortal = GUILayout.Toggle(TestMap.DummiesImmortal, " Immortal (lethal hits refill HP instead of killing)", Array.Empty<GUILayoutOption>()); TestMap.DummiesAutoHeal = GUILayout.Toggle(TestMap.DummiesAutoHeal, " Auto-heal 2.5s after the last hit", Array.Empty<GUILayoutOption>()); TestMap.DummiesWalkBack = GUILayout.Toggle(TestMap.DummiesWalkBack, " Walk back to their spot after being knocked away", Array.Empty<GUILayoutOption>()); GUILayout.Label("<color=#8fa0b0>Turn immortality off to test kill effects (Detonater, Bloodthirsty). The sandbox revives them after 2.5s.</color>", small, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); DrawDummy(TestMap.Dummy(DummyKind.Target)); GUILayout.Space(8f); Player val = TestMap.Dummy(DummyKind.Shooter); DrawDummy(val); if ((Object)(object)val != (Object)null) { TestMap.ShooterFiring = GUILayout.Toggle(TestMap.ShooterFiring, " Shooting at you", Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"Fires every {TestMap.ShooterInterval:0.0#}s", small, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); if (GUILayout.Button("−", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { TestMap.ShooterInterval = Mathf.Max(0.1f, TestMap.ShooterInterval - ((TestMap.ShooterInterval > 1f) ? 0.5f : 0.1f)); } if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { TestMap.ShooterInterval = Mathf.Min(5f, TestMap.ShooterInterval + ((TestMap.ShooterInterval >= 1f) ? 0.5f : 0.1f)); } GUILayout.EndHorizontal(); Gun gun = val.data.weaponHandler.gun; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($"Bullet damage {gun.damage * 55f:0.#}", small, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); if (GUILayout.Button("÷2", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) })) { gun.damage *= 0.5f; } if (GUILayout.Button("×2", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) })) { gun.damage *= 2f; } if (GUILayout.Button("55", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) })) { gun.damage = 1f; } GUILayout.EndHorizontal(); GUILayout.Label("<color=#8fa0b0>Give the shooter cards from the Cards tab to test what they do to you.</color>", small, Array.Empty<GUILayoutOption>()); } GUILayout.Space(10f); if (GUILayout.Button("Respawn missing dummies", Array.Empty<GUILayoutOption>())) { TestMap.RespawnMissingDummies(); } if (!GUILayout.Button("Send dummies back to their spots", Array.Empty<GUILayoutOption>())) { return; } DummyKind[] array = new DummyKind[2] { DummyKind.Target, DummyKind.Shooter }; for (int i = 0; i < array.Length; i++) { Player val2 = TestMap.Dummy(array[i]); if ((Object)(object)val2 != (Object)null) { TestMap.Teleport(val2, ((Component)val2).GetComponent<TestDummy>().Home); } } } private void DrawDummy(Player p) { if ((Object)(object)p == (Object)null) { GUILayout.Label("<color=#ffcc66>(dummy missing)</color>", small, Array.Empty<GUILayoutOption>()); return; } TestDummy component = ((Component)p).GetComponent<TestDummy>(); GUILayout.Label(component.Name, bold, Array.Empty<GUILayoutOption>()); GUILayout.Label(p.data.dead ? "Dead (reviving…)" : ($"HP {p.data.health:0.#} / {p.data.maxHealth:0.#} DPS (3s) {component.Dps:0.#}\n" + $"Total {component.TotalDamage:0.#} over {component.Hits} hits Biggest hit {component.BiggestHit:0.#}"), small, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Max HP", small, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); float[] array = new float[4] { 100f, 250f, 500f, 1000f }; for (int i = 0; i < array.Length; i++) { float num = array[i]; if (GUILayout.Button(num.ToString("0"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { p.data.maxHealth = num; p.data.health = num; } } if (GUILayout.Button("Reset stats", Array.Empty<GUILayoutOption>())) { component.ResetStats(); } GUILayout.EndHorizontal(); } private void DrawToolsTab() { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) if (GUILayout.Button("Reset physics objects", Array.Empty<GUILayoutOption>())) { TestMap.ResetProps(); } if (GUILayout.Button("Clear bullets and lingering effects", Array.Empty<GUILayoutOption>())) { TestMap.ClearBullets(); } if (GUILayout.Button("Reset everything (props, bullets, HP, positions, log)", Array.Empty<GUILayoutOption>())) { TestMap.ResetEverything(); } if (GUILayout.Button("Place Treasure map X (normally happens each round)", Array.Empty<GUILayoutOption>())) { TreasureMap.PlaceNow(); } GUILayout.Space(8f); GUILayout.Label("You", bold, Array.Empty<GUILayoutOption>()); TestMap.GodMode = GUILayout.Toggle(TestMap.GodMode, " God mode (lethal hits refill your HP)", Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Player human = TestMap.Human; GUI.enabled = (Object)(object)human != (Object)null; if (GUILayout.Button("Heal to full", Array.Empty<GUILayoutOption>()) && (Object)(object)human != (Object)null) { human.data.health = human.data.maxHealth; } if (GUILayout.Button("Back to spawn", Array.Empty<GUILayoutOption>()) && (Object)(object)human != (Object)null) { TestMap.Teleport(human, TestMap.PlayerSpawn); } if (GUILayout.Button("Refill block", Array.Empty<GUILayoutOption>()) && (Object)(object)human != (Object)null) { human.data.block.ResetCD(false); } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.Space(8f); GUILayout.Label("Game speed", bold, Array.Empty<GUILayoutOption>()); int num = Array.IndexOf(Speeds, TestMap.TimeScale); int num2 = GUILayout.Toolbar((num < 0) ? 2 : num, SpeedNames, Array.Empty<GUILayoutOption>()); if (Speeds[num2] != TestMap.TimeScale) { TestMap.SetTimeScale(Speeds[num2]); } GUILayout.Label("<color=#8fa0b0>Slows players and bullets; boxes still fall at normal speed.</color>", small, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); GUILayout.Label("Stats of:", bold, Array.Empty<GUILayoutOption>()); targetIndex = GUILayout.Toolbar(targetIndex, Targets, Array.Empty<GUILayoutOption>()); statsScroll = GUILayout.BeginScrollView(statsScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(330f) }); GUILayout.Label(StatsText(SelectedPlayer()), small, Array.Empty<GUILayoutOption>()); GUILayout.EndScrollView(); } private static string StatsText(Player p) { if ((Object)(object)p == (Object)null) { return "(not here)"; } CharacterData data = p.data; Gun gun = data.weaponHandler.gun; GunAmmo componentInChildren = ((Component)gun).GetComponentInChildren<GunAmmo>(); CharacterStatModifiers stats = data.stats; float num = (((Object)(object)componentInChildren != (Object)null) ? ((componentInChildren.reloadTime + componentInChildren.reloadTimeAdd) * componentInChildren.reloadTimeMultiplier) : 0f); return $"HP {data.health:0.#} / {data.maxHealth:0.#} regen {data.healthHandler.regeneration:0.#}/s\n" + $"Bullet damage {gun.damage * 55f:0.#} (×{gun.damage:0.##})\n" + $"Bullets per shot {gun.numberOfProjectiles} bounces {gun.reflects}\n" + $"Attack speed {gun.attackSpeed:0.###}s (lower = faster)\n" + $"Bullet speed ×{gun.projectileSpeed:0.##} sim speed ×{gun.projectielSimulatonSpeed:0.##}\n" + $"Ammo {(((Object)(object)componentInChildren != (Object)null) ? componentInChildren.maxAmmo : 0)} reload {num:0.##}s\n" + $"Block cooldown {data.block.cooldown:0.##}s\n" + $"Move speed ×{stats.movementSpeed:0.##} jump ×{stats.jump:0.##} extra jumps {stats.numberOfJumps}\n" + $"Lifesteal {stats.lifeSteal:0.##} size ×{stats.sizeMultiplier:0.##}\n\n" + "Cards: " + string.Join(", ", from c in data.currentCards where (Object)(object)c != (Object)null select c.cardName); } private void DrawLog(int id) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); logOnlyDummies = GUILayout.Toggle(logOnlyDummies, " Only hits on dummies", Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { DamageLog.Records.Clear(); } GUILayout.EndHorizontal(); logScroll = GUILayout.BeginScrollView(logScroll, Array.Empty<GUILayoutOption>()); int num = 0; foreach (DamageRecord record in DamageLog.Records) { if (logOnlyDummies && ((Object)(object)record.victim == (Object)null || (Object)(object)((Component)record.victim).GetComponent<TestDummy>() == (Object)null)) { continue; } num++; GUILayout.Label($"{record.source}: {NameOf(record.attacker)} → {NameOf(record.victim)} <color=#8fa0b0>{Time.time - record.time:0.0}s ago</color>", bold, Array.Empty<GUILayoutOption>()); foreach (string step in record.steps) { GUILayout.Label(" " + step, small, Array.Empty<GUILayoutOption>()); } string text; if (record.blocked) { text = "<color=#66ccff>Blocked: no damage</color>"; } else if (record.applied < 0f) { text = $"<color=#b0ff66>Spread over time: {record.current:0.#} total (shows as separate ticks)</color>"; } else { text = $"<color=#ff7766>HP {record.hpBefore:0.#} → {(record.refilled ? 0f : record.hpAfter):0.#} (−{record.applied:0.#} of {record.maxHp:0} max)</color>"; if (record.refilled) { text += "\n <color=#ffd633>Lethal: refilled to full (immortal)</color>"; } } GUILayout.Label(" " + text, small, Array.Empty<GUILayoutOption>()); GUILayout.Space(6f); } if (num == 0) { GUILayout.Label("No hits yet. Shoot a dummy!", smallDim, Array.Empty<GUILayoutOption>()); } GUILayout.EndScrollView(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 22f)); } private static string NameOf(Player p) { if ((Object)(object)p == (Object)null) { return "?"; } TestDummy component = ((Component)p).GetComponent<TestDummy>(); if ((Object)(object)component != (Object)null) { return component.Name; } Player val = DoublingCherry.MasterOf(p); if ((Object)(object)val != (Object)null) { if (!((Object)(object)val == (Object)(object)TestMap.Human)) { return "Copy of player " + (val.playerID + 1); } return "Your copy"; } if (!((Object)(object)p == (Object)(object)TestMap.Human)) { return "Player " + (p.playerID + 1); } return "You"; } private void DrawWorldText() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a0: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) Camera val = (((Object)(object)MainCam.instance != (Object)null) ? MainCam.instance.cam : null); if ((Object)(object)val == (Object)null) { return; } Rect val3 = default(Rect); for (int num = DamageLog.Numbers.Count - 1; num >= 0; num--) { DamageLog.FloatingNumber floatingNumber = DamageLog.Numbers[num]; float num2 = Time.time - floatingNumber.born; if (num2 > 1.2f) { DamageLog.Numbers.RemoveAt(num); } else { Vector2 val2 = ToGui(val, floatingNumber.pos + Vector3.up * num2 * 1.5f); ((Rect)(ref val3))..ctor(val2.x - 100f, val2.y - 15f, 200f, 30f); float num3 = 1f - num2 / 1.2f; shadow.normal.textColor = new Color(0f, 0f, 0f, num3 * 0.8f); GUI.Label(new Rect(((Rect)(ref val3)).x + 2f, ((Rect)(ref val3)).y + 2f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), floatingNumber.text, shadow); worldNumber.normal.textColor = new Color(floatingNumber.color.r, floatingNumber.color.g, floatingNumber.color.b, num3); GUI.Label(val3, floatingNumber.text, worldNumber); } } if ((Object)(object)PlayerManager.instance == (Object)null) { return; } foreach (Player player in PlayerManager.instance.players) { TestDummy testDummy = (((Object)(object)player != (Object)null) ? ((Component)player).GetComponent<TestDummy>() : null); if (!((Object)(object)testDummy == (Object)null) && !player.data.dead) { Vector2 val4 = ToGui(val, ((Component)player).transform.position + Vector3.down * 1.6f); GUI.Label(new Rect(val4.x - 120f, val4.y, 240f, 40f), $"<b>{testDummy.Name}</b>\n{player.data.health:0} / {player.data.maxHealth:0} HP DPS {testDummy.Dps:0}", worldLabel); } } } private Vector2 ToGui(Camera cam, Vector3 world) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) Vector3 val = cam.WorldToScreenPoint(world); return new Vector2(val.x / scale, ((float)Screen.height - val.y) / scale); } } } namespace CustomCards.Patches { [HarmonyPatch(typeof(HealthHandler), "CallTakeDamage")] internal static class DamageReductionPatch { [HarmonyPriority(200)] private static void Prefix(HealthHandler __instance, ref Vector2 damage) { //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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00e6: Unknown result type (might be due to invalid IL or missing references) if (damage == Vector2.zero) { return; } Player component = ((Component)__instance).GetComponent<Player>(); if ((Object)(object)component == (Object)null) { return; } float num = ((Vector2)(ref damage)).magnitude; int num2 = CardUtils.CountCard(component, "Slippery"); if (num2 > 0) { Vector2 val = CardUtils.Velocity(component); if (((Vector2)(ref val)).magnitude > 2f) { float before = num; float num3 = Mathf.Min(0.75f, 0.25f * (float)num2); num *= 1f - num3; DamageLog.Step($"Slippery −{num3 * 100f:0}%", before, num); } } int num4 = CardUtils.CountCard(component, "Plating"); if (num4 > 0) { float before2 = num; num = Mathf.Max(1f, num - 8f * (float)num4); DamageLog.Step($"Plating −{8f * (float)num4:0}", before2, num); } damage = ((Vector2)(ref damage)).normalized * num; } } [HarmonyPatch(typeof(Gun), "ApplyProjectileStats")] internal static class BulletDamageBonusPatch { private static void Postfix(Gun __instance, GameObject obj) { Player shooter = __instance.player; if ((Object)(object)shooter == (Object)null) { return; } ProjectileHit component = obj.GetComponent<ProjectileHit>(); if ((Object)(object)component == (Object)null) { return; } float num = 1f; BulletNotes bulletNotes = null; if (DamageLog.Enabled) { bulletNotes = obj.GetComponent<BulletNotes>(); if ((Object)(object)bulletNotes == (Object)null) { bulletNotes = obj.AddComponent<BulletNotes>(); } bulletNotes.mods.Clear(); bulletNotes.fired = component.damage; } int num2 = CardUtils.CountCard(shooter, "Fragile"); if (num2 > 0 && shooter.data.maxHealth > 0f) { float num3 = Mathf.Clamp01(1f - shooter.data.health / shooter.data.maxHealth); float num4 = 1f + 1f * (float)num2 * num3; num *= num4; bulletNotes?.mods.Add($"Fragile ×{num4:0.##} ({num3 * 100f:0}% HP missing)"); } int num5 = CardUtils.CountCard(shooter, "One Man Army"); if (num5 > 0) { int num6 = CardUtils.Enemies(shooter).Count((Player e) => Vector2.Distance(Vector2.op_Implicit(((Component)e).transform.position), Vector2.op_Implicit(((Component)shooter).transform.position)) <= 7.5f); float num7 = 1f + 0.3f * (float)num5 * (float)num6; num *= num7; bulletNotes?.mods.Add($"One Man Army ×{num7:0.##} ({num6} enemies near)"); } component.damage *= num; if ((Object)(object)bulletNotes != (Object)null) { bulletNotes.finalAtFire = component.damage; } } } [HarmonyPatch(typeof(HealthHandler), "DoDamage")] internal static class TookDamagePatch { private static void Prefix(HealthHandler __instance, out float __state) { CharacterData component = ((Component)__instance).GetComponent<CharacterData>(); __state = (Object.op_Implicit((Object)(object)component) ? component.health : 0f); } private static void Postfix(HealthHandler __instance, float __state) { CharacterData component = ((Component)__instance).GetComponent<CharacterData>(); if (!((Object)(object)component == (Object)null) && !(component.health >= __state)) { FlameOnBehaviour component2 = ((Component)__instance).GetComponent<FlameOnBehaviour>(); if (Object.op_Implicit((Object)(object)component2)) { component2.Ignite(); } WoundedBehaviour component3 = ((Component)__instance).GetComponent<WoundedBehaviour>(); if (Object.op_Implicit((Object)(object)component3)) { component3.CheckTrigger(); } } } } [HarmonyPatch(typeof(HealthHandler), "RPCA_Die")] internal static class PlayerDiedPatch { private static void Prefix(HealthHandler __instance, out bool __state) { CharacterData component = ((Component)__instance).GetComponent<CharacterData>(); __state = Object.op_Implicit((Object)(object)component) && component.isPlaying && !component.dead; } private static void Postfix(HealthHandler __instance, bool __state) { if (__state) { Player component = ((Component)__instance).GetComponent<Player>(); if (!((Object)(object)component == (Object)null) && component.data.dead) { Detonater.OnPlayerDied(component); Bloodthirsty.OnPlayerDied(component); } } } } [HarmonyPatch(typeof(ProjectileHit), "RPCA_DoHit")] internal static class TeslaHitPatch { private static void Postfix(ProjectileHit __instance, Vector2 hitPoint, int viewID, int colliderID, bool wasBlocked) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!wasBlocked && !((Object)(object)__instance == (Object)null)) { NormalizeHitWindowPatch.Pending = null; Tesla.OnBulletHit(__instance, hitPoint, viewID, colliderID); } } } [HarmonyPatch(typeof(GeneralInput), "Update")] internal static class BloodthirstyInputPatch { private static void Postfix(GeneralInput __instance, CharacterData ___data) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_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 (__instance.controlledElseWhere || (Object)(object)___data == (Object)null || GameManager.lockInput || !___data.isPlaying) { return; } Player player = ___data.player; if (!Bloodthirsty.IsForced(player)) { return; } Player val = CardUtils.ClosestEnemy(player); if (!((Object)(object)val == (Object)null)) { float num = ((Component)val).transform.position.x - ((Component)player).transform.position.x; if (!(Mathf.Abs(num) < 0.5f)) { __instance.direction = new Vector3(Mathf.Sign(num), __instance.direction.y, 0f); __instance.latestPressedDirection = __instance.direction; } } } } internal static class PerPointResets { public static void RegisterHooks() { GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler _) => Reset())); GameModeManager.AddHook("PointStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler _) => Reset())); } private static IEnumerator Reset() { WoundedBehaviour.UsedThisPoint.Clear(); Bloodthirsty.Reset(); yield break; } } internal static class GreedPicks { private static readonly Dictionary<int, int> bonusPicks = new Dictionary<int, int>(); private static readonly HashSet<int> skippedPlayerIDs = new HashSet<int>(); private static bool decisionReceived; internal static bool StartingBonusPick; private const float DecisionTimeout = 3f; public static void RegisterHooks() { GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler _) => ResetAll())); GameModeManager.AddHook("PickStart", (Func<IGameModeHandler, IEnumerator>)OnPickStart); GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler _) => ResetAll())); } public static void AddBonusPicks(int playerID, int count) { bonusPicks.TryGetValue(playerID, out var value); bonusPicks[playerID] = value + count; } private static IEnumerator ResetAll() { bonusPicks.Clear(); skippedPlayerIDs.Clear(); decisionReceived = false; yield break; } private static IEnumerator OnPickStart(IGameModeHandler gm) { if (PhotonNetwork.OfflineMode || PhotonNetwork.IsMasterClient) { int[] array = (from p in PlayerManager.instance.players where Random.value < GreedCard.SkipChance(CardUtils.CountCard(p, "Greed")) select p.playerID).ToArray(); NetworkingManager.RPC(typeof(GreedPicks), "RPCA_SetSkippedPlayers", new object[1] { array }); } float waited = 0f; while (!decisionReceived && waited < 3f) { waited += Time.unscaledDeltaTime; yield return null; } if (!decisionReceived) { CustomCardsPlugin.Log.LogWarning((object)"Greed: no skip decision from host; nobody skipped this pick phase."); } } [UnboundRPC] public static void RPCA_SetSkippedPlayers(int[] playerIDs) { skippedPlayerIDs.Clear(); foreach (int item in playerIDs) { skippedPlayerIDs.Add(item); } decisionReceived = true; } public static bool IsSkipped(int playerID) { return skippedPlayerIDs.Contains(playerID); } public static IEnumerator SkippedPick() { UIHandler.instance.ShowJoinGameText("GREED - PICK SKIPPED", new Color(0.6f, 0.2f, 0.8f)); yield return (object)new WaitForSecondsRealtime(1.5f); UIHandler.instance.HideJoinGameText(); UIHandler.instance.StopShowPicker(); CardChoiceVisuals.instance.Hide(); } public static IEnumerator PickThenBonusPicks(IEnumerator normalPick, int playerID) { yield return normalPick; while (true) { yield return (object)new WaitForSecondsRealtime(0.25f); if (bonusPicks.TryGetValue(playerID, out var value) && value > 0) { bonusPicks[playerID] = value - 1; int num = PlayerManager.instance.players.FindIndex((Player p) => p.playerID == playerID); if (num >= 0) { CardChoiceVisuals.instance.Show(num, true); StartingBonusPick = true; IEnumerator enumerator; try { enumerator = CardChoice.instance.DoPick(1, playerID, (PickerType)1); } finally { StartingBonusPick = false; } yield return enumerator; continue; } break; } break; } } } [HarmonyPatch(typeof(CardChoice), "DoPick")] internal static class GreedDoPickPatch { private static bool Prefix(int picketIDToSet, PickerType pType, ref IEnumerator __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if (GreedPicks.StartingBonusPick || (int)pType != 1 || !GreedPicks.IsSkipped(picketIDToSet)) { return true; } __result = GreedPicks.SkippedPick(); return false; } private static void Postfix(int picketIDToSet, PickerType pType, ref IEnumerator __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if (!GreedPicks.StartingBonusPick && (int)pType == 1) { __result = GreedPicks.PickThenBonusPicks(__result, picketIDToSet); } } } [HarmonyPatch(typeof(Gun), "ApplyProjectileStats")] internal static class NeoLifetimePatch { private static void Postfix(Gun __instance, GameObject obj) { int num = CardUtils.CountCard(__instance.player, "Neo"); if (num > 0) { RemoveAfterSeconds component = obj.GetComponent<RemoveAfterSeconds>(); if ((Object)(object)component != (Object)null) { component.seconds /= Mathf.Pow(0.5f, (float)num); } } } } [HarmonyPatch(typeof(ProjectileHit), "RPCA_DoHit")] internal static class NormalizeHitWindowPatch { internal static ProjectileHit Pending; private static void Prefix(ProjectileHit __instance) { Pending = ((CardUtils.CountCard(__instance.ownPlayer, "Normalize") > 0) ? __instance : null); } private static Exception Finalizer(Exception __exception) { Pending = null; return __exception; } } [HarmonyPatch(typeof(HealthHandler), "CallTakeDamage")] internal static class NormalizeDamagePatch { private static void Prefix(HealthHandler __instance, ref Vector2 damage) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0079: Unknown result type (might be due to invalid IL or missing references) ProjectileHit pending = NormalizeHitWindowPatch.Pending; if (!((Object)(object)pending == (Object)null)) { NormalizeHitWindowPatch.Pending = null; CharacterData component = ((Component)__instance).GetComponent<CharacterData>(); if (!((Object)(object)component == (Object)null) && !(damage == Vector2.zero)) { int num = CardUtils.CountCard(pending.ownPlayer, "Normalize"); float num2 = NormalizeCard.PercentFor(((Vector2)(ref damage)).magnitude, Mathf.Max(num, 1)); float magnitude = ((Vector2)(ref damage)).magnitude; damage = ((Vector2)(ref damage)).normalized * (component.maxHealth * num2); DamageLog.Step($"Normalize ({num2 * 100f:0.#}% of {component.maxHealth:0} max HP)", magnitude, ((Vector2)(ref damage)).magnitude); } } } } internal static class PiercerClash { private static readonly FieldRef<ProjectileHitEmpower, bool> EmpowerDone = AccessTools.FieldRefAccess<ProjectileHitEmpower, bool>("done"); public static bool Applies(ProjectileHit a, ProjectileHit b, out int stacksA, out int stacksB) { stacksA = (stacksB = 0); if ((Object)(object)a == (Object)null || (Object)(object)b == (Object)null || (Object)(object)a == (Object)(object)b) { return false; } Player ownPlayer = a.ownPlayer; Player ownPlayer2 = b.ownPlayer; if ((Object)(object)ownPlayer == (Object)null || (Object)(object)ownPlayer2 == (Object)null) { return false; } stacksA = CardUtils.CountCard(ownPlayer, "Piercer"); stacksB = CardUtils.CountCard(ownPlayer2, "Piercer"); if (stacksA == 0 && stacksB == 0) { return false; } if (ownPlayer.teamID == ownPlayer2.teamID) { stacksA = (stacksB = Mathf.Max(stacksA, stacksB)); } return true; } public static void Resolve(ProjectileHit hitBullet, ProjectileHit incoming, int hitStacks, int incomingStacks, HitInfo hit) { //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_0040: 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_0037: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (!ClashMemory.IsNewContact(((Component)hitBullet).gameObject, ((Component)incoming).gameObject)) { return; } Vector2 val = ContactNormal(hit, ((Component)incoming).gameObject, ((Component)hitBullet).gameObject); Vector2 val2 = hit?.point ?? Vector2.op_Implicit(((Component)hitBullet).transform.position); ProjectileCollision componentInChildren = ((Component)hitBullet).GetComponentInChildren<ProjectileCollision>(); ProjectileCollision componentInChildren2 = ((Component)incoming).GetComponentInChildren<ProjectileCollision>(); if (hitStacks > incomingStacks) { if (Object.op_Implicit((Object)(object)componentInChildren2)) { componentInChildren2.TakeDamage(float.MaxValue); } TriggerHitEffects(((Component)hitBullet).gameObject, val2, -val, componentInChildren2); return; } if (incomingStacks > hitStacks) { if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.TakeDamage(float.MaxValue); } TriggerHitEffects(((Component)incoming).gameObject, val2, val, componentInChildren); return; } Reflect(((Component)incoming).gameObject, val); Reflect(((Component)hitBullet).gameObject, -val); ((Component)incoming).transform.position = Vector2.op_Implicit(val2 + val * 0.05f); RayCastTrail component = ((Component)incoming).GetComponent<RayCastTrail>(); if (Object.op_Implicit((Object)(object)component)) { component.MoveRay(); } TriggerHitEffects(((Component)incoming).gameObject, val2, val, componentInChildren); TriggerHitEffects(((Component)hitBullet).gameObject, val2, -val, componentInChildren2); } private static Vector2 ContactNormal(HitInfo hit, GameObject incoming, GameObject hitBullet) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result ty