Decompiled source of Cano ContentTools v1.0.1

Cano.ContentTools.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GUIFramework;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Cano.ContentTools")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("Cano.ContentTools")]
[assembly: AssemblyTitle("Cano.ContentTools")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace Cano.ContentTools
{
	internal enum ActorKind
	{
		Creature,
		Item
	}
	internal sealed class ActorEntry
	{
		public string Prefab;

		public string Name;

		public string Info;

		public ActorKind Kind;

		public bool Free;

		public bool Walk;

		public ActorEntry Alias;

		public GameObject Go;

		public ActorEntry Eff => Alias ?? this;

		public string Key => ((Kind == ActorKind.Creature) ? "c:" : "i:") + Prefab + (Walk ? ":walk" : "");
	}
	internal sealed class ActorAction
	{
		public string Id;

		public string Label;

		public KeyCode Key;

		public KeyCode Default;

		public bool Special;

		public int Slot;

		public bool Secondary;

		public ItemDrop Weapon;

		public bool GpAlone;

		public EffectList Sound;

		public ActorAction Mod;

		public bool IsMod;
	}
	internal static class ActorCatalog
	{
		private static List<ActorEntry> _all;

		private static ZNetScene _built;

		public static List<ActorEntry> All
		{
			get
			{
				if (_all == null || (Object)(object)_built != (Object)(object)ZNetScene.instance)
				{
					Build();
				}
				return _all;
			}
		}

		public static string Clean(string raw, string fallback)
		{
			string text = raw;
			try
			{
				if (!string.IsNullOrEmpty(raw) && Localization.instance != null)
				{
					text = Localization.instance.Localize(raw);
				}
			}
			catch
			{
			}
			if (string.IsNullOrEmpty(text))
			{
				return fallback;
			}
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = false;
			string text2 = text;
			foreach (char c in text2)
			{
				switch (c)
				{
				case '<':
					flag = true;
					continue;
				case '>':
					flag = false;
					continue;
				}
				if (!flag)
				{
					stringBuilder.Append(c);
				}
			}
			text = stringBuilder.ToString().Trim();
			if (text.Length == 0 || text[0] == '$' || text[0] == '[')
			{
				return fallback;
			}
			return text;
		}

		public static string Split(string camel)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < camel.Length; i++)
			{
				if (i > 0 && char.IsUpper(camel[i]) && !char.IsUpper(camel[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(camel[i]);
			}
			return stringBuilder.ToString();
		}

		private static void Build()
		{
			_all = new List<ActorEntry>();
			_built = ZNetScene.instance;
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			try
			{
				foreach (string prefabName in ZNetScene.instance.GetPrefabNames())
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
					if ((Object)(object)prefab == (Object)null)
					{
						continue;
					}
					Character component = prefab.GetComponent<Character>();
					if (!((Object)(object)component == (Object)null) && !((Object)(object)prefab.GetComponent<Player>() != (Object)null) && !((Object)(object)prefab.GetComponent<ZNetView>() == (Object)null))
					{
						string text = "Faction: " + Split(((object)Unsafe.As<Faction, Faction>(ref component.m_faction)/*cast due to .constrained prefix*/).ToString());
						if (!string.IsNullOrEmpty(component.m_group))
						{
							text = text + "   Group: " + component.m_group;
						}
						if (component.m_boss)
						{
							text += "   Boss";
						}
						_all.Add(new ActorEntry
						{
							Prefab = prefabName,
							Name = Clean(component.m_name, prefabName),
							Info = text,
							Kind = ActorKind.Creature,
							Go = prefab
						});
					}
				}
				GameObject prefab2 = ZNetScene.instance.GetPrefab("odin");
				if ((Object)(object)prefab2 != (Object)null && (Object)(object)prefab2.GetComponent<Odin>() != (Object)null)
				{
					_all.Add(new ActorEntry
					{
						Prefab = "odin",
						Name = "Odin",
						Info = "The ghost of Odin   Flies freely, nothing can touch him",
						Kind = ActorKind.Creature,
						Free = true,
						Go = prefab2
					});
				}
				if ((Object)(object)prefab2 != (Object)null && (Object)(object)prefab2.GetComponent<Odin>() != (Object)null)
				{
					_all.Add(new ActorEntry
					{
						Prefab = "odin",
						Name = "Odin (Walking)",
						Info = "Odin on his feet   Walks and runs on the ground like a player",
						Kind = ActorKind.Creature,
						Free = true,
						Walk = true,
						Go = prefab2
					});
				}
				foreach (string prefabName2 in ZNetScene.instance.GetPrefabNames())
				{
					GameObject prefab3 = ZNetScene.instance.GetPrefab(prefabName2);
					if ((Object)(object)prefab3 == (Object)null)
					{
						continue;
					}
					Raven componentInChildren = prefab3.GetComponentInChildren<Raven>(true);
					Valkyrie component2 = prefab3.GetComponent<Valkyrie>();
					if ((Object)(object)componentInChildren == (Object)null && (Object)(object)component2 == (Object)null)
					{
						continue;
					}
					if ((Object)(object)componentInChildren != (Object)null)
					{
						string name = (componentInChildren.m_isMunin ? "Munin" : (prefabName2.ToLower().Contains("munin") ? "Munin" : "Hugin"));
						if (prefabName2.ToLower().Contains("hugin"))
						{
							name = "Hugin";
						}
						_all.Add(new ActorEntry
						{
							Prefab = prefabName2,
							Name = name,
							Info = "Odin's raven   Flies freely, nothing can touch it",
							Kind = ActorKind.Creature,
							Free = true,
							Go = prefab3
						});
					}
					else
					{
						_all.Add(new ActorEntry
						{
							Prefab = prefabName2,
							Name = "Valkyrie",
							Info = "Carries new players into the world   Flies freely",
							Kind = ActorKind.Creature,
							Free = true,
							Go = prefab3
						});
					}
				}
				foreach (string prefabName3 in ZNetScene.instance.GetPrefabNames())
				{
					GameObject prefab4 = ZNetScene.instance.GetPrefab(prefabName3);
					if (!((Object)(object)prefab4 == (Object)null))
					{
						Trader component3 = prefab4.GetComponent<Trader>();
						if (!((Object)(object)component3 == (Object)null) && !((Object)(object)prefab4.GetComponent<Character>() != (Object)null))
						{
							_all.Add(new ActorEntry
							{
								Prefab = prefabName3,
								Name = Clean(component3.m_name, prefabName3),
								Info = "Trader   Walks and runs on the ground like a player",
								Kind = ActorKind.Creature,
								Free = true,
								Walk = true,
								Go = prefab4
							});
						}
					}
				}
				try
				{
					bool flag = false;
					bool flag2 = false;
					foreach (ActorEntry item in _all)
					{
						if (item.Name == "Valkyrie")
						{
							flag = true;
						}
						if (item.Name == "Hugin" || item.Name == "Munin")
						{
							flag2 = true;
						}
					}
					Player localPlayer = Player.m_localPlayer;
					if (!flag && (Object)(object)localPlayer != (Object)null)
					{
						FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_valkyrie");
						object obj = ((fieldInfo != null) ? fieldInfo.GetValue(localPlayer) : null);
						GameObject val = null;
						if (obj != null)
						{
							MethodInfo method = obj.GetType().GetMethod("Load", Type.EmptyTypes);
							if (method != null)
							{
								method.Invoke(obj, null);
							}
							PropertyInfo property = obj.GetType().GetProperty("Asset");
							if (property != null)
							{
								object? value = property.GetValue(obj, null);
								val = (GameObject)((value is GameObject) ? value : null);
							}
							else
							{
								FieldInfo field = obj.GetType().GetField("Asset");
								if (field != null)
								{
									object? value2 = field.GetValue(obj);
									val = (GameObject)((value2 is GameObject) ? value2 : null);
								}
							}
						}
						if ((Object)(object)val != (Object)null)
						{
							_all.Add(new ActorEntry
							{
								Prefab = ((Object)val).name,
								Name = "Valkyrie",
								Info = "Carries new players into the world   Flies freely",
								Kind = ActorKind.Creature,
								Free = true,
								Go = val
							});
						}
					}
					if (!flag2 && (Object)(object)Tutorial.instance != (Object)null && (Object)(object)Tutorial.instance.m_ravenPrefab != (Object)null)
					{
						GameObject ravenPrefab = Tutorial.instance.m_ravenPrefab;
						_all.Add(new ActorEntry
						{
							Prefab = ((Object)ravenPrefab).name,
							Name = "Hugin",
							Info = "Odin's raven   Flies freely, nothing can touch it",
							Kind = ActorKind.Creature,
							Free = true,
							Go = ravenPrefab
						});
					}
				}
				catch (Exception ex)
				{
					Plugin.Warn("Ravens / Valkyrie could not be listed: " + ex.Message);
				}
				ActorEntry actorEntry = _all.Find((ActorEntry x) => x.Name == "Hugin");
				ActorEntry actorEntry2 = _all.Find((ActorEntry x) => x.Name == "Munin");
				if (actorEntry != null && actorEntry2 == null)
				{
					_all.Add(new ActorEntry
					{
						Prefab = actorEntry.Prefab,
						Name = "Munin",
						Info = actorEntry.Info,
						Kind = ActorKind.Creature,
						Free = true,
						Go = actorEntry.Go
					});
				}
				else if (actorEntry2 != null && actorEntry == null)
				{
					_all.Add(new ActorEntry
					{
						Prefab = actorEntry2.Prefab,
						Name = "Hugin",
						Info = actorEntry2.Info,
						Kind = ActorKind.Creature,
						Free = true,
						Go = actorEntry2.Go
					});
				}
				HashSet<string> hashSet = new HashSet<string>();
				if ((Object)(object)ObjectDB.instance != (Object)null)
				{
					foreach (GameObject item2 in ObjectDB.instance.m_items)
					{
						ItemDrop val2 = (((Object)(object)item2 != (Object)null) ? item2.GetComponent<ItemDrop>() : null);
						PieceTable val3 = (((Object)(object)val2 != (Object)null && val2.m_itemData != null && val2.m_itemData.m_shared != null) ? val2.m_itemData.m_shared.m_buildPieces : null);
						if ((Object)(object)val3 == (Object)null)
						{
							continue;
						}
						foreach (GameObject piece in val3.m_pieces)
						{
							if (!((Object)(object)piece == (Object)null) && hashSet.Add(((Object)piece).name))
							{
								Piece component4 = piece.GetComponent<Piece>();
								GameObject prefab5 = ZNetScene.instance.GetPrefab(((Object)piece).name);
								if (!((Object)(object)component4 == (Object)null) && !((Object)(object)prefab5 == (Object)null))
								{
									_all.Add(new ActorEntry
									{
										Prefab = ((Object)piece).name,
										Name = Clean(component4.m_name, ((Object)piece).name),
										Info = "Build piece   Category: " + Split(((object)Unsafe.As<PieceCategory, PieceCategory>(ref component4.m_category)/*cast due to .constrained prefix*/).ToString()),
										Kind = ActorKind.Item,
										Go = prefab5
									});
								}
							}
						}
					}
				}
			}
			catch (Exception ex2)
			{
				Plugin.Warn("Could not list everything for The Paid Actor: " + ex2.Message);
			}
			ActorEntry actorEntry3 = _all.Find((ActorEntry x) => x.Kind == ActorKind.Creature && !x.Free && (Object)(object)x.Go != (Object)null && x.Prefab.IndexOf("dummy", StringComparison.OrdinalIgnoreCase) >= 0 && (Object)(object)x.Go.GetComponent<Character>() != (Object)null && (int)x.Go.GetComponent<Character>().m_faction == 12);
			if (actorEntry3 != null)
			{
				foreach (ActorEntry item3 in _all)
				{
					if (item3.Kind == ActorKind.Item && item3.Prefab.IndexOf("TrainingDummy", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						item3.Alias = actorEntry3;
					}
				}
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (ActorEntry item4 in _all)
			{
				dictionary.TryGetValue(item4.Kind.ToString() + item4.Name, out var value3);
				dictionary[item4.Kind.ToString() + item4.Name] = value3 + 1;
			}
			foreach (ActorEntry item5 in _all)
			{
				if (dictionary[item5.Kind.ToString() + item5.Name] > 1 && !item5.Name.Contains(item5.Prefab))
				{
					item5.Name = item5.Name + " (" + item5.Prefab + ")";
				}
			}
			Plugin.Dbg("The Paid Actor: " + _all.Count + " things listed.");
		}
	}
	internal static class ActorFavs
	{
		private static HashSet<string> _set;

		private static string FilePath => Path.Combine(Plugin.LocalDir, "actor_favourites.txt");

		private static void Load()
		{
			_set = new HashSet<string>();
			try
			{
				if (!File.Exists(FilePath))
				{
					return;
				}
				string[] array = File.ReadAllLines(FilePath);
				foreach (string text in array)
				{
					if (text.Trim().Length > 0)
					{
						_set.Add(text.Trim());
					}
				}
			}
			catch
			{
			}
		}

		public static bool Is(ActorEntry e)
		{
			if (_set == null)
			{
				Load();
			}
			return _set.Contains(e.Key);
		}

		public static void Toggle(ActorEntry e)
		{
			if (_set == null)
			{
				Load();
			}
			if (!_set.Add(e.Key))
			{
				_set.Remove(e.Key);
			}
			try
			{
				File.WriteAllLines(FilePath, new List<string>(_set).ToArray());
			}
			catch
			{
			}
		}
	}
	internal static class ActorKeys
	{
		private static Dictionary<string, KeyCode> _map;

		private static string FilePath => Path.Combine(Plugin.LocalDir, "actor_keys.txt");

		private static void Load()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			_map = new Dictionary<string, KeyCode>();
			try
			{
				if (!File.Exists(FilePath))
				{
					return;
				}
				string[] array = File.ReadAllLines(FilePath);
				for (int i = 0; i < array.Length; i++)
				{
					string[] array2 = array[i].Split('|');
					if (array2.Length == 3)
					{
						try
						{
							_map[array2[0] + "|" + array2[1]] = (KeyCode)Enum.Parse(typeof(KeyCode), array2[2]);
						}
						catch
						{
						}
					}
				}
			}
			catch
			{
			}
		}

		public static KeyCode Get(string prefab, string id, KeyCode fallback)
		{
			//IL_0028: 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)
			if (_map == null)
			{
				Load();
			}
			if (!_map.TryGetValue(prefab + "|" + id, out var value))
			{
				return fallback;
			}
			return value;
		}

		public static void Set(string prefab, string id, KeyCode key, KeyCode def)
		{
			//IL_000c: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (_map == null)
			{
				Load();
			}
			if (key == def)
			{
				_map.Remove(prefab + "|" + id);
			}
			else
			{
				_map[prefab + "|" + id] = key;
			}
			try
			{
				List<string> list = new List<string>();
				foreach (KeyValuePair<string, KeyCode> item in _map)
				{
					list.Add(item.Key + "|" + ((object)item.Value/*cast due to .constrained prefix*/).ToString());
				}
				File.WriteAllLines(FilePath, list.ToArray());
			}
			catch
			{
			}
		}
	}
	internal static class ActorActions
	{
		public unsafe static string KeyName(KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_002f: 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_0047: Expected I4, but got Unknown
			if ((int)k != 0)
			{
				switch (k - 303)
				{
				default:
					switch (k - 323)
					{
					case 0:
						return "LMB";
					case 1:
						return "RMB";
					case 2:
						return "MMB";
					default:
					{
						string text = ((object)(*(KeyCode*)(&k))/*cast due to .constrained prefix*/).ToString();
						if (text.StartsWith("Alpha"))
						{
							text = text.Substring(5);
						}
						else if (text.StartsWith("Keypad"))
						{
							text = "Num" + text.Substring(6);
						}
						return text;
					}
					}
				case 0:
				case 1:
					return "Shift";
				case 2:
				case 3:
					return "Ctrl";
				case 4:
				case 5:
					return "Alt";
				case 6:
				case 7:
					return "Cmd";
				}
			}
			return "-";
		}

		public static string Pretty(string s)
		{
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = true;
			foreach (char c in s)
			{
				if (c == '_' || c == ' ')
				{
					stringBuilder.Append(' ');
					flag = true;
				}
				else
				{
					stringBuilder.Append(flag ? char.ToUpperInvariant(c) : c);
					flag = false;
				}
			}
			return stringBuilder.ToString().Trim();
		}

		private static KeyCode Digit(int i)
		{
			if (i >= 0)
			{
				if (i <= 9)
				{
					if (i == 9)
					{
						return (KeyCode)48;
					}
					return (KeyCode)(49 + i);
				}
				if (i <= 19)
				{
					if (i == 19)
					{
						return (KeyCode)256;
					}
					return (KeyCode)(257 + (i - 10));
				}
				return (KeyCode)0;
			}
			return (KeyCode)0;
		}

		public static List<ItemDrop> Weapons(Humanoid h)
		{
			List<ItemDrop> list = new List<ItemDrop>();
			Action<GameObject> action = delegate(GameObject g)
			{
				if (!((Object)(object)g == (Object)null))
				{
					ItemDrop component = g.GetComponent<ItemDrop>();
					if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null && component.m_itemData.m_shared.m_attack != null && component.m_itemData.m_shared.m_secondaryAttack != null && (component.m_itemData.HavePrimaryAttack() || component.m_itemData.HaveSecondaryAttack()) && !list.Contains(component))
					{
						list.Add(component);
					}
				}
			};
			if (h.m_defaultItems != null)
			{
				GameObject[] defaultItems = h.m_defaultItems;
				foreach (GameObject obj in defaultItems)
				{
					action(obj);
				}
			}
			if (h.m_randomWeapon != null)
			{
				GameObject[] defaultItems = h.m_randomWeapon;
				foreach (GameObject obj2 in defaultItems)
				{
					action(obj2);
				}
			}
			if (h.m_randomSets != null)
			{
				ItemSet[] randomSets = h.m_randomSets;
				foreach (ItemSet val in randomSets)
				{
					if (val != null && val.m_items != null)
					{
						GameObject[] defaultItems = val.m_items;
						foreach (GameObject obj3 in defaultItems)
						{
							action(obj3);
						}
					}
				}
			}
			if (h.m_randomItems != null)
			{
				RandomItem[] randomItems = h.m_randomItems;
				foreach (RandomItem val2 in randomItems)
				{
					if (val2 != null)
					{
						action(val2.m_prefab);
					}
				}
			}
			if ((Object)(object)h.m_unarmedWeapon != (Object)null)
			{
				action(((Component)h.m_unarmedWeapon).gameObject);
			}
			return list;
		}

		private static bool IsSpecial(SharedData sh)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if (!(sh.m_aiAttackInterval >= 8f) && !(sh.m_aiMaxHealthPercentage < 0.999f))
			{
				return (int)sh.m_aiTargetType > 0;
			}
			return true;
		}

		private static EffectList VoiceOnly(EffectList l)
		{
			//IL_00a2: 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_00b4: Expected O, but got Unknown
			if (l == null || l.m_effectPrefabs == null)
			{
				return null;
			}
			List<EffectData> list = new List<EffectData>();
			EffectData[] effectPrefabs = l.m_effectPrefabs;
			foreach (EffectData val in effectPrefabs)
			{
				if (val != null && !((Object)(object)val.m_prefab == (Object)null) && val.m_enabled && !((Object)(object)val.m_prefab.GetComponentInChildren<ZSFX>(true) == (Object)null) && !((Object)(object)val.m_prefab.GetComponentInChildren<Ragdoll>(true) != (Object)null) && !((Object)(object)val.m_prefab.GetComponent<Projectile>() != (Object)null) && !((Object)(object)val.m_prefab.GetComponent<Aoe>() != (Object)null))
				{
					list.Add(val);
				}
			}
			if (list.Count != 0)
			{
				return new EffectList
				{
					m_effectPrefabs = list.ToArray()
				};
			}
			return null;
		}

		public static List<KeyValuePair<string, EffectList>> Voices(GameObject prefab)
		{
			List<KeyValuePair<string, EffectList>> v = new List<KeyValuePair<string, EffectList>>();
			if ((Object)(object)prefab == (Object)null)
			{
				return v;
			}
			Action<string, EffectList> action = delegate(string n, EffectList l)
			{
				EffectList val2 = VoiceOnly(l);
				if (val2 != null)
				{
					v.Add(new KeyValuePair<string, EffectList>(n, val2));
				}
			};
			BaseAI component = prefab.GetComponent<BaseAI>();
			MonsterAI val = (MonsterAI)(object)((component is MonsterAI) ? component : null);
			Character component2 = prefab.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				action("Idle", component.m_idleSound);
				action("Alert", component.m_alertedEffects);
			}
			if ((Object)(object)val != (Object)null)
			{
				action("Wake up", val.m_wakeupEffects);
				action("Sleep", val.m_sleepEffects);
			}
			if ((Object)(object)component2 != (Object)null)
			{
				action("Pain", component2.m_hitEffects);
				action("Death", component2.m_deathEffects);
			}
			return v;
		}

		private static string ItemName(ItemDrop d)
		{
			return ActorCatalog.Clean(d.m_itemData.m_shared.m_name, Pretty(((Object)d).name));
		}

		public static List<ActorAction> For(ActorEntry e)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			List<ActorAction> list = new List<ActorAction>();
			if (e == null)
			{
				return list;
			}
			e = e.Eff;
			if (e.Walk)
			{
				return list;
			}
			if (e.Kind == ActorKind.Item || e.Free)
			{
				list.Add(new ActorAction
				{
					Id = "rotl",
					Label = "Turn left",
					Default = (KeyCode)113
				});
				list.Add(new ActorAction
				{
					Id = "rotr",
					Label = "Turn right",
					Default = (KeyCode)101
				});
				if ((Object)(object)e.Go != (Object)null && (Object)(object)e.Go.GetComponentInChildren<Raven>(true) != (Object)null)
				{
					list.Add(new ActorAction
					{
						Id = "appear",
						Label = "Make it appear",
						Default = (KeyCode)114
					});
					list.Add(new ActorAction
					{
						Id = "keepvis",
						Label = "Keep it showing (on / off)",
						Default = (KeyCode)116
					});
				}
			}
			else
			{
				Humanoid val = (((Object)(object)e.Go != (Object)null) ? e.Go.GetComponent<Humanoid>() : null);
				List<ItemDrop> list2 = (((Object)(object)val != (Object)null) ? Weapons(val) : new List<ItemDrop>());
				List<ActorAction> list3 = new List<ActorAction>();
				List<ActorAction> list4 = new List<ActorAction>();
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				foreach (ItemDrop item in list2)
				{
					string key = ItemName(item);
					dictionary.TryGetValue(key, out var value);
					dictionary[key] = value + 1;
				}
				foreach (ItemDrop item2 in list2)
				{
					SharedData shared = item2.m_itemData.m_shared;
					string text = ItemName(item2);
					if (dictionary[text] > 1 || text.Length == 0)
					{
						text = text + " [" + Pretty(((Object)item2).name) + "]";
					}
					bool flag = IsSpecial(shared);
					List<ActorAction> list5 = (flag ? list4 : list3);
					if (item2.m_itemData.HavePrimaryAttack())
					{
						list5.Add(new ActorAction
						{
							Weapon = item2,
							Label = text,
							Special = flag
						});
					}
					if (item2.m_itemData.HaveSecondaryAttack())
					{
						list5.Add(new ActorAction
						{
							Weapon = item2,
							Label = text + " (second attack)",
							Special = flag,
							Secondary = true
						});
					}
				}
				for (int i = 0; i < list3.Count; i++)
				{
					list3[i].Slot = i;
					list3[i].Id = "a" + i;
					list3[i].Default = Digit(i);
				}
				for (int j = 0; j < list4.Count; j++)
				{
					list4[j].Slot = j;
					list4[j].Id = "s" + j;
					list4[j].Default = Digit(j);
					list4[j].GpAlone = list4.Count == 1;
					list4[j].Label = "Special: " + list4[j].Label;
				}
				list.AddRange(list3);
				list.AddRange(list4);
				MonsterAI val2 = (((Object)(object)e.Go != (Object)null) ? e.Go.GetComponent<MonsterAI>() : null);
				if ((Object)(object)val2 != (Object)null && val2.m_sleeping)
				{
					list.Add(new ActorAction
					{
						Id = "wake",
						Label = "Wake up from sleep",
						Default = Digit(list3.Count)
					});
				}
				BaseAI val3 = (((Object)(object)e.Go != (Object)null) ? e.Go.GetComponent<BaseAI>() : null);
				if ((Object)(object)val3 != (Object)null && val3.m_randomFly)
				{
					list.Add(new ActorAction
					{
						Id = "fly",
						Label = "Take off / land (tap twice)",
						Default = (KeyCode)32
					});
				}
				List<KeyValuePair<string, EffectList>> list6 = Voices(e.Go);
				if (list6.Count > 0)
				{
					ActorAction actorAction = new ActorAction
					{
						Id = "sndmod",
						Label = "Hold for sounds",
						Default = (KeyCode)113,
						IsMod = true
					};
					list.Add(actorAction);
					for (int k = 0; k < list6.Count; k++)
					{
						list.Add(new ActorAction
						{
							Id = "snd" + k,
							Label = list6[k].Key + " sound",
							Default = Digit(k),
							Sound = list6[k].Value,
							Mod = actorAction
						});
					}
				}
			}
			foreach (ActorAction item3 in list)
			{
				item3.Key = ActorKeys.Get(e.Prefab, item3.Id, item3.Default);
			}
			return list;
		}

		public static string KeyText(ActorAction a)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if (a.Id == "fly")
			{
				return KeyName(a.Key) + " x2";
			}
			if (a.Special)
			{
				if (!a.GpAlone)
				{
					return "GP + " + KeyName(a.Key);
				}
				return "GP";
			}
			if (a.Sound != null && a.Mod != null)
			{
				return KeyName(a.Mod.Key) + " + " + KeyName(a.Key);
			}
			return KeyName(a.Key);
		}
	}
	internal static class Actor
	{
		public static Character Mob;

		internal static bool Leaving;

		private static float _guardLog;

		public static GameObject ItemGo;

		public static string RecordPrefab;

		public static bool God;

		public static ActorEntry Entry;

		private static List<ActorAction> _actions = new List<ActorAction>();

		private static List<ItemDrop> _weapons = new List<ItemDrop>();

		private static int _frames;

		private static float _aimUntil;

		private static float _cameraExtra;

		private static float _hideTimer;

		private static float _orphanTimer;

		private static bool _prepared;

		private static bool _wasActive;

		private static float _size = 1f;

		private static bool _godWas;

		private static bool _ghostWas;

		private static bool _gravWas;

		private static bool _collWas;

		private static readonly List<Renderer> Hidden = new List<Renderer>();

		private static readonly List<bool> HiddenWas = new List<bool>();

		private static float _maxDistWas = -1f;

		private static readonly FieldInfo CamDistance = AccessTools.Field(typeof(GameCamera), "m_distance");

		private static readonly MethodInfo TakeInputM = AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null);

		private static bool _ravenHold;

		private static float _ravenNext;

		private static readonly Dictionary<ItemDrop, ItemData> _itemOf = new Dictionary<ItemDrop, ItemData>();

		private static float _radialUntil;

		private static readonly MethodInfo WakeM = AccessTools.Method(typeof(MonsterAI), "Wakeup", (Type[])null, (Type[])null);

		private static float _flyTap = -10f;

		private static string _emoteState = "";

		private static float _flyMul = 1f;

		private static bool _walk;

		private static float _walkYaw;

		private static float _walkPhase;

		private static float _walkAmt;

		internal const string Puppet = "CanoCT_Puppet";

		private static readonly Dictionary<int, KeyValuePair<float, bool>> PuppetCache = new Dictionary<int, KeyValuePair<float, bool>>();

		public static string LastName
		{
			get
			{
				if (Entry == null)
				{
					return "form";
				}
				return Entry.Name;
			}
		}

		public static bool Active
		{
			get
			{
				if (!((Object)(object)Mob != (Object)null))
				{
					return (Object)(object)ItemGo != (Object)null;
				}
				return true;
			}
		}

		public static Transform RecordRoot
		{
			get
			{
				if (!((Object)(object)Mob != (Object)null))
				{
					if (!((Object)(object)ItemGo != (Object)null))
					{
						return null;
					}
					return ItemGo.transform;
				}
				return ((Component)Mob).transform;
			}
		}

		public static IList<ActorAction> Actions => _actions;

		public static bool SpeedHeld
		{
			get
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)ItemGo != (Object)null && !_walk && Plugin.KeysHeld(Plugin.FlySpeedKeys.Value) && !Input.GetKey((KeyCode)308))
				{
					return !Input.GetKey((KeyCode)307);
				}
				return false;
			}
		}

		internal static bool Protected(GameObject go)
		{
			if (Active && !Leaving && (Object)(object)Mob != (Object)null && (Object)(object)go != (Object)null)
			{
				return (Object)(object)go == (Object)(object)((Component)Mob).gameObject;
			}
			return false;
		}

		internal static void NoteBlocked(string how)
		{
			if (!(Time.unscaledTime < _guardLog))
			{
				_guardLog = Time.unscaledTime + 3f;
				string text = "";
				try
				{
					text = new StackTrace(2, fNeedFileInfo: false).ToString();
				}
				catch
				{
				}
				if (text.Length > 900)
				{
					text = text.Substring(0, 900);
				}
				Plugin.Dbg("The Paid Actor: something tried to remove your creature (" + how + ") and was stopped. Who asked:\n" + text);
			}
		}

		public static void ReloadKeys()
		{
			if (Entry != null)
			{
				_actions = ActorActions.For(Entry);
			}
		}

		private static bool InputOk(Player p)
		{
			if ((Object)(object)p == (Object)null || Dialog.Open)
			{
				return false;
			}
			try
			{
				return TakeInputM == null || (bool)TakeInputM.Invoke(p, null);
			}
			catch
			{
				return true;
			}
		}

		private static bool Hold(KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)k != 0)
			{
				return Input.GetKey(k);
			}
			return false;
		}

		private static bool Down(KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)k != 0)
			{
				return Input.GetKeyDown(k);
			}
			return false;
		}

		public static string Become(ActorEntry e, int level, float size, bool god)
		{
			//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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				return "There is no character to become anything.";
			}
			if (e == null || (Object)(object)e.Go == (Object)null)
			{
				return "Pick something from the list first.";
			}
			e = e.Eff;
			if (!Plugin.ActorOn.Value)
			{
				return "The Paid Actor is switched off in the settings.";
			}
			if (Admin.Deny())
			{
				return "Only admins can use The Paid Actor here.";
			}
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return "The world is not ready yet.";
			}
			if (Active)
			{
				UnBecome(poof: true, toast: false);
			}
			size = Mathf.Clamp(size, 0.25f, 4f);
			Vector3 position = ((Component)localPlayer).transform.position;
			Quaternion rot = Quaternion.Euler(0f, ((Component)localPlayer).transform.eulerAngles.y, 0f);
			string text;
			try
			{
				text = (e.Free ? BecomeFree(localPlayer, e, size, position, rot) : ((e.Kind == ActorKind.Creature) ? BecomeCreature(localPlayer, e, level, size, god, position, rot) : BecomeItem(localPlayer, e, size, position, rot)));
			}
			catch (Exception ex)
			{
				Plugin.Warn("Become failed: " + ex);
				UnBecome(poof: false, toast: false);
				return "Could not become " + e.Name + " (see the log).";
			}
			if (text != null)
			{
				UnBecome(poof: false, toast: false);
				return text;
			}
			Entry = e;
			ActorEntry became = e;
			Character bm = Mob;
			Undo.Push("becoming " + e.Name, delegate
			{
				if (Active && Entry == became && (Object)(object)Mob == (Object)(object)bm)
				{
					UnBecome(poof: true, toast: true);
				}
			});
			RecordPrefab = ((e.Kind == ActorKind.Creature && !e.Free) ? e.Prefab : null);
			God = god && e.Kind == ActorKind.Creature && !e.Free;
			_size = size;
			_actions = ActorActions.For(e);
			foreach (ActorAction action in _actions)
			{
				Plugin.Dbg("The Paid Actor: " + e.Prefab + " action " + action.Id + " '" + action.Label + "' key " + ActorActions.KeyText(action) + (((Object)(object)action.Weapon != (Object)null) ? (" item " + ((Object)action.Weapon).name + " anim '" + (action.Secondary ? action.Weapon.m_itemData.m_shared.m_secondaryAttack.m_attackAnimation : action.Weapon.m_itemData.m_shared.m_attack.m_attackAnimation) + "'") : ""));
			}
			_frames = 0;
			_prepared = false;
			_wasActive = true;
			Pocket(localPlayer);
			PoofAt(position);
			return null;
		}

		private static string BecomeCreature(Player p, ActorEntry e, int level, float size, bool god, Vector3 at, Quaternion rot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: 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)
			GameObject val = Object.Instantiate<GameObject>(e.Go, at + Vector3.up * 0.1f, rot);
			Character component = val.GetComponent<Character>();
			ZNetView component2 = val.GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || !component2.IsValid())
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
				return e.Name + " cannot be spawned here.";
			}
			Mob = component;
			float num = Mathf.Clamp(component.GetHeight() * 0.2f * size, 0f, 2f);
			if (num > 0.01f)
			{
				Transform transform = val.transform;
				transform.position += Vector3.up * num;
				Rigidbody component3 = val.GetComponent<Rigidbody>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.position = val.transform.position;
				}
			}
			Tameable[] components = val.GetComponents<Tameable>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			Growup[] components2 = val.GetComponents<Growup>();
			for (int i = 0; i < components2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components2[i]);
			}
			Procreation[] components3 = val.GetComponents<Procreation>();
			for (int i = 0; i < components3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components3[i]);
			}
			CharacterTimedDestruction[] components4 = val.GetComponents<CharacterTimedDestruction>();
			for (int i = 0; i < components4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components4[i]);
			}
			component.m_onDamaged = null;
			component.m_onDeath = null;
			ZDO zDO = component2.GetZDO();
			zDO.Set("CanoCT_Puppet", p.GetPlayerID());
			zDO.Persistent = false;
			if (level > 1)
			{
				component.SetLevel(Mathf.Clamp(level, 1, 3));
			}
			if (!Mathf.Approximately(size, 1f))
			{
				Vector3 val2 = e.Go.transform.localScale * size;
				val.transform.localScale = val2;
				zDO.Set(ZDOVars.s_scaleHash, val2);
			}
			_cameraExtra = Mathf.Max(0f, component.GetHeight() * 0.85f - 1.7f);
			return null;
		}

		private static string BecomeFree(Player p, ActorEntry e, float size, Vector3 at, Quaternion rot)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			float num = 1.2f;
			_walk = e.Walk;
			if (e.Walk)
			{
				float num2 = default(float);
				num = (((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetSolidHeight(at, ref num2, 1000)) ? Mathf.Max(0f, num2 - at.y) : 0f);
				_walkYaw = ((Quaternion)(ref rot)).eulerAngles.y;
				_walkPhase = 0f;
				_walkAmt = 0f;
			}
			GameObject val = LoopPieces.VisualCopy(e.Go, at + Vector3.up * num, rot, e.Go.transform.localScale * size);
			if ((Object)(object)val == (Object)null)
			{
				return e.Name + " cannot be shown here.";
			}
			((Object)val).name = "ContentToolsActorItem";
			ItemGo = val;
			_cameraExtra = 0.9f * size;
			try
			{
				FixVisitor(e.Go, val, e.Name);
			}
			catch (Exception ex)
			{
				Plugin.Warn("Visitor setup failed: " + ex.Message);
			}
			return null;
		}

		private static void FixVisitor(GameObject prefab, GameObject copy, string who)
		{
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			bool flag = who == "Munin";
			Raven[] componentsInChildren = prefab.GetComponentsInChildren<Raven>(true);
			Raven val = null;
			Raven[] array = componentsInChildren;
			foreach (Raven val2 in array)
			{
				if (val2.m_isMunin == flag)
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null && componentsInChildren.Length != 0)
			{
				val = componentsInChildren[0];
			}
			string text = "";
			array = componentsInChildren;
			foreach (Raven val3 in array)
			{
				text = text + ((Object)val3).name + (val3.m_isMunin ? "(Munin) " : "(Hugin) ");
			}
			string text2 = "";
			Renderer[] componentsInChildren2 = copy.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val4 in componentsInChildren2)
			{
				string text3 = "";
				Material[] sharedMaterials = val4.sharedMaterials;
				foreach (Material val5 in sharedMaterials)
				{
					text3 = text3 + (((Object)(object)val5 != (Object)null) ? ((Object)val5).name : "none") + ",";
				}
				text2 = text2 + ((Object)val4).name + "[" + text3.TrimEnd(',') + "] ";
			}
			Plugin.Dbg("The Paid Actor: " + ((Object)prefab).name + " has " + componentsInChildren.Length + " raven script(s): " + text + "| parts: " + text2);
			if (componentsInChildren.Length > 1 && (Object)(object)val != (Object)null)
			{
				array = componentsInChildren;
				foreach (Raven val6 in array)
				{
					if (!((Object)(object)val6 == (Object)(object)val))
					{
						Transform val7 = copy.transform.Find(PathFrom(prefab.transform, ((Component)val6).transform));
						if ((Object)(object)val7 != (Object)null && (Object)(object)val7 != (Object)(object)copy.transform)
						{
							((Component)val7).gameObject.SetActive(false);
						}
					}
				}
				Transform val8 = copy.transform.Find(PathFrom(prefab.transform, ((Component)val).transform));
				if ((Object)(object)val8 != (Object)null && (Object)(object)val8 != (Object)(object)copy.transform)
				{
					((Component)val8).gameObject.SetActive(true);
				}
			}
			else if (componentsInChildren.Length == 1)
			{
				string value = (flag ? "munin" : "hugin");
				string value2 = (flag ? "hugin" : "munin");
				Transform[] componentsInChildren3 = copy.GetComponentsInChildren<Transform>(true);
				foreach (Transform val9 in componentsInChildren3)
				{
					string text4 = ((Object)val9).name.ToLowerInvariant();
					if (text4.Contains(value2) && !text4.Contains(value))
					{
						((Component)val9).gameObject.SetActive(false);
					}
					else if (text4.Contains(value))
					{
						((Component)val9).gameObject.SetActive(true);
					}
				}
			}
			Animator val10 = RavenAnimator(copy);
			if ((Object)(object)val10 != (Object)null)
			{
				val10.cullingMode = (AnimatorCullingMode)0;
				string text5 = "";
				AnimatorControllerParameter[] parameters = val10.parameters;
				foreach (AnimatorControllerParameter val11 in parameters)
				{
					text5 = text5 + val11.name + "(" + ((object)val11.type/*cast due to .constrained prefix*/).ToString() + ") ";
				}
				Plugin.Dbg("The Paid Actor: " + ((Object)prefab).name + " animator parameters: " + text5);
			}
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			if ((Object)(object)val.m_exclamation != (Object)null)
			{
				Transform[] componentsInChildren3 = copy.GetComponentsInChildren<Transform>(true);
				foreach (Transform val12 in componentsInChildren3)
				{
					if (((Object)val12).name == ((Object)val.m_exclamation).name)
					{
						((Component)val12).gameObject.SetActive(false);
					}
				}
			}
			if ((Object)(object)val.m_visual != (Object)null)
			{
				Transform[] componentsInChildren3 = copy.GetComponentsInChildren<Transform>(true);
				foreach (Transform val13 in componentsInChildren3)
				{
					if (((Object)val13).name == ((Object)val.m_visual).name)
					{
						((Component)val13).gameObject.SetActive(true);
					}
				}
			}
			_ravenHold = true;
			_ravenNext = 0f;
		}

		private static string PathFrom(Transform root, Transform t)
		{
			if ((Object)(object)t == (Object)(object)root)
			{
				return "";
			}
			string text = ((Object)t).name;
			Transform parent = t.parent;
			while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private static Animator RavenAnimator(GameObject copy)
		{
			Animator[] componentsInChildren = copy.GetComponentsInChildren<Animator>(true);
			Animator[] array = componentsInChildren;
			foreach (Animator val in array)
			{
				if (((Component)val).gameObject.activeInHierarchy)
				{
					return val;
				}
			}
			if (componentsInChildren.Length == 0)
			{
				return null;
			}
			return componentsInChildren[0];
		}

		private static void RavenKeys()
		{
			//IL_0005: 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)
			if (Down(KeyOf("keepvis")))
			{
				_ravenHold = !_ravenHold;
				ActorUi.Info(_ravenHold ? "It will stay in sight." : "It is free to hide again.");
			}
			if (Down(KeyOf("appear")))
			{
				RavenAppear(asked: true);
			}
			else if (_ravenHold && Time.unscaledTime >= _ravenNext)
			{
				RavenAppear(asked: false);
			}
		}

		private static void RavenAppear(bool asked)
		{
			//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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			GameObject itemGo = ItemGo;
			Animator val = (((Object)(object)itemGo != (Object)null) ? RavenAnimator(itemGo) : null);
			if ((Object)(object)val == (Object)null)
			{
				if (asked)
				{
					ActorUi.Info("It has nothing to bring back.");
				}
				return;
			}
			_ravenNext = Time.unscaledTime + 1.5f;
			int num;
			if (val.isInitialized)
			{
				AnimatorStateInfo val2 = val.GetCurrentAnimatorStateInfo(0);
				if (!((AnimatorStateInfo)(ref val2)).IsTag("visible"))
				{
					val2 = val.GetNextAnimatorStateInfo(0);
					num = (((AnimatorStateInfo)(ref val2)).IsTag("visible") ? 1 : 0);
				}
				else
				{
					num = 1;
				}
			}
			else
			{
				num = 0;
			}
			bool flag = (byte)num != 0;
			if (flag && !asked)
			{
				return;
			}
			Raven val3 = null;
			if (Entry != null && (Object)(object)Entry.Go != (Object)null)
			{
				Raven[] componentsInChildren = Entry.Go.GetComponentsInChildren<Raven>(true);
				foreach (Raven val4 in componentsInChildren)
				{
					if ((Object)(object)val3 == (Object)null || val4.m_isMunin == (Entry.Name == "Munin"))
					{
						val3 = val4;
					}
				}
			}
			if ((Object)(object)val3 != (Object)null && (Object)(object)val3.m_visual != (Object)null)
			{
				Transform[] componentsInChildren2 = itemGo.GetComponentsInChildren<Transform>(true);
				foreach (Transform val5 in componentsInChildren2)
				{
					if (((Object)val5).name == ((Object)val3.m_visual).name)
					{
						((Component)val5).gameObject.SetActive(true);
					}
				}
			}
			Renderer[] componentsInChildren3 = itemGo.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				componentsInChildren3[i].enabled = true;
			}
			((Behaviour)val).enabled = true;
			val.cullingMode = (AnimatorCullingMode)0;
			if (HasParam(val, "flyaway"))
			{
				val.ResetTrigger("flyaway");
			}
			if (HasParam(val, "poff"))
			{
				val.ResetTrigger("poff");
			}
			if (HasParam(val, "teleportin"))
			{
				val.SetTrigger("teleportin");
			}
			else if (HasParam(val, "flyin"))
			{
				val.SetTrigger("flyin");
			}
			if (asked)
			{
				ActorUi.Info(flag ? "It is already here." : "It appeared.");
			}
		}

		private static string BecomeItem(Player p, ActorEntry e, float size, Vector3 at, Quaternion rot)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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)
			GameObject val = LoopPieces.Copy(new LoopPiece
			{
				Prefab = e.Prefab,
				State = 0,
				Scale = e.Go.transform.localScale * size
			}, at + Vector3.up * 1.2f, rot, keepVisual: true);
			if ((Object)(object)val == (Object)null)
			{
				return e.Name + " cannot be shown here.";
			}
			Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			((Object)val).name = "ContentToolsActorItem";
			ItemGo = val;
			_cameraExtra = 0.6f * size;
			return null;
		}

		private static void Pocket(Player p)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			_godWas = ((Character)p).InGodMode();
			_ghostWas = ((Character)p).InGhostMode();
			p.SetGodMode(true);
			p.SetGhostMode(true);
			Rigidbody component = ((Component)p).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				_gravWas = component.useGravity;
				_collWas = component.detectCollisions;
				component.useGravity = false;
				component.detectCollisions = false;
			}
			p.SetControls(Vector3.zero, false, false, false, false, false, false, false, false, false, false, false);
			Hidden.Clear();
			HiddenWas.Clear();
			_hideTimer = 0f;
			HidePlayer(p);
			if (!((Object)(object)GameCamera.instance != (Object)null))
			{
				return;
			}
			_maxDistWas = GameCamera.instance.m_maxDistance;
			float num = Mathf.Clamp(_size * (((Object)(object)Mob != (Object)null) ? Mathf.Max(1f, Mob.GetHeight() / 1.8f) : 1f), 1f, 8f);
			GameCamera.instance.m_maxDistance = _maxDistWas * num;
			if (CamDistance != null)
			{
				try
				{
					CamDistance.SetValue(GameCamera.instance, Mathf.Max((float)CamDistance.GetValue(GameCamera.instance), 4f * Mathf.Min(num, 4f)));
				}
				catch
				{
				}
			}
		}

		private static void HidePlayer(Player p)
		{
			Renderer[] componentsInChildren = ((Component)p).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled)
				{
					Hidden.Add(val);
					HiddenWas.Add(item: true);
					val.enabled = false;
				}
			}
		}

		private static void Unpocket(Player p, Vector3 at)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < Hidden.Count; i++)
			{
				if ((Object)(object)Hidden[i] != (Object)null)
				{
					Hidden[i].enabled = HiddenWas[i];
				}
			}
			Hidden.Clear();
			HiddenWas.Clear();
			if (!((Object)(object)p == (Object)null))
			{
				p.SetGodMode(_godWas);
				p.SetGhostMode(_ghostWas);
				Rigidbody component = ((Component)p).GetComponent<Rigidbody>();
				((Component)p).transform.position = at;
				if ((Object)(object)component != (Object)null)
				{
					component.position = at;
					component.linearVelocity = Vector3.zero;
					component.useGravity = _gravWas;
					component.detectCollisions = _collWas;
				}
				if ((Object)(object)GameCamera.instance != (Object)null && _maxDistWas > 0f)
				{
					GameCamera.instance.m_maxDistance = _maxDistWas;
				}
				_maxDistWas = -1f;
			}
		}

		public static void UnBecome(bool poof, bool toast)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Transform recordRoot = RecordRoot;
			Vector3 at = (((Object)(object)recordRoot != (Object)null) ? recordRoot.position : (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform.position : Vector3.zero));
			if (poof && (Object)(object)recordRoot != (Object)null)
			{
				PoofAt(at);
			}
			if ((Object)(object)Mob != (Object)null)
			{
				Leaving = true;
				try
				{
					if ((Object)(object)ZNetScene.instance != (Object)null)
					{
						ZNetScene.instance.Destroy(((Component)Mob).gameObject);
					}
					else
					{
						Object.Destroy((Object)(object)((Component)Mob).gameObject);
					}
				}
				finally
				{
					Leaving = false;
				}
			}
			if ((Object)(object)ItemGo != (Object)null)
			{
				Object.Destroy((Object)(object)ItemGo);
			}
			ActorTools.Reset();
			if (_wasActive && Entry != null && Entry.Kind == ActorKind.Creature)
			{
				int num = Cleanup.ClearTracked();
				if (num > 0)
				{
					Plugin.Dbg("The Paid Actor: removed " + num + " effect object(s) of " + Entry.Prefab + ".");
				}
				Cleanup.Linger(8f);
			}
			bool wasActive = _wasActive;
			Mob = null;
			ItemGo = null;
			_walk = false;
			RecordPrefab = null;
			Entry = null;
			_actions = new List<ActorAction>();
			_weapons.Clear();
			_wasActive = false;
			if (wasActive)
			{
				Unpocket(localPlayer, at);
			}
			if (toast && wasActive)
			{
				Plugin.Toast("You are yourself again");
			}
		}

		public static void OnMobDied()
		{
			Plugin.Toast("Your creature died");
			UnBecome(poof: true, toast: false);
			ActorUi.Info("The creature you were became too hurt. You are yourself again.");
		}

		private static void PoofAt(Vector3 at)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Fx.Poof(at, sound: true);
			Recorder.NoteEffect("vfx_crow_death", at);
			if (Plugin.PoofSoundPrefab != null)
			{
				Recorder.NoteEffect(Plugin.PoofSoundPrefab.Value, at);
			}
		}

		public static void Tick()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Cleanup.Tick();
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				if (_wasActive)
				{
					UnBecome(poof: false, toast: false);
				}
				return;
			}
			if (!Active)
			{
				if (_wasActive)
				{
					_wasActive = false;
					Unpocket(localPlayer, ((Component)localPlayer).transform.position);
					ActorUi.Info("The creature is gone. You are yourself again.");
				}
				CleanOrphans(localPlayer);
				return;
			}
			if (((Character)localPlayer).IsDead())
			{
				UnBecome(poof: false, toast: false);
				return;
			}
			_frames++;
			Transform recordRoot = RecordRoot;
			if (!_prepared && (Object)(object)Mob != (Object)null && _frames > 2)
			{
				Prepare();
			}
			if (_prepared || (Object)(object)ItemGo != (Object)null)
			{
				if ((Object)(object)Mob != (Object)null)
				{
					DriveCreature(localPlayer, Mob);
				}
				else
				{
					DriveItem(localPlayer, ItemGo.transform);
				}
			}
			Glue(localPlayer, recordRoot);
			_hideTimer -= Time.unscaledDeltaTime;
			if (_hideTimer <= 0f)
			{
				_hideTimer = 0.5f;
				HidePlayer(localPlayer);
			}
		}

		public static void LateTick()
		{
			if (Active)
			{
				Player localPlayer = Player.m_localPlayer;
				Transform recordRoot = RecordRoot;
				if ((Object)(object)localPlayer != (Object)null && (Object)(object)recordRoot != (Object)null)
				{
					Glue(localPlayer, recordRoot);
				}
				ActorTools.LateTick();
			}
		}

		private static void Glue(Player p, Transform root)
		{
			//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_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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = root.position + Vector3.up * _cameraExtra;
			((Component)p).transform.position = position;
			Rigidbody component = ((Component)p).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.position = position;
				component.linearVelocity = Vector3.zero;
				component.angularVelocity = Vector3.zero;
			}
		}

		private static void Prepare()
		{
			_prepared = true;
			Character mob = Mob;
			Humanoid val = (Humanoid)(object)((mob is Humanoid) ? mob : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			_weapons = ActorActions.Weapons(val);
			_itemOf.Clear();
			HashSet<ItemData> hashSet = new HashSet<ItemData>();
			foreach (ItemDrop weapon in _weapons)
			{
				if ((Object)(object)weapon == (Object)(object)val.m_unarmedWeapon)
				{
					_itemOf[weapon] = weapon.m_itemData;
					continue;
				}
				ItemData val2 = null;
				foreach (ItemData allItem in val.GetInventory().GetAllItems())
				{
					if (!hashSet.Contains(allItem) && (((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)(object)allItem.m_dropPrefab == (Object)(object)((Component)weapon).gameObject || ((Object)allItem.m_dropPrefab).name == ((Object)weapon).name)) || allItem.m_shared == weapon.m_itemData.m_shared))
					{
						val2 = allItem;
						break;
					}
				}
				if (val2 == null)
				{
					try
					{
						val2 = val.PickupPrefab(((Component)weapon).gameObject, 0, false);
					}
					catch (Exception ex)
					{
						Plugin.Warn("Attack item " + ((Object)weapon).name + " could not be given: " + ex.Message);
					}
				}
				if (val2 != null)
				{
					hashSet.Add(val2);
					_itemOf[weapon] = val2;
				}
				else
				{
					Plugin.Warn("The Paid Actor: no item for the attack " + ((Object)weapon).name + ".");
				}
			}
		}

		private static ItemData FindItem(Humanoid h, ItemDrop weapon)
		{
			if ((Object)(object)weapon == (Object)null)
			{
				return null;
			}
			if ((Object)(object)weapon == (Object)(object)h.m_unarmedWeapon)
			{
				return weapon.m_itemData;
			}
			if (!_itemOf.TryGetValue(weapon, out var value))
			{
				return null;
			}
			return value;
		}

		private static void DriveCreature(Player p, Character c)
		{
			//IL_002f: 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_0037: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: 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_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Invalid comparison between Unknown and I4
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			if (Hud.InRadial())
			{
				_radialUntil = Time.time + 0.4f;
			}
			bool num = InputOk(p) && Time.time > _radialUntil;
			Vector3 lookDir = ((Character)p).GetLookDir();
			Vector3 forward = default(Vector3);
			((Vector3)(ref forward))..ctor(lookDir.x, 0f, lookDir.z);
			if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f)
			{
				forward = ((Component)p).transform.forward;
			}
			((Vector3)(ref forward)).Normalize();
			Vector3 zero = Vector3.zero;
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			bool flag4 = false;
			if (num)
			{
				if (ZInput.GetButton("Forward"))
				{
					zero.z += 1f;
				}
				if (ZInput.GetButton("Backward"))
				{
					zero.z -= 1f;
				}
				if (ZInput.GetButton("Left"))
				{
					zero.x -= 1f;
				}
				if (ZInput.GetButton("Right"))
				{
					zero.x += 1f;
				}
				Vector2 joyLeftStick = ZInput.GetJoyLeftStick();
				zero.x += joyLeftStick.x;
				zero.z += joyLeftStick.y;
				if (((Vector3)(ref zero)).magnitude > 1f)
				{
					((Vector3)(ref zero)).Normalize();
				}
				flag = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun");
				flag2 = ZInput.GetButtonDown("Jump") || ZInput.GetButtonDown("JoyJump");
				flag3 = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump");
				flag4 = Plugin.KeyHeld(Plugin.FlyDownKey.Value);
			}
			if (num)
			{
				WakeAndFly(c);
			}
			bool flag5 = c.m_flying || c.IsFlying();
			Vector3 val;
			if (flag5)
			{
				val = Quaternion.LookRotation((((Vector3)(ref lookDir)).sqrMagnitude > 0.0001f) ? lookDir : forward) * zero;
				if (flag3)
				{
					val.y += 1f;
				}
				if (flag4)
				{
					val.y -= 1f;
				}
				if (((Vector3)(ref val)).magnitude > 1f)
				{
					((Vector3)(ref val)).Normalize();
				}
			}
			else
			{
				val = Quaternion.LookRotation(forward) * zero;
			}
			bool flag6 = (flag5 ? (c.m_flyFastSpeed > c.m_flySlowSpeed + 0.05f) : (c.m_runSpeed > c.m_speed + 0.05f));
			c.SetRun(flag && flag6);
			c.SetMoveDir(val);
			if (flag2 && !flag5)
			{
				c.Jump(false);
			}
			bool flag7 = c.InAttack() || Time.time < _aimUntil;
			Vector3 val2 = (Vector3)((((Vector3)(ref zero)).sqrMagnitude > 0.01f && !flag7) ? new Vector3(val.x, flag5 ? val.y : 0f, val.z) : lookDir);
			if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
			{
				val2 = forward;
			}
			c.SetLookDir(val2, 0f);
			if (((Vector3)(ref zero)).sqrMagnitude > 0.04f || flag7 || flag2)
			{
				EmoteAnim component = ((Component)c).GetComponent<EmoteAnim>();
				if ((Object)(object)component != (Object)null && component.Playing)
				{
					component.Stop();
				}
			}
			if ((int)c.m_faction == 12 && ((Vector3)(ref zero)).sqrMagnitude > 0.0004f)
			{
				MoveDummy(c, val, flag, val2);
			}
			if (num)
			{
				ActorTools.Tick(p, c, lookDir, forward);
			}
			if (num && ActorTools.Mode == ToolKind.None)
			{
				Attacks(p, (Humanoid)(object)((c is Humanoid) ? c : null), lookDir);
			}
			if (num)
			{
				Voices(c);
			}
		}

		private static void MoveDummy(Character c, Vector3 dir, bool run, Vector3 face)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			float deltaTime = Time.deltaTime;
			Vector3 val = ((Component)c).transform.position + new Vector3(dir.x, 0f, dir.z) * (run ? 7f : 3.5f) * Mathf.Max(1f, Mathf.Sqrt(_size)) * deltaTime;
			float num = default(float);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetSolidHeight(new Vector3(val.x, val.y + 2f, val.z), ref num, 1000))
			{
				val.y = Mathf.Lerp(val.y, num, Mathf.Clamp01(14f * deltaTime));
			}
			((Component)c).transform.position = val;
			Rigidbody component = ((Component)c).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.position = val;
				component.linearVelocity = Vector3.zero;
			}
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(face.x, 0f, face.z);
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				((Component)c).transform.rotation = Quaternion.RotateTowards(((Component)c).transform.rotation, Quaternion.LookRotation(val2), 540f * deltaTime);
			}
		}

		private static void WakeAndFly(Character c)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			foreach (ActorAction action in _actions)
			{
				if (action.Id == "wake" && Down(action.Key) && !Hold(KeyOf("sndmod")))
				{
					MonsterAI component = ((Component)c).GetComponent<MonsterAI>();
					if ((Object)(object)component != (Object)null && ((BaseAI)component).IsSleeping() && WakeM != null)
					{
						try
						{
							WakeM.Invoke(component, null);
							ActorUi.Info("Woke up.");
						}
						catch (Exception ex)
						{
							Plugin.Warn("Wake up failed: " + ex.Message);
						}
					}
					else
					{
						ActorUi.Info("It is not asleep.");
					}
				}
				else
				{
					if (!(action.Id == "fly") || !Down(action.Key))
					{
						continue;
					}
					if (Time.unscaledTime - _flyTap < 0.35f)
					{
						_flyTap = -10f;
						if (c.IsFlying())
						{
							c.Land();
						}
						else
						{
							c.TakeOff();
						}
					}
					else
					{
						_flyTap = Time.unscaledTime;
					}
				}
			}
		}

		private static KeyCode KeyOf(string id)
		{
			//IL_0024: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			foreach (ActorAction action in _actions)
			{
				if (action.Id == id)
				{
					return action.Key;
				}
			}
			return (KeyCode)0;
		}

		private static void Attacks(Player p, Humanoid h, Vector3 look)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)h == (Object)null)
			{
				return;
			}
			bool button = ZInput.GetButton("GP");
			bool buttonDown = ZInput.GetButtonDown("GP");
			if (Hold(KeyOf("sndmod")))
			{
				return;
			}
			foreach (ActorAction action in _actions)
			{
				if ((Object)(object)action.Weapon == (Object)null)
				{
					continue;
				}
				bool flag = ((!action.Special) ? (!button && Hold(action.Key)) : (action.GpAlone ? buttonDown : (button && Down(action.Key))));
				if (!action.Special && !button)
				{
					int num = NormalIndex(action);
					if (num >= 0 && num <= 2 && Input.GetMouseButton(num))
					{
						flag = true;
					}
				}
				if (flag)
				{
					Fire(h, action, look);
					break;
				}
			}
		}

		private static int NormalIndex(ActorAction a)
		{
			int num = 0;
			foreach (ActorAction action in _actions)
			{
				if (!action.Special && !((Object)(object)action.Weapon == (Object)null))
				{
					if (action == a)
					{
						return num;
					}
					num++;
				}
			}
			return -1;
		}

		private static void Fire(Humanoid h, ActorAction a, Vector3 look)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (((Character)h).InAttack())
			{
				return;
			}
			ItemData val = FindItem(h, a.Weapon);
			if (val == null)
			{
				return;
			}
			((Character)h).SetLookDir(look, 0f);
			_aimUntil = Time.time + 0.7f;
			if ((Object)(object)a.Weapon == (Object)(object)h.m_unarmedWeapon)
			{
				if (h.RightItem != null)
				{
					h.UnequipItem(h.RightItem, false);
				}
				if (h.LeftItem != null && h.LeftItem.IsWeapon())
				{
					h.UnequipItem(h.LeftItem, false);
				}
			}
			else if (h.GetCurrentWeapon() != val)
			{
				h.EquipItem(val, false);
				if (h.GetCurrentWeapon() != val)
				{
					Plugin.Warn("The Paid Actor: " + ((Object)a.Weapon).name + " could not be held; its attack is skipped.");
					return;
				}
			}
			((Character)h).StartAttack((Character)null, a.Secondary);
		}

		private static void Voices(Character c)
		{
			//IL_0005: 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_004c: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!Hold(KeyOf("sndmod")))
			{
				return;
			}
			foreach (ActorAction action in _actions)
			{
				if (action.Sound != null && Down(action.Key))
				{
					try
					{
						action.Sound.Create(((Component)c).transform.position, ((Component)c).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
					}
					catch (Exception ex)
					{
						Plugin.Warn("Sound failed: " + ex.Message);
					}
					ActorUi.Info(action.Label + ".");
					break;
				}
			}
		}

		private static bool HasParam(Animator a, string name)
		{
			AnimatorControllerParameter[] parameters = a.parameters;
			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i].name == name)
				{
					return true;
				}
			}
			return false;
		}

		public static bool Emote(string emote, bool oneshot)
		{
			Character mob = Mob;
			if ((Object)(object)mob == (Object)null)
			{
				return (Object)(object)ItemGo != (Object)null;
			}
			try
			{
				Plugin.Dbg("Emote asked for: " + emote + " (oneshot " + oneshot + ") by " + ((Object)mob).name);
				Animator componentInChildren = ((Component)mob).GetComponentInChildren<Animator>();
				if (string.IsNullOrEmpty(emote))
				{
					return true;
				}
				if ((Object)(object)componentInChildren == (Object)null)
				{
					EmoteAnim emoteAnim = ((Component)mob).GetComponent<EmoteAnim>();
					if ((Object)(object)emoteAnim == (Object)null)
					{
						emoteAnim = ((Component)mob).gameObject.AddComponent<EmoteAnim>();
					}
					emoteAnim.Play(emote, oneshot, mob.GetHeight());
					return true;
				}
				string text = "emote_" + emote;
				ZSyncAnimation component = ((Component)mob).GetComponent<ZSyncAnimation>();
				if (!HasParam(componentInChildren, text))
				{
					EmoteAnim emoteAnim2 = ((Component)mob).GetComponent<EmoteAnim>();
					if ((Object)(object)emoteAnim2 == (Object)null)
					{
						emoteAnim2 = ((Component)mob).gameObject.AddComponent<EmoteAnim>();
					}
					if (!emoteAnim2.Play(emote, oneshot, mob.GetHeight()))
					{
						Plugin.Toast(mob.m_name + " cannot do '" + emote + "'");
					}
					return true;
				}
				if (!string.IsNullOrEmpty(_emoteState) && HasParam(componentInChildren, "emote_" + _emoteState))
				{
					componentInChildren.SetBool("emote_" + _emoteState, false);
				}
				_emoteState = "";
				if (oneshot)
				{
					if ((Object)(object)component != (Object)null)
					{
						component.SetTrigger(text);
					}
					else
					{
						componentInChildren.SetTrigger(text);
					}
				}
				else
				{
					_emoteState = emote;
					componentInChildren.SetBool(text, true);
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("Emote failed: " + ex.Message);
			}
			return true;
		}

		private static void SpeedWheel()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (SpeedHeld)
			{
				float y = Input.mouseScrollDelta.y;
				if (!(Mathf.Abs(y) < 0.01f))
				{
					_flyMul = Mathf.Clamp(_flyMul * Mathf.Pow(1.2f, Mathf.Sign(y)), 0.1f, 20f);
					Plugin.Toast("Flight speed x" + _flyMul.ToString("0.0#"));
				}
			}
		}

		private static void DriveWalker(Player p, Transform t)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0039: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			bool num = InputOk(p);
			Vector3 lookDir = ((Character)p).GetLookDir();
			Vector3 forward = default(Vector3);
			((Vector3)(ref forward))..ctor(lookDir.x, 0f, lookDir.z);
			if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f)
			{
				forward = ((Component)p).transform.forward;
			}
			((Vector3)(ref forward)).Normalize();
			Vector3 zero = Vector3.zero;
			bool flag = false;
			if (num)
			{
				if (ZInput.GetButton("Forward"))
				{
					zero.z += 1f;
				}
				if (ZInput.GetButton("Backward"))
				{
					zero.z -= 1f;
				}
				if (ZInput.GetButton("Left"))
				{
					zero.x -= 1f;
				}
				if (ZInput.GetButton("Right"))
				{
					zero.x += 1f;
				}
				Vector2 joyLeftStick = ZInput.GetJoyLeftStick();
				zero.x += joyLeftStick.x;
				zero.z += joyLeftStick.y;
				if (((Vector3)(ref zero)).magnitude > 1f)
				{
					((Vector3)(ref zero)).Normalize();
				}
				flag = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun");
			}
			float deltaTime = Time.deltaTime;
			Vector3 val = Quaternion.LookRotation(forward) * zero;
			float num2 = Mathf.Clamp01(((Vector3)(ref zero)).magnitude);
			float num3 = (flag ? 7f : 3.5f) * Mathf.Max(1f, Mathf.Sqrt(_size));
			Vector3 val2 = t.position + val * num3 * deltaTime;
			if (num2 > 0.05f)
			{
				_walkYaw = Mathf.MoveTowardsAngle(_walkYaw, Mathf.Atan2(val.x, val.z) * 57.29578f, 540f * deltaTime);
			}
			float num4 = default(float);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetSolidHeight(new Vector3(val2.x, val2.y + 2f, val2.z), ref num4, 1000))
			{
				val2.y = Mathf.Lerp(val2.y, num4, Mathf.Clamp01(14f * deltaTime));
			}
			_walkAmt = Mathf.MoveTowards(_walkAmt, num2 * (flag ? 1.6f : 1f), 6f * deltaTime);
			_walkPhase += _walkAmt * (flag ? 10f : 7f) * deltaTime;
			float num5 = Mathf.Min(_walkAmt, 1.6f);
			val2.y += Mathf.Abs(Mathf.Sin(_walkPhase)) * 0.07f * num5;
			t.position = val2;
			t.rotation = Quaternion.Euler(6f * num5, _walkYaw, Mathf.Sin(_walkPhase) * 4f * num5);
		}

		private static void DriveItem(Player p, Transform t)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: 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_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: 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_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			if (_walk)
			{
				DriveWalker(p, t);
				return;
			}
			bool num = InputOk(p);
			Vector3 lookDir = ((Character)p).GetLookDir();
			Vector3 forward = default(Vector3);
			((Vector3)(ref forward))..ctor(lookDir.x, 0f, lookDir.z);
			if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f)
			{
				forward = ((Component)p).transform.forward;
			}
			((Vector3)(ref forward)).Normalize();
			Vector3 zero = Vector3.zero;
			bool flag = false;
			float num2 = 0f;
			if (num)
			{
				if (ZInput.GetButton("Forward"))
				{
					zero.z += 1f;
				}
				if (ZInput.GetButton("Backward"))
				{
					zero.z -= 1f;
				}
				if (ZInput.GetButton("Left"))
				{
					zero.x -= 1f;
				}
				if (ZInput.GetButton("Right"))
				{
					zero.x += 1f;
				}
				Vector2 joyLeftStick = ZInput.GetJoyLeftStick();
				zero.x += joyLeftStick.x;
				zero.z += joyLeftStick.y;
				if (((Vector3)(ref zero)).magnitude > 1f)
				{
					((Vector3)(ref zero)).Normalize();
				}
				flag = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun");
				if (ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"))
				{
					num2 += 1f;
				}
				if (Plugin.KeyHeld(Plugin.FlyDownKey.Value))
				{
					num2 -= 1f;
				}
				float num3 = 0f;
				if (Hold(KeyOf("rotr")))
				{
					num3 += 1f;
				}
				if (Hold(KeyOf("rotl")))
				{
					num3 -= 1f;
				}
				if (num3 != 0f)
				{
					t.Rotate(0f, num3 * 90f * Time.deltaTime, 0f, (Space)0);
				}
				if (Entry != null && Entry.Free && (Object)(object)ItemGo != (Object)null && (Object)(object)Entry.Go != (Object)null && (Object)(object)Entry.Go.GetComponentInChildren<Raven>(true) != (Object)null)
				{
					RavenKeys();
				}
			}
			Vector3 val = Quaternion.LookRotation(forward) * zero + Vector3.up * num2;
			SpeedWheel();
			float num4 = Plugin.PieceSpeed.Value * _flyMul * (flag ? 2.5f : 1f) * Mathf.Max(1f, Mathf.Sqrt(_size));
			t.position += val * num4 * Time.deltaTime;
		}

		private static void CleanOrphans(Player p)
		{
			if (Plugin.CleanOrphans == null || !Plugin.CleanOrphans.Value)
			{
				return;
			}
			_orphanTimer -= Time.unscaledDeltaTime;
			if (_orphanTimer > 0f)
			{
				return;
			}
			_orphanTimer = 6f;
			try
			{
				long playerID = p.GetPlayerID();
				foreach (Character item in new List<Character>(Character.GetAllCharacters()))
				{
					if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)Mob) && !item.IsPlayer())
					{
						ZNetView component = ((Component)item).GetComponent<ZNetView>();
						if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner() && component.GetZDO().GetLong("CanoCT_Puppet", 0L) == playerID)
						{
							Plugin.Dbg("The Paid Actor: removed a creature left over from an earlier session (" + ((Object)item).name + ").");
							ZNetScene.instance.Destroy(((Component)item).gameObject);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("Orphan check failed: " + ex.Message);
			}
		}

		internal static bool IsPuppet(Object owner, ZNetView nv)
		{
			if (owner == (Object)null || (Object)(object)nv == (Object)null)
			{
				return false;
			}
			int instanceID = owner.GetInstanceID();
			if (PuppetCache.TryGetValue(instanceID, out var value) && value.Key > Time.time)
			{
				return value.Value;
			}
			bool flag = false;
			try
			{
				flag = nv.IsValid() && nv.GetZDO().GetLong("CanoCT_Puppet", 0L) != 0;
			}
			catch
			{
			}
			if (PuppetCache.Count > 2000)
			{
				PuppetCache.Clear();
			}
			PuppetCache[instanceID] = new KeyValuePair<float, bool>(Time.time + 1.5f, flag);
			return flag;
		}
	}
	internal static class ActorPatches
	{
		[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
		[HarmonyPrefix]
		private static bool ControllerFixed()
		{
			return !Actor.Active;
		}

		[HarmonyPatch(typeof(Player), "UseHotbarItem")]
		[HarmonyPrefix]
		private static bool Hotbar()
		{
			return !Actor.Active;
		}

		[HarmonyPatch(typeof(Player), "StartGuardianPower")]
		[HarmonyPrefix]
		private static bool GuardianPower(ref bool __result)
		{
			if (!Actor.Active)
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(Player), "StartEmote")]
		[HarmonyPrefix]
		private static bool Emote(Player __instance, string emote, bool oneshot, ref bool __result)
		{
			if (!Actor.Active || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (!Plugin.ActorEmotes.Value)
			{
				__result = false;
				return false;
			}
			__result = Actor.Emote(emote, oneshot);
			return false;
		}

		[HarmonyPatch(typeof(ZNetScene), "Destroy")]
		[HarmonyPrefix]
		private static bool KeepMobScene(GameObject go)
		{
			if (!Actor.Protected(go))
			{
				return true;
			}
			Actor.NoteBlocked("ZNetScene.Destroy");
			return false;
		}

		[HarmonyPatch(typeof(ZDOMan), "DestroyZDO")]
		[HarmonyPrefix]
		private static bool KeepMobZdo(ZDO zdo)
		{
			if (zdo == null || !Actor.Active || Actor.Leaving || (Object)(object)Actor.Mob == (Object)null)
			{
				return true;
			}
			ZNetView component = ((Component)Actor.Mob).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() != zdo)
			{
				return true;
			}
			Actor.NoteBlocked("ZDOMan.DestroyZDO");
			return false;
		}

		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		[HarmonyPrefix]
		private static bool Damage(Character __instance)
		{
			if (Actor.God || ActorTools.Mode != ToolKind.None)
			{
				return !((Object)(object)__instance == (Object)(object)Actor.Mob);
			}
			return true;
		}

		[HarmonyPatch(typeof(Character), "OnDeath")]
		[HarmonyPrefix]
		private static bool Death(Character __instance)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Actor.Mob)
			{
				return true;
			}
			Actor.OnMobDied();
			return false;
		}

		[HarmonyPatch(typeof(Humanoid), "GetAimDir")]
		[HarmonyPostfix]
		private static void AimDir(Humanoid __instance, ref Vector3 __result)
		{
			//IL_0029: 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_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)
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Actor.Mob) && !((Object)(object)Player.m_localPlayer == (Object)null))
			{
				Vector3 lookDir = ((Character)Player.m_localPlayer).GetLookDir();
				if (((Vector3)(ref lookDir)).sqrMagnitude > 0.0001f)
				{
					__result = ((Vector3)(ref lookDir)).normalized;
				}
			}
		}

		[HarmonyPatch(typeof(BaseAI), "UpdateAI")]
		[HarmonyPrefix]
		private static bool UpdateAi(BaseAI __instance, ref bool __result, ZNetView ___m_nview)
		{
			if (!Actor.IsPuppet((Object)(object)__instance, ___m_nview))
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(ZNetView), "Awake")]
		[HarmonyPostfix]
		private static void ViewAwake(ZNetView __instance)
		{
			//IL_002f: 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_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_003b: 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)
			Cleanup.Track(__instance);
			try
			{
				ZDO zDO = __instance.GetZDO();
				if (zDO != null && !__instance.m_syncInitialScale && zDO.GetLong("CanoCT_Puppet", 0L) != 0L)
				{
					Vector3 vec = zDO.GetVec3(ZDOVars.s_scaleHash, Vector3.zero);
					if (vec != Vector3.zero)
					{
						((Component)__instance).transform.localScale = vec;
					}
				}
			}
			catch
			{
			}
		}
	}
	internal static class ActorNet
	{
		private sealed class Remote
		{
			public GameObject Go;

			public string Prefab;

			public Vector3 Pos;

			public Vector3 Scale;

			public Quaternion Rot;

			public float Seen;
		}

		internal sealed class RemoteTarget : MonoBehaviour, IDestructible
		{
			internal long Owner;

			private float _last;

			public void Damage(HitData hit)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				if (!(Time.time - _last < 0.7f))
				{
					_last = Time.time;
					SendPoof(Owner);
					Fx.Poof(((Component)this).transform.position, sound: true);
				}
			}

			public DestructibleType GetDestructibleType()
			{
				return (DestructibleType)4;
			}
		}

		private const string RPiece = "CanoCT_Piece";

		private const string RPoof = "CanoCT_Poof";

		private const int Version = 1;

		private static ZRoutedRpc _rpc;

		private static readonly Dictionary<long, Remote> Others = new Dictionary<long, Remote>();

		private static float _sendAt;

		private static bool _sending;

		private static int _layer = -1;

		public static void Register()
		{
			try
			{
				ZRoutedRpc instance = ZRoutedRpc.instance;
				if (instance != null && instance != _rpc)
				{
					Clear();
					_rpc = instance;
					_sending = false;
					instance.Register<ZPackage>("CanoCT_Piece", (Action<long, ZPackage>)OnPiece);
					instance.Register<ZPackage>("CanoCT_Poof", (Action<long, ZPackage>)OnPoof);
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("Piece sync could not register: " + ex.Message);
			}
		}

		private static void Clear()
		{
			foreach (Remote value in Others.Values)
			{
				if ((Object)(object)value.Go != (Object)null)
				{
					Object.Destroy((Object)(object)value.Go);
				}
			}
			Others.Clear();
		}

		private static void Send(bool on)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_005d: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			if (_rpc == null || ZRoutedRpc.instance != _rpc)
			{
				return;
			}
			try
			{
				ZPackage val = new ZPackage();
				val.Write(1);
				val.Write(on);
				if (on && (Object)(object)Actor.ItemGo != (Object)null && Actor.Entry != null)
				{
					Transform transform = Actor.ItemGo.transform;
					val.Write(Actor.Entry.Prefab);
					val.Write(transform.position);
					val.Write(transform.rotation);
					val.Write(transform.localScale);
				}
				else
				{
					on = false;
				}
				_rpc.InvokeRoutedRPC(0L, "CanoCT_Piece", new object[1] { val });
			}
			catch (Exception ex)
			{
				Plugin.Warn("Piece sync: sending failed: " + ex.Message);
			}
		}

		private static void OnPoof(long sender, ZPackage pkg)
		{
			try
			{
				if (Plugin.PoofByOthers.Value && !((Object)(object)Actor.ItemGo == (Object)null) && Actor.Entry != null && Actor.Entry.Kind == ActorKind.Item && !Actor.Entry.Free)
				{
					string lastName = Actor.LastName;
					Actor.UnBecome(poof: true, toast: false);
					Plugin.Toast("Someone poofed you out of the " + lastName);
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("Poof message failed: " + ex.Message);
			}
		}

		internal static void SendPoof(long target)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if (_rpc == null || ZRoutedRpc.instance != _rpc)
			{
				return;
			}
			try
			{
				ZPackage val = new ZPackage();
				val.Write(1);
				_rpc.InvokeRoutedRPC(target, "CanoCT_Poof", new object[1] { val });
			}
			catch (Exception ex)
			{
				Plugin.Warn("Poof could not be sent: " + ex.Message);
			}
		}

		private static void AddHitBox(GameObject go, long owner)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = default(Bounds);
			((Bounds)(ref bounds))..ctor(go.transform.position, Vector3.zero);
			bool flag = false;
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(false);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is ParticleSystemRenderer))
				{
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			if (flag)
			{
				if (_layer < 0)
				{
					_layer = LayerMask.NameToLayer("piece_nonsolid");
				}
				GameObject val2 = new GameObject("ContentToolsPoofTarget")
				{
					layer = ((_layer >= 0) ? _layer : 0)
				};
				val2.transform.SetParent(go.transform, false);
				BoxCollider obj = val2.AddComponent<BoxCollider>();
				((Collider)obj).isTrigger = true;
				Vector3 lossyScale = go.transform.lossyScale;
				Vector3 center = go.transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
				obj.center = center;
				obj.size = new Vector3(((Bounds)(ref bounds)).size.x / Mathf.Max(0.001f, lossyScale.x), ((Bounds)(ref bounds)).size.y / Mathf.Max(0.001f, lossyScale.y), ((Bounds)(ref bounds)).size.z / Mathf.Max(0.001f, lossyScale.z));
				val2.AddComponent<RemoteTarget>().Owner = owner;
			}
		}

		private static void OnPiece(long sender, ZPackage pkg)
		{
			//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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be