Decompiled source of RunAwards v0.2.1
RunAwards.dll
Decompiled 2 weeks 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Burst2Flame; using Burst2Flame.Observable; using HarmonyLib; using HexMapTools; using Microsoft.CodeAnalysis; using ModNet; using ModsMenu; using StolenRealmModAPI; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RunAwards")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+52158c7d25a1953ef0dc1b873b569982776fd2a0")] [assembly: AssemblyProduct("RunAwards")] [assembly: AssemblyTitle("RunAwards")] [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 RunAwards { internal enum AwardKind { Brag, Roast, Odd, Mvp } internal sealed class AwardDef { internal string Id; internal string Title; internal string Blurb; internal string Singular; internal string Plural; internal AwardKind Kind; internal Stat Stat; internal bool Lowest; internal float Weight = 1f; internal string FixedText; internal string Format(float v) { if (FixedText != null) { return FixedText; } long num = (long)Math.Round(v); return num.ToString("N0") + " " + ((num == 1) ? Singular : Plural); } } internal sealed class AwardResult { internal AwardDef Def; internal List<HeroStats> Winners; internal float Value; internal string ValueText; } internal static class Awards { private static readonly AwardDef[] Catalog = new AwardDef[26] { Def("heavy_hitter", "Heavy Hitter", "Most damage dealt", AwardKind.Brag, Stat.Damage, "damage", "damage", lowest: false, 6f), Def("slayer", "Slayer", "Finished off the most enemies", AwardKind.Brag, Stat.Kills, "kill", "kills", lowest: false, 4f), Def("guardian_angel", "Guardian Angel", "Most healing done", AwardKind.Brag, Stat.Healing, "healed", "healed", lowest: false, 3f), Def("one_punch", "One-Punch", "Biggest single hit", AwardKind.Brag, Stat.BiggestHit, "damage in one hit", "damage in one hit", lowest: false, 2f), Def("giant_slayer", "Giant Slayer", "Finished off the most bosses and champions", AwardKind.Brag, Stat.BossKills, "big one", "big ones", lowest: false, 3f), Def("beastmaster", "Beastmaster", "Most damage dealt by summons", AwardKind.Brag, Stat.SummonDamage, "summon damage", "summon damage", lowest: false, 1.5f), Def("untouchable", "Untouchable", "Dodged the most attacks", AwardKind.Brag, Stat.Dodges, "dodge", "dodges", lowest: false, 1.5f), Def("first_blood", "First Blood", "Landed the first kill of the adventure", AwardKind.Brag, Stat.FirstBlood, null, null, lowest: false, 1.5f, "Struck first"), Def("floor_inspector", "Floor Inspector", "Got knocked out the most", AwardKind.Roast, Stat.Deaths, "knockout", "knockouts", lowest: false, 3f), Def("punching_bag", "Punching Bag", "Took the most damage", AwardKind.Roast, Stat.DamageTaken, "damage taken", "damage taken", lowest: false, 1.5f), Def("friendly_fire", "Friendly Fire", "Most damage dealt to their own party", AwardKind.Roast, Stat.FriendlyFire, "damage to friends", "damage to friends", lowest: false, 2.5f), Def("kill_stealer", "Kill Stealer", "Finished off enemies a teammate had mostly beaten", AwardKind.Roast, Stat.KillSteals, "stolen kill", "stolen kills", lowest: false, 2f), Def("stormtrooper", "Stormtrooper", "Missed the most attacks", AwardKind.Roast, Stat.Misses, "miss", "misses", lowest: false, 2f), Def("high_maintenance", "High Maintenance", "Received the most healing", AwardKind.Roast, Stat.HealingReceived, "healing received", "healing received"), Def("pacifist", "Pacifist", "Dealt the least damage", AwardKind.Roast, Stat.Damage, "damage", "damage", lowest: true), Def("couch_potato", "Couch Potato", "Walked the fewest tiles", AwardKind.Roast, Stat.Tiles, "tile", "tiles", lowest: true, 0.7f), Def("potion_addict", "Potion Addict", "Drank the most potions, brews and tonics", AwardKind.Odd, Stat.Potions, "potion", "potions", lowest: false, 2f), Def("treasure_hunter", "Treasure Hunter", "Found the most gold", AwardKind.Odd, Stat.Gold, "gold", "gold"), Def("loot_goblin", "Loot Goblin", "Got the most items", AwardKind.Odd, Stat.Loot, "item", "items"), Def("lucky_streak", "Lucky Streak", "Most critical hits", AwardKind.Odd, Stat.Crits, "critical hit", "critical hits", lowest: false, 1.5f), Def("iron_wall", "Iron Wall", "Most damage blocked by armor, resistances and shields", AwardKind.Odd, Stat.Blocked, "blocked", "blocked"), Def("overkill", "Overkill", "Most extra damage on finishing blows", AwardKind.Odd, Stat.Overkill, "wasted damage", "wasted damage", lowest: false, 1.5f), Def("close_call", "Close Call", "Survived the most hits with under 10% health left", AwardKind.Odd, Stat.CloseCalls, "close call", "close calls", lowest: false, 2f), Def("vandal", "Vandal", "Smashed the most barrels and shrines", AwardKind.Odd, Stat.Smashed, "object smashed", "objects smashed"), Def("marathon", "Marathon Runner", "Walked the most tiles", AwardKind.Odd, Stat.Tiles, "tile", "tiles", lowest: false, 0.7f), Def("prickly", "Prickly", "Most damage reflected back at attackers", AwardKind.Odd, Stat.Thorns, "reflected", "reflected") }; internal static int Count => Catalog.Length; private static AwardDef Def(string id, string title, string blurb, AwardKind kind, Stat stat, string one, string many, bool lowest = false, float weight = 1f, string fixedText = null) { return new AwardDef { Id = id, Title = title, Blurb = blurb, Kind = kind, Stat = stat, Singular = one, Plural = many, Lowest = lowest, Weight = weight, FixedText = fixedText }; } internal static List<AwardResult> Pick(Snapshot s, out AwardResult mvp) { mvp = null; List<HeroStats> heroes = s.Heroes; if (heroes.Count == 0) { return new List<AwardResult>(); } Random rng = new Random(s.Seed); List<AwardResult> list = new List<AwardResult>(); AwardDef[] catalog = Catalog; foreach (AwardDef awardDef in catalog) { if ((awardDef.Kind != AwardKind.Roast || Plugin.Roasts.Value) && (awardDef.Kind != AwardKind.Odd || Plugin.OddStats.Value) && s.Knows(awardDef.Stat)) { AwardResult awardResult = Evaluate(awardDef, heroes); if (awardResult != null) { list.Add(awardResult); } } } int num = Math.Max(1, Plugin.MaxAwards.Value); List<AwardResult> chosen = new List<AwardResult>(); foreach (HeroStats h in heroes) { if (chosen.Count >= num) { break; } if (!chosen.Any((AwardResult r) => r.Winners.Contains(h))) { List<AwardResult> list2 = list.Where((AwardResult r) => !chosen.Contains(r) && r.Winners.Contains(h)).ToList(); List<AwardResult> list3 = list2.Where((AwardResult r) => r.Def.Kind != AwardKind.Roast).ToList(); AwardResult awardResult2 = Draw((list3.Count > 0) ? list3 : list2, rng); if (awardResult2 != null) { chosen.Add(awardResult2); } } } while (chosen.Count < num) { AwardResult awardResult3 = Draw(list.Where((AwardResult r) => !chosen.Contains(r)).ToList(), rng); if (awardResult3 == null) { break; } chosen.Add(awardResult3); } List<AwardResult> list4 = (from r in chosen orderby Rank(r.Def.Kind), Array.IndexOf(Catalog, r.Def) select r).ToList(); mvp = Mvp(heroes, list4, s.Roguelike); return list4; static int Rank(AwardKind k) { return k switch { AwardKind.Roast => 1, AwardKind.Odd => 0, _ => 2, }; } } private static AwardResult Draw(List<AwardResult> from, Random rng) { if (from.Count == 0) { return null; } double num = from.Sum((AwardResult r) => r.Def.Weight); double num2 = rng.NextDouble() * num; foreach (AwardResult item in from) { num2 -= (double)item.Def.Weight; if (num2 <= 0.0) { return item; } } return from[from.Count - 1]; } private static AwardResult Evaluate(AwardDef def, List<HeroStats> heroes) { List<float> source = heroes.Select((HeroStats h) => h[def.Stat]).ToList(); float best = (def.Lowest ? source.Min() : source.Max()); if (source.Max() < 1f) { return null; } if (def.Lowest && heroes.Count < 2) { return null; } List<HeroStats> list = heroes.Where((HeroStats h) => Math.Abs(h[def.Stat] - best) < 0.5f).ToList(); if (heroes.Count >= 2 && list.Count == heroes.Count) { return null; } return new AwardResult { Def = def, Winners = list, Value = best, ValueText = def.Format(best) }; } private static AwardResult Mvp(List<HeroStats> heroes, List<AwardResult> shown, bool roguelike) { HeroStats heroStats = heroes.OrderByDescending(Wins).ThenByDescending((HeroStats h) => h[Stat.Damage] + h[Stat.Healing]).First(); int num = Wins(heroStats); AwardDef def = new AwardDef { Id = "mvp", Title = (roguelike ? "Hero of the Run" : "Hero of the Adventure"), Blurb = "Won the most awards", Kind = AwardKind.Mvp, Stat = Stat.Damage }; string valueText = ((num > 0) ? string.Format("{0} award{1}", num, (num == 1) ? "" : "s") : $"{heroStats[Stat.Damage] + heroStats[Stat.Healing]:N0} damage and healing"); return new AwardResult { Def = def, Winners = new List<HeroStats> { heroStats }, Value = num, ValueText = valueText }; int Wins(HeroStats h) { return shown.Count((AwardResult r) => r.Def.Kind != AwardKind.Roast && r.Winners.Contains(h)); } } internal static void Log(List<AwardResult> list, AwardResult mvp, int seed) { if (!Plugin.LogStats.Value) { return; } List<string> list2 = list.Select((AwardResult r) => " " + r.Def.Title + ": " + string.Join(", ", r.Winners.Select((HeroStats w) => w.Name)) + " (" + r.ValueText + ")").ToList(); if (mvp != null) { list2.Add(" " + mvp.Def.Title + ": " + mvp.Winners[0].Name + " (" + mvp.ValueText + ")"); } Plugin.ModLog.LogInfo((object)($"Awards ({list.Count} + MVP, draw {seed}):\n" + string.Join("\n", list2))); } } internal class AwardShow : MonoBehaviour { private sealed class Slot { internal HeroStats Stats; internal RectTransform Rt; internal RectTransform StarRow; internal CanvasGroup Group; internal Image Glow; internal Image Edge; internal Image Star; internal TextMeshProUGUI Name; internal float HomeX; internal int Stars; } private sealed class Confetto { internal RectTransform Rt; internal Image Img; internal Vector2 Vel; internal float Spin; internal float Life; internal float MaxLife; } private sealed class Tween { internal float Start; internal float Duration; internal Action<float> Apply; } internal static AwardShow Instance; private static readonly Color Gold = Hex("F5C451"); private static readonly Color Tan = Hex("CBB396"); private static readonly Color Dim = Hex("8C7B6A"); private static readonly Color SlotBg = Hex("1D1613"); private static readonly Color SlotEdge = Hex("5A4636"); private static readonly Color RoastRed = Hex("E0704F"); private static readonly Color Ink = Hex("0B0806"); private static readonly Color[] ConfettiColors = (Color[])(object)new Color[6] { Hex("F5C451"), Hex("E0704F"), Hex("5FC2B4"), Hex("F2EDE4"), Hex("9C7BD8"), Hex("7CC46A") }; private static readonly FieldRef<Portrait, RawImage> PortraitImage = AccessTools.FieldRefAccess<Portrait, RawImage>("playerImage"); private static readonly FieldRef<PortraitManager, Portrait[]> Portraits = AccessTools.FieldRefAccess<PortraitManager, Portrait[]>("portraits"); private const float SlotW = 180f; private const float SlotH = 236f; private const float SlotGap = 28f; private const float PortraitSize = 150f; private Canvas _canvas; private CanvasGroup _group; private RectTransform _rays; private RectTransform _titleBlock; private RectTransform _row; private RectTransform _confettiRoot; private TextMeshProUGUI _header; private TextMeshProUGUI _counter; private TextMeshProUGUI _title; private TextMeshProUGUI _blurb; private TextMeshProUGUI _value; private TextMeshProUGUI _footer; private TMP_FontAsset _bodyFont; private TMP_FontAsset _titleFont; private readonly List<Slot> _slots = new List<Slot>(); private readonly List<Confetto> _confetti = new List<Confetto>(); private readonly List<Tween> _tweens = new List<Tween>(); private Coroutine _running; private bool _advance; private bool _skipAll; private float _clock; private Snapshot _pendingLocal; private bool _pending; private bool _waitForHost; private float _pendingAt; private float _lastEndAt = -999f; internal bool Playing => _running != null; private void Awake() { Instance = this; } internal static void OnAdventureEnd(bool victory) { AwardShow instance = Instance; if (!((Object)(object)instance == (Object)null) && Plugin.Enabled.Value && !(Time.unscaledTime - instance._lastEndAt < 10f)) { instance._lastEndAt = Time.unscaledTime; Snapshot snapshot = RunStats.BuildLocal(); RunStats.Log(snapshot, victory ? "Adventure won" : "Adventure over"); if (Heroes.IsServer) { AwardSync.Share(snapshot); } instance._pendingLocal = snapshot; instance._pending = true; instance._pendingAt = Time.unscaledTime; instance._waitForHost = !Heroes.IsServer && AwardSync.InMultiplayer; } } internal void Preview() { if (Playing) { Abort("preview key pressed again"); return; } Snapshot snapshot = RunStats.BuildLocal(); if (snapshot.Heroes.Count == 0 || RunStats.IsEmpty(snapshot)) { snapshot = RunStats.BuildDemo(); } RunStats.Log(snapshot, "Preview"); Play(snapshot, preview: true); } internal void Abort(string why) { _pending = false; if (Playing) { ((MonoBehaviour)this).StopCoroutine(_running); _running = null; ShowAudio.Instance?.StopAll(); _tweens.Clear(); ClearConfetti(); if ((Object)(object)_canvas != (Object)null) { ((Component)_canvas).gameObject.SetActive(false); } Plugin.ModLog.LogInfo((object)("Awards show stopped (" + why + ").")); } } private void Update() { try { Tick(); } catch (Exception e) { Tracker.Fail("AwardShow", e); } } private void Tick() { //IL_0137: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; if (_pending && unscaledTime - _pendingAt >= 1.2f) { Snapshot snapshot = (_waitForHost ? AwardSync.Received(60f) : null); if (!_waitForHost || snapshot != null || unscaledTime - _pendingAt >= 6f) { _pending = false; Snapshot snap = ((snapshot != null) ? snapshot : _pendingLocal); if (_waitForHost && snapshot == null) { Plugin.ModLog.LogWarning((object)"No stats from the host (host without Run Awards?): showing what this PC saw."); } if (snapshot != null) { RunStats.ResolveNames(snapshot); RunStats.Log(snapshot, "Host's final stats"); } if (Playing) { Abort("the adventure ended"); } Play(snap, preview: false); } } if (Playing) { _clock += Time.unscaledDeltaTime * Plugin.Speed.Value; if (Input.GetKeyDown((KeyCode)32) || Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)) { _advance = true; } RunTweens(); UpdateConfetti(Time.unscaledDeltaTime); if ((Object)(object)_rays != (Object)null) { ((Transform)_rays).localEulerAngles = new Vector3(0f, 0f, (0f - _clock) * 6f); } } } private void Play(Snapshot snap, bool preview) { AwardResult mvp; List<AwardResult> list = Awards.Pick(snap, out mvp); if (mvp == null) { Plugin.ModLog.LogInfo((object)"No heroes to give awards to."); return; } Awards.Log(list, mvp, snap.Seed); if ((Object)(object)_canvas == (Object)null) { Build(); } SetUpSlots(snap); _running = ((MonoBehaviour)this).StartCoroutine(Run(snap, list, mvp, preview)); } private IEnumerator Run(Snapshot snap, List<AwardResult> awards, AwardResult mvp, bool preview) { AwardShow awardShow = this; AwardShow awardShow2 = this; bool advance = false; awardShow2._skipAll = false; awardShow._advance = advance; _clock = 0f; ((Component)_canvas).gameObject.SetActive(true); _group.alpha = 0f; ((TMP_Text)_header).text = (preview ? "Awards Preview" : (snap.Roguelike ? "Run Awards" : "Adventure Awards")); ((TMP_Text)_counter).text = ((snap.Source == "demo") ? "Made-up numbers: nothing tracked yet" : ""); TextMeshProUGUI title = _title; TextMeshProUGUI blurb = _blurb; string text = (((TMP_Text)_value).text = ""); string text3 = (((TMP_Text)blurb).text = text); ((TMP_Text)title).text = text3; ((TMP_Text)_footer).text = "Click or Space: next"; Animate(0.35f, delegate(float k) { _group.alpha = k; }); RectTransform headerRt = ((TMP_Text)_header).rectTransform; Animate(0.6f, delegate(float k) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) headerRt.anchoredPosition = new Vector2(0f, Mathf.LerpUnclamped(700f, 430f, BackOut(k))); }); for (int num = 0; num < _slots.Count; num++) { Slot s = _slots[num]; ((Transform)s.Rt).localScale = Vector3.zero; float delay = 0.25f + (float)num * 0.08f; Animate(0.4f, delegate(float k) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) ((Transform)s.Rt).localScale = Vector3.one * BackOut(k); }, delay); } yield return Wait(1.2f, skippable: false); for (int i = 0; i < awards.Count; i++) { if (_skipAll) { break; } yield return PlayAward(awards[i], i, awards.Count); } if (!_skipAll) { yield return PlayMvp(mvp); } if (!_skipAll) { ((TMP_Text)_footer).text = "Click or Space to continue"; yield return Wait(12f); } ((TMP_Text)_footer).text = ""; float from = _group.alpha; Animate(0.4f, delegate(float k) { _group.alpha = Mathf.Lerp(from, 0f, k); }); yield return WaitRaw(0.4f); ShowAudio.Instance?.StopAll(); ClearConfetti(); _tweens.Clear(); ((Component)_canvas).gameObject.SetActive(false); _running = null; } private IEnumerator PlayAward(AwardResult r, int index, int count) { bool roast = r.Def.Kind == AwardKind.Roast; ResetSlots(1f); ((TMP_Text)_counter).text = $"Award {index + 1} of {count}"; ((TMP_Text)_title).text = r.Def.Title; ((Graphic)_title).color = (roast ? RoastRed : Gold); ((TMP_Text)_blurb).text = r.Def.Blurb; ((TMP_Text)_value).text = ""; SlideTitleIn(); yield return Wait(0.45f, skippable: false); List<Slot> winners = _slots.Where((Slot s) => r.Winners.Contains(s.Stats)).ToList(); yield return Drumroll(winners, (_slots.Count > 1) ? 1.9f : 0.8f); if (_skipAll) { yield break; } ShowAudio.Instance?.Reveal(r.Def.Kind); RevealValue(r.ValueText); foreach (Slot slot in _slots) { if (winners.Contains(slot)) { Crown(slot, roast ? RoastRed : Gold, 1.18f, !roast); } else { Fade(slot, 0.35f); } } if (roast) { foreach (Slot item in winners) { Shake(item); } } else { foreach (Slot item2 in winners) { Burst(item2.Rt, 45); } } yield return Wait(2.6f); Animate(0.25f, delegate(float k) { SetTitleAlpha(1f - k); }); yield return WaitRaw(0.25f); } private IEnumerator PlayMvp(AwardResult mvp) { ResetSlots(1f); ((TMP_Text)_counter).text = ""; ((TMP_Text)_title).text = mvp.Def.Title; ((Graphic)_title).color = Gold; ((TMP_Text)_blurb).text = "And the final award goes to..."; ((TMP_Text)_value).text = ""; SlideTitleIn(); yield return Wait(0.6f, skippable: false); Slot winner = _slots.First((Slot slot) => mvp.Winners.Contains(slot.Stats)); yield return Drumroll(new List<Slot> { winner }, (_slots.Count > 1) ? 2.6f : 1.2f); if (_skipAll) { yield break; } ShowAudio.Instance?.Reveal(AwardKind.Mvp); ((TMP_Text)_blurb).text = mvp.Def.Blurb; RevealValue(mvp.ValueText); foreach (Slot s in _slots) { if (s != winner) { Fade(s, 0f); continue; } Vector2 from = s.Rt.anchoredPosition; Vector2 to = new Vector2(0f, -60f); Animate(0.6f, delegate(float k) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) s.Rt.anchoredPosition = Vector2.LerpUnclamped(from, to, BackOut(k)); }); Crown(s, Gold, 1.35f, star: true); } Burst(winner.Rt, 80); Animate(0.01f, delegate { Burst(winner.Rt, 60); }, 0.45f); Animate(0.01f, delegate { Burst(winner.Rt, 60); }, 0.9f); yield return Wait(1.5f, skippable: false); } private IEnumerator Drumroll(List<Slot> winners, float seconds) { ShowAudio.Instance?.StartRoll(); Slot target = ((winners.Count > 0) ? winners[0] : _slots[0]); if (_slots.Count == 1) { Highlight(target); yield return Wait(seconds); yield break; } List<float> intervals = new List<float>(); float num = 0f; int num2 = 0; while (num < seconds) { float num3 = Mathf.Clamp01(num / seconds); float num4 = Mathf.Lerp(0.06f, 0.34f, num3 * num3); intervals.Add(num4); num += num4; num2++; } int[] order = new int[intervals.Count]; Random random = new Random(Environment.TickCount); int num5 = _slots.IndexOf(target); for (int num6 = order.Length - 1; num6 >= 0; num6--) { order[num6] = num5; int num7; do { num7 = random.Next(_slots.Count); } while (num7 == num5); num5 = num7; } for (int i = 0; i < order.Length; i++) { Highlight(_slots[order[i]]); float until = _clock + intervals[i]; while (_clock < until) { if (_skipAll) { yield break; } if (_advance) { _advance = false; Highlight(target); yield break; } yield return null; } } } private void ResetSlots(float alpha) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) foreach (Slot slot in _slots) { ((Transform)slot.Rt).localScale = Vector3.one; slot.Rt.anchoredPosition = new Vector2(slot.HomeX, 0f); slot.Group.alpha = alpha; ((Graphic)slot.Edge).color = SlotEdge; ((Component)slot.Glow).gameObject.SetActive(false); ((Component)slot.Star).gameObject.SetActive(false); ((Graphic)slot.Name).color = Tan; } } private void Highlight(Slot on) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) foreach (Slot slot in _slots) { bool flag = slot == on; ((Graphic)slot.Edge).color = (flag ? Tan : SlotEdge); ((Transform)slot.Rt).localScale = Vector3.one * (flag ? 1.07f : 1f); ((Graphic)slot.Name).color = (flag ? Color.white : Tan); } } private void Crown(Slot s, Color color, float scale, bool star) { //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) ((Graphic)s.Edge).color = color; ((Graphic)s.Name).color = Color.white; ((Graphic)s.Glow).color = color; ((Component)s.Glow).gameObject.SetActive(true); float from = ((Transform)s.Rt).localScale.x; Animate(0.55f, delegate(float k) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) ((Transform)s.Rt).localScale = Vector3.one * Mathf.LerpUnclamped(from, scale, ElasticOut(k)); }); Animate(0.4f, delegate(float k) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) ((Transform)((Graphic)s.Glow).rectTransform).localScale = Vector3.one * Mathf.Lerp(0.4f, 1f, k); }); if (star) { ((Graphic)s.Star).color = color; ((Component)s.Star).gameObject.SetActive(true); Animate(0.5f, delegate(float k) { //IL_0010: 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_0025: Unknown result type (might be due to invalid IL or missing references) ((Transform)((Graphic)s.Star).rectTransform).localScale = Vector3.one * BackOut(k) * 1f; }); AddRowStar(s); } } private void Fade(Slot s, float to) { float from = s.Group.alpha; Animate(0.3f, delegate(float k) { s.Group.alpha = Mathf.Lerp(from, to, k); }); } private void Shake(Slot s) { Animate(0.6f, delegate(float k) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) float num = 14f * (1f - k); s.Rt.anchoredPosition = new Vector2(s.HomeX + Mathf.Sin(k * 40f) * num, 0f); }, 0.15f); } private void AddRowStar(Slot s) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) Image img = NewImage("RowStar", (Transform)(object)s.StarRow, ShowArt.Star, Gold); ((Graphic)img).rectTransform.sizeDelta = new Vector2(22f, 22f); s.Stars++; int childCount = ((Transform)s.StarRow).childCount; for (int i = 0; i < childCount; i++) { ((RectTransform)((Transform)s.StarRow).GetChild(i)).anchoredPosition = new Vector2(((float)i - (float)(childCount - 1) / 2f) * 24f, 0f); } ((Transform)((Graphic)img).rectTransform).localScale = Vector3.zero; Animate(0.35f, delegate(float k) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) ((Transform)((Graphic)img).rectTransform).localScale = Vector3.one * BackOut(k); }, 0.25f); } private void SlideTitleIn() { SetTitleAlpha(0f); Animate(0.35f, delegate(float k) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) _titleBlock.anchoredPosition = new Vector2(Mathf.Lerp(320f, 0f, CubicOut(k)), 190f); SetTitleAlpha(k); }); } private void SetTitleAlpha(float a) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI[] array = (TextMeshProUGUI[])(object)new TextMeshProUGUI[3] { _title, _blurb, _value }; foreach (TextMeshProUGUI obj in array) { Color color = ((Graphic)obj).color; color.a = a; ((Graphic)obj).color = color; } } private void RevealValue(string text) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)_value).text = text; Color color = ((Graphic)_value).color; color.a = 1f; ((Graphic)_value).color = color; Animate(0.35f, delegate(float k) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) ((Transform)((TMP_Text)_value).rectTransform).localScale = Vector3.one * Mathf.Lerp(1.6f, 1f, CubicOut(k)); }); } private void Burst(RectTransform from, int count) { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) Vector2 anchoredPosition = Vector2.op_Implicit(((Transform)_confettiRoot).InverseTransformPoint(((Transform)from).position)) + new Vector2(0f, 60f); Random random = new Random(Environment.TickCount + count); for (int i = 0; i < count; i++) { Confetto confetto = _confetti.FirstOrDefault((Confetto x) => x.Life <= 0f); if (confetto == null) { if (_confetti.Count >= 300) { break; } Image val = NewImage("Confetto", (Transform)(object)_confettiRoot, ShowArt.Square, Color.white); confetto = new Confetto { Img = val, Rt = ((Graphic)val).rectTransform }; _confetti.Add(confetto); } float num = Mathf.Lerp(25f, 155f, (float)random.NextDouble()) * (MathF.PI / 180f); float num2 = Mathf.Lerp(500f, 1150f, (float)random.NextDouble()); confetto.Vel = new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * num2; confetto.Spin = Mathf.Lerp(-720f, 720f, (float)random.NextDouble()); confetto.MaxLife = (confetto.Life = Mathf.Lerp(1.6f, 2.6f, (float)random.NextDouble())); ((Graphic)confetto.Img).color = ConfettiColors[random.Next(ConfettiColors.Length)]; confetto.Rt.sizeDelta = new Vector2(Mathf.Lerp(8f, 16f, (float)random.NextDouble()), Mathf.Lerp(5f, 9f, (float)random.NextDouble())); confetto.Rt.anchoredPosition = anchoredPosition; ((Transform)confetto.Rt).localEulerAngles = new Vector3(0f, 0f, (float)random.Next(360)); ((Component)confetto.Img).gameObject.SetActive(true); } } private void UpdateConfetti(float dt) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) foreach (Confetto item in _confetti) { if (!(item.Life <= 0f)) { item.Life -= dt; if (item.Life <= 0f) { ((Component)item.Img).gameObject.SetActive(false); continue; } item.Vel.y -= 1400f * dt; item.Vel *= 1f - 1.2f * dt; RectTransform rt = item.Rt; rt.anchoredPosition += item.Vel * dt; RectTransform rt2 = item.Rt; ((Transform)rt2).localEulerAngles = ((Transform)rt2).localEulerAngles + new Vector3(0f, 0f, item.Spin * dt); Color color = ((Graphic)item.Img).color; color.a = Mathf.Clamp01(item.Life / 0.5f); ((Graphic)item.Img).color = color; } } } private void ClearConfetti() { foreach (Confetto item in _confetti) { item.Life = 0f; if ((Object)(object)item.Img != (Object)null) { ((Component)item.Img).gameObject.SetActive(false); } } } private IEnumerator Wait(float seconds, bool skippable = true) { float until = _clock + seconds; while (_clock < until && !_skipAll) { if (_advance) { _advance = false; if (skippable) { break; } } yield return null; } } private IEnumerator WaitRaw(float seconds) { float until = Time.unscaledTime + seconds; while (Time.unscaledTime < until) { yield return null; } } private void Animate(float duration, Action<float> apply, float delay = 0f) { _tweens.Add(new Tween { Start = _clock + delay, Duration = Mathf.Max(0.001f, duration), Apply = apply }); } private void RunTweens() { for (int num = _tweens.Count - 1; num >= 0; num--) { Tween tween = _tweens[num]; if (!(_clock < tween.Start)) { float num2 = Mathf.Clamp01((_clock - tween.Start) / tween.Duration); tween.Apply(num2); if (num2 >= 1f) { _tweens.RemoveAt(num); } } } } private static float CubicOut(float k) { return 1f - Mathf.Pow(1f - k, 3f); } private static float BackOut(float k) { return 1f + 2.70158f * Mathf.Pow(k - 1f, 3f) + 1.70158f * Mathf.Pow(k - 1f, 2f); } private static float ElasticOut(float k) { if (k <= 0f) { return 0f; } if (k >= 1f) { return 1f; } return Mathf.Pow(2f, -10f * k) * Mathf.Sin((k * 10f - 0.75f) * (MathF.PI * 2f / 3f)) + 1f; } private void Build() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: 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_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Unknown result type (might be due to invalid IL or missing references) FindFonts(); GameObject val = new GameObject("RunAwardsCanvas", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 1100; CanvasScaler obj = val.AddComponent<CanvasScaler>(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 0.5f; val.AddComponent<GraphicRaycaster>(); _group = val.AddComponent<CanvasGroup>(); Image obj2 = NewImage("Backdrop", val.transform, null, Ink); Stretch(((Graphic)obj2).rectTransform); ((Graphic)obj2).raycastTarget = true; ((Component)obj2).gameObject.AddComponent<ShowClick>().OnClick = delegate { _advance = true; }; Image val2 = NewImage("Rays", val.transform, ShowArt.Rays, new Color(Gold.r, Gold.g, Gold.b, 0.025f)); _rays = ((Graphic)val2).rectTransform; _rays.sizeDelta = new Vector2(1500f, 1500f); _rays.anchoredPosition = new Vector2(0f, 40f); _header = NewText("Header", val.transform, _titleFont, 46f, new Vector2(0f, 430f), new Vector2(1200f, 70f)); ((Graphic)_header).color = Gold; ((TMP_Text)_header).characterSpacing = 8f; ((TMP_Text)_header).fontStyle = (FontStyles)16; _counter = NewText("Counter", val.transform, _bodyFont, 22f, new Vector2(0f, 378f), new Vector2(900f, 30f)); ((Graphic)_counter).color = Dim; _titleBlock = new GameObject("Title", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)_titleBlock).SetParent(val.transform, false); _titleBlock.anchoredPosition = new Vector2(0f, 190f); _title = NewText("AwardTitle", (Transform)(object)_titleBlock, _titleFont, 76f, new Vector2(0f, 40f), new Vector2(1600f, 100f)); ((Graphic)_title).color = Gold; ((TMP_Text)_title).outlineWidth = 0.18f; ((TMP_Text)_title).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue); _blurb = NewText("Blurb", (Transform)(object)_titleBlock, _bodyFont, 30f, new Vector2(0f, -28f), new Vector2(1400f, 44f)); ((Graphic)_blurb).color = Tan; _value = NewText("Value", (Transform)(object)_titleBlock, _bodyFont, 38f, new Vector2(0f, -88f), new Vector2(1400f, 52f)); ((Graphic)_value).color = Color.white; _row = new GameObject("Heroes", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)_row).SetParent(val.transform, false); _row.anchoredPosition = new Vector2(0f, -170f); _footer = NewText("Footer", val.transform, _bodyFont, 20f, new Vector2(0f, -490f), new Vector2(900f, 30f)); ((Graphic)_footer).color = Dim; TextMeshProUGUI val3 = NewText("SkipAll", val.transform, _bodyFont, 22f, Vector2.zero, new Vector2(200f, 40f)); RectTransform rectTransform = ((TMP_Text)val3).rectTransform; RectTransform rectTransform2 = ((TMP_Text)val3).rectTransform; RectTransform rectTransform3 = ((TMP_Text)val3).rectTransform; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(1f, 1f); rectTransform3.pivot = val4; Vector2 anchorMin = (rectTransform2.anchorMax = val4); rectTransform.anchorMin = anchorMin; ((TMP_Text)val3).rectTransform.anchoredPosition = new Vector2(-40f, -30f); ((TMP_Text)val3).alignment = (TextAlignmentOptions)516; ((TMP_Text)val3).text = "Skip all >>"; ((Graphic)val3).color = Tan; ((Graphic)val3).raycastTarget = true; ((Component)val3).gameObject.AddComponent<ShowClick>().OnClick = delegate { _skipAll = true; }; _confettiRoot = new GameObject("Confetti", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)_confettiRoot).SetParent(val.transform, false); val.SetActive(false); } private void SetUpSlots(Snapshot snap) { //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) foreach (Slot slot2 in _slots) { Object.Destroy((Object)(object)((Component)slot2.Rt).gameObject); } _slots.Clear(); List<Character> list = Heroes.Party(); Dictionary<string, Character> dictionary = new Dictionary<string, Character>(); foreach (Character item in list) { dictionary[Heroes.Key(item)] = item; } Root root = Heroes.Root; bool mp = root != null && (Object)(object)NetworkingManager.Instance != (Object)null && !NetworkingManager.Instance.IsPlayingAsSinglePlayer; int count = snap.Heroes.Count; float num = (float)count * 180f + (float)(count - 1) * 28f; for (int i = 0; i < count; i++) { HeroStats heroStats = snap.Heroes[i]; dictionary.TryGetValue(heroStats.Key, out var value); if (value != null) { heroStats.Name = Heroes.SafeName(value); } Slot slot = BuildSlot(heroStats, value, root, mp); slot.HomeX = (0f - num) / 2f + 90f + (float)i * 208f; slot.Rt.anchoredPosition = new Vector2(slot.HomeX, 0f); _slots.Add(slot); } ((Transform)_row).localScale = Vector3.one * ((count > 6) ? (6f / (float)count) : 1f); } private Slot BuildSlot(HeroStats stats, Character c, Root root, bool mp) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_0310: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Hero " + stats.Name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_row, false); RectTransform component = val.GetComponent<RectTransform>(); component.sizeDelta = new Vector2(180f, 236f); Slot slot = new Slot { Stats = stats, Rt = component, Group = val.AddComponent<CanvasGroup>() }; slot.Glow = NewImage("Glow", (Transform)(object)component, ShowArt.Glow, Gold); ((Graphic)slot.Glow).rectTransform.sizeDelta = new Vector2(420f, 420f); ((Component)slot.Glow).gameObject.SetActive(false); Image obj = NewImage("Panel", (Transform)(object)component, ShowArt.Panel, SlotBg); obj.type = (Type)1; ((Graphic)obj).rectTransform.sizeDelta = new Vector2(180f, 236f); slot.Edge = NewImage("Edge", (Transform)(object)component, ShowArt.Frame, SlotEdge); slot.Edge.type = (Type)1; ((Graphic)slot.Edge).rectTransform.sizeDelta = new Vector2(180f, 236f); Color color = Tan; string text = null; if (c != null && root != null) { try { color = Color.Lerp(root.GetPlayerControllerColor(c.OwnerID, c.ControllerPlayerId), Color.white, 0.3f); color.a = 1f; string text2 = default(string); if (mp && root.ConnectionNameDict.TryGetValue(c.OwnerID, ref text2)) { text = root.ConnectionNameDictFiltered(c.OwnerID); } } catch (Exception e) { Tracker.Fail("player color", e); } } Rect uv; Texture val2 = FindPortrait(c, out uv); if ((Object)(object)val2 != (Object)null) { RawImage obj2 = new GameObject("Portrait", new Type[1] { typeof(RectTransform) }).AddComponent<RawImage>(); ((Component)obj2).transform.SetParent((Transform)(object)component, false); obj2.texture = val2; obj2.uvRect = uv; ((Graphic)obj2).raycastTarget = false; ((Graphic)obj2).rectTransform.sizeDelta = new Vector2(150f, 150f); ((Graphic)obj2).rectTransform.anchoredPosition = new Vector2(0f, 30f); } else { Image val3 = NewImage("Disc", (Transform)(object)component, ShowArt.Disc, color); ((Graphic)val3).rectTransform.sizeDelta = new Vector2(120f, 120f); ((Graphic)val3).rectTransform.anchoredPosition = new Vector2(0f, 30f); TextMeshProUGUI obj3 = NewText("Initial", (Transform)(object)((Graphic)val3).rectTransform, _titleFont, 64f, Vector2.zero, new Vector2(120f, 120f)); ((TMP_Text)obj3).text = (string.IsNullOrEmpty(stats.Name) ? "?" : stats.Name.Substring(0, 1).ToUpperInvariant()); ((Graphic)obj3).color = Ink; } slot.Name = NewText("Name", (Transform)(object)component, _bodyFont, 22f, new Vector2(0f, -70f), new Vector2(220f, 30f)); ((TMP_Text)slot.Name).text = stats.Name; ((Graphic)slot.Name).color = Tan; if (text != null) { TextMeshProUGUI obj4 = NewText("Player", (Transform)(object)component, _bodyFont, 16f, new Vector2(0f, -95f), new Vector2(220f, 24f)); ((TMP_Text)obj4).text = text; ((Graphic)obj4).color = color; } slot.StarRow = new GameObject("Stars", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)slot.StarRow).SetParent((Transform)(object)component, false); slot.StarRow.anchoredPosition = new Vector2(0f, -138f); slot.Star = NewImage("Star", (Transform)(object)component, ShowArt.Star, Gold); ((Graphic)slot.Star).rectTransform.sizeDelta = new Vector2(64f, 64f); ((Graphic)slot.Star).rectTransform.anchoredPosition = new Vector2(0f, 152f); ((Component)slot.Star).gameObject.SetActive(false); return slot; } private static Texture FindPortrait(Character c, out Rect uv) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) uv = new Rect(0f, 0f, 1f, 1f); if (c == null) { return null; } PortraitManager instance = PortraitManager.Instance; Portrait[] array = (((Object)(object)instance != (Object)null) ? Portraits.Invoke(instance) : null); if (array == null) { return null; } Portrait[] array2 = array; foreach (Portrait val in array2) { if (!((Object)(object)val == (Object)null) && val.Character == c) { RawImage val2 = PortraitImage.Invoke(val); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.texture == (Object)null) { return null; } uv = val2.uvRect; return val2.texture; } } return null; } private void FindFonts() { List<TMP_FontAsset> fonts = (from f in Resources.FindObjectsOfTypeAll<TMP_FontAsset>() where (Object)(object)f != (Object)null select f).ToList(); _titleFont = Pick("Title Font (Trajan Pro Regular) SDF", "Trajan"); _bodyFont = Pick("Regular Font (Minion Pro Regular) SDF", "Minion"); if ((Object)(object)_bodyFont == (Object)null) { TextMeshProUGUI val = ((IEnumerable<TextMeshProUGUI>)Object.FindObjectsOfType<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => (Object)(object)((TMP_Text)t).font != (Object)null)); _bodyFont = (((Object)(object)val != (Object)null) ? ((TMP_Text)val).font : TMP_Settings.defaultFontAsset); } if ((Object)(object)_titleFont == (Object)null) { _titleFont = _bodyFont; } Plugin.ModLog.LogInfo((object)("Show fonts: title " + (((Object)(object)_titleFont != (Object)null) ? ((Object)_titleFont).name : "none") + ", body " + (((Object)(object)_bodyFont != (Object)null) ? ((Object)_bodyFont).name : "none"))); TMP_FontAsset Pick(string plain, string family) { return ((IEnumerable<TMP_FontAsset>)fonts).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name == plain)) ?? ((IEnumerable<TMP_FontAsset>)fonts).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf(family, StringComparison.OrdinalIgnoreCase) >= 0)); } } private static Image NewImage(string name, Transform parent, Sprite sprite, Color color) { //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_0033: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); Image obj = val.AddComponent<Image>(); obj.sprite = sprite; ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; return obj; } private static TextMeshProUGUI NewText(string name, Transform parent, TMP_FontAsset font, float size, Vector2 pos, Vector2 box) { //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_005d: 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_0081: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); if ((Object)(object)font != (Object)null) { ((TMP_Text)val2).font = font; } ((TMP_Text)val2).fontSize = size; ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).color = Tan; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).rectTransform.anchoredPosition = pos; ((TMP_Text)val2).rectTransform.sizeDelta = box; return val2; } private static void Stretch(RectTransform rt) { //IL_0001: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; Vector2 offsetMin = (rt.offsetMax = Vector2.zero); rt.offsetMin = offsetMin; } private static Color Hex(string rgb) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); ColorUtility.TryParseHtmlString("#" + rgb, ref result); return result; } } internal class ShowClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal Action OnClick; public void OnPointerClick(PointerEventData e) { OnClick?.Invoke(); } } internal static class AwardSync { private static class Bridge { internal static bool IsMultiplayer() { return ModNetApi.IsMultiplayer; } internal static bool Send(string payload) { return ModNetApi.Send("runawards", payload, (Character)null); } internal static void Hook() { ModNetApi.Register("runawards", (Action<NetMessage>)delegate(NetMessage m) { string payload = m.Payload; PlayerInfo sender = m.Sender; OnMessage(payload, (sender != null) ? sender.Name : null); }); } } private const string Channel = "runawards"; private static bool _available; private static int _incomingId = -1; private static readonly List<HeroStats> Incoming = new List<HeroStats>(); private static Snapshot _received; private static float _receivedAt = -999f; internal static bool InMultiplayer { get { if (_available) { return IsMultiplayer(); } return false; } } internal static void Init() { _available = true; Bridge.Hook(); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool IsMultiplayer() { return Bridge.IsMultiplayer(); } internal static Snapshot Received(float maxAge) { if (_received == null || !(Time.unscaledTime - _receivedAt <= maxAge)) { return null; } return _received; } internal static void Share(Snapshot s) { if (!InMultiplayer) { return; } int seed = s.Seed; int num = 0; foreach (HeroStats hero in s.Heroes) { string arg = string.Join(",", hero.V.Select((float v) => v.ToString("0.#", CultureInfo.InvariantCulture))); if (Send($"hero|{seed}|{hero.Key}|{arg}")) { num++; } } bool flag = Send($"done|{seed}|{s.Heroes.Count}|{(s.Roguelike ? 1 : 0)}|{s.Known}"); Plugin.ModLog.LogInfo((object)((flag && num == s.Heroes.Count) ? $"Sent the final stats ({num} heroes) to the other players." : $"Could not send all final stats (heroes {num}/{s.Heroes.Count}, done {flag}): ModNet not ready?")); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool Send(string payload) { return Bridge.Send(payload); } private static void OnMessage(string payload, string sender) { string[] array = payload.Split('|'); if (array.Length < 3 || !int.TryParse(array[1], out var result)) { return; } if (result != _incomingId) { _incomingId = result; Incoming.Clear(); } string text = array[0]; if (!(text == "hero")) { if (text == "done" && array.Length >= 5) { int.TryParse(array[2], out var result2); int.TryParse(array[4], out var result3); _received = new Snapshot { Known = result3, Roguelike = (array[3] == "1"), Source = "host", Seed = result }; _received.Heroes.AddRange(Incoming); _receivedAt = Time.unscaledTime; Plugin.ModLog.LogInfo((object)string.Format("Got the final stats from {0}: {1}/{2} heroes.", sender ?? "the host", Incoming.Count, result2)); } } else if (array.Length >= 4) { HeroStats heroStats = new HeroStats(array[2], "Hero"); string[] array2 = array[3].Split(','); for (int i = 0; i < array2.Length && i < HeroStats.Count; i++) { float.TryParse(array2[i], NumberStyles.Float, CultureInfo.InvariantCulture, out heroStats.V[i]); } Incoming.Add(heroStats); } } } internal static class MenuCard { private const string Dim = "#9A8F85"; internal static void Register() { ModsMenuApi.AddSection("com.helvetica.runawards", (Action<SectionBuilder>)Build); } private static void Build(SectionBuilder b) { b.AddSubheader("This adventure so far"); Snapshot snap = RunStats.BuildLocal(); if (snap.Heroes.Count == 0) { b.AddLabel("<color=#9A8F85>No party yet.</color>"); } else { foreach (HeroStats hero in snap.Heroes) { HeroStats h = hero; IEnumerable<string> values = new string[6] { Part(Stat.Damage, "damage", "damage"), Part(Stat.Kills, "kill", "kills"), Part(Stat.Healing, "healed", "healed"), Part(Stat.Deaths, "knockout", "knockouts"), Part(Stat.Potions, "potion", "potions"), Part(Stat.Tiles, "tile", "tiles") }.Where((string p) => p != null); b.AddLabel(h.Name + ": <color=#9A8F85>" + string.Join(" · ", values) + "</color>"); string Part(Stat s, string one, string many) { if (!snap.Knows(s)) { return null; } return $"{h[s]:N0} {(Mathf.Approximately(h[s], 1f) ? one : many)}"; } } if (!snap.Knows(Stat.Kills)) { b.AddLabel("<color=#9A8F85>Kills and the other combat stats come from the host when the adventure ends.</color>"); } } b.AddButton("Preview the awards show", (Action)delegate { AwardShow.Instance?.Preview(); }, "Plays the show now with these numbers (made-up ones if nothing was tracked yet)."); } } [BepInPlugin("com.helvetica.runawards", "Run Awards", "0.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : StolenRealmMod { public const string PluginGuid = "com.helvetica.runawards"; public const string PluginName = "Run Awards"; public const string PluginVersion = "0.2.1"; internal static ManualLogSource ModLog; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> MaxAwards; internal static ConfigEntry<float> Speed; internal static ConfigEntry<bool> Roasts; internal static ConfigEntry<bool> OddStats; internal static ConfigEntry<float> Volume; internal static ConfigEntry<KeyboardShortcut> PreviewKey; internal static ConfigEntry<bool> LogStats; protected override void OnModLoaded() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) ModLog = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Track stats during adventures and play the awards show when one ends."); MaxAwards = ((BaseUnityPlugin)this).Config.Bind<int>("Show", "MaxAwards", 8, new ConfigDescription("Most awards shown before the Hero of the Adventure, drawn at random from those that apply.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 15), Array.Empty<object>())); Speed = ((BaseUnityPlugin)this).Config.Bind<float>("Show", "Speed", 1f, new ConfigDescription("Pace of the show. 2 = twice as fast.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>())); Roasts = ((BaseUnityPlugin)this).Config.Bind<bool>("Show", "Roasts", true, "Include joke awards: knockouts, damage taken, friendly fire, stolen kills, misses, healing received, least damage, fewest tiles."); OddStats = ((BaseUnityPlugin)this).Config.Bind<bool>("Show", "OddStats", true, "Include odd-stat awards: potions, gold, items, critical hits, blocked damage, overkill, close calls, smashed barrels, tiles walked, reflected damage."); Volume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.7f, new ConfigDescription("Volume of the drumroll and fanfares (on top of the game's sound effects volume).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); PreviewKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "PreviewKey", new KeyboardShortcut((KeyCode)97, (KeyCode[])(object)new KeyCode[2] { (KeyCode)306, (KeyCode)304 }), "Play the show now with the stats so far (made-up numbers if nothing was tracked yet)."); LogStats = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogStats", false, "Write each run's stat table and the chosen awards to the BepInEx log."); GameObject val = new GameObject("RunAwards"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<Runner>(); val.AddComponent<ShowAudio>(); val.AddComponent<AwardShow>(); if (Chainloader.PluginInfos.ContainsKey("com.helvetica.modnet")) { AwardSync.Init(); } if (Chainloader.PluginInfos.ContainsKey("com.helvetica.modsmenu")) { MenuCard.Register(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Run Awards v0.2.1 loaded."); } } internal class Runner : MonoBehaviour { private const float PollInterval = 0.1f; private const int MaxStep = 8; private readonly Dictionary<string, HexCell> _lastCell = new Dictionary<string, HexCell>(); private readonly Dictionary<string, bool> _lastDead = new Dictionary<string, bool>(); private int _generation = -1; private float _nextPoll; private string _lastError; private void Update() { //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) try { KeyboardShortcut value = Plugin.PreviewKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !TypingInChat()) { AwardShow.Instance?.Preview(); } if (Plugin.Enabled.Value && !(Time.unscaledTime < _nextPoll)) { _nextPoll = Time.unscaledTime + 0.1f; Poll(); } } catch (Exception ex) { if (ex.ToString() != _lastError) { _lastError = ex.ToString(); Plugin.ModLog.LogError((object)ex); } } } private void Poll() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (_generation != RunStats.Generation) { _generation = RunStats.Generation; _lastCell.Clear(); _lastDead.Clear(); } if (Heroes.Root == null) { return; } bool isServer = Heroes.IsServer; foreach (Character item in Heroes.Party()) { string key = Heroes.Key(item); HexCell cell = item.Cell; if ((Object)(object)cell != (Object)null) { if (_lastCell.TryGetValue(key, out var value) && (Object)(object)value != (Object)null && value != cell) { int num = Distance(value.Coordinates, cell.Coordinates); if (num > 0 && num <= 8) { RunStats.Add(item, Stat.Tiles, num); } } _lastCell[key] = cell; } if (!isServer) { bool isDead = item.IsDead; if (_lastDead.TryGetValue(key, out var value2) && !value2 && isDead) { RunStats.Add(item, Stat.Deaths, 1f); } _lastDead[key] = isDead; } } } private static int Distance(HexCoordinates a, HexCoordinates b) { return (Math.Abs(((HexCoordinates)(ref a)).X - ((HexCoordinates)(ref b)).X) + Math.Abs(((HexCoordinates)(ref a)).Y - ((HexCoordinates)(ref b)).Y) + Math.Abs(((HexCoordinates)(ref a)).Z - ((HexCoordinates)(ref b)).Z)) / 2; } private static bool TypingInChat() { MessageWindowManager instance = MessageWindowManager.instance; if ((Object)(object)instance != (Object)null) { return instance.TextInputIsFocused; } return false; } } internal enum Stat { Damage, Kills, BossKills, Healing, BiggestHit, SummonDamage, Deaths, DamageTaken, FriendlyFire, Gold, Loot, Blocked, Crits, Tiles, Thorns, Potions, Dodges, Misses, Overkill, CloseCalls, HealingReceived, Smashed, FirstBlood, KillSteals } internal sealed class HeroStats { internal static readonly int Count = Enum.GetValues(typeof(Stat)).Length; internal readonly string Key; internal string Name; internal readonly float[] V = new float[Count]; internal float this[Stat s] { get { return V[(int)s]; } set { V[(int)s] = value; } } internal HeroStats(string key, string name) { Key = key; Name = name; } internal HeroStats Copy() { HeroStats heroStats = new HeroStats(Key, Name); Array.Copy(V, heroStats.V, Count); return heroStats; } } internal sealed class Snapshot { internal readonly List<HeroStats> Heroes = new List<HeroStats>(); internal int Known; internal bool Roguelike; internal string Source; internal int Seed = Random.Range(1, 1000000); internal static int AllKnown => (1 << HeroStats.Count) - 1; internal static int ClientKnown => Bit(Stat.Damage) | Bit(Stat.Healing) | Bit(Stat.Gold) | Bit(Stat.Loot) | Bit(Stat.Deaths) | Bit(Stat.Tiles); internal bool Knows(Stat s) { return (Known & (1 << (int)s)) != 0; } internal static int Bit(Stat s) { return 1 << (int)s; } } internal static class Heroes { internal static Root Root { get { NetworkingManager instance = NetworkingManager.Instance; if (!((Object)(object)instance != (Object)null) || instance.NetworkManager == null) { return null; } return ((Observer<Root>)(object)instance.NetworkManager).Root; } } internal static bool IsServer { get { NetworkingManager instance = NetworkingManager.Instance; if ((Object)(object)instance != (Object)null) { return instance.IsServer; } return false; } } internal static bool IsHero(Character c) { if (c != null && c.TeamIndex == 0 && c.SummonMaster == null && !c.IsSummon && !c.IsNPC) { if (c.IsAI) { return c.IsAIControlledPlayer; } return true; } return false; } internal static Character Credit(Character c) { if (c == null) { return null; } if (IsHero(c)) { return c; } Character summonMaster = c.SummonMaster; if (summonMaster == null || !IsHero(summonMaster)) { return null; } return summonMaster; } internal static string Key(Character c) { string guid = c.Guid; if (!string.IsNullOrEmpty(guid)) { return guid; } return "n:" + SafeName(c); } internal static string SafeName(Character c) { try { return c.CharacterName ?? "Hero"; } catch { return "Hero"; } } internal static List<Character> Party() { Root root = Root; List<Character> list = ((root != null) ? root.PartyCharacters : null); if (list != null) { return list.Where(IsHero).ToList(); } return new List<Character>(); } } internal static class RunStats { internal static readonly Dictionary<string, HeroStats> Heroes = new Dictionary<string, HeroStats>(); internal static int Generation; internal static float StartedAt; internal static bool FirstBloodTaken; internal static void Reset(string why) { Heroes.Clear(); FirstBloodTaken = false; Tracker.ResetBattleState(); Generation++; StartedAt = Time.unscaledTime; Plugin.ModLog.LogInfo((object)("Tracking a new adventure (" + why + ").")); } internal static HeroStats Of(Character hero) { string key = RunAwards.Heroes.Key(hero); if (!Heroes.TryGetValue(key, out var value)) { value = (Heroes[key] = new HeroStats(key, RunAwards.Heroes.SafeName(hero))); } return value; } internal static void Add(Character hero, Stat s, float v) { if (hero != null && v != 0f) { Of(hero)[s] += v; } } internal static void Max(Character hero, Stat s, float v) { if (hero != null) { HeroStats heroStats = Of(hero); if (v > heroStats[s]) { heroStats[s] = v; } } } internal static Snapshot BuildLocal() { bool isServer = RunAwards.Heroes.IsServer; Snapshot snapshot = new Snapshot { Known = (isServer ? Snapshot.AllKnown : Snapshot.ClientKnown), Source = (isServer ? "host" : "local (no host data)") }; Root root = RunAwards.Heroes.Root; snapshot.Roguelike = root != null && root.PlayingRoguelike; foreach (Character item in RunAwards.Heroes.Party()) { string key = RunAwards.Heroes.Key(item); HeroStats value; HeroStats heroStats = (Heroes.TryGetValue(key, out value) ? value.Copy() : new HeroStats(key, RunAwards.Heroes.SafeName(item))); heroStats.Name = RunAwards.Heroes.SafeName(item); MergeGameStats(root, item, heroStats); snapshot.Heroes.Add(heroStats); } return snapshot; } private static void MergeGameStats(Root root, Character c, HeroStats h) { if (root == null || root.QuestStats == null) { return; } CharacterQuestStats val = null; foreach (CharacterQuestStats questStat in root.QuestStats) { if (questStat != null && questStat.Character == c) { val = questStat; break; } } if (val == null) { return; } ObservableDictionary<int, float> questStats = val.QuestStats; if (questStats != null) { float value = default(float); if (questStats.TryGetValue(7, ref value)) { h[Stat.Damage] = value; } float value2 = default(float); if (questStats.TryGetValue(8, ref value2)) { h[Stat.Healing] = value2; } float value3 = default(float); if (questStats.TryGetValue(1, ref value3)) { h[Stat.Gold] = value3; } } if (val.Items != null) { h[Stat.Loot] = val.Items.Count; } } internal static Snapshot BuildDemo() { Snapshot snapshot = new Snapshot { Known = Snapshot.AllKnown, Source = "demo" }; List<Character> list = RunAwards.Heroes.Party(); IList obj = ((list.Count > 0) ? ((IList)list.Select((Character c) => (RunAwards.Heroes.Key(c), RunAwards.Heroes.SafeName(c))).ToList()) : ((IList)new string[4] { "Aldric", "Brynn", "Cora", "Dax" }.Select((string n) => ("n:" + n, n: n)).ToList())); Random random = new Random(Environment.TickCount); foreach (var item3 in (List<(string, string)>)obj) { string item = item3.Item1; string item2 = item3.Item2; HeroStats heroStats = new HeroStats(item, item2); heroStats[Stat.Damage] = random.Next(800, 9000); heroStats[Stat.Kills] = random.Next(0, 14); heroStats[Stat.BossKills] = ((random.Next(0, 3) == 0) ? 1 : 0); heroStats[Stat.Healing] = ((random.Next(0, 3) == 0) ? random.Next(200, 3000) : 0); heroStats[Stat.BiggestHit] = random.Next(60, 700); heroStats[Stat.SummonDamage] = ((random.Next(0, 4) == 0) ? random.Next(100, 1500) : 0); heroStats[Stat.Deaths] = random.Next(0, 4); heroStats[Stat.DamageTaken] = random.Next(300, 5000); heroStats[Stat.FriendlyFire] = ((random.Next(0, 3) == 0) ? random.Next(10, 300) : 0); heroStats[Stat.Gold] = random.Next(50, 900); heroStats[Stat.Loot] = random.Next(0, 9); heroStats[Stat.Blocked] = random.Next(100, 2500); heroStats[Stat.Crits] = random.Next(0, 12); heroStats[Stat.Tiles] = random.Next(40, 400); heroStats[Stat.Thorns] = ((random.Next(0, 4) == 0) ? random.Next(10, 200) : 0); heroStats[Stat.Potions] = random.Next(0, 6); heroStats[Stat.Dodges] = random.Next(0, 7); heroStats[Stat.Misses] = ((random.Next(0, 3) == 0) ? random.Next(1, 4) : 0); heroStats[Stat.Overkill] = random.Next(0, 400); heroStats[Stat.CloseCalls] = random.Next(0, 3); heroStats[Stat.HealingReceived] = random.Next(0, 2500); heroStats[Stat.Smashed] = random.Next(0, 5); heroStats[Stat.KillSteals] = random.Next(0, 3); snapshot.Heroes.Add(heroStats); } snapshot.Heroes[random.Next(snapshot.Heroes.Count)][Stat.FirstBlood] = 1f; return snapshot; } internal static void ResolveNames(Snapshot s) { Dictionary<string, Character> dictionary = new Dictionary<string, Character>(); foreach (Character item in RunAwards.Heroes.Party()) { dictionary[RunAwards.Heroes.Key(item)] = item; } foreach (HeroStats hero in s.Heroes) { if (dictionary.TryGetValue(hero.Key, out var value)) { hero.Name = RunAwards.Heroes.SafeName(value); } } } internal static bool IsEmpty(Snapshot s) { return s.Heroes.All((HeroStats h) => h.V.All((float v) => v == 0f)); } internal static void Log(Snapshot s, string title) { if (!Plugin.LogStats.Value) { return; } List<string> list = new List<string>(); list.Add($"{title}: {s.Heroes.Count} heroes, source {s.Source}, roguelike {s.Roguelike}"); List<string> list2 = list; List<Stat> source = Enum.GetValues(typeof(Stat)).Cast<Stat>().ToList(); list2.Add(" " + string.Join(" | ", source.Select((Stat st) => (!s.Knows(st)) ? (st.ToString() + "(?)") : st.ToString()))); foreach (HeroStats h in s.Heroes) { list2.Add(" " + h.Name + ": " + string.Join(" | ", source.Select((Stat st) => h[st].ToString("0")))); } Plugin.ModLog.LogInfo((object)string.Join("\n", list2)); } } internal static class ShowArt { private static Sprite _panel; private static Sprite _frame; private static Sprite _star; private static Sprite _rays; private static Sprite _glow; private static Sprite _square; private static Sprite _disc; internal static Sprite Panel => _panel ?? (_panel = RoundedRect(64, 18, 0f)); internal static Sprite Frame => _frame ?? (_frame = RoundedRect(64, 18, 4f)); internal static Sprite Star => _star ?? (_star = MakeStar(128)); internal static Sprite Rays => _rays ?? (_rays = MakeRays(512, 18)); internal static Sprite Glow => _glow ?? (_glow = MakeGlow(128)); internal static Sprite Square => _square ?? (_square = MakeSquare()); internal static Sprite Disc => _disc ?? (_disc = MakeDisc(128)); private static Texture2D NewTexture(int w, int h) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown return new Texture2D(w, h, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1, hideFlags = (HideFlags)61 }; } private static Sprite Finish(Texture2D t, Color32[] px, Vector4 border = default(Vector4)) { //IL_0028: 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_0043: Unknown result type (might be due to invalid IL or missing references) t.SetPixels32(px); t.Apply(false, true); Sprite obj = Sprite.Create(t, new Rect(0f, 0f, (float)((Texture)t).width, (float)((Texture)t).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, border); ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static byte A(float a) { return (byte)Mathf.RoundToInt(Mathf.Clamp01(a) * 255f); } private static float RoundedBoxSdf(float x, float y, float half, float radius) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Abs(x) - (half - radius); float num2 = Mathf.Abs(y) - (half - radius); Vector2 val = new Vector2(Mathf.Max(num, 0f), Mathf.Max(num2, 0f)); return ((Vector2)(ref val)).magnitude + Mathf.Min(Mathf.Max(num, num2), 0f) - radius; } private static Sprite RoundedRect(int size, int radius, float outline) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) Texture2D t = NewTexture(size, size); Color32[] array = (Color32[])(object)new Color32[size * size]; float num = (float)size / 2f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = RoundedBoxSdf((float)j + 0.5f - num, (float)i + 0.5f - num, num - 0.5f, radius); float num3 = Mathf.Clamp01(0.5f - num2); if (outline > 0f) { num3 = Mathf.Min(num3, Mathf.Clamp01(num2 + outline + 0.5f)); } array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, A(num3)); } } int num4 = radius + 2; return Finish(t, array, new Vector4((float)num4, (float)num4, (float)num4, (float)num4)); } private static Sprite MakeStar(int size) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) Texture2D t = NewTexture(size, size); Color32[] array = (Color32[])(object)new Color32[size * size]; float num = (float)size / 2f; float num2 = (float)size * 0.48f; float num3 = num2 * 0.45f; Vector2[] array2 = (Vector2[])(object)new Vector2[10]; for (int i = 0; i < 10; i++) { float num4 = MathF.PI / 2f + (float)i * MathF.PI / 5f; float num5 = ((i % 2 == 0) ? num2 : num3); array2[i] = new Vector2(Mathf.Cos(num4) * num5, Mathf.Sin(num4) * num5); } for (int j = 0; j < size; j++) { for (int k = 0; k < size; k++) { float num6 = PolygonSdf(new Vector2((float)k + 0.5f - num, (float)j + 0.5f - num), array2); array[j * size + k] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, A(0.5f - num6)); } } return Finish(t, array); } private static float PolygonSdf(Vector2 p, Vector2[] v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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) float num = Vector2.Dot(p - v[0], p - v[0]); float num2 = 1f; int i = 0; int num3 = v.Length - 1; for (; i < v.Length; i++) { Vector2 val = v[num3] - v[i]; Vector2 val2 = p - v[i]; Vector2 val3 = val2 - val * Mathf.Clamp01(Vector2.Dot(val2, val) / Vector2.Dot(val, val)); num = Mathf.Min(num, Vector2.Dot(val3, val3)); bool flag = p.y >= v[i].y; bool flag2 = p.y < v[num3].y; bool flag3 = val.x * val2.y > val.y * val2.x; if ((flag && flag2 && flag3) || (!flag && !flag2 && !flag3)) { num2 = 0f - num2; } num3 = i; } return num2 * Mathf.Sqrt(num); } private static Sprite MakeRays(int size, int count) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Texture2D t = NewTexture(size, size); Color32[] array = (Color32[])(object)new Color32[size * size]; float num = (float)size / 2f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = (float)j + 0.5f - num; float num3 = (float)i + 0.5f - num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3) / num; float num5 = Mathf.Pow(Mathf.Clamp01(Mathf.Cos(Mathf.Atan2(num3, num2) * (float)count) * 0.5f + 0.5f), 3f); float num6 = Mathf.Clamp01(1f - num4) * Mathf.Clamp01(num4 * 4f); array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, A(num5 * num6)); } } return Finish(t, array); } private static Sprite MakeGlow(int size) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Texture2D t = NewTexture(size, size); Color32[] array = (Color32[])(object)new Color32[size * size]; float num = (float)size / 2f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = (float)j + 0.5f - num; float num3 = (float)i + 0.5f - num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3) / num; float num5 = Mathf.Clamp01(1f - num4); array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, A(num5 * num5)); } } return Finish(t, array); } private static Sprite MakeDisc(int size) { //IL_0095: 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_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) Texture2D t = NewTexture(size, size); Color32[] array = (Color32[])(object)new Color32[size * size]; float num = (float)size / 2f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = (float)j + 0.5f - num; float num3 = (float)i + 0.5f - num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3) - (num - 1f); array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, A(0.5f - num4)); } } return Finish(t, array); } private static Sprite MakeSquare() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Texture2D t = NewTexture(4, 4); Color32[] array = (Color32[])(object)new Color32[16]; for (int i = 0; i < array.Length; i++) { array[i] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); } return Finish(t, array); } } internal class ShowAudio : MonoBehaviour { private const int Rate = 44100; private static readonly FieldRef<SoundManager, AudioMixerGroup> SfxGroup = AccessTools.FieldRefAccess<SoundManager, AudioMixerGroup>("sfxMixerGroup"); internal static ShowAudio Instance; private AudioSource _roll; private AudioSource _oneShot; private AudioClip _rollClip; private AudioClip _fanfare; private AudioClip _womp; private AudioClip _mvp; private AudioClip _tick; private void Awake() { Instance = this; _roll = NewSource(); _oneShot = NewSource(); } private AudioSource NewSource() { AudioSource obj = ((Component)this).gameObject.AddComponent<AudioSource>(); obj.playOnAwake = false; obj.spatialBlend = 0f; obj.ignoreListenerPause = true; return obj; } private void Route() { SoundManager instance = SoundManager.instance; AudioMixerGroup outputAudioMixerGroup = (((Object)(object)instance != (Object)null) ? SfxGroup.Invoke(instance) : null); _roll.outputAudioMixerGroup = outputAudioMixerGroup; _oneShot.outputAudioMixerGroup = outputAudioMixerGroup; AudioSource roll = _roll; float volume = (_oneShot.volume = Plugin.Volume.Value); roll.volume = volume; } private void Build() { if (!((Object)(object)_rollClip != (Object)null)) { _rollClip = Drumroll(6f); _fanfare = Fanfare(big: false); _mvp = Fanfare(big: true); _womp = Womp(); _tick = Tick(); } } internal void StartRoll() { Build(); Route(); _roll.clip = _rollClip; _roll.time = 0f; _roll.Play(); } internal void StopRoll() { _roll.Stop(); } internal void Reveal(AwardKind kind) { Build(); Route(); StopRoll(); AudioClip val = (AudioClip)(kind switch { AwardKind.Mvp => _mvp, AwardKind.Roast => _womp, _ => _fanfare, }); _oneShot.PlayOneShot(val); } internal void TickSound() { Build(); Route(); _oneShot.PlayOneShot(_tick, 0.35f); } internal void StopAll() { if ((Object)(object)_roll != (Object)null) { _roll.Stop(); } if ((Object)(object)_oneShot != (Object)null) { _oneShot.Stop(); } } private static AudioClip Clip(string name, float[] data) { AudioClip obj = AudioClip.Create("RunAwards." + name, data.Length, 1, 44100, false); obj.SetData(data, 0); ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static AudioClip Drumroll(float seconds) { int num = (int)(seconds * 44100f); float[] array = new float[num]; Random random = new Random(7); float num2 = 0f; float num3 = 0f; double num4 = 0.0; int num5 = -100000; float num6 = 0f; for (int i = 0; i < num; i++) { float num7 = (float)i / 44100f; if ((double)num7 >= num4) { num5 = i; num6 = 0.55f + 0.45f * (float)random.NextDouble(); num4 = (double)num7 + 1.0 / 26.0 * (0.85 + 0.3 * random.NextDouble()); } float num8 = (float)(i - num5) / 44100f; float num9 = num6 * Mathf.Exp((0f - num8) * 38f); float num10 = (float)(random.NextDouble() * 2.0 - 1.0); num2 += (num10 - num2) * 0.35f; float num11 = num2 - num3; num3 += (num2 - num3) * 0.05f; float num12 = Mathf.Sin(MathF.PI * 380f * num8) * Mathf.Exp((0f - num8) * 60f) * 0.4f; float num13 = Mathf.Lerp(0.25f, 1f, Mathf.Clamp01(num7 / 2f)); array[i] = (num11 * 1.6f + num12) * num9 * num13 * 0.5f; } return Clip("drumroll", array); } private static void Note(float[] d, float start, float dur, float freq, float amp, float brightness = 1f, float bendTo = 0f) { int num = (int)(start * 44100f); int num2 = (int)(dur * 44100f); double num3 = 0.0; for (int i = 0; i < num2 && num + i < d.Length; i++) { float num4 = (float)i / 44100f; float num5 = ((bendTo > 0f) ? Mathf.Lerp(freq, bendTo, num4 / dur) : freq); num5 *= 1f + 0.006f * Mathf.Sin(MathF.PI * 11f * num4) * Mathf.Clamp01(num4 * 3f); num3 += Math.PI * 2.0 * (double)num5 / 44100.0; float num6 = Mathf.Clamp01(num4 / 0.03f); float num7 = Mathf.Clamp01((dur - num4) / 0.08f); float num8 = 0f; for (int j = 1; j <= 6; j++) { num8 += Mathf.Sin((float)(num3 * (double)j)) / (float)j * Mathf.Pow(brightness * Mathf.Clamp01(num4 * 12f + 0.3f), (float)(j - 1)); } d[num + i] += num8 * amp * num6 * num7; } } private static void Cymbal(float[] d, float start, float dur, float amp) { int num = (int)(start * 44100f); int num2 = (int)(dur * 44100f); Random random = new Random(3); float num3 = 0f; for (int i = 0; i < num2 && num + i < d.Length; i++) { float num4 = (float)i / 44100f; float num5 = (float)(random.NextDouble() * 2.0 - 1.0); float num6 = num5 - num3; num3 = num5; d[num + i] += num6 * amp * Mathf.Exp((0f - num4) * 2.2f); } } private static AudioClip Fanfare(bool big) { float num = (big ? 2.6f : 1.5f); float[] array = new float[(int)(num * 44100f)]; float num2 = (big ? 0.14f : 0.11f); Note(array, 0f, num2, 523.25f, 0.22f); Note(array, num2, num2, 659.25f, 0.22f); Note(array, num2 * 2f, num2, 783.99f, 0.22f); Note(array, num2 * 3f, num - num2 * 3f - 0.05f, 1046.5f, 0.24f); if (big) { Note(array, num2 * 3f, num - num2 * 3f - 0.05f, 659.25f, 0.14f); Note(array, num2 * 3f, num - num2 * 3f - 0.05f, 783.99f, 0.14f); Cymbal(array, num2 * 3f, 2f, 0.22f); } else { Cymbal(array, num2 * 3f, 1.1f, 0.12f); } Normalize(array, 0.8f); return Clip(big ? "mvp" : "fanfare", array); } private static AudioClip Womp() { float[] array = new float[97020]; Note(array, 0f, 0.32f, 392f, 0.25f, 0.55f); Note(array, 0.36f, 0.32f, 369.99f, 0.25f, 0.55f); Note(array, 0.72f, 0.32f, 349.23f, 0.25f, 0.55f); int num = 47628; int num2 = 44100; double num3 = 0.0; for (int i = 0; i < num2; i++) { float num4 = (float)i / 44100f; float num5 = Mathf.Lerp(329.63f, 300f, num4) * (1f + 0.035f * Mathf.Sin(MathF.PI * 12f * num4) * Mathf.Clamp01(num4 * 2f)); num3 += Math.PI * 2.0 * (double)num5 / 44100.0; float num6 = Mathf.Clamp01(num4 / 0.03f) * Mathf.Clamp01((1f - num4) / 0.25f); float num7 = 0f; for (int j = 1; j <= 6; j++) { num7 += Mathf.Sin((float)(num3 * (double)j)) / (float)j * Mathf.Pow(0.55f, (float)(j - 1)); } array[num + i] += num7 * 0.25f * num6; } Normalize(array, 0.75f); return Clip("womp", array); } private static AudioClip Tick() { float[] array = new float[1764]; for (int i = 0; i < array.Length; i++) { float num = (float)i / 44100f; array[i] = Mathf.Sin(MathF.PI * 3000f * num) * Mathf.Exp((0f - num) * 140f) * 0.6f; } return Clip("tick", array); } private static void Normalize(float[] d, float peak) { float num = 0f; foreach (float num2 in d) { num = Mathf.Max(num, Mathf.Abs(num2)); } if (!(num <= 0f)) { float num3 = peak / num; for (int j = 0; j < d.Length; j++) { d[j] *= num3; } } } } internal static class Tracker { private const int EnemyTeam = 1; private const int ObjectTeam = 2; private const float CloseCallRatio = 0.1f; internal static readonly Stack<Character> Sources = new Stack<Character>(); internal static readonly Stack<Character> MeasuredSources = new Stack<Character>(); private static readonly Dictionary<Character, Character> LastHitter = new Dictionary<Character, Character>(); internal static readonly Dictionary<Character, float> HealthBefore = new Dictionary<Character, float>(); private static readonly Dictionary<Character, Dictionary<string, float>> Landed = new Dictionary<Character, Dictionary<string, float>>(); private static readonly HashSet<string> Logged = new HashSet<string>(); private static HashSet<ActionInfo> _consumableActions; private static Character CurrentSource { get { if (Sources.Count <= 0) { return null; } return Sources.Peek(); } } private static bool Tracking { get { if (Plugin.Enabled.Value) { return Heroes.IsServer; } return false; } } internal static void ResetBattleState() { LastHitter.Clear(); Landed.Clear(); } internal static void OnBattleStat(Character c, BattleStat stat, float amount) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected I4, but got Unknown if (c == null || amount <= 0f || !Tracking) { return; } bool flag = Heroes.IsHero(c); switch ((int)stat) { case 0: if (flag) { RunStats.Add(c, Stat.Damage, amount); RunStats.Max(c, Stat.BiggestHit, amount); } break; case 1: if (flag) { RunStats.Add(c, Stat.SummonDamage, amount); RunStats.Add(c, Stat.Damage, amount); } break; case 2: if (flag) { RunStats.Add(c, Stat.Thorns, amount); RunStats.Add(c, Stat.Damage, amount); } break; case 3: { Character val = Heroes.Credit(CurrentSource); float value; float num = (HealthBefore.TryGetValue(c, out value) ? value : (c.Health + amount)); HealthBefore[c] = Math.Max(0f, num - amount); if (flag) { RunStats.Add(c, Stat.DamageTaken, amount); if (val != null && val != c) { RunStats.Add(val, Stat.FriendlyFire, amount); } float num2 = num - amount; if (num2 > 0f && num2 <= c.MaxHealth * 0.1f) { RunStats.Add(c, Stat.CloseCalls, 1f); } } else { if (c.TeamIndex == 0 || val == null) { break; } LastHitter[c] = val; if (c.TeamIndex == 1 && num > 0f) { if (amount > num) { RunStats.Add(val, Stat.Overkill, amount - num); } if (!Landed.TryGetValue(c, out var value2)) { value2 = (Landed[c] = new Dictionary<string, float>()); } string key = Heroes.Key(val); value2.TryGetValue(key, out var value3); value2[key] = value3 + Math.Min(amount, num); } } break; } case 11: if (flag) { RunStats.Add(c, Stat.HealingReceived, amount); } break; case 5: case 6: case 7: case 8: case 9: if (flag) { RunStats.Add(c, Stat.Blocked, amount); } break; case 10: if (flag) { RunStats.Add(c, Stat.Healing, amount); } break; case 4: break; } } internal static void OnDeath(Character victim) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Invalid comparison between Unknown and I4 //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 //IL_017b: Unknown result type (might be due to invalid IL or missing references) if (!Tracking) { return; } if (Heroes.IsHero(victim)) { RunStats.Add(victim, Stat.Deaths, 1f); if (Plugin.LogStats.Value) { Plugin.ModLog.LogInfo((object)("Knocked out: " + Heroes.SafeName(victim))); } } else { if (victim.TeamIndex == 0) { return; } Character value = Heroes.Credit(Current