Decompiled source of CrewAwards v0.1.0

CrewAwards.dll

Decompiled an hour ago
using System;
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 System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("CrewAwardsTest")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CrewAwards")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+7c0998b00ce2f81b3e981b4cd57c6ba97da4d910")]
[assembly: AssemblyProduct("CrewAwards")]
[assembly: AssemblyTitle("CrewAwards")]
[assembly: AssemblyVersion("0.1.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 CrewAwards
{
	internal enum Kind
	{
		Main,
		Praise,
		Neutral,
		Joke
	}
	internal sealed class AwardDef
	{
		internal string Id;

		internal string Title;

		internal string Icon;

		internal Kind Kind;

		internal Stat Stat;

		internal double Min;

		internal bool Lowest;

		internal bool FullDaysOnly;

		internal Func<double, string> Line;
	}
	internal sealed class AwardPick
	{
		internal string Id;

		internal List<string> Names = new List<string>();

		internal double Value;

		internal double Standout;

		internal AwardDef Def => Awards.ById(Id);

		internal string NameText => string.Join(" & ", Names);
	}
	internal sealed class AwardsResult
	{
		internal const int Version = 1;

		internal int QuotaIndex;

		internal int Days;

		internal int Crew;

		internal int Quota;

		internal int Collected;

		internal string Closed = "";

		internal bool Solo;

		internal bool Final;

		internal int QuotasMet;

		internal readonly List<AwardPick> Picks = new List<AwardPick>();

		internal const char NameSep = '\u001f';

		internal string Serialize()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("CR").Append(1).Append('|')
				.Append(QuotaIndex)
				.Append('|')
				.Append(Clean(Closed))
				.Append('|')
				.Append(Days)
				.Append('|')
				.Append(Crew)
				.Append('|')
				.Append(Solo ? 1 : 0)
				.Append('|')
				.Append(Quota)
				.Append('|')
				.Append(Collected)
				.Append('|')
				.Append(Final ? 1 : 0)
				.Append('|')
				.Append(QuotasMet)
				.Append('\n');
			foreach (AwardPick pick in Picks)
			{
				stringBuilder.Append(pick.Id).Append('\t').Append(string.Join('\u001f'.ToString(), pick.Names.Select(Clean)))
					.Append('\t')
					.Append(pick.Value.ToString("R", CultureInfo.InvariantCulture))
					.Append('\n');
			}
			return stringBuilder.ToString();
		}

		private static string Clean(string s)
		{
			return (s ?? "").Replace('\t', ' ').Replace('\n', ' ').Replace('|', '/')
				.Replace('\u001f', ' ');
		}

		internal static AwardsResult Parse(string text)
		{
			try
			{
				if (string.IsNullOrEmpty(text))
				{
					return null;
				}
				string[] array = text.Split('\n');
				string[] array2 = array[0].Split('|');
				if (array2.Length < 8 || array2[0] != "CR" + 1)
				{
					return null;
				}
				AwardsResult awardsResult = new AwardsResult
				{
					QuotaIndex = int.Parse(array2[1], CultureInfo.InvariantCulture),
					Closed = array2[2],
					Days = int.Parse(array2[3], CultureInfo.InvariantCulture),
					Crew = int.Parse(array2[4], CultureInfo.InvariantCulture),
					Solo = (array2[5] == "1"),
					Quota = int.Parse(array2[6], CultureInfo.InvariantCulture),
					Collected = int.Parse(array2[7], CultureInfo.InvariantCulture)
				};
				if (array2.Length >= 10)
				{
					awardsResult.Final = array2[8] == "1";
					awardsResult.QuotasMet = int.Parse(array2[9], CultureInfo.InvariantCulture);
				}
				for (int i = 1; i < array.Length; i++)
				{
					string[] array3 = array[i].Split('\t');
					if (array3.Length >= 3 && Awards.ById(array3[0]) != null)
					{
						awardsResult.Picks.Add(new AwardPick
						{
							Id = array3[0],
							Names = array3[1].Split('\u001f').ToList(),
							Value = double.Parse(array3[2], NumberStyles.Float, CultureInfo.InvariantCulture)
						});
					}
				}
				return awardsResult;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("CrewAwards: could not read an awards result: " + ex.Message));
				return null;
			}
		}

		internal string HistoryLine()
		{
			AwardPick awardPick = Picks.FirstOrDefault();
			string text = ((awardPick == null) ? "no awards" : (Solo ? ("solo, " + awardPick.Def.Title + ": " + awardPick.Def.Line(awardPick.Value)) : (awardPick.Def.Title + ": " + awardPick.NameText + " (" + awardPick.Def.Line(awardPick.Value) + ")")));
			return string.Format("QUOTA {0} {1}, {2} {3}, {4} crew. {5}", QuotaIndex + 1, Closed.ToUpperInvariant(), Days, (Days == 1) ? "day" : "days", Crew, text);
		}

		internal string TerminalText()
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (Final)
			{
				stringBuilder.Append("FINAL AWARDS: FIRED AFTER ").Append(QuotasMet).Append((QuotasMet == 1) ? " QUOTA MET\n" : " QUOTAS MET\n");
				stringBuilder.Append(Days).Append((Days == 1) ? " day, " : " days, ").Append(Crew)
					.Append((Crew == 1) ? " crew\n\n" : " crew\n\n");
				if (Picks.Count == 0)
				{
					stringBuilder.Append("Nobody stood out this run.\n");
				}
				foreach (AwardPick pick in Picks)
				{
					stringBuilder.Append("* ").Append(pick.Def.Title.ToUpperInvariant());
					if (!Solo)
					{
						stringBuilder.Append(": ").Append(pick.NameText);
					}
					stringBuilder.Append("\n  ").Append(pick.Def.Line(pick.Value)).Append('\n');
				}
				return stringBuilder.ToString();
			}
			stringBuilder.Append(Solo ? "QUOTA REPORT" : "CREW AWARDS").Append(": QUOTA ").Append(QuotaIndex + 1)
				.Append(' ')
				.Append(Closed.ToUpperInvariant())
				.Append('\n');
			stringBuilder.Append(Awards.Money(Collected)).Append(" / ").Append(Awards.Money(Quota))
				.Append(", ")
				.Append(Days)
				.Append((Days == 1) ? " day, " : " days, ")
				.Append(Crew)
				.Append((Crew == 1) ? " crew\n\n" : " crew\n\n");
			if (Picks.Count == 0)
			{
				stringBuilder.Append("Nobody stood out this quota.\n");
			}
			foreach (AwardPick pick2 in Picks)
			{
				stringBuilder.Append("* ").Append(pick2.Def.Title.ToUpperInvariant());
				if (!Solo)
				{
					stringBuilder.Append(": ").Append(pick2.NameText);
				}
				stringBuilder.Append("\n  ").Append(pick2.Def.Line(pick2.Value)).Append('\n');
			}
			return stringBuilder.ToString();
		}
	}
	internal static class Awards
	{
		internal const int MaxCards = 6;

		internal const int MaxPerPlayer = 2;

		internal const int MaxJokes = 2;

		internal const int SoloCount = 3;

		internal static readonly AwardDef[] All = new AwardDef[14]
		{
			new AwardDef
			{
				Id = "employee",
				Title = "Employee of the Quota",
				Icon = "star",
				Kind = Kind.Main,
				Stat = Stat.ScrapAboard,
				Min = 1.0,
				Line = (double v) => Money(v) + " of scrap brought aboard"
			},
			new AwardDef
			{
				Id = "hardhat",
				Title = "Hard Hat",
				Icon = "helmet",
				Kind = Kind.Praise,
				Stat = Stat.DamageSurvived,
				Min = 40.0,
				Line = (double v) => "Took " + N(v) + " damage and lived"
			},
			new AwardDef
			{
				Id = "exterminator",
				Title = "Exterminator",
				Icon = "crosshair",
				Kind = Kind.Praise,
				Stat = Stat.Kills,
				Min = 1.0,
				Line = (double v) => Times(v, "Killed a monster", "Killed {0} monsters")
			},
			new AwardDef
			{
				Id = "bodybag",
				Title = "Body Bag",
				Icon = "cross",
				Kind = Kind.Praise,
				Stat = Stat.Bodies,
				Min = 1.0,
				Line = (double v) => Times(v, "Carried a crewmate home", "Carried {0} crewmates home")
			},
			new AwardDef
			{
				Id = "lastout",
				Title = "Last One Out",
				Icon = "door",
				Kind = Kind.Praise,
				Stat = Stat.LastAboard,
				Min = 1.0,
				Line = (double v) => Times(v, "Last aboard before takeoff", "Last aboard before takeoff {0} times")
			},
			new AwardDef
			{
				Id = "closeshave",
				Title = "Close Shave",
				Icon = "heart",
				Kind = Kind.Praise,
				Stat = Stat.CloseShaves,
				Min = 1.0,
				Line = (double v) => Times(v, "Dropped below 20 HP and lived", "Dropped below 20 HP and lived, {0} times")
			},
			new AwardDef
			{
				Id = "marathon",
				Title = "Marathon",
				Icon = "boot",
				Kind = Kind.Neutral,
				Stat = Stat.Distance,
				Min = 300.0,
				Line = (double v) => (!(v >= 1000.0)) ? ("Walked " + N(v) + " m") : ("Walked " + (v / 1000.0).ToString("0.0", CultureInfo.InvariantCulture) + " km")
			},
			new AwardDef
			{
				Id = "bigspender",
				Title = "Big Spender",
				Icon = "coin",
				Kind = Kind.Neutral,
				Stat = Stat.Spent,
				Min = 60.0,
				Line = (double v) => "Spent " + Money(v) + " at the terminal"
			},
			new AwardDef
			{
				Id = "paranoid",
				Title = "Paranoid",
				Icon = "eye",
				Kind = Kind.Neutral,
				Stat = Stat.Turns,
				Min = 20.0,
				Line = (double v) => "Looked over their shoulder " + N(v) + " times"
			},
			new AwardDef
			{
				Id = "lightsout",
				Title = "Lights Out",
				Icon = "bulb",
				Kind = Kind.Neutral,
				Stat = Stat.DarkTime,
				Min = 60.0,
				Line = (double v) => Minutes(v) + " inside with no light"
			},
			new AwardDef
			{
				Id = "shipscat",
				Title = "Ship's Cat",
				Icon = "cat",
				Kind = Kind.Joke,
				Stat = Stat.ShipTime,
				Min = 120.0,
				Line = (double v) => Minutes(v) + " on the ship while landed"
			},
			new AwardDef
			{
				Id = "frequentflier",
				Title = "Frequent Flier",
				Icon = "skull",
				Kind = Kind.Joke,
				Stat = Stat.Deaths,
				Min = 1.0,
				Line = (double v) => Times(v, "Died once", "Died {0} times")
			},
			new AwardDef
			{
				Id = "butterfingers",
				Title = "Butterfingers",
				Icon = "box",
				Kind = Kind.Joke,
				Stat = Stat.ScrapLeft,
				Min = 30.0,
				Line = (double v) => Money(v) + " of scrap left behind on moons"
			},
			new AwardDef
			{
				Id = "tourist",
				Title = "Tourist",
				Icon = "camera",
				Kind = Kind.Joke,
				Stat = Stat.ScrapAboard,
				Min = 50.0,
				Lowest = true,
				FullDaysOnly = true,
				Line = (double v) => "Only " + Money(v) + " of scrap brought aboard"
			}
		};

		private static string N(double v)
		{
			return Math.Round(v).ToString("N0", CultureInfo.InvariantCulture);
		}

		internal static string Money(double v)
		{
			return "$" + N(v);
		}

		private static string Times(double v, string one, string many)
		{
			if (Math.Round(v) != 1.0)
			{
				return string.Format(many, N(v));
			}
			return one;
		}

		private static string Minutes(double s)
		{
			if (!(s < 90.0))
			{
				return (s / 60.0).ToString("0", CultureInfo.InvariantCulture) + " minutes";
			}
			return N(s) + " seconds";
		}

		internal static AwardDef ById(string id)
		{
			return All.FirstOrDefault((AwardDef a) => a.Id == id);
		}

		internal static AwardsResult Pick(QuotaTally t, int quota, int collected)
		{
			AwardsResult r = new AwardsResult
			{
				QuotaIndex = t.QuotaIndex,
				Closed = t.Closed,
				Days = t.Days,
				Quota = quota,
				Collected = collected
			};
			List<Entry> list = t.Entries.Values.Where((Entry e) => e[Stat.DaysPresent] > 0.0).ToList();
			if (list.Count == 0)
			{
				list = t.Entries.Values.ToList();
			}
			r.Crew = list.Count;
			if (list.Count == 0)
			{
				return r;
			}
			if (list.Count == 1)
			{
				r.Solo = true;
				Entry me = list[0];
				foreach (var item in (from awardDef in All
					where !awardDef.Lowest
					select (a: awardDef, v: me[awardDef.Stat]) into x
					where x.v >= x.a.Min
					orderby x.v / Math.Max(1E-06, x.a.Min) descending
					select x).Take(3))
				{
					r.Picks.Add(new AwardPick
					{
						Id = item.a.Id,
						Names = { me.Name },
						Value = item.v,
						Standout = item.v / item.a.Min
					});
				}
				return r;
			}
			List<AwardPick> list2 = new List<AwardPick>();
			AwardDef[] all = All;
			foreach (AwardDef a in all)
			{
				List<Entry> list3 = (a.FullDaysOnly ? list.Where((Entry e) => e[Stat.DaysPresent] >= (double)t.Days).ToList() : list);
				if (list3.Count < 2)
				{
					continue;
				}
				List<(Entry, double)> list4 = list3.Select((Entry e) => (e: e, v: e[a.Stat])).ToList();
				double best = (a.Lowest ? list4.Min<(Entry, double)>(((Entry e, double v) x) => x.v) : list4.Max<(Entry, double)>(((Entry e, double v) x) => x.v));
				List<(Entry, double)> list5 = list4.Where<(Entry, double)>(((Entry e, double v) x) => Math.Abs(x.v - best) < 1E-06).ToList();
				if (list5.Count == list4.Count)
				{
					continue;
				}
				List<double> source = (from x in list4
					where Math.Abs(x.v - best) >= 1E-06
					select x.v).ToList();
				double num2 = (a.Lowest ? source.Min() : source.Max());
				double num3 = (a.Lowest ? (num2 - best) : (best - num2));
				if (!(a.Lowest ? (num3 < a.Min) : (best < a.Min)))
				{
					double val = list4.Average<(Entry, double)>(((Entry e, double v) x) => x.v);
					list2.Add(new AwardPick
					{
						Id = a.Id,
						Value = best,
						Standout = num3 / Math.Max(1.0, val),
						Names = list5.Select<(Entry, double), string>(((Entry e, double v) x) => x.e.Name).OrderBy<string, string>((string n) => n, StringComparer.Ordinal).ToList()
					});
				}
			}
			Dictionary<string, int> count = new Dictionary<string, int>();
			int jokes = 0;
			AwardPick awardPick = list2.FirstOrDefault((AwardPick p) => p.Id == "employee");
			if (awardPick != null)
			{
				Take(awardPick);
			}
			foreach (AwardPick item2 in from p in list2
				where p.Id != "employee"
				orderby p.Standout descending, Array.IndexOf(All, p.Def)
				select p)
			{
				if (r.Picks.Count >= 6)
				{
					break;
				}
				if ((item2.Def.Kind != Kind.Joke || jokes < 2) && !item2.Names.Any((string n) => count.TryGetValue(n, out var value) && value >= 2))
				{
					Take(item2);
				}
			}
			return r;
			void Take(AwardPick p)
			{
				r.Picks.Add(p);
				foreach (string name in p.Names)
				{
					count[name] = ((!count.TryGetValue(name, out var value)) ? 1 : (value + 1));
				}
				if (p.Def.Kind == Kind.Joke)
				{
					jokes++;
				}
			}
		}
	}
	internal static class Host
	{
		internal const string SaveKeyLive = "CrewAwards.Tally";

		internal const string SaveKeyLast = "CrewAwards.LastQuota";

		internal const string SaveKeyResult = "CrewAwards.LastAwards";

		internal const string SaveKeyHistory = "CrewAwards.History";

		internal const string SaveKeyRun = "CrewAwards.Run";

		internal const int HistoryMax = 40;

		internal const float TallyWait = 10f;

		internal const float KillCredit = 10f;

		internal const float CloseShaveConfirm = 5f;

		internal static QuotaTally Live = new QuotaTally();

		internal static QuotaTally Last;

		internal static QuotaTally Run = new QuotaTally();

		private static float _firedAt = -1000f;

		internal static string LastResult = "";

		internal static string History = "";

		internal static bool Loaded;

		private static readonly HashSet<ulong> Waiting = new HashSet<ulong>();

		private static float _waitUntil = -1f;

		private static string _closeReason;

		private static int _closeNextIndex;

		private static int _closeQuota;

		private static int _closeCollected;

		internal static readonly HashSet<ulong> Modded = new HashSet<ulong>();

		private static readonly Dictionary<GrabbableObject, int> Holder = new Dictionary<GrabbableObject, int>();

		private static readonly Dictionary<EnemyAI, (int player, float t)> LastHit = new Dictionary<EnemyAI, (int, float)>();

		private static readonly HashSet<EnemyAI> DeadSeen = new HashSet<EnemyAI>();

		private static bool[] _prevDead = new bool[0];

		private static bool[] _prevIn = new bool[0];

		private static float[] _boardTime = new float[0];

		private static bool _wasLanded;

		private static bool _leftDone;

		private static float _landTime;

		private static float _nextHolderScan;

		internal static bool IsHost => Net.IsHost;

		private static string SaveFile
		{
			get
			{
				if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
				{
					return null;
				}
				return GameNetworkManager.Instance.currentSaveFileName;
			}
		}

		private static bool CanSave
		{
			get
			{
				if (SaveFile != null)
				{
					return SaveFile != "LCChallengeFile";
				}
				return false;
			}
		}

		private static PlayerControllerB[] Players
		{
			get
			{
				if (!((Object)(object)StartOfRound.Instance != (Object)null))
				{
					return null;
				}
				return StartOfRound.Instance.allPlayerScripts;
			}
		}

		internal static void Log(string s)
		{
			Plugin.Log.LogInfo((object)("CrewAwards: " + s));
		}

		internal static void OnSessionStart()
		{
			Waiting.Clear();
			_waitUntil = -1f;
			_closeReason = null;
			Modded.Clear();
			ResetDay();
			Live = new QuotaTally();
			Last = null;
			Run = new QuotaTally();
			Loaded = false;
			LastResult = "";
			History = "";
			_firedAt = -1000f;
			if (IsHost)
			{
				int num = (((Object)(object)TimeOfDay.Instance != (Object)null) ? TimeOfDay.Instance.timesFulfilledQuota : 0);
				Live = LoadTally("CrewAwards.Tally");
				if (Live == null)
				{
					Live = new QuotaTally
					{
						QuotaIndex = num
					};
					Log($"no saved tally; quota #{num + 1} starts empty");
				}
				else if (Live.QuotaIndex != num)
				{
					Log($"saved tally is for quota #{Live.QuotaIndex + 1} but the save is on quota #{num + 1}; starting empty");
					Live = new QuotaTally
					{
						QuotaIndex = num
					};
				}
				else
				{
					Log($"loaded the saved tally: quota #{num + 1}, {Live.Days} days, {Live.Entries.Count} players");
				}
				Last = LoadTally("CrewAwards.LastQuota");
				LastResult = LoadString("CrewAwards.LastAwards");
				History = LoadString("CrewAwards.History");
				Run = LoadTally("CrewAwards.Run") ?? new QuotaTally();
				if (num == 0 && Run.QuotaIndex > 0)
				{
					Log("the save is back on quota #1; the run tally starts empty");
					Run = new QuotaTally();
				}
				Loaded = true;
				Plaque.Show(AwardsResult.Parse(LastResult));
				if (Plugin.LogTally.Value)
				{
					Log("tally on load\n" + Live.DebugText("QUOTA TALLY"));
				}
			}
		}

		private static QuotaTally LoadTally(string key)
		{
			try
			{
				if (!CanSave || !ES3.KeyExists(key, SaveFile))
				{
					return null;
				}
				return QuotaTally.Parse(ES3.Load<string>(key, SaveFile));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("CrewAwards: could not read " + key + ": " + ex.Message));
				return null;
			}
		}

		private static string LoadString(string key)
		{
			try
			{
				return (CanSave && ES3.KeyExists(key, SaveFile)) ? (ES3.Load<string>(key, SaveFile) ?? "") : "";
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("CrewAwards: could not read " + key + ": " + ex.Message));
				return "";
			}
		}

		internal static void Save()
		{
			if (!IsHost || !Loaded || !CanSave)
			{
				return;
			}
			try
			{
				ES3.Save<string>("CrewAwards.Tally", Live.Serialize(), SaveFile);
				if (Last != null)
				{
					ES3.Save<string>("CrewAwards.LastQuota", Last.Serialize(), SaveFile);
				}
				ES3.Save<string>("CrewAwards.LastAwards", LastResult ?? "", SaveFile);
				ES3.Save<string>("CrewAwards.History", History ?? "", SaveFile);
				ES3.Save<string>("CrewAwards.Run", Run.Serialize(), SaveFile);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("CrewAwards: save failed: " + ex.Message));
			}
		}

		internal static void ResetForTest()
		{
			int quotaIndex = (((Object)(object)TimeOfDay.Instance != (Object)null) ? TimeOfDay.Instance.timesFulfilledQuota : 0);
			Live = new QuotaTally
			{
				QuotaIndex = quotaIndex
			};
			Last = null;
			LastResult = "";
			History = "";
			Run = new QuotaTally();
			if (CanSave)
			{
				try
				{
					string[] array = new string[5] { "CrewAwards.Tally", "CrewAwards.LastQuota", "CrewAwards.LastAwards", "CrewAwards.History", "CrewAwards.Run" };
					for (int i = 0; i < array.Length; i++)
					{
						ES3.DeleteKey(array[i], SaveFile);
					}
				}
				catch
				{
				}
			}
			Save();
			Net.BroadcastTally();
		}

		private static void ResetDay()
		{
			Holder.Clear();
			LastHit.Clear();
			DeadSeen.Clear();
			_leftDone = false;
		}

		internal static PlayerControllerB PlayerOf(ulong clientId)
		{
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			if (instance.ClientPlayerList != null && instance.ClientPlayerList.TryGetValue(clientId, out var value) && value >= 0 && value < instance.allPlayerScripts.Length)
			{
				return instance.allPlayerScripts[value];
			}
			return null;
		}

		internal static void Tick()
		{
			if (!IsHost || !Loaded)
			{
				return;
			}
			StartOfRound instance = StartOfRound.Instance;
			PlayerControllerB[] players = Players;
			if ((Object)(object)instance == (Object)null || players == null)
			{
				return;
			}
			if (_prevDead.Length != players.Length)
			{
				_prevDead = new bool[players.Length];
				_prevIn = new bool[players.Length];
				_boardTime = new float[players.Length];
			}
			float time = Time.time;
			bool shipHasLanded = instance.shipHasLanded;
			if (shipHasLanded && !_wasLanded)
			{
				ResetDay();
				_landTime = time;
				for (int i = 0; i < players.Length; i++)
				{
					_boardTime[i] = -1f;
					_prevIn[i] = (Object)(object)players[i] != (Object)null && players[i].isInHangarShipRoom;
				}
			}
			_wasLanded = shipHasLanded;
			for (int j = 0; j < players.Length; j++)
			{
				PlayerControllerB val = players[j];
				if (!((Object)(object)val == (Object)null))
				{
					bool isPlayerDead = val.isPlayerDead;
					if (isPlayerDead && !_prevDead[j] && !instance.inShipPhase)
					{
						Live.Add(val, Stat.Deaths, 1.0);
						Log("death: " + val.playerUsername);
					}
					_prevDead[j] = isPlayerDead;
					bool flag = val.isInHangarShipRoom && !isPlayerDead;
					if (!instance.inShipPhase && flag && !_prevIn[j] && val.isPlayerControlled)
					{
						_boardTime[j] = time;
					}
					_prevIn[j] = flag;
				}
			}
			if (time >= _nextHolderScan && !instance.inShipPhase)
			{
				_nextHolderScan = time + 0.2f;
				for (int k = 0; k < players.Length; k++)
				{
					PlayerControllerB val2 = players[k];
					if ((Object)(object)val2 == (Object)null || !val2.isPlayerControlled)
					{
						continue;
					}
					if (val2.ItemSlots != null)
					{
						GrabbableObject[] itemSlots = val2.ItemSlots;
						foreach (GrabbableObject val3 in itemSlots)
						{
							if ((Object)(object)val3 != (Object)null)
							{
								Holder[val3] = k;
							}
						}
					}
					if ((Object)(object)val2.currentlyHeldObjectServer != (Object)null)
					{
						Holder[val2.currentlyHeldObjectServer] = k;
					}
				}
				RoundManager instance2 = RoundManager.Instance;
				if ((Object)(object)instance2 != (Object)null && instance2.SpawnedEnemies != null)
				{
					foreach (EnemyAI spawnedEnemy in instance2.SpawnedEnemies)
					{
						if (!((Object)(object)spawnedEnemy == (Object)null) && spawnedEnemy.isEnemyDead && !DeadSeen.Contains(spawnedEnemy))
						{
							DeadSeen.Add(spawnedEnemy);
							if (LastHit.TryGetValue(spawnedEnemy, out (int, float) value) && time - value.Item2 <= 10f && value.Item1 >= 0 && value.Item1 < players.Length)
							{
								Live.Add(players[value.Item1], Stat.Kills, 1.0);
								Log("kill: " + spawnedEnemy.enemyType?.enemyName + " by " + players[value.Item1].playerUsername);
							}
							else
							{
								Log($"enemy died with no player hit in the last {10f:F0} s: {spawnedEnemy.enemyType?.enemyName}");
							}
						}
					}
				}
			}
			if (_waitUntil > 0f && (Waiting.Count == 0 || Time.realtimeSinceStartup >= _waitUntil))
			{
				if (Waiting.Count > 0)
				{
					Log($"no day tally from {Waiting.Count} client(s) after {10f:F0} s; their own counters for the day are lost");
				}
				Waiting.Clear();
				_waitUntil = -1f;
				DayDone();
			}
			if (_closeReason != null && _waitUntil < 0f)
			{
				DoClose();
			}
		}

		internal static void OnHit(EnemyAI e, int playerWhoHit)
		{
			if (IsHost && !((Object)(object)e == (Object)null) && playerWhoHit >= 0)
			{
				LastHit[e] = (playerWhoHit, Time.time);
			}
		}

		internal static void OnElevator(PlayerControllerB p, GrabbableObject g, bool wasIn, bool persisted)
		{
			if (!(!IsHost || !Loaded || (Object)(object)g == (Object)null || (Object)(object)p == (Object)null || persisted) && wasIn != g.isInShipRoom)
			{
				int scrapValue = g.scrapValue;
				Live.Add(p, Stat.ScrapAboard, g.isInShipRoom ? scrapValue : (-scrapValue));
				Log(string.Format("scrap {0}: {1} ${2} by {3}", g.isInShipRoom ? "aboard" : "taken out", g.itemProperties?.itemName, scrapValue, p.playerUsername));
			}
		}

		internal static void OnShipLeft()
		{
			if (!IsHost || !Loaded || _leftDone)
			{
				return;
			}
			_leftDone = true;
			StartOfRound instance = StartOfRound.Instance;
			PlayerControllerB[] players = Players;
			if ((Object)(object)instance == (Object)null || players == null)
			{
				return;
			}
			int num = -1;
			float num2 = -1f;
			int num3 = 0;
			for (int i = 0; i < players.Length; i++)
			{
				PlayerControllerB val = players[i];
				if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead && val.isInHangarShipRoom)
				{
					num3++;
					if (_boardTime[i] > num2)
					{
						num2 = _boardTime[i];
						num = i;
					}
				}
			}
			if (num3 >= 2 && num >= 0 && num2 > _landTime)
			{
				Live.Add(players[num], Stat.LastAboard, 1.0);
				Log($"last aboard: {players[num].playerUsername} ({num3} aboard)");
			}
			DepositItemsDesk val2 = Object.FindObjectOfType<DepositItemsDesk>();
			GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
			foreach (GrabbableObject val3 in array)
			{
				if ((Object)(object)val3 == (Object)null || !Holder.TryGetValue(val3, out var value) || value < 0 || value >= players.Length)
				{
					continue;
				}
				RagdollGrabbableObject val4 = (RagdollGrabbableObject)(object)((val3 is RagdollGrabbableObject) ? val3 : null);
				if (val4 != null)
				{
					DeadBodyInfo ragdoll = val4.ragdoll;
					if ((val3.isInShipRoom || ((Object)(object)ragdoll != (Object)null && ragdoll.isInShip)) && (Object)(object)ragdoll != (Object)null && (Object)(object)ragdoll.playerScript != (Object)(object)players[value])
					{
						Live.Add(players[value], Stat.Bodies, 1.0);
						Log("body home: " + ragdoll.playerScript?.playerUsername + " carried by " + players[value].playerUsername);
					}
				}
				else if (!((Object)(object)val3.itemProperties == (Object)null) && val3.itemProperties.isScrap && val3.scrapValue > 0 && !val3.deactivated && !val3.isInShipRoom && !val3.isInElevator && (!val3.isHeld || !((Object)(object)val3.playerHeldBy != (Object)null) || !val3.playerHeldBy.isInHangarShipRoom) && (!((Object)(object)val2 != (Object)null) || !((Object)(object)((Component)val3).transform.parent == (Object)(object)((Component)val2.deskObjectsContainer).transform)))
				{
					Live.Add(players[value], Stat.ScrapLeft, val3.scrapValue);
					Log($"left behind: {val3.itemProperties.itemName} ${val3.scrapValue}, last held by {players[value].playerUsername}");
				}
			}
		}

		internal static void OnDayEnd()
		{
			if (!IsHost || !Loaded)
			{
				return;
			}
			StartOfRound instance = StartOfRound.Instance;
			PlayerControllerB[] players = Players;
			Live.Days++;
			for (int i = 0; i < players.Length; i++)
			{
				PlayerControllerB val = players[i];
				if (!((Object)(object)val == (Object)null) && (val.isPlayerControlled || val.isPlayerDead))
				{
					Live.Add(val, Stat.DaysPresent, 1.0);
					Live.Add(val, Stat.Turns, instance.gameStats.allPlayerStats[i].turnAmount);
				}
			}
			Waiting.Clear();
			foreach (ulong connectedClientsId in Net.NM.ConnectedClientsIds)
			{
				if (connectedClientsId != 0L && Modded.Contains(connectedClientsId))
				{
					Waiting.Add(connectedClientsId);
				}
			}
			_waitUntil = Time.realtimeSinceStartup + 10f;
			Log($"day {Live.Days} over; waiting for {Waiting.Count} client tally(s)");
		}

		internal static void OnDayTally(ulong sender, PlayerControllerB p, double[] v)
		{
			if (IsHost && Loaded && !((Object)(object)p == (Object)null))
			{
				Entry entry = Live.Get(p);
				for (int i = 0; i < Stats.Own.Length && i < v.Length; i++)
				{
					entry[Stats.Own[i]] += v[i];
				}
				Waiting.Remove(sender);
				Log("day tally from " + p.playerUsername + ": " + string.Join(" ", Stats.Own.Select((Stat s, int num) => Stats.Label(s) + "=" + Stats.F((num < v.Length) ? v[num] : 0.0))));
			}
		}

		private static void DayDone()
		{
			Save();
			Net.BroadcastTally();
			if (Plugin.LogTally.Value)
			{
				Log("tally after the day\n" + Live.DebugText("QUOTA TALLY"));
			}
		}

		internal static void RequestClose(string reason, int nextIndex, int quota, int collected)
		{
			if (!IsHost || !Loaded)
			{
				return;
			}
			if (reason == "fired")
			{
				if (Time.realtimeSinceStartup - _firedAt < 120f)
				{
					return;
				}
				_firedAt = Time.realtimeSinceStartup;
			}
			_closeReason = reason;
			_closeNextIndex = nextIndex;
			_closeQuota = quota;
			_closeCollected = collected;
			if (_waitUntil < 0f)
			{
				DoClose();
			}
			else
			{
				Log("quota " + reason + ": closing once the day's tallies are in");
			}
		}

		private static void DoClose()
		{
			Live.Closed = _closeReason;
			Last = Live;
			Live = new QuotaTally
			{
				QuotaIndex = _closeNextIndex
			};
			Log($"quota closed ({_closeReason}); the next tally is quota #{_closeNextIndex + 1}");
			if (Plugin.LogTally.Value)
			{
				Log("closed quota\n" + Last.DebugText("LAST QUOTA"));
			}
			bool num = _closeReason == "met";
			_closeReason = null;
			AwardsResult awardsResult = Awards.Pick(Last, _closeQuota, _closeCollected);
			AwardsResult awardsResult2 = awardsResult;
			if (num)
			{
				Run.AddAll(Last);
				Run.QuotaIndex++;
			}
			else
			{
				QuotaTally quotaTally = new QuotaTally
				{
					QuotaIndex = Last.QuotaIndex,
					Closed = "fired"
				};
				quotaTally.AddAll(Run);
				quotaTally.AddAll(Last);
				awardsResult2 = Awards.Pick(quotaTally, _closeQuota, _closeCollected);
				awardsResult2.Final = true;
				awardsResult2.QuotasMet = Run.QuotaIndex;
				Log($"final awards for the run: {Run.QuotaIndex} quota(s) met, {quotaTally.Days} days");
				Run = new QuotaTally();
			}
			LastResult = awardsResult2.Serialize();
			List<string> list = (History ?? "").Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();
			if (list.Count > 0 && list[list.Count - 1].Contains(" FIRED,"))
			{
				list.Clear();
			}
			list.Add(awardsResult.HistoryLine());
			if (list.Count > 40)
			{
				list.RemoveRange(0, list.Count - 40);
			}
			History = string.Join("\n", list);
			Log("awards picked:\n" + awardsResult2.TerminalText());
			Save();
			Net.BroadcastTally();
			Net.BroadcastAwards(live: true);
			Reel.Queue(awardsResult2);
		}
	}
	internal static class Hud
	{
		private static GameObject _go;

		private static RawImage _img;

		private static RectTransform _frame;

		private static GameObject _backdrop;

		internal static bool Showing
		{
			get
			{
				if ((Object)(object)_go != (Object)null)
				{
					return _go.activeSelf;
				}
				return false;
			}
		}

		internal static bool Centred { get; private set; }

		internal static void Show(Texture tex, bool centred)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)tex == (Object)null))
			{
				if ((Object)(object)_go == (Object)null)
				{
					Build();
				}
				Centred = centred;
				float num = ((tex.height > 0) ? ((float)tex.width / (float)tex.height) : 1.7777778f);
				float num2 = (centred ? 1100f : 560f);
				float num3 = num2 / num;
				_backdrop.SetActive(centred);
				Vector2 val = default(Vector2);
				if (centred)
				{
					RectTransform frame = _frame;
					RectTransform frame2 = _frame;
					((Vector2)(ref val))..ctor(0.5f, 0.5f);
					frame2.anchorMax = val;
					frame.anchorMin = val;
					_frame.pivot = new Vector2(0.5f, 0.5f);
					_frame.anchoredPosition = Vector2.zero;
				}
				else
				{
					RectTransform frame3 = _frame;
					RectTransform frame4 = _frame;
					((Vector2)(ref val))..ctor(1f, 1f);
					frame4.anchorMax = val;
					frame3.anchorMin = val;
					_frame.pivot = new Vector2(1f, 1f);
					_frame.anchoredPosition = new Vector2(-40f, -40f);
				}
				_frame.sizeDelta = new Vector2(num2 + 8f, num3 + 8f);
				_img.texture = tex;
				_go.SetActive(true);
			}
		}

		internal static void Hide()
		{
			if ((Object)(object)_go != (Object)null)
			{
				_go.SetActive(false);
			}
		}

		private static void Build()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0050: 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_0093: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_0138: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: 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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			_go = new GameObject("CrewAwards.Hud");
			Object.DontDestroyOnLoad((Object)(object)_go);
			Canvas obj = _go.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 400;
			CanvasScaler obj2 = _go.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 0.5f;
			_backdrop = new GameObject("Backdrop", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			_backdrop.transform.SetParent(_go.transform, false);
			RectTransform val = (RectTransform)_backdrop.transform;
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			Vector2 offsetMin = (val.offsetMax = Vector2.zero);
			val.offsetMin = offsetMin;
			Image component = _backdrop.GetComponent<Image>();
			((Graphic)component).color = new Color(0.03f, 0.03f, 0.05f, 1f);
			((Graphic)component).raycastTarget = false;
			_backdrop.SetActive(false);
			Image obj3 = Reel.Img(_go.transform, "Frame", Reel.Dim, Vector2.one, Vector2.one, Vector2.one, Vector2.zero, Vector2.one);
			_frame = (RectTransform)((Component)obj3).transform;
			_img = Reel.Raw(((Component)obj3).transform, "Reel", new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero, Color.white);
			RectTransform val2 = (RectTransform)((Component)_img).transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = new Vector2(4f, 4f);
			val2.offsetMax = new Vector2(-4f, -4f);
			_go.SetActive(false);
		}
	}
	internal static class Icons
	{
		private abstract class Shape
		{
			internal abstract float Dist(Vector2 p);
		}

		private sealed class Seg : Shape
		{
			private readonly Vector2 _a;

			private readonly Vector2 _b;

			internal Seg(float ax, float ay, float bx, float by)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				_a = new Vector2(ax, ay);
				_b = new Vector2(bx, by);
			}

			internal override float Dist(Vector2 p)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: 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_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				Vector2 val = _b - _a;
				float num = ((((Vector2)(ref val)).sqrMagnitude < 1E-08f) ? 0f : Mathf.Clamp01(Vector2.Dot(p - _a, val) / ((Vector2)(ref val)).sqrMagnitude));
				Vector2 val2 = p - (_a + val * num);
				return ((Vector2)(ref val2)).magnitude;
			}
		}

		private sealed class Arc : Shape
		{
			private readonly Vector2 _c;

			private readonly float _r;

			private readonly float _a0;

			private readonly float _a1;

			private readonly bool _fill;

			internal Arc(float cx, float cy, float r, float a0 = 0f, float a1 = 360f, bool fill = false)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				_c = new Vector2(cx, cy);
				_r = r;
				_a0 = a0;
				_a1 = a1;
				_fill = fill;
			}

			internal override float Dist(Vector2 p)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: 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_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				Vector2 val = p - _c;
				float magnitude = ((Vector2)(ref val)).magnitude;
				if (_fill)
				{
					return Mathf.Max(0f, magnitude - _r);
				}
				if (_a1 - _a0 >= 359.9f)
				{
					return Mathf.Abs(magnitude - _r);
				}
				if (Mathf.Repeat(Mathf.Atan2(val.y, val.x) * 57.29578f - _a0, 360f) <= _a1 - _a0)
				{
					return Mathf.Abs(magnitude - _r);
				}
				Vector2 val2 = _c + new Vector2(Mathf.Cos(_a0 * (MathF.PI / 180f)), Mathf.Sin(_a0 * (MathF.PI / 180f))) * _r;
				Vector2 val3 = _c + new Vector2(Mathf.Cos(_a1 * (MathF.PI / 180f)), Mathf.Sin(_a1 * (MathF.PI / 180f))) * _r;
				Vector2 val4 = p - val2;
				float magnitude2 = ((Vector2)(ref val4)).magnitude;
				val4 = p - val3;
				return Mathf.Min(magnitude2, ((Vector2)(ref val4)).magnitude);
			}
		}

		private const int Size = 160;

		private static readonly Dictionary<string, Texture2D> Cache = new Dictionary<string, Texture2D>();

		private static IEnumerable<Shape> Poly(bool closed, params float[] xy)
		{
			int n = xy.Length / 2;
			for (int i = 0; i < n - 1; i++)
			{
				yield return new Seg(xy[2 * i], xy[2 * i + 1], xy[2 * i + 2], xy[2 * i + 3]);
			}
			if (closed && n > 2)
			{
				yield return new Seg(xy[2 * n - 2], xy[2 * n - 1], xy[0], xy[1]);
			}
		}

		private static List<Shape> Shapes(string name)
		{
			List<Shape> list = new List<Shape>();
			switch (name)
			{
			case "star":
			{
				float[] array = new float[20];
				for (int i = 0; i < 10; i++)
				{
					float num = (90f + (float)i * 36f) * (MathF.PI / 180f);
					float num2 = ((i % 2 == 0) ? 0.9f : 0.38f);
					array[2 * i] = Mathf.Cos(num) * num2;
					array[2 * i + 1] = Mathf.Sin(num) * num2 - 0.05f;
				}
				list.AddRange(Poly(closed: true, array));
				break;
			}
			case "helmet":
				list.Add(new Arc(0f, -0.15f, 0.7f, 0f, 180f));
				list.Add(new Seg(-0.9f, -0.15f, 0.9f, -0.15f));
				list.Add(new Seg(0f, 0.55f, 0f, 0.15f));
				break;
			case "crosshair":
				list.Add(new Arc(0f, 0f, 0.62f));
				list.Add(new Arc(0f, 0f, 0.1f, 0f, 360f, fill: true));
				list.Add(new Seg(0f, 0.9f, 0f, 0.35f));
				list.Add(new Seg(0f, -0.9f, 0f, -0.35f));
				list.Add(new Seg(0.9f, 0f, 0.35f, 0f));
				list.Add(new Seg(-0.9f, 0f, -0.35f, 0f));
				break;
			case "cross":
				list.AddRange(Poly(true, -0.25f, 0.85f, 0.25f, 0.85f, 0.25f, 0.35f, 0.75f, 0.35f, 0.75f, -0.15f, 0.25f, -0.15f, 0.25f, -0.65f, -0.25f, -0.65f, -0.25f, -0.15f, -0.75f, -0.15f, -0.75f, 0.35f, -0.25f, 0.35f));
				list.Add(new Seg(-0.9f, -0.85f, 0.9f, -0.85f));
				break;
			case "door":
				list.AddRange(Poly(false, -0.55f, -0.9f, -0.55f, 0.85f, 0.55f, 0.85f, 0.55f, -0.9f));
				list.Add(new Seg(-0.85f, -0.9f, 0.85f, -0.9f));
				list.Add(new Arc(0.3f, -0.05f, 0.07f, 0f, 360f, fill: true));
				break;
			case "heart":
				list.AddRange(Poly(false, -0.95f, -0.05f, -0.45f, -0.05f, -0.3f, 0.35f, -0.1f, -0.7f, 0.12f, 0.75f, 0.3f, -0.05f, 0.95f, -0.05f));
				break;
			case "boot":
				list.AddRange(Poly(true, -0.35f, 0.9f, 0.1f, 0.9f, 0.1f, 0.05f, 0.85f, -0.3f, 0.85f, -0.8f, -0.55f, -0.8f, -0.55f, 0.9f));
				break;
			case "coin":
				list.Add(new Arc(0f, 0f, 0.82f));
				list.Add(new Arc(0.02f, 0.2f, 0.22f, 20f, 270f));
				list.Add(new Arc(-0.02f, -0.24f, 0.22f, 200f, 450f));
				list.Add(new Seg(0f, 0.6f, 0f, -0.62f));
				break;
			case "eye":
				list.Add(new Arc(0f, -0.62f, 1.05f, 38f, 142f));
				list.Add(new Arc(0f, 0.62f, 1.05f, 218f, 322f));
				list.Add(new Arc(0f, 0f, 0.22f, 0f, 360f, fill: true));
				break;
			case "bulb":
				list.Add(new Arc(0f, 0.2f, 0.5f, -50f, 230f));
				list.Add(new Seg(-0.32f, -0.18f, -0.25f, -0.5f));
				list.Add(new Seg(0.32f, -0.18f, 0.25f, -0.5f));
				list.Add(new Seg(-0.25f, -0.62f, 0.25f, -0.62f));
				list.Add(new Seg(-0.18f, -0.8f, 0.18f, -0.8f));
				list.Add(new Seg(-0.85f, 0.85f, 0.85f, -0.85f));
				break;
			case "cat":
				list.AddRange(Poly(false, -0.6f, 0.05f, -0.62f, 0.85f, -0.22f, 0.45f, 0.22f, 0.45f, 0.62f, 0.85f, 0.6f, 0.05f));
				list.Add(new Arc(0f, 0.05f, 0.6f, 180f));
				list.Add(new Arc(-0.25f, 0.08f, 0.08f, 0f, 360f, fill: true));
				list.Add(new Arc(0.25f, 0.08f, 0.08f, 0f, 360f, fill: true));
				list.Add(new Seg(-0.95f, -0.12f, -0.45f, -0.18f));
				list.Add(new Seg(0.95f, -0.12f, 0.45f, -0.18f));
				break;
			case "skull":
				list.Add(new Arc(0f, 0.2f, 0.68f, -40f, 220f));
				list.AddRange(Poly(false, -0.52f, -0.24f, -0.38f, -0.24f, -0.38f, -0.75f, 0.38f, -0.75f, 0.38f, -0.24f, 0.52f, -0.24f));
				list.Add(new Arc(-0.26f, 0.12f, 0.15f, 0f, 360f, fill: true));
				list.Add(new Arc(0.26f, 0.12f, 0.15f, 0f, 360f, fill: true));
				break;
			case "box":
				list.AddRange(Poly(true, -0.7f, -0.8f, 0.7f, -0.8f, 0.7f, 0.25f, -0.7f, 0.25f));
				list.Add(new Seg(-0.3f, 0.95f, 0.05f, 0.5f));
				list.Add(new Seg(0.35f, 0.95f, 0.1f, 0.55f));
				break;
			case "camera":
				list.AddRange(Poly(true, -0.85f, -0.6f, 0.85f, -0.6f, 0.85f, 0.4f, 0.35f, 0.4f, 0.22f, 0.65f, -0.22f, 0.65f, -0.35f, 0.4f, -0.85f, 0.4f));
				list.Add(new Arc(0f, -0.1f, 0.32f));
				break;
			default:
				list.Add(new Arc(0f, 0f, 0.7f));
				break;
			}
			return list;
		}

		internal static Texture2D Get(string name)
		{
			//IL_0036: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if (Cache.TryGetValue(name ?? "", out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			List<Shape> list = Shapes(name);
			value = new Texture2D(160, 160, (TextureFormat)4, false)
			{
				name = "CrewAwards.Icon." + name,
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[25600];
			float num = 0.0125f;
			Vector2 p = default(Vector2);
			for (int i = 0; i < 160; i++)
			{
				for (int j = 0; j < 160; j++)
				{
					((Vector2)(ref p))..ctor(((float)j + 0.5f) * num - 1f, ((float)i + 0.5f) * num - 1f);
					float num2 = float.MaxValue;
					foreach (Shape item in list)
					{
						num2 = Math.Min(num2, item.Dist(p));
					}
					float num3 = Mathf.Clamp01((0.075f - num2) / num + 0.5f);
					array[i * 160 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num3 * 255f));
				}
			}
			value.SetPixels32(array);
			value.Apply(false, true);
			Cache[name ?? ""] = value;
			return value;
		}
	}
	internal static class Local
	{
		internal const float ShaveHp = 20f;

		internal static readonly DayCounters Day = new DayCounters();

		private static float _shaveAt = -1f;

		private static Vector3 _lastPos;

		private static bool _hadPos;

		private static float _nextDark;

		internal static bool LastDark;

		internal static bool LastOwnLight;

		internal static bool LastNearLight;

		private static PlayerControllerB Me
		{
			get
			{
				if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
				{
					return null;
				}
				return GameNetworkManager.Instance.localPlayerController;
			}
		}

		internal static void OnSessionStart()
		{
			Day.Clear();
			_shaveAt = -1f;
			_hadPos = false;
		}

		internal static void OnDamaged(PlayerControllerB p, int before)
		{
			if ((Object)(object)p == (Object)null || (Object)(object)p != (Object)(object)Me)
			{
				return;
			}
			int num = Mathf.Max(0, p.health);
			if (p.isPlayerDead)
			{
				num = 0;
			}
			int num2 = before - num;
			if (num2 > 0)
			{
				Day[Stat.Damage] += num2;
				if ((float)before >= 20f && (float)num < 20f && num > 0 && !p.isPlayerDead && _shaveAt < 0f)
				{
					_shaveAt = Time.time;
				}
			}
		}

		internal static void OnSpent(int credits)
		{
			if (credits > 0)
			{
				Day[Stat.Spent] += credits;
				Host.Log($"spent {credits} credits at the terminal");
			}
		}

		internal static void Tick()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB me = Me;
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)me == (Object)null || (Object)(object)instance == (Object)null)
			{
				_hadPos = false;
				return;
			}
			float deltaTime = Time.deltaTime;
			bool flag = me.isPlayerControlled && !me.isPlayerDead;
			if (_shaveAt >= 0f)
			{
				if (me.isPlayerDead)
				{
					_shaveAt = -1f;
				}
				else if (Time.time - _shaveAt >= 5f)
				{
					Day[Stat.CloseShaves] += 1.0;
					_shaveAt = -1f;
					Host.Log("close shave");
				}
			}
			bool flag2 = instance.shipHasLanded && !instance.inShipPhase;
			Vector3 position = ((Component)me).transform.position;
			if (flag2 && flag && !me.inVehicleAnimation && _hadPos)
			{
				Vector3 val = position - _lastPos;
				val.y = 0f;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (magnitude < 1.5f)
				{
					Day[Stat.Distance] += magnitude;
				}
			}
			_lastPos = position;
			_hadPos = true;
			if (flag2 && flag && me.isInHangarShipRoom)
			{
				Day[Stat.ShipTime] += deltaTime;
			}
			if (Time.time >= _nextDark)
			{
				_nextDark = Time.time + 0.5f;
				LastDark = false;
				if (flag2 && flag && me.isInsideFactory)
				{
					LastOwnLight = HasOwnLight(me);
					LastNearLight = !LastOwnLight && NearFacilityLight(me);
					LastDark = !LastOwnLight && !LastNearLight;
				}
			}
			if (LastDark && flag2 && flag && me.isInsideFactory)
			{
				Day[Stat.DarkTime] += deltaTime;
			}
		}

		private static bool HasOwnLight(PlayerControllerB me)
		{
			if ((Object)(object)me.helmetLight != (Object)null && ((Behaviour)me.helmetLight).enabled)
			{
				return true;
			}
			if (me.ItemSlots != null)
			{
				GrabbableObject[] itemSlots = me.ItemSlots;
				foreach (GrabbableObject obj in itemSlots)
				{
					FlashlightItem val = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null);
					if (val != null && ((GrabbableObject)val).isBeingUsed)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool NearFacilityLight(PlayerControllerB me)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//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_0058: 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_00b1: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			RoundManager instance = RoundManager.Instance;
			if ((Object)(object)instance == (Object)null || instance.allPoweredLights == null)
			{
				return false;
			}
			Vector3 val = (((Object)(object)me.gameplayCamera != (Object)null) ? ((Component)me.gameplayCamera).transform.position : (((Component)me).transform.position + Vector3.up * 1.6f));
			int collidersAndRoomMaskAndDefault = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			foreach (Light allPoweredLight in instance.allPoweredLights)
			{
				if ((Object)(object)allPoweredLight == (Object)null || !((Behaviour)allPoweredLight).isActiveAndEnabled || allPoweredLight.intensity <= 0.01f)
				{
					continue;
				}
				Vector3 position = ((Component)allPoweredLight).transform.position;
				float num = Mathf.Min(allPoweredLight.range, 12f);
				float num2 = Vector3.Distance(val, position);
				if (!(num2 > num))
				{
					Vector3 val2 = val - position;
					Vector3 val3 = position + ((Vector3)(ref val2)).normalized * Mathf.Min(0.5f, num2 * 0.5f);
					if (!Physics.Linecast(val, val3, collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static void OnDayEnd()
		{
			PlayerControllerB me = Me;
			if (!((Object)(object)me == (Object)null))
			{
				if (_shaveAt >= 0f && !me.isPlayerDead)
				{
					Day[Stat.CloseShaves] += 1.0;
					Host.Log("close shave (day ended alive)");
				}
				_shaveAt = -1f;
				Day[Stat.DamageSurvived] = (me.isPlayerDead ? 0.0 : Day[Stat.Damage]);
				Host.Log("own day tally: " + Day.Text());
				Net.SendDayTally((double[])Day.V.Clone());
				Day.Clear();
			}
		}
	}
	internal static class Net
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static HandleNamedMessageDelegate <>9__20_0;

			public static HandleNamedMessageDelegate <>9__20_1;

			public static HandleNamedMessageDelegate <>9__20_2;

			public static HandleNamedMessageDelegate <>9__20_3;

			internal void <Register>b__20_0(ulong s, FastBufferReader r)
			{
				if (IsHost)
				{
					Host.Modded.Add(s);
					Host.Log($"client {s} has Crew Awards");
					SendTallyTo(s);
					SendAwardsTo(s, live: false);
				}
			}

			internal void <Register>b__20_1(ulong s, FastBufferReader r)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				if (IsHost)
				{
					byte b = default(byte);
					((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
					byte b2 = default(byte);
					((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref b2, default(ForPrimitives));
					double[] array = new double[b2];
					for (int i = 0; i < b2; i++)
					{
						((FastBufferReader)(ref r)).ReadValueSafe<double>(ref array[i], default(ForPrimitives));
					}
					if (b != 1)
					{
						Plugin.Log.LogWarning((object)$"CrewAwards: day tally v{b} from client {s} (we read v{(byte)1}); using it as far as it matches");
					}
					Host.Modded.Add(s);
					Host.OnDayTally(s, Host.PlayerOf(s), array);
				}
			}

			internal void <Register>b__20_2(ulong s, FastBufferReader r)
			{
				if (!IsHost)
				{
					string clientLive = default(string);
					((FastBufferReader)(ref r)).ReadValueSafe(ref clientLive, false);
					string clientLast = default(string);
					((FastBufferReader)(ref r)).ReadValueSafe(ref clientLast, false);
					ClientLive = clientLive;
					ClientLast = clientLast;
					TalliesReceived++;
					Host.Log($"tally from the host ({TalliesReceived})");
				}
			}

			internal void <Register>b__20_3(ulong s, FastBufferReader r)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				if (!IsHost)
				{
					string text = default(string);
					((FastBufferReader)(ref r)).ReadValueSafe(ref text, false);
					string clientHistory = default(string);
					((FastBufferReader)(ref r)).ReadValueSafe(ref clientHistory, false);
					bool flag = default(bool);
					((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
					ClientResult = text;
					ClientHistory = clientHistory;
					AwardsReceived++;
					Host.Log(string.Format("awards from the host ({0}, {1})", AwardsReceived, flag ? "quota just closed" : "on join"));
					if (flag)
					{
						Reel.Queue(AwardsResult.Parse(text));
					}
					else
					{
						Plaque.Show(AwardsResult.Parse(text));
					}
				}
			}
		}

		internal const string Hello = "CrewAwards.Hello";

		internal const string Day = "CrewAwards.Day";

		internal const string Tally = "CrewAwards.Tally";

		internal const string AwardsMsg = "CrewAwards.Awards";

		internal const byte DayVersion = 1;

		private static CustomMessagingManager _registeredOn;

		internal static string ClientLive = "";

		internal static string ClientLast = "";

		internal static int TalliesReceived;

		internal static int AwardsReceived;

		internal static string ClientResult = "";

		internal static string ClientHistory = "";

		private static bool _helloSent;

		internal static NetworkManager NM => NetworkManager.Singleton;

		internal static bool Online
		{
			get
			{
				if ((Object)(object)NM != (Object)null && NM.IsListening)
				{
					return NM.CustomMessagingManager != null;
				}
				return false;
			}
		}

		internal static bool IsHost
		{
			get
			{
				if (Online)
				{
					return NM.IsServer;
				}
				return false;
			}
		}

		internal static string ResultText
		{
			get
			{
				if (!IsHost)
				{
					return ClientResult;
				}
				return Host.LastResult;
			}
		}

		internal static string HistoryText
		{
			get
			{
				if (!IsHost)
				{
					return ClientHistory;
				}
				return Host.History;
			}
		}

		internal static void OnSessionStart()
		{
			ClientLive = "";
			ClientLast = "";
			TalliesReceived = 0;
			AwardsReceived = 0;
			ClientResult = "";
			ClientHistory = "";
			_helloSent = false;
		}

		internal static void Register()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			NetworkManager nM = NM;
			if ((Object)(object)nM == (Object)null || nM.CustomMessagingManager == null || _registeredOn == nM.CustomMessagingManager)
			{
				return;
			}
			CustomMessagingManager customMessagingManager = nM.CustomMessagingManager;
			object obj = <>c.<>9__20_0;
			if (obj == null)
			{
				HandleNamedMessageDelegate val = delegate(ulong s, FastBufferReader r)
				{
					if (IsHost)
					{
						Host.Modded.Add(s);
						Host.Log($"client {s} has Crew Awards");
						SendTallyTo(s);
						SendAwardsTo(s, live: false);
					}
				};
				<>c.<>9__20_0 = val;
				obj = (object)val;
			}
			customMessagingManager.RegisterNamedMessageHandler("CrewAwards.Hello", (HandleNamedMessageDelegate)obj);
			object obj2 = <>c.<>9__20_1;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = delegate(ulong s, FastBufferReader r)
				{
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0014: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_0044: Unknown result type (might be due to invalid IL or missing references)
					//IL_004a: Unknown result type (might be due to invalid IL or missing references)
					if (IsHost)
					{
						byte b = default(byte);
						((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
						byte b2 = default(byte);
						((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref b2, default(ForPrimitives));
						double[] array = new double[b2];
						for (int i = 0; i < b2; i++)
						{
							((FastBufferReader)(ref r)).ReadValueSafe<double>(ref array[i], default(ForPrimitives));
						}
						if (b != 1)
						{
							Plugin.Log.LogWarning((object)$"CrewAwards: day tally v{b} from client {s} (we read v{(byte)1}); using it as far as it matches");
						}
						Host.Modded.Add(s);
						Host.OnDayTally(s, Host.PlayerOf(s), array);
					}
				};
				<>c.<>9__20_1 = val2;
				obj2 = (object)val2;
			}
			customMessagingManager.RegisterNamedMessageHandler("CrewAwards.Day", (HandleNamedMessageDelegate)obj2);
			object obj3 = <>c.<>9__20_2;
			if (obj3 == null)
			{
				HandleNamedMessageDelegate val3 = delegate(ulong s, FastBufferReader r)
				{
					if (!IsHost)
					{
						string clientLive = default(string);
						((FastBufferReader)(ref r)).ReadValueSafe(ref clientLive, false);
						string clientLast = default(string);
						((FastBufferReader)(ref r)).ReadValueSafe(ref clientLast, false);
						ClientLive = clientLive;
						ClientLast = clientLast;
						TalliesReceived++;
						Host.Log($"tally from the host ({TalliesReceived})");
					}
				};
				<>c.<>9__20_2 = val3;
				obj3 = (object)val3;
			}
			customMessagingManager.RegisterNamedMessageHandler("CrewAwards.Tally", (HandleNamedMessageDelegate)obj3);
			object obj4 = <>c.<>9__20_3;
			if (obj4 == null)
			{
				HandleNamedMessageDelegate val4 = delegate(ulong s, FastBufferReader r)
				{
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					//IL_0028: Unknown result type (might be due to invalid IL or missing references)
					if (!IsHost)
					{
						string text = default(string);
						((FastBufferReader)(ref r)).ReadValueSafe(ref text, false);
						string clientHistory = default(string);
						((FastBufferReader)(ref r)).ReadValueSafe(ref clientHistory, false);
						bool flag = default(bool);
						((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
						ClientResult = text;
						ClientHistory = clientHistory;
						AwardsReceived++;
						Host.Log(string.Format("awards from the host ({0}, {1})", AwardsReceived, flag ? "quota just closed" : "on join"));
						if (flag)
						{
							Reel.Queue(AwardsResult.Parse(text));
						}
						else
						{
							Plaque.Show(AwardsResult.Parse(text));
						}
					}
				};
				<>c.<>9__20_3 = val4;
				obj4 = (object)val4;
			}
			customMessagingManager.RegisterNamedMessageHandler("CrewAwards.Awards", (HandleNamedMessageDelegate)obj4);
			_registeredOn = customMessagingManager;
			_helloSent = false;
			Plugin.Log.LogInfo((object)"CrewAwards: messages registered.");
		}

		internal unsafe static void TickHello()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (_helloSent || !Online || IsHost)
			{
				return;
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null || !val.isPlayerControlled)
			{
				return;
			}
			FastBufferWriter val2 = default(FastBufferWriter);
			((FastBufferWriter)(ref val2))..ctor(8, (Allocator)2, -1);
			try
			{
				NM.CustomMessagingManager.SendNamedMessage("CrewAwards.Hello", 0uL, val2, (NetworkDelivery)3);
				_helloSent = true;
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val2))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal unsafe static void SendDayTally(double[] v)
		{
			//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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (!Online)
			{
				return;
			}
			if (IsHost)
			{
				Host.OnDayTally(0uL, GameNetworkManager.Instance?.localPlayerController, v);
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(16 + v.Length * 8, (Allocator)2, -1);
			try
			{
				byte b = 1;
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
				b = (byte)v.Length;
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
				for (int i = 0; i < v.Length; i++)
				{
					double num = v[i];
					((FastBufferWriter)(ref val)).WriteValueSafe<double>(ref num, default(ForPrimitives));
				}
				NM.CustomMessagingManager.SendNamedMessage("CrewAwards.Day", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal static void BroadcastTally()
		{
			if (!IsHost)
			{
				return;
			}
			foreach (ulong connectedClientsId in NM.ConnectedClientsIds)
			{
				if (connectedClientsId != 0L && Host.Modded.Contains(connectedClientsId))
				{
					SendTallyTo(connectedClientsId);
				}
			}
		}

		internal static void BroadcastAwards(bool live)
		{
			if (!IsHost)
			{
				return;
			}
			foreach (ulong connectedClientsId in NM.ConnectedClientsIds)
			{
				if (connectedClientsId != 0L && Host.Modded.Contains(connectedClientsId))
				{
					SendAwardsTo(connectedClientsId, live);
				}
			}
		}

		private unsafe static void SendAwardsTo(ulong cid, bool live)
		{
			//IL_004f: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost || cid == 0L)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(1024, (Allocator)2, 65536);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(Host.LastResult ?? "", false);
				((FastBufferWriter)(ref val)).WriteValueSafe(Host.History ?? "", false);
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref live, default(ForPrimitives));
				NM.CustomMessagingManager.SendNamedMessage("CrewAwards.Awards", cid, val, (NetworkDelivery)4);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private unsafe static void SendTallyTo(ulong cid)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost || cid == 0L)
			{
				return;
			}
			string text = Host.Live?.Serialize() ?? "";
			string text2 = Host.Last?.Serialize() ?? "";
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(1024, (Allocator)2, 65536);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
				((FastBufferWriter)(ref val)).WriteValueSafe(text2, false);
				NM.CustomMessagingManager.SendNamedMessage("CrewAwards.Tally", cid, val, (NetworkDelivery)4);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}
	}
	internal sealed class Runner : MonoBehaviour
	{
		private void Update()
		{
			try
			{
				if (!Net.Online)
				{
					Reel.Stop();
					return;
				}
				Net.Register();
				Net.TickHello();
				Local.Tick();
				Host.Tick();
				Reel.Tick();
				Plaque.Tick();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: " + ex));
			}
		}

		private void LateUpdate()
		{
			try
			{
				Reel.LateTick();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: reel: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class SessionStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				Net.OnSessionStart();
				Local.OnSessionStart();
				Plaque.OnSessionStart();
				Reel.OnSessionStart();
				Host.OnSessionStart();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: session start: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
	internal static class DamagePatch
	{
		[HarmonyPrefix]
		private static void Prefix(PlayerControllerB __instance, out int __state)
		{
			__state = __instance.health;
		}

		[HarmonyPostfix]
		private static void Postfix(PlayerControllerB __instance, int __state)
		{
			try
			{
				Local.OnDamaged(__instance, __state);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: damage: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SetItemInElevator")]
	internal static class ElevatorPatch
	{
		[HarmonyPrefix]
		private static void Prefix(GrabbableObject gObject, out (bool wasIn, bool persisted) __state)
		{
			__state = (((Object)(object)gObject != (Object)null) ? (wasIn: gObject.isInShipRoom, persisted: gObject.scrapPersistedThroughRounds) : (wasIn: false, persisted: true));
		}

		[HarmonyPostfix]
		private static void Postfix(PlayerControllerB __instance, GrabbableObject gObject, (bool wasIn, bool persisted) __state)
		{
			try
			{
				Host.OnElevator(__instance, gObject, __state.wasIn, __state.persisted);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: elevator: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "HitEnemyServerRpc")]
	internal static class HitPatch
	{
		[HarmonyPrefix]
		private static void Prefix(EnemyAI __instance, int playerWhoHit)
		{
			try
			{
				Host.OnHit(__instance, playerWhoHit);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: hit: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "LoadNewNodeIfAffordable")]
	internal static class SpendPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Terminal __instance, out int __state)
		{
			__state = __instance.groupCredits;
		}

		[HarmonyPostfix]
		private static void Postfix(Terminal __instance, int __state)
		{
			try
			{
				Local.OnSpent(__state - __instance.groupCredits);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: spend: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
	internal static class DayEndPatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			try
			{
				Host.OnDayEnd();
				Local.OnDayEnd();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: day end: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ShipHasLeft")]
	internal static class ShipLeftPatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			try
			{
				Host.OnShipLeft();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: ship left: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")]
	internal static class QuotaMetPatch
	{
		[HarmonyPrefix]
		private static void Prefix(TimeOfDay __instance)
		{
			if (!((NetworkBehaviour)__instance).IsServer)
			{
				return;
			}
			try
			{
				Host.RequestClose("met", __instance.timesFulfilledQuota + 1, __instance.profitQuota, __instance.quotaFulfilled);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: quota met: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc")]
	internal static class FiredEarlyPatch
	{
		[HarmonyPrefix]
		private static void Prefix(StartOfRound __instance)
		{
			if (!((NetworkBehaviour)__instance).IsServer)
			{
				return;
			}
			try
			{
				TimeOfDay instance = TimeOfDay.Instance;
				Host.RequestClose("fired", 0, ((Object)(object)instance != (Object)null) ? instance.profitQuota : 0, ((Object)(object)instance != (Object)null) ? instance.quotaFulfilled : 0);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: fired: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "ShowPlayersFiredScreen")]
	internal static class FiredScreenPatch
	{
		[HarmonyPostfix]
		private static void Postfix(bool show)
		{
			Reel.FiredScreenUp = show;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")]
	internal static class FiredPatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			try
			{
				TimeOfDay instance = TimeOfDay.Instance;
				Host.RequestClose("fired", 0, ((Object)(object)instance != (Object)null) ? instance.profitQuota : 0, ((Object)(object)instance != (Object)null) ? instance.quotaFulfilled : 0);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: fired: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "SaveGame")]
	internal static class SavePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				Host.Save();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("CrewAwards: save: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	internal static class TerminalCommand
	{
		private static TerminalNode _node;

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(Terminal __instance, ref TerminalNode __result)
		{
			try
			{
				string text = Handle(__instance);
				if (text != null)
				{
					if ((Object)(object)_node == (Object)null)
					{
						_node = ScriptableObject.CreateInstance<TerminalNode>();
						((Object)_node).name = "CrewAwardsReply";
						_node.clearPreviousText = true;
						_node.maxCharactersToType = 25;
					}
					_node.displayText = text;
					__result = _node;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("CrewAwards: terminal: " + ex));
			}
		}

		private static string Handle(Terminal term)
		{
			if ((Object)(object)term.screenText == (Object)null)
			{
				return null;
			}
			string text = term.screenText.text;
			int num = Mathf.Clamp(term.textAdded, 0, text.Length);
			string[] array = new string((from c in text.Substring(text.Length - num)
				where !char.IsPunctuation(c)
				select c).ToArray()).Trim().Split(new char[1] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length == 0 || array[0].ToLowerInvariant() != "awards")
			{
				return null;
			}
			string text2 = ((array.Length > 1) ? array[1].Trim().ToLowerInvariant() : "");
			if (text2 == "debug")
			{
				return DebugText() + "\n";
			}
			if (text2 == "all")
			{
				string historyText = Net.HistoryText;
				return "CREW AWARDS: THIS RUN\n\n" + (string.IsNullOrEmpty(historyText) ? "No quota has closed yet this run.\n" : (historyText.Replace("\n", "\n\n") + "\n")) + "\n";
			}
			AwardsResult awardsResult = AwardsResult.Parse(Net.ResultText);
			if (awardsResult == null)
			{
				return "CREW AWARDS\n\nNo awards yet. They're given on the ship monitor when a quota is met.\nAWARDS ALL lists every quota this run.\n\n";
			}
			return awardsResult.TerminalText() + "\nAWARDS ALL lists every quota this run.\n\n";
		}

		internal static string DebugText()
		{
			StringBuilder stringBuilder = new StringBuilder("AWARDS DEBUG\n");
			QuotaTally quotaTally;
			QuotaTally quotaTally2;
			if (Net.IsHost)
			{
				quotaTally = Host.Live;
				quotaTally2 = Host.Last;
				stringBuilder.Append("(host)\n");
			}
			else
			{
				quotaTally = QuotaTally.Parse(Net.ClientLive);
				quotaTally2 = QuotaTally.Parse(Net.ClientLast);
				stringBuilder.Append((quotaTally == null) ? "(no tally from the host yet; does the host have Crew Awards?)\n" : "(client: the host's copy as of the last day)\n");
			}
			if (quotaTally != null)
			{
				stringBuilder.Append(quotaTally.DebugText("QUOTA TALLY"));
			}
			if (quotaTally2 != null)
			{
				stringBuilder.Append(quotaTally2.DebugText("LAST QUOTA"));
			}
			stringBuilder.Append("Your day so far: ").Append(Local.Day.Text()).Append('\n');
			return stringBuilder.ToString();
		}
	}
	internal static class Plaque
	{
		internal const float W = 0.56f;

		internal const float H = 0.42f;

		internal const float Border = 0.035f;

		internal const float Depth = 0.03f;

		private const int Layer = 5;

		private static readonly Vector3 Spot = new Vector3(0f, 3100f, 0f);

		internal static GameObject Current;

		internal static string Name = "";

		internal static string Where = "";

		private static AwardsResult _pending;

		private static bool _hasPending;

		private static string _shownKey;

		private static Texture2D _faceTex;

		internal static int TimesPlaced;

		internal static readonly int[] Why = new int[4];

		internal static readonly Dictionary<string, int> InWay = new Dictionary<string, int>();

		internal static string WhyText => $"no wall {Why[0]}, off-plane {Why[1]}, not flat {Why[2]}, blocked {Why[3]}" + ((InWay.Count > 0) ? (" (" + string.Join(", ", InWay.Select((KeyValuePair<string, int> kv) => $"{kv.Key} x{kv.Value}")) + ")") : "");

		internal static void OnSessionStart()
		{
			Remove();
			_pending = null;
			_hasPending = false;
		}

		internal static void Show(AwardsResult r)
		{
			_pending = r;
			_hasPending = true;
		}

		internal static void Tick()
		{
			if (!_hasPending)
			{
				return;
			}
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.elevatorTransform == (Object)null || (Object)(object)instance.mapScreen == (Object)null)
			{
				return;
			}
			_hasPending = false;
			AwardsResult pending = _pending;
			_pending = null;
			string text = Winner(pending);
			if (text == null || !Plugin.ShowPlaque.Value)
			{
				if ((Object)(object)Current != (Object)null)
				{
					Host.Log("plaque taken down");
				}
				Remove();
				return;
			}
			string text2 = $"{pending.QuotaIndex}|{text}";
			if (!((Object)(object)Current != (Object)null) || !(_shownKey == text2))
			{
				Remove();
				Build(pending, text);
				_shownKey = text2;
			}
		}

		internal static string Winner(AwardsResult r)
		{
			if (r == null || r.Final || r.Closed != "met")
			{
				return null;
			}
			AwardPick awardPick = r.Picks.FirstOrDefault((AwardPick p) => p.Id == "employee");
			if (awardPick != null)
			{
				return awardPick.NameText;
			}
			if (r.Solo && r.Picks.Count > 0)
			{
				return r.Picks[0].NameText;
			}
			return null;
		}

		internal static void Remove()
		{
			if ((Object)(object)Current != (Object)null)
			{
				Object.Destroy((Object)(object)Current);
			}
			Current = null;
			Name = "";
			Where = "";
			_shownKey = null;
		}

		private static void Build(AwardsResult r, string name)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_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)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			ManualCameraRenderer mapScreen = instance.mapScreen;
			if (!FindSpot(instance, mapScreen, out var pos, out var normal, out var where))
			{
				Host.Log("plaque: no spot found; none this quota");
				return;
			}
			if ((Object)(object)_faceTex != (Object)null)
			{
				Object.Destroy((Object)(object)_faceTex);
			}
			_faceTex = RenderFace(r, name);
			GameObject val = new GameObject("CrewAwards.Plaque");
			val.transform.SetPositionAndRotation(pos + normal * 0.019f, Quaternion.LookRotation(-normal, Vector3.up));
			val.transform.SetParent(instance.elevatorTransform, true);
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = "Frame";
			Object.Destroy((Object)(object)obj.GetComponent<Collider>());
			obj.transform.SetParent(val.transform, false);
			obj.transform.localScale = new Vector3(0.63f, 0.48999998f, 0.03f);
			((Renderer)obj.GetComponent<MeshRenderer>()).sharedMaterial = FrameMat(mapScreen);
			GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)5);
			((Object)obj2).name = "Face";
			Object.Destroy((Object)(object)obj2.GetComponent<Collider>());
			obj2.transform.SetParent(val.transform, false);
			obj2.transform.localPosition = new Vector3(0f, 0f, -0.016999999f);
			obj2.transform.localScale = new Vector3(0.56f, 0.42f, 1f);
			((Renderer)obj2.GetComponent<MeshRenderer>()).sharedMaterial = FaceMat(mapScreen, _faceTex);
			Current = val;
			Name = name;
			Where = where;
			TimesPlaced++;
			Host.Log($"plaque up: {name}, quota {r.QuotaIndex + 1}, {where} at {val.transform.position} facing {normal}; probe: {WhyText}");
		}

		private static Material FrameMat(ManualCameraRenderer ms)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			Material val = null;
			if ((Object)(object)ms != (Object)null && (Object)(object)ms.mesh != (Object)null)
			{
				val = ((Renderer)ms.mesh).sharedMaterials.Where((Material m, int i) => i != ms.materialIndex && (Object)(object)m != (Object)null && (Object)(object)m.shader != (Object)null && ((Object)m.shader).name.Contains("Lit") && !((Object)m.shader).name.Contains("Unlit")).FirstOrDefault();
			}
			Material val2;
			if ((Object)(object)val != (Object)null)
			{
				val2 = new Material(val);
			}
			else
			{
				Shader val3 = Shader.Find("HDRP/Lit");
				val2 = (((Object)(object)val3 != (Object)null) ? new Material(val3) : new Material(ms.onScreenMat));
			}
			((Object)val2).name = "CrewAwards.PlaqueFrame";
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.55f, 0.4f, 0.17f);
			if (val2.HasProperty("_BaseColor"))
			{
				val2.SetColor("_BaseColor", val4);
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", val4);
			}
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", 0.6f);
			}
			if (val2.HasProperty("_Smoothness"))
			{
				val2.SetFloat("_Smoothness", 0.45f);
			}
			return val2;
		}

		private static Material FaceMat(ManualCameraRenderer ms, Texture2D tex)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(ms.onScreenMat)
			{
				name = "CrewAwards.PlaqueFace"
			};
			bool flag = false;
			string[] texturePropertyNames = val.GetTexturePropertyNames();
			foreach (string text in texturePropertyNames)
			{
				if (val.GetTexture(text) is RenderTexture)
				{
					val.SetTexture(text, (Texture)(object)tex);
					flag = true;
				}
			}
			if (!flag)
			{
				val.mainTexture = (Texture)(object)tex;
			}
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.5f, 0.5f, 0.5f, 1f);
			if (val.HasProperty("_UnlitColor"))
			{
				val.SetColor("_UnlitColor", val2);
			}
			if (val.HasProperty("_EmissiveColor"))
			{
				val.SetColor("_EmissiveColor", Color.black);
			}
			return val;
		}

		private static Texture2D RenderFace(AwardsResult r, string name)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: 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_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: 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_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Expected O, but got Unknown
			RenderTexture val = new RenderTexture(640, 480, 24, (RenderTextureFormat)0);
			val.Create();
			GameObject val2 = new GameObject("CrewAwards.PlaqueFace")
			{
				layer = 5
			};
			val2.transform.position = Spot;
			Camera val3 = val2.AddComponent<Camera>();
			((Behaviour)val3).enabled = false;
			val3.clearFlags = (CameraClearFlags)2;
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.12f, 0.075f, 0.045f);
			val3.backgroundColor = val4;
			val3.cullingMask = 32;
			val3.orthographic = true;
			val3.orthographicSize = 1f;
			val3.nearClipPlane = 0.01f;
			val3.farClipPlane = 10f;
			val3.targetTexture = val;
			HDAdditionalCameraData obj = val2.AddComponent<HDAdditionalCameraData>();
			obj.clearColorMode = (ClearColorMode)1;
			obj.backgroundColorHDR = val4;
			obj.volumeLayerMask = LayerMask.op_Implicit(0);
			GameObject val5 = new GameObject("Canvas")
			{
				layer = 5
			};
			val5.transform.SetParent(val2.transform, false);
			Canvas obj2 = val5.AddComponent<Canvas>();
			obj2.renderMode = (RenderMode)1;
			obj2.worldCamera = val3;
			obj2.planeDistance = 1f;
			CanvasScaler obj3 = val5.AddComponent<CanvasScaler>();
			obj3.uiScaleMode = (ScaleMode)1;
			obj3.referenceResolution = new Vector2(640f, 480f);
			Transform transform = val5.transform;
			Color val6 = default(Color);
			((Color)(ref val6))..ctor(0.93f, 0.74f, 0.36f);
			Color col = default(Color);
			((Color)(ref col))..ctor(1f, 0.93f, 0.78f);
			TMP_FontAsset font = Reel.Font();
			Reel.Img(((Component)Reel.Img(transform, "Border", val6, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(-36f, -36f))).transform, "Inner", new Color(0.12f, 0.075f, 0.045f), Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(-8f, -8f));
			Reel.Raw(transform, "Star", new Vector2(0.5f, 1f), new Vector2(0f, -88f), new Vector2(84f, 84f), val6).texture = (Texture)(object)Icons.Get("star");
			Reel.Text(transform, "Title", font, 40f, val6, (TextAlignmentOptions)514, new Vector2(0.5f, 0.5f), new Vector2(0f, 74f), new Vector2(560f, 50f), autoSize: true, 24f);
			Reel.Text(transform, "Name", font, 84f, col, (TextAlignmentOptions)514, new Vector2(0.5f, 0.5f), new Vector2(0f, -6f), new Vector2(560f, 100f), autoSize: true, 30f);
			Reel.Text(transform, "Quota", font, 30f, val6, (TextAlignmentOptions)514, new Vector2(0.5f, 0.5f), new Vector2(0f, -86f), new Vector2(560f, 40f), autoSize: true, 18f);
			Reel.Text(transform, "Company", font, 22f, val6, (TextAlignmentOptions)514, new Vector2(0.5f, 0f), new Vector2(0f, 52f), new Vector2(400f, 30f), autoSize: true, 14f);
			TextMeshProUGUI[] componentsInChildren = val5.GetComponentsInChildren<TextMeshProUGUI>();
			((TMP_Text)componentsInChildren[0]).text = (r.Solo ? "QUOTA REPORT" : "EMPLOYEE OF THE QUOTA");
			((TMP_Text)componentsInChildren[1]).text = name;
			((TMP_Text)componentsInChildren[2]).text = $"Quota {r.QuotaIndex + 1}  -  {Awards.Money(r.Collected)} / {Awards.Money(r.Quota)}";
			((TMP_Text)componentsInChildren[3]).text = "THE COMPANY";
			Reel.SetLayer(val2.transform);
			Canvas.ForceUpdateCanvases();
			TextMeshProUGUI[] array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				((TMP_Text)array[i]).ForceMeshUpdate(false, false);
			}
			val3.Render();
			val3.Render();
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = val;
			Texture2D val7 = new Texture2D(640, 480, (TextureFormat)3, true)
			{
				name = "CrewAwards.PlaqueFace",
				filterMode = (FilterMode)2,
				anisoLevel = 4
			};
			val7.ReadPixels(new Rect(0f, 0f, 640f, 480f), 0, 0);
			val7.Apply(true);
			RenderTexture.active = active;
			val3.targetTexture = null;
			val.Release();
			Object.Destroy((Object)(object)val);
			Object.Destroy((Object)(object)val2);
			return val7;
		}

		private static bool FindSpot(StartOfRound sor, ManualCameraRenderer ms, out Vector3 pos, out Vector3 normal, out string where)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missin