Decompiled source of Gentlemens Mutators v1.2.0

GentlemensMutators/GentlemensMutators.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using AGD.ModAPI;
using AGD.Modding;
using AGDKit;
using Character;
using Core;
using DisputeLib;
using FMOD;
using FMOD.Studio;
using FMODUnity;
using FishNet;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using Game;
using HeldItems;
using Items;
using Newtonsoft.Json.Linq;
using Perks;
using Player;
using TMPro;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Events;
using UnityEngine.Playables;
using UnityEngine.Rendering;
using UnityEngine.UI;
using Util;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace GentlemensMutators
{
	internal static class MutHud
	{
		private static MutHudRunner _runner;

		public static int Index = -1;

		public static int Serial = -1;

		public static float BannerStart = -99f;

		public static float LastInfo = -99f;

		public static void Install()
		{
			MutNet.OnInfo += OnInfo;
			_runner = Kit.Host.AddComponent<MutHudRunner>();
		}

		public static void Uninstall()
		{
			MutNet.OnInfo -= OnInfo;
			if ((Object)(object)_runner != (Object)null)
			{
				Object.Destroy((Object)(object)_runner);
			}
		}

		private static void OnInfo(MutInfo i)
		{
			LastInfo = Time.time;
			if (i.Index < 0)
			{
				Index = -1;
			}
			else if (i.Serial != Serial || i.Index != Index)
			{
				Serial = i.Serial;
				Index = i.Index;
				if (i.Age < 3f)
				{
					BannerStart = Time.time - i.Age;
				}
				MutatorDef mutatorDef = Mutators.ByIndex(i.Index);
				Kit.Log("[mutators] client: " + ((mutatorDef != null) ? mutatorDef.Title : "?") + " (#" + i.Serial + ", age " + i.Age.ToString("0.0") + ")");
			}
		}
	}
	internal class MutHudRunner : MonoBehaviour
	{
		private const float BannerTime = 3.6f;

		private GameObject _canvas;

		private CanvasGroup _banner;

		private CanvasGroup _badge;

		private Image _bannerTop;

		private Image _bannerBottom;

		private Image _badgeStripe;

		private TextMeshProUGUI _title;

		private TextMeshProUGUI _sub;

		private TextMeshProUGUI _badgeText;

		private RectTransform _titleRt;

		private int _shown = -1;

		private int _shownIndex = -1;

		private void Update()
		{
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			MutatorDef mutatorDef = Mutators.ByIndex(MutHud.Index);
			if (mutatorDef == null || !(Time.time - MutHud.LastInfo <= 6f))
			{
				if ((Object)(object)_canvas != (Object)null && _canvas.activeSelf)
				{
					_canvas.SetActive(false);
				}
				return;
			}
			if ((Object)(object)_canvas == (Object)null)
			{
				Build();
			}
			if (!_canvas.activeSelf)
			{
				_canvas.SetActive(true);
			}
			if (_shown != MutHud.Serial || _shownIndex != MutHud.Index)
			{
				_shown = MutHud.Serial;
				_shownIndex = MutHud.Index;
				Fill(mutatorDef);
			}
			float num = Time.time - MutHud.BannerStart;
			bool flag = num >= 0f && num < 3.6f;
			float alpha = (flag ? (Mathf.Clamp01(num / 0.25f) * Mathf.Clamp01((3.6f - num) / 0.5f)) : 0f);
			_banner.alpha = alpha;
			float num2 = (flag ? (1f + 0.3f * Mathf.Max(0f, 1f - num / 0.3f)) : 1f);
			((Transform)_titleRt).localScale = new Vector3(num2, num2, 1f);
			_badge.alpha = (flag ? Mathf.Clamp01((num - 3.1f) / 0.5f) : 1f);
		}

		private void Fill(MutatorDef def)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)_title).text = def.Title.ToUpperInvariant();
			((Graphic)_title).color = def.Tint;
			((TMP_Text)_sub).text = def.Sub;
			((TMP_Text)_badgeText).text = def.Title;
			Image bannerTop = _bannerTop;
			Image bannerBottom = _bannerBottom;
			Color val = (((Graphic)_badgeStripe).color = def.Tint);
			Color color = (((Graphic)bannerBottom).color = val);
			((Graphic)bannerTop).color = color;
		}

		private void Build()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_007e: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0158: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: 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_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			TMP_FontAsset font = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null && ((Object)f).name == "Caprasimo"));
			_canvas = new GameObject("MutatorsHud");
			Object.DontDestroyOnLoad((Object)(object)_canvas);
			Canvas obj = _canvas.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 400;
			CanvasScaler obj2 = _canvas.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 1f;
			RectTransform val = Rect("Banner", _canvas.transform, new Vector2(0f, 0.8f), new Vector2(1f, 0.8f), new Vector2(0f, 180f));
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.6f);
			_banner = ((Component)val).gameObject.AddComponent<CanvasGroup>();
			_banner.blocksRaycasts = false;
			_bannerTop = Stripe(val, 1f);
			_bannerBottom = Stripe(val, 0f);
			Text(val, "ROUND MUTATOR", font, 24f, new Vector2(0f, 62f), Color.white);
			_title = Text(val, "", font, 76f, new Vector2(0f, 4f), Color.white);
			_titleRt = ((TMP_Text)_title).rectTransform;
			_sub = Text(val, "", font, 30f, new Vector2(0f, -58f), Color.white);
			RectTransform val2 = Rect("Badge", _canvas.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(420f, 40f));
			val2.anchoredPosition = new Vector2(0f, -34f);
			((Graphic)((Component)val2).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.5f);
			_badge = ((Component)val2).gameObject.AddComponent<CanvasGroup>();
			_badge.blocksRaycasts = false;
			RectTransform val3 = Rect("Stripe", (Transform)(object)val2, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(6f, 0f));
			val3.pivot = new Vector2(0f, 0.5f);
			_badgeStripe = ((Component)val3).gameObject.AddComponent<Image>();
			_badgeText = Text(val2, "", font, 24f, Vector2.zero, Color.white);
		}

		private static RectTransform Rect(string name, Transform parent, Vector2 min, Vector2 max, Vector2 size)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform;
			((Transform)val).SetParent(parent, false);
			val.anchorMin = min;
			val.anchorMax = max;
			val.sizeDelta = size;
			val.anchoredPosition = Vector2.zero;
			return val;
		}

		private static Image Stripe(RectTransform parent, float y)
		{
			//IL_000c: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)Rect("Stripe", (Transform)(object)parent, new Vector2(0f, y), new Vector2(1f, y), new Vector2(0f, 6f))).gameObject.AddComponent<Image>();
		}

		private static TextMeshProUGUI Text(RectTransform parent, string s, TMP_FontAsset font, float size, Vector2 pos, Color c)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Rect("Text", (Transform)(object)parent, new Vector2(0f, 0.5f), new Vector2(1f, 0.5f), new Vector2(0f, size * 1.4f));
			obj.anchoredPosition = pos;
			TextMeshProUGUI val = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)val).font = font;
			}
			((TMP_Text)val).text = s;
			((TMP_Text)val).fontSize = size;
			((Graphic)val).color = c;
			((TMP_Text)val).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val).enableWordWrapping = false;
			((Graphic)val).raycastTarget = false;
			return val;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_canvas != (Object)null)
			{
				Object.Destroy((Object)(object)_canvas);
			}
		}
	}
	public class MutatorDef
	{
		public string Key;

		public string Title;

		public string Sub;

		public Color Tint;

		public float DamageMul = 1f;

		public float LifeSteal;

		public float Speed;

		public float Gravity;

		public bool Drunk;

		public bool Specialist;

		public float DeathBlastRadius;

		public float DeathBlastDamage;
	}
	public static class Mutators
	{
		public static readonly MutatorDef[] All = new MutatorDef[7]
		{
			new MutatorDef
			{
				Key = "glass",
				Title = "Glass Cannon",
				Sub = "Every hit does 2.5x damage",
				Tint = new Color(1f, 0.35f, 0.3f),
				DamageMul = 2.5f
			},
			new MutatorDef
			{
				Key = "vampires",
				Title = "Vampires",
				Sub = "Heal for half the damage you deal",
				Tint = new Color(1f, 0.3f, 0.45f),
				LifeSteal = 0.5f
			},
			new MutatorDef
			{
				Key = "speed",
				Title = "Speed Demons",
				Sub = "Everyone runs 1.6x faster",
				Tint = new Color(1f, 0.8f, 0.15f),
				Speed = 1.6f
			},
			new MutatorDef
			{
				Key = "moon",
				Title = "Moon Gravity",
				Sub = "Gravity is 40% of normal",
				Tint = new Color(0.6f, 0.75f, 1f),
				Gravity = 0.4f
			},
			new MutatorDef
			{
				Key = "drunk",
				Title = "Happy Hour",
				Sub = "The first round is on the house",
				Tint = new Color(0.95f, 0.6f, 0.15f),
				Drunk = true
			},
			new MutatorDef
			{
				Key = "specialist",
				Title = "Specialists",
				Sub = "Your first pickup is the only one you get this round",
				Tint = new Color(0.4f, 0.9f, 0.5f),
				Specialist = true
			},
			new MutatorDef
			{
				Key = "boom",
				Title = "Explosive Exits",
				Sub = "The fallen go out with a bang",
				Tint = new Color(1f, 0.5f, 0.1f),
				DeathBlastRadius = 4.5f,
				DeathBlastDamage = 35f
			}
		};

		public static MutatorDef ByIndex(int i)
		{
			if (i < 0 || i >= All.Length)
			{
				return null;
			}
			return All[i];
		}

		public static int IndexOf(string key)
		{
			for (int i = 0; i < All.Length; i++)
			{
				if (All[i].Key == key)
				{
					return i;
				}
			}
			return -1;
		}
	}
	public struct MutInfo
	{
		public int Index;

		public int Serial;

		public float Age;
	}
	internal static class MutNet
	{
		private const string Info = "info";

		public static event Action<MutInfo> OnInfo;

		public static void Register()
		{
			if (!Kit.Context.Network.RegisterClientHandler("info", (Action<ModReader>)GotInfo))
			{
				Kit.Warn("[mutators] client message handler not registered");
			}
		}

		private static void GotInfo(ModReader r)
		{
			MutInfo obj = default(MutInfo);
			obj.Index = r.ReadInt();
			obj.Serial = r.ReadInt();
			obj.Age = r.ReadFloat();
			if (MutNet.OnInfo != null)
			{
				MutNet.OnInfo(obj);
			}
		}

		public static void Send(int index, int serial, float age)
		{
			IModNetwork network = Kit.Context.Network;
			if (network.IsServer)
			{
				network.SendToClients("info", (Action<ModWriter>)delegate(ModWriter w)
				{
					w.WriteInt(index);
					w.WriteInt(serial);
					w.WriteFloat(age);
				}, true, true);
			}
		}
	}
	public class Plugin : IModPlugin
	{
		public void OnLoad(IModContext context)
		{
			Kit.Init(context);
			Kit.Try("net", MutNet.Register);
			Kit.Try("server", MutServer.Install);
			Kit.Try("hud", MutHud.Install);
			Kit.Log("loaded " + Mutators.All.Length + " mutators");
		}

		public void OnUnload()
		{
			MutServer.Uninstall();
			MutHud.Uninstall();
			Kit.Shutdown();
		}
	}
	internal static class MutServer
	{
		public static int Active = -1;

		public static int Serial;

		public static int ForceNext = -1;

		public static int Rolls;

		public static int Blasts;

		public static int Gifts;

		private static int _last = -1;

		private static float _rolledAt;

		private static float _nextApply;

		private static float _nextSend;

		private static readonly Random _rng = new Random();

		private static readonly Dictionary<CoreCharacterController, List<int>> _status = new Dictionary<CoreCharacterController, List<int>>();

		private static readonly HashSet<PlayerController> _gifted = new HashSet<PlayerController>();

		private static readonly List<KeyValuePair<PlayerController, HeldPerk>> _given = new List<KeyValuePair<PlayerController, HeldPerk>>();

		private static MutServerRunner _runner;

		public static int TestOverride = -1;

		private static int _optVer = -1;

		private static bool _enabled = true;

		public static MutatorDef Def => Mutators.ByIndex(Active);

		public static bool Enabled
		{
			get
			{
				if (TestOverride >= 0)
				{
					return TestOverride == 1;
				}
				int version = ModOptions.Version;
				if (version != _optVer)
				{
					_optVer = version;
					_enabled = ModOptions.Bool(Kit.ModId, "enabled", fallback: true);
				}
				return _enabled;
			}
		}

		public static void Install()
		{
			Kit.Context.Events.OnRoundStart += OnRoundStart;
			Kit.Context.Events.OnRoundEnd += OnRoundEnd;
			Kit.Context.Events.OnTakeDamage += OnTakeDamage;
			Kit.Context.Events.OnKill += OnKill;
			_runner = Kit.Host.AddComponent<MutServerRunner>();
		}

		public static void Uninstall()
		{
			if (Kit.Context != null)
			{
				Kit.Context.Events.OnRoundStart -= OnRoundStart;
				Kit.Context.Events.OnRoundEnd -= OnRoundEnd;
				Kit.Context.Events.OnTakeDamage -= OnTakeDamage;
				Kit.Context.Events.OnKill -= OnKill;
			}
			Clear();
			if ((Object)(object)_runner != (Object)null)
			{
				Object.Destroy((Object)(object)_runner);
			}
		}

		private static void OnRoundStart(RoundEvent e)
		{
			if (InstanceFinder.IsServerStarted)
			{
				if (!Enabled)
				{
					Kit.Log("[mutators] off (Mod Manager option): no mutator this round");
				}
				else
				{
					Roll();
				}
			}
		}

		private static void OnRoundEnd(RoundEvent e)
		{
			if (InstanceFinder.IsServerStarted)
			{
				Clear();
				MutNet.Send(-1, Serial, 0f);
			}
		}

		public static void Roll()
		{
			int num = Mutators.All.Length;
			int num2;
			if (ForceNext >= 0 && ForceNext < num)
			{
				num2 = ForceNext;
				ForceNext = -1;
			}
			else
			{
				num2 = _rng.Next(num);
				if (num > 1 && num2 == _last)
				{
					num2 = (num2 + 1 + _rng.Next(num - 1)) % num;
				}
			}
			Activate(num2);
		}

		public static void Activate(int idx)
		{
			Clear();
			MutatorDef mutatorDef = Mutators.ByIndex(idx);
			if (mutatorDef != null)
			{
				Active = idx;
				_last = idx;
				Serial++;
				Rolls++;
				_rolledAt = Time.time;
				_nextApply = 0f;
				_nextSend = 0f;
				Kit.Log("[mutators] round mutator: " + mutatorDef.Title + " (#" + Serial + ")");
			}
		}

		public static void Clear()
		{
			foreach (KeyValuePair<CoreCharacterController, List<int>> item in _status)
			{
				if ((Object)(object)item.Key == (Object)null)
				{
					continue;
				}
				StatusEffectController statusEffectController = item.Key.statusEffectController;
				foreach (int item2 in item.Value)
				{
					try
					{
						if ((Object)(object)statusEffectController != (Object)null && statusEffectController.HasStatusEffect(item2))
						{
							statusEffectController.RemoveStatusEffect(item2, false);
						}
					}
					catch (Exception ex)
					{
						Kit.Warn("[mutators] remove status: " + ex.Message);
					}
				}
			}
			_status.Clear();
			_gifted.Clear();
			foreach (KeyValuePair<PlayerController, HeldPerk> item3 in _given)
			{
				try
				{
					SyncList<HeldPerk> val = (((Object)(object)item3.Key != (Object)null) ? item3.Key.PerkInventory : null);
					if (val == null)
					{
						continue;
					}
					if (val.Contains(item3.Value))
					{
						val.Remove(item3.Value);
						continue;
					}
					HeldPerk val2 = null;
					using (IEnumerator<HeldPerk> enumerator4 = item3.Key.GetHeldPerks<AlwaysGetFirstItem>().GetEnumerator())
					{
						if (enumerator4.MoveNext())
						{
							val2 = enumerator4.Current;
						}
					}
					if (val2 != null)
					{
						val.Remove(val2);
					}
				}
				catch (Exception ex2)
				{
					Kit.Warn("[mutators] take back Specialist: " + ex2.Message);
				}
			}
			_given.Clear();
			Active = -1;
		}

		public static void Tick()
		{
			if (Active < 0 || !InstanceFinder.IsServerStarted)
			{
				return;
			}
			if (!Enabled)
			{
				Clear();
				MutNet.Send(-1, Serial, 0f);
				Kit.Log("[mutators] switched off mid-round");
				return;
			}
			MutatorDef def = Def;
			if (Time.time >= _nextSend)
			{
				_nextSend = Time.time + 2f;
				MutNet.Send(Active, Serial, Time.time - _rolledAt);
			}
			if (Time.time < _nextApply)
			{
				return;
			}
			_nextApply = Time.time + 0.5f;
			SessionManager instance = SessionManager.Instance;
			if ((Object)(object)instance == (Object)null || instance.serverPlayers == null)
			{
				return;
			}
			foreach (PlayerController serverPlayer in instance.serverPlayers)
			{
				if ((Object)(object)serverPlayer == (Object)null)
				{
					continue;
				}
				CoreCharacterController val = Players.Char(serverPlayer);
				if (!((Object)(object)val == (Object)null) && val.IsAlive)
				{
					EnsureStatuses(val, def);
					if (def.Specialist && !_gifted.Contains(serverPlayer))
					{
						GiveSpecialist(serverPlayer);
					}
				}
			}
		}

		private static void EnsureStatuses(CoreCharacterController ch, MutatorDef def)
		{
			if (def.Speed <= 0f && def.Gravity <= 0f && !def.Drunk)
			{
				return;
			}
			if (_status.TryGetValue(ch, out var value))
			{
				bool flag = true;
				foreach (int item in value)
				{
					if (!ch.statusEffectController.HasStatusEffect(item))
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					return;
				}
				foreach (int item2 in value)
				{
					try
					{
						if (ch.statusEffectController.HasStatusEffect(item2))
						{
							ch.statusEffectController.RemoveStatusEffect(item2, false);
						}
					}
					catch (Exception)
					{
					}
				}
			}
			value = new List<int>();
			_status[ch] = value;
			if (def.Speed > 0f)
			{
				Add(ch, (StatusEffect)13, def.Speed, value);
			}
			if (def.Gravity > 0f)
			{
				Add(ch, (StatusEffect)4, def.Gravity, value);
			}
			if (def.Drunk)
			{
				Add(ch, (StatusEffect)0, 1f, value);
			}
		}

		private unsafe static void Add(CoreCharacterController ch, StatusEffect effect, float value, List<int> ids)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_001b: 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)
			try
			{
				StatusEffectController statusEffectController = ch.statusEffectController;
				int nextStatusEffectId = statusEffectController.GetNextStatusEffectId();
				StatusEffectData val = new StatusEffectData();
				val.Id = nextStatusEffectId;
				val.Effect = effect;
				val.Value = value;
				val.Owner = (NetworkBehaviour)(object)ch;
				val.RemoveAfterTime = false;
				statusEffectController.AddStatusEffect(nextStatusEffectId, val);
				ids.Add(nextStatusEffectId);
			}
			catch (Exception ex)
			{
				Kit.Warn("[mutators] status " + ((object)(*(StatusEffect*)(&effect))/*cast due to .constrained prefix*/).ToString() + ": " + ex.Message);
			}
		}

		private static void GiveSpecialist(PlayerController pc)
		{
			_gifted.Add(pc);
			try
			{
				if (pc.HasPerk<AlwaysGetFirstItem>())
				{
					return;
				}
				Perk val = Kit.FindPerk("AlwaysGetFirstItem");
				IModPlayer val2 = Adapter(pc);
				if ((Object)(object)val == (Object)null || val2 == null)
				{
					Kit.Warn("[mutators] specialist: perk " + ((Object)(object)val != (Object)null) + ", adapter " + (val2 != null));
				}
				else
				{
					if (!Kit.Context.TryGivePerk(val2, val))
					{
						return;
					}
					foreach (HeldPerk heldPerk in pc.GetHeldPerks<AlwaysGetFirstItem>())
					{
						_given.Add(new KeyValuePair<PlayerController, HeldPerk>(pc, heldPerk));
					}
					Gifts++;
				}
			}
			catch (Exception ex)
			{
				Kit.Warn("[mutators] TryGivePerk: " + ex.Message);
			}
		}

		private static void OnTakeDamage(DamageEvent e)
		{
			MutatorDef def = Def;
			if (def == null || !InstanceFinder.IsServerStarted)
			{
				return;
			}
			if (def.DamageMul != 1f)
			{
				e.Damage *= def.DamageMul;
			}
			if (def.LifeSteal > 0f && e.Attacker != null && e.Damage > 0f)
			{
				PlayerController val = Players.Pc(e.Attacker);
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)Players.Pc(e.Victim))
				{
					Players.Heal(val, e.Damage * def.LifeSteal);
				}
			}
		}

		private static void OnKill(KillEvent e)
		{
			MutatorDef def = Def;
			if (def != null && !(def.DeathBlastRadius <= 0f) && InstanceFinder.IsServerStarted)
			{
				PlayerController pc = Players.Pc(e.Victim);
				CoreCharacterController val = Players.Char(pc);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)_runner == (Object)null))
				{
					((MonoBehaviour)_runner).StartCoroutine(DeathBlast(pc, val, def, Serial));
				}
			}
		}

		private static IEnumerator DeathBlast(PlayerController pc, CoreCharacterController ch, MutatorDef def, int serial)
		{
			yield return (object)new WaitForSeconds(0.8f);
			if (serial != Serial || Active < 0 || (Object)(object)ch == (Object)null || (Object)(object)pc == (Object)null)
			{
				yield break;
			}
			Vector3 position = ((Component)ch).transform.position;
			try
			{
				Rigidbody val = (((Object)(object)ch.Model != (Object)null) ? ch.Model.rootRigidbody : null);
				if ((Object)(object)val != (Object)null)
				{
					position = val.position;
				}
			}
			catch (Exception)
			{
			}
			ExplosionManager instance = ExplosionManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Kit.Warn("[mutators] no ExplosionManager");
				yield break;
			}
			instance.CreateExplosion(position, pc, (Item)null, def.DeathBlastRadius, def.DeathBlastDamage, (GameObject)null, true, true, default(GUID), (List<CoreCharacterController>)null, false, (ThrownItem)null);
			Blasts++;
			Kit.Log("[mutators] death blast at " + ((Vector3)(ref position)).ToString("F1"));
		}

		private static IModPlayer Adapter(PlayerController pc)
		{
			Type type = ((object)pc).GetType().Assembly.GetType("AGD.Modding.ModPlayerAdapter");
			if (type == null)
			{
				return null;
			}
			object? obj = Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new object[1] { pc }, null);
			return (IModPlayer)((obj is IModPlayer) ? obj : null);
		}
	}
	internal class MutServerRunner : MonoBehaviour
	{
		private void Update()
		{
			try
			{
				MutServer.Tick();
			}
			catch (Exception ex)
			{
				Kit.Warn("[mutators] tick: " + ex.Message);
			}
		}
	}
}
namespace AGDKit
{
	public static class Anim
	{
		public static class Slots
		{
			public const string Idle = "root|Idle-NonOrnate";

			public const string Move = "root|ForwardMovement(ArmsTest2)";

			public const string Aim = "Aiming_NoItem";

			public const string Use = "Using_NoItem";

			public const string UsePhase2 = "UsingPhase2_NoItem";

			public const string UsePhase3 = "UsingPhase3_NoItem";
		}

		public static AnimationClip Clip(string itemName, string slot)
		{
			Item val = Kit.FindItem(itemName);
			if ((Object)(object)val == (Object)null || (Object)(object)val.OverrideController == (Object)null)
			{
				Kit.Warn("Anim.Clip: no item/controller " + itemName);
				return null;
			}
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
			val.OverrideController.GetOverrides(list);
			foreach (KeyValuePair<AnimationClip, AnimationClip> item in list)
			{
				if ((Object)(object)item.Key != (Object)null && ((Object)item.Key).name == slot)
				{
					return item.Value ?? item.Key;
				}
			}
			Kit.Warn("Anim.Clip: slot " + slot + " not found on " + itemName);
			return null;
		}

		public static AnimatorOverrideController Override(AnimatorOverrideController baseOc, Dictionary<string, AnimationClip> slots, string name)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			AnimatorOverrideController val = new AnimatorOverrideController(baseOc.runtimeAnimatorController);
			((Object)val).name = name;
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
			baseOc.GetOverrides(list);
			for (int i = 0; i < list.Count; i++)
			{
				if ((Object)(object)list[i].Key != (Object)null && slots.TryGetValue(((Object)list[i].Key).name, out var value) && (Object)(object)value != (Object)null)
				{
					list[i] = new KeyValuePair<AnimationClip, AnimationClip>(list[i].Key, value);
				}
			}
			val.ApplyOverrides((IList<KeyValuePair<AnimationClip, AnimationClip>>)list);
			foreach (string s in slots.Keys)
			{
				if (!list.Any((KeyValuePair<AnimationClip, AnimationClip> p) => (Object)(object)p.Key != (Object)null && ((Object)p.Key).name == s))
				{
					Kit.Warn("Anim.Override: unknown slot " + s);
				}
			}
			return val;
		}
	}
	public class Spin : MonoBehaviour
	{
		public Vector3 Axis = Vector3.up;

		public float Speed = 360f;

		private void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.Rotate(Axis, Speed * Time.deltaTime, (Space)1);
		}
	}
	public class Bob : MonoBehaviour
	{
		public Vector3 Direction = Vector3.up;

		public float Amplitude = 0.05f;

		public float Frequency = 1.5f;

		private Vector3 _start;

		private void Awake()
		{
			//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)
			_start = ((Component)this).transform.localPosition;
		}

		private void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localPosition = _start + Direction * Mathf.Sin(Time.time * Frequency * (float)Math.PI * 2f) * Amplitude;
		}
	}
	public class Glow : MonoBehaviour
	{
		public Color Color = Color.cyan;

		public float Min = 0.5f;

		public float Max = 2f;

		public float Frequency = 1f;

		private Material _m;

		private void Awake()
		{
			Renderer component = ((Component)this).GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				_m = component.material;
				_m.EnableKeyword("_EMISSION");
			}
		}

		private void Update()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_m == (Object)null))
			{
				float num = Mathf.Lerp(Min, Max, 0.5f + 0.5f * Mathf.Sin(Time.time * Frequency * (float)Math.PI * 2f));
				_m.SetColor("_EmissionColor", Color * num);
			}
		}
	}
	public static class Lights
	{
		public static Light Point(Transform parent, Color color, float intensity = 1.5f, float range = 3f)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Light");
			val.transform.SetParent(parent, false);
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = color;
			obj.intensity = intensity;
			obj.range = range;
			obj.shadows = (LightShadows)0;
			return obj;
		}
	}
	public static class Art
	{
		private static readonly Dictionary<string, Texture2D> _tex = new Dictionary<string, Texture2D>();

		public static Texture2D Texture(string relative, bool linear = false)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			if (_tex.TryGetValue(relative, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			string text = Kit.Asset(relative);
			if (!File.Exists(text))
			{
				Kit.Warn("missing texture " + text);
				return null;
			}
			value = new Texture2D(2, 2, (TextureFormat)4, true, linear);
			ImageConversion.LoadImage(value, File.ReadAllBytes(text), false);
			((Object)value).name = Path.GetFileNameWithoutExtension(text);
			((Texture)value).wrapMode = (TextureWrapMode)0;
			((Texture)value).filterMode = (FilterMode)2;
			((Texture)value).anisoLevel = 4;
			_tex[relative] = value;
			return value;
		}

		public static Sprite Sprite(string relative, float pixelsPerUnit = 50f)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = Texture(relative);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), pixelsPerUnit);
			((Object)obj).name = ((Object)val).name;
			return obj;
		}

		public static Texture2D ReadableCopy(Sprite src)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007e: 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_009d: Expected O, but got Unknown
			Rect val;
			try
			{
				val = src.textureRect;
			}
			catch
			{
				val = src.rect;
			}
			Texture2D texture = src.texture;
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Graphics.Blit((Texture)(object)texture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			int num = Mathf.RoundToInt(((Rect)(ref val)).width);
			int num2 = Mathf.RoundToInt(((Rect)(ref val)).height);
			Texture2D val2 = new Texture2D(num, num2, (TextureFormat)4, false);
			val2.ReadPixels(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, (float)num, (float)num2), 0, 0);
			val2.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return val2;
		}

		public static Sprite Recolor(Sprite src, Color tint, string name)
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)src == (Object)null)
			{
				return null;
			}
			Texture2D val = ReadableCopy(src);
			Color[] pixels = val.GetPixels();
			for (int i = 0; i < pixels.Length; i++)
			{
				Color val2 = pixels[i];
				float num = Mathf.Max(val2.r, Mathf.Max(val2.g, val2.b)) * 0.6f + (val2.r + val2.g + val2.b) / 3f * 0.4f;
				Color val3 = Color.Lerp(val2, new Color(tint.r * num * 1.35f, tint.g * num * 1.35f, tint.b * num * 1.35f), 0.7f);
				val3.a = val2.a;
				pixels[i] = val3;
			}
			val.SetPixels(pixels);
			val.Apply();
			((Object)val).name = name;
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), src.pixelsPerUnit);
			((Object)obj).name = name;
			return obj;
		}

		public static void SavePng(Texture2D t, string path)
		{
			Directory.CreateDirectory(Path.GetDirectoryName(path));
			File.WriteAllBytes(path, ImageConversion.EncodeToPNG(t));
		}
	}
	public static class Bundles
	{
		private static readonly Dictionary<string, AssetBundle> _loaded = new Dictionary<string, AssetBundle>();

		public static BundleRef Load(string relative)
		{
			if (!_loaded.TryGetValue(relative, out var value) || (Object)(object)value == (Object)null)
			{
				string text = Kit.Asset(relative);
				if (!File.Exists(text))
				{
					Kit.Warn("missing bundle " + text);
					return new BundleRef(null);
				}
				string want = Path.GetFileName(text).ToLowerInvariant();
				value = AssetBundle.GetAllLoadedAssetBundles().FirstOrDefault((Func<AssetBundle, bool>)((AssetBundle x) => ((Object)x).name == want)) ?? AssetBundle.LoadFromFile(text);
				if ((Object)(object)value == (Object)null)
				{
					Kit.Warn("could not load bundle " + text + " (built with a different Unity version?)");
					return new BundleRef(null);
				}
				if (_loaded.Count == 0)
				{
					Kit.OnShutdown(delegate
					{
						foreach (AssetBundle value2 in _loaded.Values)
						{
							if ((Object)(object)value2 != (Object)null)
							{
								value2.Unload(false);
							}
						}
						_loaded.Clear();
					});
				}
				_loaded[relative] = value;
			}
			return new BundleRef(value);
		}
	}
	public class BundleRef
	{
		public readonly AssetBundle Bundle;

		public BundleRef(AssetBundle b)
		{
			Bundle = b;
		}

		public T Asset<T>(string name) where T : Object
		{
			if ((Object)(object)Bundle == (Object)null)
			{
				return default(T);
			}
			T val = Bundle.LoadAsset<T>(name);
			if ((Object)(object)val == (Object)null)
			{
				Kit.Warn("bundle " + ((Object)Bundle).name + " has no " + typeof(T).Name + " '" + name + "'. Contains: " + string.Join(", ", Bundle.GetAllAssetNames()));
			}
			return val;
		}

		public GameObject Prefab(string name)
		{
			GameObject val = this.Asset<GameObject>(name);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, Kit.Templates);
			((Object)val2).name = name;
			Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val3 in componentsInChildren)
			{
				Material[] sharedMaterials = val3.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					sharedMaterials[j] = FixMaterial(sharedMaterials[j]);
				}
				val3.sharedMaterials = sharedMaterials;
			}
			return val2;
		}

		public static Material FixMaterial(Material m)
		{
			//IL_00ee: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m == (Object)null || (Object)(object)m.shader == (Object)null)
			{
				return m;
			}
			Shader val = Shader.Find(((Object)m.shader).name);
			if (!(((Object)m.shader).name == "Standard") && !((Object)m.shader).name.StartsWith("Standard (") && !((Object)m.shader).name.StartsWith("Legacy Shaders/") && !((Object)m.shader).name.StartsWith("Mobile/") && !((Object)m.shader).name.StartsWith("Autodesk") && (Object)(object)val != (Object)null && val.isSupported)
			{
				m.shader = val;
				return m;
			}
			Color color = (m.HasProperty("_BaseColor") ? m.GetColor("_BaseColor") : (m.HasProperty("_Color") ? m.GetColor("_Color") : Color.white));
			Texture val2 = (m.HasProperty("_BaseMap") ? m.GetTexture("_BaseMap") : (m.HasProperty("_MainTex") ? m.GetTexture("_MainTex") : null));
			float metallic = (m.HasProperty("_Metallic") ? m.GetFloat("_Metallic") : 0f);
			float smoothness = (m.HasProperty("_Smoothness") ? m.GetFloat("_Smoothness") : (m.HasProperty("_Glossiness") ? m.GetFloat("_Glossiness") : 0.3f));
			Color emission = ((m.IsKeywordEnabled("_EMISSION") && m.HasProperty("_EmissionColor")) ? m.GetColor("_EmissionColor") : Color.black);
			Material val3 = Models.Material(color, null, smoothness, metallic, emission);
			if ((Object)(object)val2 != (Object)null)
			{
				val3.SetTexture("_BaseMap", val2);
			}
			((Object)val3).name = ((Object)m).name + " (URP)";
			Kit.Log("bundle material '" + ((Object)m).name + "' used " + ((Object)m.shader).name + " -> converted to URP/Lit");
			return val3;
		}

		public AnimationClip Clip(string name)
		{
			return this.Asset<AnimationClip>(name);
		}

		public Texture2D Texture(string name)
		{
			return this.Asset<Texture2D>(name);
		}

		public Sprite Sprite(string name)
		{
			return this.Asset<Sprite>(name);
		}
	}
	public static class Kit
	{
		private static readonly List<Action> _cleanup = new List<Action>();

		private static GameObject _host;

		public static IModContext Context { get; private set; }

		public static string ModId { get; private set; }

		public static string Root { get; private set; }

		public static string DataDir { get; private set; }

		public static GameObject Host
		{
			get
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Expected O, but got Unknown
				if ((Object)(object)_host == (Object)null)
				{
					_host = new GameObject("AGDKit_" + ModId);
					Object.DontDestroyOnLoad((Object)(object)_host);
				}
				return _host;
			}
		}

		public static Transform Templates
		{
			get
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				Transform val = Host.transform.Find("Templates");
				if ((Object)(object)val == (Object)null)
				{
					GameObject val2 = new GameObject("Templates");
					val2.SetActive(false);
					val2.transform.SetParent(Host.transform, false);
					val = val2.transform;
				}
				return val;
			}
		}

		public static GameDesignData Design => GameSingleton.GameDesignData;

		public static void Init(IModContext context)
		{
			Context = context;
			ModId = context.ModId;
			Root = context.InstallPath;
			DataDir = Path.Combine(Path.Combine(Application.persistentDataPath, "ModData"), ModId);
			Directory.CreateDirectory(DataDir);
			_cleanup.Clear();
		}

		public static void Shutdown()
		{
			for (int num = _cleanup.Count - 1; num >= 0; num--)
			{
				try
				{
					_cleanup[num]();
				}
				catch (Exception ex)
				{
					Error("cleanup: " + ex);
				}
			}
			_cleanup.Clear();
			if ((Object)(object)_host != (Object)null)
			{
				Object.Destroy((Object)(object)_host);
			}
			_host = null;
		}

		public static void OnShutdown(Action a)
		{
			_cleanup.Add(a);
		}

		public static string Asset(string relative)
		{
			return Path.Combine(Path.Combine(Root, "assets"), relative.Replace('/', Path.DirectorySeparatorChar));
		}

		public static Item FindItem(string name)
		{
			return ((IEnumerable<Item>)Design.itemList).FirstOrDefault((Func<Item, bool>)((Item i) => (Object)(object)i != (Object)null && ((Object)i).name == name));
		}

		public static Perk FindPerk(string name)
		{
			return ((IEnumerable<Perk>)Design.perks).FirstOrDefault((Func<Perk, bool>)((Perk p) => (Object)(object)p != (Object)null && ((Object)p).name == name));
		}

		public static ItemTag Tag(string name)
		{
			return ((IEnumerable<ItemTag>)Design.itemTagList).FirstOrDefault((Func<ItemTag, bool>)((ItemTag t) => (Object)(object)t != (Object)null && ((Object)t).name == name));
		}

		public static void Log(string msg)
		{
			Debug.Log((object)("[" + ModId + "] " + msg));
		}

		public static void Warn(string msg)
		{
			Debug.LogWarning((object)("[" + ModId + "] " + msg));
		}

		public static void Error(string msg)
		{
			Debug.LogError((object)("[" + ModId + "] " + msg));
		}

		public static void Try(string what, Action fn)
		{
			try
			{
				fn();
			}
			catch (Exception ex)
			{
				Error(what + " failed: " + ex);
			}
		}
	}
	public static class Reflect
	{
		private const BindingFlags F = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly Dictionary<KeyValuePair<Type, string>, FieldInfo> FieldCache = new Dictionary<KeyValuePair<Type, string>, FieldInfo>();

		private static FieldInfo Field(Type type, string name)
		{
			KeyValuePair<Type, string> key = new KeyValuePair<Type, string>(type, name);
			if (FieldCache.TryGetValue(key, out var value))
			{
				return value;
			}
			Type type2 = type;
			while (type2 != null && value == null)
			{
				value = type2.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				type2 = type2.BaseType;
			}
			FieldCache[key] = value;
			return value;
		}

		public static bool Has(object o, string field)
		{
			if (o != null)
			{
				return Field(o.GetType(), field) != null;
			}
			return false;
		}

		public static void Set(object o, string field, object value)
		{
			FieldInfo fieldInfo = Field(o.GetType(), field);
			if (fieldInfo == null)
			{
				Kit.Warn("no field " + o.GetType().Name + "." + field);
				return;
			}
			if (value != null && !fieldInfo.FieldType.IsInstanceOfType(value))
			{
				value = Convert.ChangeType(value, fieldInfo.FieldType);
			}
			fieldInfo.SetValue(o, value);
		}

		public static T Get<T>(object o, string field)
		{
			FieldInfo fieldInfo = ((o == null) ? null : Field(o.GetType(), field));
			if (!(fieldInfo == null))
			{
				return (T)fieldInfo.GetValue(o);
			}
			return default(T);
		}

		public static object Call(object o, string method, params object[] args)
		{
			Type type = o.GetType();
			while (type != null)
			{
				MethodInfo methodInfo = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo x) => x.Name == method && x.GetParameters().Length == args.Length);
				if (methodInfo != null)
				{
					return methodInfo.Invoke(o, args);
				}
				type = type.BaseType;
			}
			throw new MissingMethodException(o.GetType().Name, method);
		}
	}
	public static class Models
	{
		private static Material _base;

		public static Material Material(Color color, string texture = null, float smoothness = 0.3f, float metallic = 0f, Color emission = default(Color), string normalMap = null)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_base == (Object)null)
			{
				Item val = Kit.FindItem("Sword");
				Renderer val2 = (((Object)(object)val != (Object)null) ? ((IEnumerable<Renderer>)val.prefab.GetComponentsInChildren<Renderer>(true)).FirstOrDefault((Func<Renderer, bool>)((Renderer x) => (Object)(object)x.sharedMaterial != (Object)null && ((Object)x.sharedMaterial.shader).name == "Universal Render Pipeline/Lit")) : null);
				_base = (Material)(((Object)(object)val2 != (Object)null) ? ((object)val2.sharedMaterial) : ((object)new Material(Shader.Find("Universal Render Pipeline/Lit"))));
			}
			Material val3 = new Material(_base);
			((Object)val3).name = "kit_" + ColorUtility.ToHtmlStringRGB(color);
			val3.SetTexture("_BaseMap", (Texture)(object)((texture != null) ? Art.Texture(texture) : null));
			val3.SetColor("_BaseColor", color);
			val3.SetTexture("_MetallicGlossMap", (Texture)null);
			val3.DisableKeyword("_METALLICSPECGLOSSMAP");
			val3.SetFloat("_Metallic", metallic);
			val3.SetFloat("_Smoothness", smoothness);
			val3.DisableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A");
			if (normalMap != null)
			{
				val3.SetTexture("_BumpMap", (Texture)(object)Art.Texture(normalMap, linear: true));
				val3.EnableKeyword("_NORMALMAP");
			}
			else
			{
				val3.SetTexture("_BumpMap", (Texture)null);
				val3.DisableKeyword("_NORMALMAP");
			}
			if (((Color)(ref emission)).maxColorComponent > 0f)
			{
				val3.EnableKeyword("_EMISSION");
				val3.SetColor("_EmissionColor", emission);
				val3.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
			}
			return val3;
		}

		public static List<Renderer> WeaponRenderers(GameObject prefab)
		{
			HashSet<Transform> debug = DebugObjects(prefab);
			return (from r in prefab.GetComponentsInChildren<Renderer>(true)
				where (r is MeshRenderer || r is SkinnedMeshRenderer) && ActiveInPrefab(((Component)r).transform, prefab.transform) && !r.sharedMaterials.Any((Material m) => (Object)(object)m != (Object)null && (Object)(object)m.shader != (Object)null && ((Object)m.shader).name.Contains("Ghost")) && !PathContains(((Component)r).transform, prefab.transform, "Aim Indicator") && !UnderAny(((Component)r).transform, prefab.transform, debug)
				select r).ToList();
		}

		public static HashSet<Transform> DebugObjects(GameObject prefab)
		{
			HashSet<Transform> hashSet = new HashSet<Transform>();
			MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				while (type != null && type != typeof(MonoBehaviour))
				{
					FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (fieldInfo.Name.IndexOf("debug", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							object? value = fieldInfo.GetValue(val);
							Transform val2 = (Transform)((value is Transform) ? value : null);
							GameObject val3 = (GameObject)((value is GameObject) ? value : null);
							if ((Object)(object)val2 != (Object)null)
							{
								hashSet.Add(val2);
							}
							else if ((Object)(object)val3 != (Object)null)
							{
								hashSet.Add(val3.transform);
							}
						}
					}
					type = type.BaseType;
				}
			}
			return hashSet;
		}

		private static bool ActiveInPrefab(Transform t, Transform root)
		{
			while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)root)
			{
				if (!((Component)t).gameObject.activeSelf)
				{
					return false;
				}
				t = t.parent;
			}
			return true;
		}

		private static bool UnderAny(Transform t, Transform root, HashSet<Transform> set)
		{
			while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)root)
			{
				if (set.Contains(t))
				{
					return true;
				}
				t = t.parent;
			}
			return false;
		}

		private static bool PathContains(Transform t, Transform root, string name)
		{
			while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)root)
			{
				if (((Object)t).name.Contains(name))
				{
					return true;
				}
				t = t.parent;
			}
			return false;
		}

		public static void Tint(IEnumerable<Renderer> renderers, Color tint)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			foreach (Renderer renderer in renderers)
			{
				Material[] sharedMaterials = renderer.sharedMaterials;
				for (int i = 0; i < sharedMaterials.Length; i++)
				{
					if ((Object)(object)sharedMaterials[i] == (Object)null)
					{
						continue;
					}
					Material val = new Material(sharedMaterials[i]);
					string[] array = new string[2] { "_BaseColor", "_Color" };
					foreach (string text in array)
					{
						if (val.HasProperty(text))
						{
							val.SetColor(text, val.GetColor(text) * tint);
						}
					}
					sharedMaterials[i] = val;
				}
				renderer.sharedMaterials = sharedMaterials;
			}
		}

		public static void ReplaceVisual(GameObject prefab, GameObject model, bool fit)
		{
			//IL_00e2: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: 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_01c3: 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_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: 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_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: 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_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			List<Renderer> list = WeaponRenderers(prefab);
			List<GameObject> list2 = SeasonalVariants(prefab);
			foreach (GameObject item in list2)
			{
				Renderer[] componentsInChildren = item.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if ((val is MeshRenderer || val is SkinnedMeshRenderer) && !list.Contains(val))
					{
						list.Add(val);
					}
				}
			}
			if (list.Count == 0)
			{
				Kit.Warn("ReplaceVisual: no visible renderers on " + ((Object)prefab).name);
				model.transform.SetParent(prefab.transform, false);
				return;
			}
			Renderer val2 = list.OrderByDescending(delegate(Renderer r)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				if (!((Object)(object)MeshOf(r) != (Object)null))
				{
					return 0f;
				}
				Bounds bounds = MeshOf(r).bounds;
				Vector3 size2 = ((Bounds)(ref bounds)).size;
				return ((Vector3)(ref size2)).sqrMagnitude * Lossy(((Component)r).transform);
			}).First();
			Transform val3 = ((val2 is SkinnedMeshRenderer && (Object)(object)((SkinnedMeshRenderer)val2).rootBone != (Object)null) ? ((SkinnedMeshRenderer)val2).rootBone : ((Component)val2).transform);
			Bounds val4 = (Bounds)(((Object)(object)MeshOf(val2) != (Object)null) ? MeshOf(val2).bounds : new Bounds(Vector3.zero, Vector3.one));
			foreach (Renderer item2 in list)
			{
				item2.enabled = false;
				MeshFilter component = ((Component)item2).GetComponent<MeshFilter>();
				if ((Object)(object)component != (Object)null)
				{
					component.sharedMesh = null;
				}
				SkinnedMeshRenderer val5 = (SkinnedMeshRenderer)(object)((item2 is SkinnedMeshRenderer) ? item2 : null);
				if ((Object)(object)val5 != (Object)null)
				{
					val5.sharedMesh = null;
				}
			}
			model.transform.SetParent(val3, false);
			if (fit)
			{
				Bounds val6 = LocalBounds(model);
				Vector3 size = ((Bounds)(ref val4)).size;
				Vector3 val7 = ((size.x >= size.y && size.x >= size.z) ? Vector3.right : ((size.y >= size.z) ? Vector3.up : Vector3.forward));
				float num = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
				float num2 = Mathf.Max(((Bounds)(ref val6)).size.y, 0.0001f);
				model.transform.localRotation = Quaternion.FromToRotation(Vector3.up, val7);
				model.transform.localScale = Vector3.one * (num / num2);
				Vector3 val8 = model.transform.localRotation * (((Bounds)(ref val6)).center * (num / num2));
				model.transform.localPosition = ((Bounds)(ref val4)).center - val8;
			}
			Transform val9 = null;
			foreach (GameObject item3 in list2)
			{
				if ((Object)(object)val3 == (Object)(object)item3.transform || val3.IsChildOf(item3.transform))
				{
					val9 = item3.transform;
				}
			}
			if ((Object)(object)val9 != (Object)null)
			{
				model.transform.SetParent(val9.parent, true);
			}
		}

		private static List<GameObject> SeasonalVariants(GameObject root)
		{
			List<GameObject> list = new List<GameObject>();
			GameObjectEventOverride[] componentsInChildren = root.GetComponentsInChildren<GameObjectEventOverride>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				IList list2 = Reflect.Get<IList>(componentsInChildren[i], "overrides");
				if (list2 == null)
				{
					continue;
				}
				foreach (object item in list2)
				{
					FieldInfo field = item.GetType().GetField("value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					GameObject val = (GameObject)((field != null) ? /*isinst with value type is only supported in some contexts*/: null);
					if ((Object)(object)val != (Object)null && !list.Contains(val))
					{
						list.Add(val);
					}
				}
			}
			return list;
		}

		private static float Lossy(Transform t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Vector3 lossyScale = t.lossyScale;
			return lossyScale.x * lossyScale.y * lossyScale.z;
		}

		private static Mesh MeshOf(Renderer r)
		{
			SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null);
			if ((Object)(object)val != (Object)null)
			{
				return val.sharedMesh;
			}
			MeshFilter component = ((Component)r).GetComponent<MeshFilter>();
			if (!((Object)(object)component != (Object)null))
			{
				return null;
			}
			return component.sharedMesh;
		}

		public static Bounds LocalBounds(GameObject root)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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)
			//IL_00a7: 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_00ae: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds result = default(Bounds);
			Matrix4x4 worldToLocalMatrix = root.transform.worldToLocalMatrix;
			MeshFilter[] componentsInChildren = root.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null)
				{
					continue;
				}
				Matrix4x4 val2 = worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				Bounds bounds = val.sharedMesh.bounds;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
					Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3);
					if (!flag)
					{
						((Bounds)(ref result))..ctor(val4, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val4);
					}
				}
			}
			return result;
		}

		public static GameObject LoadObj(string relative, Dictionary<string, Material> materials = null)
		{
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			//IL_0136: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Expected O, but got Unknown
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			string path = Kit.Asset(relative);
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<Vector3> list3 = new List<Vector3>();
			List<Vector3> list4 = new List<Vector3>();
			List<Vector2> list5 = new List<Vector2>();
			List<Vector3> list6 = new List<Vector3>();
			List<KeyValuePair<string, List<int>>> list7 = new List<KeyValuePair<string, List<int>>>();
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			string text = null;
			List<int> list8 = null;
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length == 0 || text2[0] == '#')
				{
					continue;
				}
				string[] array2 = text2.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
				switch (array2[0])
				{
				case "v":
					list.Add(new Vector3(0f - float.Parse(array2[1], invariantCulture), float.Parse(array2[2], invariantCulture), float.Parse(array2[3], invariantCulture)));
					break;
				case "vt":
					list2.Add(new Vector2(float.Parse(array2[1], invariantCulture), float.Parse(array2[2], invariantCulture)));
					break;
				case "vn":
					list3.Add(new Vector3(0f - float.Parse(array2[1], invariantCulture), float.Parse(array2[2], invariantCulture), float.Parse(array2[3], invariantCulture)));
					break;
				case "mtllib":
					text = text2.Substring(7).Trim();
					break;
				case "usemtl":
					list8 = new List<int>();
					list7.Add(new KeyValuePair<string, List<int>>((array2.Length > 1) ? array2[1] : "default", list8));
					break;
				case "f":
				{
					if (list8 == null)
					{
						list8 = new List<int>();
						list7.Add(new KeyValuePair<string, List<int>>("default", list8));
					}
					List<int> list9 = new List<int>();
					for (int j = 1; j < array2.Length; j++)
					{
						if (!dictionary.TryGetValue(array2[j], out var value))
						{
							string[] array3 = array2[j].Split('/');
							list4.Add(list[Ix(array3[0], list.Count)]);
							list5.Add((array3.Length > 1 && array3[1].Length > 0) ? list2[Ix(array3[1], list2.Count)] : Vector2.zero);
							list6.Add((array3.Length > 2 && array3[2].Length > 0) ? list3[Ix(array3[2], list3.Count)] : Vector3.zero);
							value = list4.Count - 1;
							dictionary[array2[j]] = value;
						}
						list9.Add(value);
					}
					for (int k = 1; k + 1 < list9.Count; k++)
					{
						list8.Add(list9[0]);
						list8.Add(list9[k + 1]);
						list8.Add(list9[k]);
					}
					break;
				}
				}
			}
			Mesh val = new Mesh();
			((Object)val).name = Path.GetFileNameWithoutExtension(path);
			if (list4.Count > 65000)
			{
				val.indexFormat = (IndexFormat)1;
			}
			val.SetVertices(list4);
			val.SetUVs(0, list5);
			val.subMeshCount = list7.Count;
			for (int l = 0; l < list7.Count; l++)
			{
				val.SetTriangles(list7[l].Value, l);
			}
			if (list3.Count > 0)
			{
				val.SetNormals(list6);
			}
			else
			{
				val.RecalculateNormals();
			}
			val.RecalculateTangents();
			val.RecalculateBounds();
			Dictionary<string, Material> mtl = ((text != null) ? ParseMtl(Path.Combine(Path.GetDirectoryName(relative) ?? "", text)) : new Dictionary<string, Material>());
			GameObject val2 = new GameObject(((Object)val).name);
			val2.transform.SetParent(Kit.Templates, false);
			val2.AddComponent<MeshFilter>().sharedMesh = val;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = ((IEnumerable<KeyValuePair<string, List<int>>>)list7).Select((Func<KeyValuePair<string, List<int>>, Material>)delegate(KeyValuePair<string, List<int>> s)
			{
				//IL_0038: 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: Unknown result type (might be due to invalid IL or missing references)
				if (materials != null && materials.TryGetValue(s.Key, out var value2))
				{
					return value2;
				}
				return mtl.TryGetValue(s.Key, out value2) ? value2 : Material(Color.gray);
			}).ToArray();
			return val2;
		}

		private static int Ix(string s, int count)
		{
			int num = int.Parse(s);
			if (num >= 0)
			{
				return num - 1;
			}
			return count + num;
		}

		private static Dictionary<string, Material> ParseMtl(string relative)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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)
			Dictionary<string, Material> result = new Dictionary<string, Material>();
			string path = Kit.Asset(relative);
			if (!File.Exists(path))
			{
				return result;
			}
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			string name = null;
			Color kd = Color.white;
			Color ke = Color.black;
			string map = null;
			float pm = 0f;
			float pr = 0.7f;
			Action action = delegate
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				if (name != null)
				{
					result[name] = Material(kd, map, 1f - pr, pm, ke);
				}
			};
			string[] array = File.ReadAllLines(path);
			for (int num = 0; num < array.Length; num++)
			{
				string[] array2 = array[num].Trim().Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length != 0)
				{
					switch (array2[0])
					{
					case "newmtl":
						action();
						name = array2[1];
						kd = Color.white;
						ke = Color.black;
						map = null;
						pm = 0f;
						pr = 0.7f;
						break;
					case "Kd":
						kd = new Color(float.Parse(array2[1], invariantCulture), float.Parse(array2[2], invariantCulture), float.Parse(array2[3], invariantCulture));
						break;
					case "Ke":
						ke = new Color(float.Parse(array2[1], invariantCulture), float.Parse(array2[2], invariantCulture), float.Parse(array2[3], invariantCulture));
						break;
					case "Pm":
						pm = float.Parse(array2[1], invariantCulture);
						break;
					case "Pr":
						pr = float.Parse(array2[1], invariantCulture);
						break;
					case "map_Kd":
						map = Path.Combine(Path.GetDirectoryName(relative) ?? "", array2[^1]).Replace('\\', '/');
						break;
					}
				}
			}
			action();
			return result;
		}
	}
	public class ModelBuilder
	{
		public readonly GameObject Root;

		public ModelBuilder(string name)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			Root = new GameObject(name);
			Root.transform.SetParent(Kit.Templates, false);
		}

		public Transform Add(PrimitiveType type, Material mat, Vector3 position, Vector3 scale, Vector3 euler = default(Vector3), Transform parent = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(type);
			Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>());
			obj.transform.SetParent(parent ?? Root.transform, false);
			obj.transform.localPosition = position;
			obj.transform.localEulerAngles = euler;
			obj.transform.localScale = scale;
			obj.GetComponent<Renderer>().sharedMaterial = mat;
			return obj.transform;
		}

		public Transform Box(Material m, Vector3 pos, Vector3 size, Vector3 euler = default(Vector3))
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Add((PrimitiveType)3, m, pos, size, euler);
		}

		public Transform Cylinder(Material m, Vector3 pos, float height, float diameter, Vector3 euler = default(Vector3))
		{
			//IL_0003: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			return Add((PrimitiveType)2, m, pos, new Vector3(diameter, height * 0.5f, diameter), euler);
		}

		public Transform Sphere(Material m, Vector3 pos, float diameter)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			return Add((PrimitiveType)0, m, pos, Vector3.one * diameter);
		}

		public Transform Ellipsoid(Material m, Vector3 pos, Vector3 size, Vector3 euler = default(Vector3))
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Add((PrimitiveType)0, m, pos, size, euler);
		}

		public Transform Capsule(Material m, Vector3 pos, float height, float diameter, Vector3 euler = default(Vector3))
		{
			//IL_0003: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			return Add((PrimitiveType)1, m, pos, new Vector3(diameter, height * 0.5f, diameter), euler);
		}

		public Transform Mesh(GameObject meshObject, Vector3 position, Vector3 scale, Vector3 euler = default(Vector3))
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			meshObject.transform.SetParent(Root.transform, false);
			meshObject.transform.localPosition = position;
			meshObject.transform.localEulerAngles = euler;
			meshObject.transform.localScale = scale;
			return meshObject.transform;
		}

		public GameObject Build()
		{
			return Root;
		}
	}
	public static class ModPerks
	{
		public static PerkBuilder<T> New<T>(string id) where T : Perk
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			T val = ScriptableObject.CreateInstance<T>();
			Perk val2 = Kit.FindPerk("Extra Health") ?? Kit.Design.perks.First((Perk x) => (Object)(object)x != (Object)null);
			((Perk)val).availability = val2.availability;
			((Perk)val).chanceModifier = val2.chanceModifier;
			((Perk)val).valueCategory = (PerkValueCategory)0;
			((Perk)val).perkCategory = (PerkCategory)6;
			return new PerkBuilder<T>(id, val);
		}

		public static PerkBuilder<T> Clone<T>(string basePerkName, string id) where T : Perk
		{
			Perk obj = Kit.FindPerk(basePerkName);
			T val = (T)(object)((obj is T) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException("No base perk '" + basePerkName + "' of type " + typeof(T).Name);
			}
			PerkBuilder<T> perkBuilder = new PerkBuilder<T>(id, Object.Instantiate<T>(val));
			((Perk)perkBuilder.Perk).icon = ((Perk)val).icon;
			return perkBuilder;
		}
	}
	public class PerkBuilder<T> where T : Perk
	{
		public readonly string Id;

		public readonly T Perk;

		private string _title;

		private string _desc;

		public PerkBuilder(string id, T perk)
		{
			Id = id;
			Perk = perk;
			_title = id;
			_desc = "";
		}

		public PerkBuilder<T> Title(string t)
		{
			_title = t;
			return this;
		}

		public PerkBuilder<T> Desc(string d)
		{
			_desc = d;
			return this;
		}

		public PerkBuilder<T> Value(PerkValueCategory v)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			((Perk)Perk).valueCategory = v;
			return this;
		}

		public PerkBuilder<T> Category(PerkCategory c)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			((Perk)Perk).perkCategory = c;
			return this;
		}

		public PerkBuilder<T> Chance(float c)
		{
			((Perk)Perk).chanceModifier = c;
			return this;
		}

		public PerkBuilder<T> Consumable(bool c)
		{
			((Perk)Perk).isConsumable = c;
			return this;
		}

		public PerkBuilder<T> Icon(string relative)
		{
			Sprite val = Art.Sprite(relative, 100f);
			if ((Object)(object)val != (Object)null)
			{
				((Perk)Perk).icon = val;
			}
			return this;
		}

		public PerkBuilder<T> Icon(Sprite s)
		{
			((Perk)Perk).icon = s;
			return this;
		}

		public PerkBuilder<T> IconFrom(string perkName, Color tint)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Perk val = Kit.FindPerk(perkName);
			if ((Object)(object)val != (Object)null)
			{
				((Perk)Perk).icon = Art.Recolor(val.icon, tint, "icon_" + Id);
			}
			return this;
		}

		public PerkBuilder<T> Configure(Action<T> fn)
		{
			fn(Perk);
			return this;
		}

		public T Register()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			((Object)(object)Perk).name = Kit.ModId + "_" + Id;
			((Perk)Perk).dontIncludeInPool = false;
			Kit.Context.RegisterPerk(Id, (ScriptableObject)(object)Perk, new ModPerkMetadata
			{
				Title = _title,
				Description = _desc
			});
			return Perk;
		}
	}
	public static class Players
	{
		public static PlayerController Pc(IModPlayer p)
		{
			if (p != null)
			{
				return Reflect.Get<PlayerController>(p, "_player");
			}
			return null;
		}

		public static CoreCharacterController Char(IModPlayer p)
		{
			return Char(Pc(p));
		}

		public static CoreCharacterController Char(PlayerController pc)
		{
			CoreCharacterController result = default(CoreCharacterController);
			if (!((Object)(object)pc != (Object)null) || !pc.TryGetTargetCharacter(ref result))
			{
				return null;
			}
			return result;
		}

		public static int Count<T>(PlayerController pc) where T : Perk
		{
			if (!((Object)(object)pc == (Object)null))
			{
				return pc.GetPerks<T>().Count();
			}
			return 0;
		}

		public static int Count<T>(IModPlayer p) where T : Perk
		{
			return Count<T>(Pc(p));
		}

		public static void Flash<T>(PlayerController pc) where T : Perk
		{
			if ((Object)(object)pc == (Object)null)
			{
				return;
			}
			try
			{
				T val = pc.GetPerks<T>().FirstOrDefault();
				if ((Object)(object)val != (Object)null)
				{
					pc.ActivatePerk((Perk)(object)val, false);
				}
			}
			catch
			{
			}
		}

		public static void Heal(PlayerController pc, float amount)
		{
			CoreCharacterController val = Char(pc);
			if ((Object)(object)val != (Object)null && val.IsAlive && ((NetworkBehaviour)val).IsServerInitialized)
			{
				val.Heal(amount, true);
			}
		}

		public static Vector3 Position(PlayerController pc)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			CoreCharacterController val = Char(pc);
			if (!((Object)(object)val != (Object)null))
			{
				return Vector3.zero;
			}
			return ((Component)val).transform.position;
		}
	}
	public static class ModWeapons
	{
		private static readonly List<Item> _added = new List<Item>();

		private static bool _hooked;

		public static IList<Item> Registered => _added;

		public static WeaponBuilder Clone(string baseItemName, string id)
		{
			Item val = Kit.FindItem(baseItemName);
			if ((Object)(object)val == (Object)null || (Object)(object)val.prefab == (Object)null)
			{
				throw new ArgumentException("No base item '" + baseItemName + "' with a held prefab");
			}
			if (!_hooked)
			{
				_hooked = true;
				Kit.OnShutdown(delegate
				{
					foreach (Item item in _added)
					{
						Kit.Design.itemList.Remove(item);
					}
					_added.Clear();
					_hooked = false;
				});
			}
			return new WeaponBuilder(val, id);
		}

		internal static void Add(Item item)
		{
			Kit.Design.itemList.Add(item);
			_added.Add(item);
		}
	}
	public class WeaponBuilder
	{
		public readonly Item Base;

		public readonly Item Item;

		public readonly GameObject Prefab;

		public readonly GameObject PedestalPrefab;

		private readonly string _id;

		private readonly List<Action<GameObject, bool>> _looks = new List<Action<GameObject, bool>>();

		public WeaponBuilder(Item src, string id)
		{
			Base = src;
			_id = id;
			Prefab = Object.Instantiate<GameObject>(src.prefab, Kit.Templates);
			((Object)Prefab).name = Kit.ModId + "_" + id;
			Item = Object.Instantiate<Item>(src);
			((Object)Item).name = Kit.ModId + "_" + id;
			Item.prefab = Prefab;
			if ((Object)(object)src.pedestalPrefab != (Object)null)
			{
				PedestalPrefab = Object.Instantiate<GameObject>(src.pedestalPrefab, Kit.Templates);
				((Object)PedestalPrefab).name = Kit.ModId + "_" + id + "_pedestal";
				Item.pedestalPrefab = PedestalPrefab;
			}
		}

		public WeaponBuilder Stat(string componentType, string field, object value)
		{
			Component val = Component(componentType);
			if ((Object)(object)val == (Object)null)
			{
				Kit.Warn(_id + ": no component " + componentType + " on " + ((Object)Base).name);
			}
			else
			{
				Reflect.Set(val, field, value);
			}
			return this;
		}

		public Component Component(string typeName)
		{
			return ((IEnumerable<Component>)Prefab.GetComponentsInChildren<Component>(true)).FirstOrDefault((Func<Component, bool>)((Component x) => (Object)(object)x != (Object)null && ((object)x).GetType().Name == typeName));
		}

		public WeaponBuilder Grip(Vector3 deltaPos, Vector3 deltaEuler)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0028: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0043: 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)
			Quaternion val = Quaternion.Euler(deltaEuler);
			int num = 0;
			foreach (Transform item in Prefab.transform)
			{
				Transform val2 = item;
				val2.localPosition = val * val2.localPosition + deltaPos;
				val2.localRotation = val * val2.localRotation;
				num++;
			}
			if (num == 0)
			{
				Kit.Warn(_id + ": held prefab of " + ((Object)Base).name + " has no child to move, Grip ignored");
			}
			return this;
		}

		public WeaponBuilder SpawnChance(float multiplierOfBase)
		{
			Item.spawnChanceMultiplier = Base.spawnChanceMultiplier * multiplierOfBase;
			return this;
		}

		public WeaponBuilder MaxPerRound(int n)
		{
			Item.maxPerRound = n;
			return this;
		}

		public WeaponBuilder Configure(Action<Item, GameObject> fn)
		{
			fn(Item, Prefab);
			return this;
		}

		public WeaponBuilder Look(Action<GameObject, bool> fn)
		{
			fn(Prefab, arg2: false);
			_looks.Add(fn);
			return this;
		}

		public WeaponBuilder Scale(float s)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			Prefab.transform.localScale = Base.prefab.transform.localScale * s;
			_looks.Add(delegate(GameObject go, bool isDrop)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if (!isDrop)
				{
					Transform transform = go.transform;
					transform.localScale *= s;
				}
			});
			return this;
		}

		public WeaponBuilder Tint(Color c)
		{
			//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)
			return Look(delegate(GameObject go, bool isDrop)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				Models.Tint(Models.WeaponRenderers(go), c);
			});
		}

		public WeaponBuilder Icon(string relative)
		{
			Sprite val = Art.Sprite(relative);
			if ((Object)(object)val != (Object)null)
			{
				Item.icon = val;
			}
			return this;
		}

		public WeaponBuilder IconTint(Color c)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Item.icon = Art.Recolor(Base.icon, c, ((Object)Item).name);
			return this;
		}

		public WeaponBuilder Model(GameObject model, bool fit = true)
		{
			GameObject source = Object.Instantiate<GameObject>(model, Kit.Templates);
			((Object)source).name = ((Object)model).name + "_source";
			Models.ReplaceVisual(Prefab, model, fit);
			_looks.Add(delegate(GameObject go, bool isDrop)
			{
				Models.ReplaceVisual(go, Object.Instantiate<GameObject>(source, Kit.Templates), fit);
			});
			return this;
		}

		public WeaponBuilder Animations(Dictionary<string, AnimationClip> slots)
		{
			Item.OverrideController = Anim.Override(Base.OverrideController, slots, ((Object)Item).name);
			foreach (KeyValuePair<string, AnimationClip> slot in slots)
			{
				string text = slot.Key.Replace("root|", "").Replace("(", "").Replace(")", "");
				Preview.Animation(_id + "_" + text, slot.Value, Item);
				Preview.Animation(_id + "_" + text + "_base", Anim.Clip(((Object)Base).name, slot.Key), Base);
			}
			return this;
		}

		public WeaponBuilder UseSound(string relative, float volume = 1f, float pitchJitter = 0.08f)
		{
			PlaySoundOnUse playSoundOnUse = Prefab.AddComponent<PlaySoundOnUse>();
			playSoundOnUse.Sound = relative;
			playSoundOnUse.Volume = volume;
			playSoundOnUse.PitchJitter = pitchJitter;
			return this;
		}

		private static void ProtectTemplate(GameObject template)
		{
			if ((Object)(object)template.GetComponent<ClearHideFlagsOnSpawn>() == (Object)null)
			{
				template.AddComponent<ClearHideFlagsOnSpawn>();
			}
			Transform[] componentsInChildren = template.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Object)((Component)componentsInChildren[i]).gameObject).hideFlags = (HideFlags)52;
			}
		}

		public Item Register()
		{
			if ((Object)(object)PedestalPrefab != (Object)null)
			{
				foreach (Action<GameObject, bool> look in _looks)
				{
					look(PedestalPrefab, arg2: false);
				}
			}
			if ((Object)(object)Base.dropPrefab != (Object)null && _looks.Count > 0)
			{
				Prefab.AddComponent<ExpiryWatcher>().Item = Item;
				DropSkinner.Register(Item, ((Object)Base.dropPrefab).name, _looks);
			}
			ProtectTemplate(Prefab);
			if ((Object)(object)PedestalPrefab != (Object)null)
			{
				ProtectTemplate(PedestalPrefab);
			}
			ModWeapons.Add(Item);
			Kit.Log("weapon " + ((Object)Item).name + " (from " + ((Object)Base).name + ")");
			return Item;
		}
	}
	public class ClearHideFlagsOnSpawn : MonoBehaviour
	{
		private void Awake()
		{
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Object)((Component)componentsInChildren[i]).gameObject).hideFlags = (HideFlags)0;
			}
			Object.Destroy((Object)(object)this);
		}
	}
	public class PlaySoundOnUse : MonoBehaviour
	{
		public string Sound;

		public float Volume = 1f;

		public float PitchJitter = 0.08f;

		public string State = "Using";

		private unsafe void Awake()
		{
			HeldItem componentInChildren = ((Component)this).GetComponentInChildren<HeldItem>();
			if ((Object)(object)componentInChildren == (Object)null || componentInChildren.onUseStateChange == null)
			{
				return;
			}
			componentInChildren.onUseStateChange.AddListener((UnityAction<ItemUseState, ItemUseState>)delegate(ItemUseState prev, ItemUseState next)
			{
				//IL_0026: 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)
				if (((object)(*(ItemUseState*)(&next))/*cast due to .constrained prefix*/).ToString() == State)
				{
					Sfx.Play(Sound, ((Component)this).transform.position, Volume, 1f + Random.Range(0f - PitchJitter, PitchJitter));
				}
			});
		}
	}
	public class ExpiryWatcher : MonoBehaviour
	{
		public Item Item;

		private static bool _quitting;

		private void OnApplicationQuit()
		{
			_quitting = true;
		}

		private void OnDestroy()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!_quitting && (Object)(object)Item != (Object)null)
			{
				DropSkinner.Report(Item, ((Component)this).transform.position);
			}
		}
	}
	public class DropSkinner : MonoBehaviour
	{
		private class Rule
		{
			public string DropName;

			public List<Action<GameObject, bool>> Looks;
		}

		private class Pending
		{
			public Item Item;

			public Vector3 Pos;

			public float Time;
		}

		private static readonly Dictionary<Item, Rule> _rules = new Dictionary<Item, Rule>();

		private static readonly List<Pending> _pending = new List<Pending>();

		private static readonly HashSet<int> _done = new HashSet<int>();

		private static DropSkinner _instance;

		private float _next;

		internal static void Register(Item item, string dropPrefabName, List<Action<GameObject, bool>> looks)
		{
			_rules[item] = new Rule
			{
				DropName = dropPrefabName,
				Looks = looks
			};
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = Kit.Host.AddComponent<DropSkinner>();
				Kit.OnShutdown(delegate
				{
					_rules.Clear();
					_pending.Clear();
					_done.Clear();
					_instance = null;
				});
			}
		}

		internal static void Report(Item item, Vector3 pos)
		{
			//IL_001f: 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)
			if (_rules.ContainsKey(item))
			{
				_pending.Add(new Pending
				{
					Item = item,
					Pos = pos,
					Time = Time.time
				});
			}
		}

		private void Update()
		{
			//IL_00e2: 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)
			if (_pending.Count == 0 || Time.time < _next)
			{
				return;
			}
			_next = Time.time + 0.05f;
			_pending.RemoveAll((Pending p) => Time.time - p.Time > 1.5f);
			if (_pending.Count == 0)
			{
				return;
			}
			ItemDrop[] array = Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0);
			foreach (ItemDrop val in array)
			{
				if ((Object)(object)val == (Object)null || _done.Contains(((Object)val).GetInstanceID()))
				{
					continue;
				}
				Pending pending = null;
				float num2 = 3f;
				foreach (Pending item in _pending)
				{
					Rule rule = _rules[item.Item];
					if (((Object)val).name.StartsWith(rule.DropName))
					{
						float num3 = Vector3.Distance(((Component)val).transform.position, item.Pos);
						if (num3 < num2)
						{
							num2 = num3;
							pending = item;
						}
					}
				}
				if (pending == null)
				{
					continue;
				}
				_done.Add(((Object)val).GetInstanceID());
				_pending.Remove(pending);
				GameObject gameObject = ((Component)val).gameObject;
				foreach (Action<GameObject, bool> look in _rules[pending.Item].Looks)
				{
					try
					{
						look(gameObject, arg2: true);
					}
					catch (Exception ex)
					{
						Kit.Warn("drop re-skin " + ((Object)pending.Item).name + ": " + ex.Message);
					}
				}
			}
		}
	}
	public static class Preview
	{
		private class AnimEntry
		{
			public string Label;

			public AnimationClip Clip;

			public Item Item;
		}

		private class PreviewRunner : MonoBehaviour
		{
			private class Rig
			{
				public GameObject Stage;

				public GameObject Copy;

				public Animator Anim;

				public HumanPoseHandler Handler;

				public HumanPose Pose;

				public Transform Mount;

				public Bounds Box;

				public float Scale;

				public void Destroy()
				{
					if (Handler != null)
					{
						Handler.Dispose();
					}
					Object.Destroy((Object)(object)Stage);
				}
			}

			private static bool _requestsTaken;

			private string _dir;

			private static bool _mountRead;

			private static string _mountBone;

			private static Vector3 _mountPos;

			private static Quaternion _mountRot = Quaternion.identity;

			private static Vector3 _mountScale = Vector3.one;

			private IEnumerator Start()
			{
				yield return null;
				yield return null;
				_dir = Path.Combine(Kit.DataDir, "preview");
				if (Directory.Exists(_dir))
				{
					string[] files = Directory.GetFiles(_dir, "*.png");
					for (int i = 0; i < files.Length; i++)
					{
						File.Delete(files[i]);
					}
				}
				Directory.CreateDirectory(_dir);
				foreach (Perk p in SessionContentRegistry.ModPerkList)
				{
					if (!((Object)(object)p == (Object)null) && ((Object)p).name.StartsWith(Kit.ModId + "_") && !((Object)(object)p.icon == (Object)null))
					{
						Kit.Try("preview icon " + ((Object)p).name, delegate
						{
							Art.SavePng(Art.ReadableCopy(p.icon), Path.Combine(_dir, "perk_" + ((Object)p).name + ".png"));
						});
					}
				}
				foreach (Item item in ModWeapons.Registered)
				{
					Item it = item;
					if ((Object)(object)it.icon != (Object)null)
					{
						Kit.Try("preview icon " + ((Object)it).name, delegate
						{
							Art.SavePng(Art.ReadableCopy(it.icon), Path.Combine(_dir, "icon_" + ((Object)it).name + ".png"));
						});
					}
					Vector3[] sides = (Vector3[])(object)new Vector3[2]
					{
						new Vector3(1f, 0.35f, -0.6f),
						new Vector3(0f, 0f, -1f)
					};
					for (int v = 0; v < sides.Length; v++)
					{
						string file = Path.Combine(_dir, "model_" + ((Object)it).name + "_" + v + ".png");
						foreach (object item2 in Safe("preview " + ((Object)it).name, RenderModel(it.prefab, sides[v], weaponOnly: true, delegate(Texture2D t)
						{
							Art.SavePng(t, file);
						})))
						{
							yield return item2;
						}
					}
					if (!((Object)(object)it.pedestalPrefab != (Object)null))
					{
						continue;
					}
					string file2 = Path.Combine(_dir, "pedestal_" + ((Object)it).name + ".png");
					foreach (object item3 in Safe("preview pedestal " + ((Object)it).name, RenderModel(it.pedestalPrefab, sides[0], weaponOnly: false, delegate(Texture2D t)
					{
						Art.SavePng(t, file2);
					})))
					{
						yield return item3;
					}
				}
				Animator rig = FindCharacter();
				if (_anims.Count > 0 && (Object)(object)rig == (Object)null)
				{
					Kit.Warn("preview: no humanoid character model found for animation filmstrips");
				}
				if ((Object)(object)rig != (Object)null)
				{
					foreach (AnimEntry anim in _anims)
					{
						string file3 = Path.Combine(_dir, "anim_" + anim.Label + ".png");
						AnimEntry animEntry = anim;
						foreach (object item4 in Safe("preview anim " + anim.Label, RenderClip(rig, animEntry.Clip, animEntry.Item, delegate(Texture2D t)
						{
							Art.SavePng(t, file3);
						})))
						{
							yield return item4;
						}
					}
				}
				if (!_requestsTaken && (Object)(object)rig != (Object)null && AppDomain.CurrentDomain.GetData("AGDKit.PreviewRequestsTaken") == null)
				{
					_requestsTaken = true;
					AppDomain.CurrentDomain.SetData("AGDKit.PreviewRequestsTaken", Kit.ModId);
					string[] array = File.ReadAllLines(FlagPath);
					if (array.Any((string l) => l.Contains("=")))
					{
						Directory.CreateDirectory(RequestDir);
					}
					string[] array2 = array;
					foreach (string text in array2)
					{
						int num = text.IndexOf('=');
						if (num < 0)
						{
							continue;
						}
						string text2 = text.Substring(0, num);
						string text3 = text.Substring(num + 1).Trim();
						switch (text2)
						{
						case "spec":
						{
							string text4 = text3;
							string name = null;
							if (text3.Contains("|"))
							{
								text4 = text3.Split('|')[0];
								name = text3.Split('|')[1];
							}
							string file5 = Path.Combine(RequestDir, "spec_" + Path.GetFileName(text4).Replace(".anim.json", "") + ".png");
							foreach (object item5 in Safe("preview spec " + text4, RenderSpec(rig, text4, FindAnyItem(name), delegate(Texture2D t)
							{
								Art.SavePng(t, file5);
							})))
							{
								yield return item5;
							}
							break;
						}
						case "muscles":
						{
							string file4 = Path.Combine(RequestDir, "muscles_" + text3.Split(',')[0].Trim().Replace(" ", "") + ".png");
							foreach (object item6 in Safe("preview muscles", RenderMuscleSheet(rig, (from m in text3.Split(',')
								select m.Trim()).ToArray(), delegate(Texture2D t)
							{
								Art.SavePng(t, file4);
							})))
							{
								yield return item6;
							}
							break;
						}
						case "dumpclip":
							foreach (object item7 in Safe("dump clip " + text3, DumpClip(rig, text3)))
							{
								yield return item7;
							}
							break;
						}
					}
					Kit.Log("preview requests written to " + RequestDir);
				}
				Kit.Log("preview done " + _dir);
				Object.Destroy((Object)(object)this);
			}

			private static Item FindAnyItem(string name)
			{
				if (st