Decompiled source of RunAwards v0.2.1

RunAwards.dll

Decompiled 2 weeks ago
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