Decompiled source of PlayAsMob v1.0.3

plugins/PlayAsMob/PlayAsMob.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("PlayAsMob.RuntimeTests")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("PlayAsMob")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+1dc033dea39071e9b43f2cdfd627c8e5b6e4409b")]
[assembly: AssemblyProduct("PlayAsMob")]
[assembly: AssemblyTitle("PlayAsMob")]
[assembly: AssemblyVersion("1.0.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PlayAsMob
{
	internal sealed class AttackSlots
	{
		internal sealed class Entry
		{
			internal ItemData Item;

			internal bool Secondary;

			internal string Name => (Object.op_Implicit((Object)(object)Item.m_dropPrefab) ? ((Object)Item.m_dropPrefab).name : Item.m_shared.m_name) + (Secondary ? " (secondary)" : "");
		}

		private readonly List<Entry>[] _slots = new List<Entry>[3]
		{
			new List<Entry>(),
			new List<Entry>(),
			new List<Entry>()
		};

		private readonly int[] _next = new int[3];

		private readonly Humanoid _mob;

		private float _nextAttack;

		private int _activeSlot = -1;

		private static readonly FieldRef<Humanoid, Attack> CurrentAttack = AccessTools.FieldRefAccess<Humanoid, Attack>("m_currentAttack");

		internal AttackSlots(Character character)
		{
			_mob = (Humanoid)(object)((character is Humanoid) ? character : null);
			if (!Object.op_Implicit((Object)(object)_mob))
			{
				return;
			}
			List<ItemData> list = new List<ItemData>(_mob.GetInventory().GetAllItems());
			ItemData currentWeapon = _mob.GetCurrentWeapon();
			if (currentWeapon != null && !list.Contains(currentWeapon))
			{
				list.Add(currentWeapon);
			}
			List<Entry> list2 = new List<Entry>();
			foreach (ItemData item in list.Where((ItemData i) => i.IsWeapon()))
			{
				if (item.HavePrimaryAttack())
				{
					list2.Add(new Entry
					{
						Item = item
					});
				}
				if (item.HaveSecondaryAttack())
				{
					list2.Add(new Entry
					{
						Item = item,
						Secondary = true
					});
				}
			}
			list2 = list2.OrderBy((Entry e) => Rank(e)).ToList();
			for (int num = 0; num < list2.Count; num++)
			{
				_slots[num % 3].Add(list2[num]);
			}
			if (list2.Count <= 0)
			{
				return;
			}
			for (int num2 = 0; num2 < 3; num2++)
			{
				if (_slots[num2].Count == 0)
				{
					_slots[num2].Add(list2[num2 % list2.Count]);
				}
			}
		}

		private static int Rank(Entry e)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Invalid comparison between Unknown and I4
			string text = e.Name.ToLowerInvariant();
			if (text.Contains("troll_punch") || text.Contains("troll_log_swing"))
			{
				return -30;
			}
			if (text.Contains("troll_groundslam") || text.Contains("troll_log_slam"))
			{
				return -20;
			}
			if (text.Contains("troll_throw"))
			{
				return -10;
			}
			Attack val = (e.Secondary ? e.Item.m_shared.m_secondaryAttack : e.Item.m_shared.m_attack);
			if ((int)e.Item.m_shared.m_aiTargetType != 0)
			{
				return 20;
			}
			if ((int)val.m_attackType != 2)
			{
				return 0;
			}
			return 10;
		}

		internal string Describe(int slot)
		{
			if (_slots[slot].Count != 0)
			{
				return string.Join(" / ", _slots[slot].Select((Entry e) => e.Name));
			}
			return "brak ataku";
		}

		internal void UpdateHeldSlot(int slot)
		{
			if (Object.op_Implicit((Object)(object)_mob) && slot != _activeSlot)
			{
				Attack val = CurrentAttack.Invoke(_mob);
				if (val != null && val.m_loopingAttack)
				{
					val.Stop();
				}
			}
		}

		internal bool TryAttack(int slot)
		{
			if (!Object.op_Implicit((Object)(object)_mob) || ((Character)_mob).IsDead() || Time.time < _nextAttack || ((Character)_mob).InAttack() || _slots[slot].Count == 0)
			{
				return false;
			}
			List<Entry> list = _slots[slot];
			Entry entry = list[_next[slot] % list.Count];
			if (Time.time - entry.Item.m_lastAttackTime < entry.Item.m_shared.m_aiAttackInterval)
			{
				return false;
			}
			if (_mob.GetCurrentWeapon() != entry.Item)
			{
				if (Object.op_Implicit((Object)(object)_mob.m_unarmedWeapon) && entry.Item == _mob.m_unarmedWeapon.m_itemData)
				{
					_mob.UnequipItem(_mob.GetCurrentWeapon(), false);
				}
				else if (!_mob.EquipItem(entry.Item, false))
				{
					return false;
				}
			}
			if (!((Character)_mob).StartAttack((Character)null, entry.Secondary))
			{
				return false;
			}
			_activeSlot = slot;
			_next[slot] = (_next[slot] + 1) % list.Count;
			_nextAttack = Time.time + 0.2f;
			return true;
		}
	}
	internal static class AxisBinding
	{
		internal static Func<float> Create(Type inputType, string name)
		{
			MethodInfo method = inputType.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null);
			if (method != null && method.ReturnType == typeof(float))
			{
				return (Func<float>)Delegate.CreateDelegate(typeof(Func<float>), method);
			}
			MethodInfo method2 = inputType.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(bool) }, null);
			if (method2 != null && method2.ReturnType == typeof(float))
			{
				ParameterInfo parameterInfo = method2.GetParameters()[0];
				if (parameterInfo.HasDefaultValue)
				{
					object defaultValue = parameterInfo.DefaultValue;
					if (defaultValue is bool)
					{
						bool defaultValue2 = (bool)defaultValue;
						Func<bool, float> read = (Func<bool, float>)Delegate.CreateDelegate(typeof(Func<bool, float>), method2);
						return () => read(defaultValue2);
					}
				}
			}
			throw new MissingMethodException(inputType.FullName, name + "() or " + name + "(optional bool)");
		}
	}
	internal sealed class CommandOptions
	{
		public string Name;

		public int Level = 1;

		public bool Exit;

		public bool Help;

		public bool Attacks;

		public static bool TryParse(string[] args, out CommandOptions options, out string error)
		{
			options = new CommandOptions();
			error = null;
			if (args == null || args.Length < 2)
			{
				options.Help = true;
				return true;
			}
			string text = args[1];
			options.Exit = string.Equals(text, "exit", StringComparison.OrdinalIgnoreCase);
			options.Help = string.Equals(text, "help", StringComparison.OrdinalIgnoreCase);
			options.Attacks = string.Equals(text, "attacks", StringComparison.OrdinalIgnoreCase);
			if (options.Exit || options.Help || options.Attacks)
			{
				if (args.Length == 2)
				{
					return true;
				}
				error = "Ta podkomenda nie przyjmuje dodatkowych argumentow.";
				return false;
			}
			if (args.Length > 3 || string.IsNullOrWhiteSpace(text))
			{
				error = "Uzycie: playasmob <prefab> [poziom=1] | exit | attacks";
				return false;
			}
			if (args.Length == 3 && (!int.TryParse(args[2], NumberStyles.None, CultureInfo.InvariantCulture, out options.Level) || options.Level < 1))
			{
				error = "Poziom musi byc dodatnia liczba calkowita: 1 = 0 gwiazdek, 2 = 1 gwiazdka.";
				return false;
			}
			options.Name = text;
			return true;
		}
	}
	internal static class InputAxes
	{
		internal static readonly Func<float> RightX = AxisBinding.Create(typeof(ZInput), "GetJoyRightStickX");

		internal static readonly Func<float> RightY = AxisBinding.Create(typeof(ZInput), "GetJoyRightStickY");

		internal static readonly Func<float> LeftX = AxisBinding.Create(typeof(ZInput), "GetJoyLeftStickX");

		internal static readonly Func<float> LeftY = AxisBinding.Create(typeof(ZInput), "GetJoyLeftStickY");
	}
	[HarmonyPatch(typeof(Player), "TakeInput")]
	internal static class BodyInputPatch
	{
		private static bool Prefix(Player __instance, ref bool __result)
		{
			if ((Object)(object)PlayAsMobPlugin.Current?.Player != (Object)(object)__instance)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "PlayerAttackInput")]
	internal static class BodyAttackInputPatch
	{
		private static bool Prefix(Player __instance)
		{
			return (Object)(object)PlayAsMobPlugin.Current?.Player != (Object)(object)__instance;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	internal static class BodyAttackPatch
	{
		private static bool Prefix(Humanoid __instance, ref bool __result)
		{
			if ((Object)(object)PlayAsMobPlugin.Current?.Player != (Object)(object)__instance)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateMotion")]
	internal static class BodyMotionPatch
	{
		private static bool Prefix(Character __instance)
		{
			return (Object)(object)PlayAsMobPlugin.Current?.Player != (Object)(object)__instance;
		}
	}
	[HarmonyPatch(typeof(Character), "AlwaysRotateCamera")]
	internal static class MobFacingPatch
	{
		private static bool Prefix(Character __instance, ref bool __result)
		{
			if ((Object)(object)PlayAsMobPlugin.Current?.Mob != (Object)(object)__instance)
			{
				return true;
			}
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Attack), "GetProjectileSpawnPoint")]
	internal static class ProjectileAimPatch
	{
		private static void Postfix(Humanoid ___m_character, Vector3 spawnPoint, ref Vector3 aimDir)
		{
			//IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			Possession current = PlayAsMobPlugin.Current;
			if (current != null && (Object)(object)current.Mob == (Object)(object)___m_character)
			{
				aimDir = current.AimDirection(spawnPoint);
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
	internal static class CameraPatch
	{
		private static bool Prefix(GameCamera __instance)
		{
			Possession current = PlayAsMobPlugin.Current;
			if (current == null || !Object.op_Implicit((Object)(object)current.Mob))
			{
				return true;
			}
			if (GameCamera.InFreeFly())
			{
				__instance.ToggleFreeFly();
			}
			current.UpdateCamera(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateListner")]
	internal static class ListenerPatch
	{
		private static void Postfix(AudioListener ___m_listner)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Possession current = PlayAsMobPlugin.Current;
			if (current != null && Object.op_Implicit((Object)(object)current.Mob) && Object.op_Implicit((Object)(object)___m_listner))
			{
				((Component)___m_listner).transform.position = current.Mob.GetEyePoint();
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "SetReferencePosition")]
	internal static class ReferencePatch
	{
		[HarmonyPriority(0)]
		private static void Prefix(ref Vector3 __0)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Possession current = PlayAsMobPlugin.Current;
			if (current != null && Object.op_Implicit((Object)(object)current.Mob))
			{
				__0 = ((Component)current.Mob).transform.position;
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "Update")]
	internal static class BodyTerrainPatch
	{
		private static readonly Func<ZoneSystem, Vector3, bool> CreateZones = AccessTools.MethodDelegate<Func<ZoneSystem, Vector3, bool>>(AccessTools.Method(typeof(ZoneSystem), "CreateLocalZones", (Type[])null, (Type[])null), (object)null, true);

		private static float _next;

		private static void Postfix(ZoneSystem __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Possession current = PlayAsMobPlugin.Current;
			if (current != null && !(Time.time < _next) && (int)ZNet.GetConnectionStatus() == 2)
			{
				_next = Time.time + 0.1f;
				CreateZones(__instance, current.Anchor);
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "CreateObjects")]
	internal static class BodyObjectsPatch
	{
		private static readonly List<ZDO> Near = new List<ZDO>();

		private static readonly List<ZDO> Far = new List<ZDO>();

		private static readonly HashSet<ZDO> Seen = new HashSet<ZDO>();

		private static void Prefix(List<ZDO> __0, List<ZDO> __1)
		{
			//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_0033: Unknown result type (might be due to invalid IL or missing references)
			Possession current = PlayAsMobPlugin.Current;
			if (current == null || ZDOMan.instance == null || !Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return;
			}
			try
			{
				ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(current.Anchor), ZNet.instance.GetSyncedSimulationDistance(), Near, Far);
				Seen.UnionWith(__0);
				foreach (ZDO item in Near)
				{
					if (Seen.Add(item))
					{
						__0.Add(item);
					}
				}
				__1.RemoveAll(Seen.Contains);
				Seen.UnionWith(__1);
				foreach (ZDO item2 in Far)
				{
					if (Seen.Add(item2))
					{
						__1.Add(item2);
					}
				}
			}
			finally
			{
				Near.Clear();
				Far.Clear();
				Seen.Clear();
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Shutdown")]
	internal static class ShutdownPatch
	{
		private static void Prefix()
		{
			PlayAsMobPlugin.End(null);
		}
	}
	[BepInPlugin("com.tenzly.playasmob", "PlayAsMob", "1.0.3")]
	public sealed class PlayAsMobPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ConsoleEventFailable <0>__Execute;

			public static ConsoleOptionsFetcher <1>__Options;

			public static Func<GameObject, bool> <2>__IsMob;
		}

		public const string Id = "com.tenzly.playasmob";

		internal static Possession Current;

		internal static ManualLogSource Log;

		private static PlayAsMobPlugin _instance;

		private Harmony _harmony;

		private ConfigEntry<bool> _showHud;

		private GUIStyle _hudStyle;

		private void Awake()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			_instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_showHud = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMobHud", true, "Show creature health and its three attack slots while possessing.");
			_harmony = new Harmony("com.tenzly.playasmob");
			_harmony.PatchAll(typeof(PlayAsMobPlugin).Assembly);
			object obj = <>O.<0>__Execute;
			if (obj == null)
			{
				ConsoleEventFailable val = Execute;
				<>O.<0>__Execute = val;
				obj = (object)val;
			}
			object obj2 = <>O.<1>__Options;
			if (obj2 == null)
			{
				ConsoleOptionsFetcher val2 = Options;
				<>O.<1>__Options = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("playasmob", "Control a creature: playasmob <prefab> [level=1] | exit | attacks | help", (ConsoleEventFailable)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, true, false, false);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"PlayAsMob 1.0.3: registered playasmob; native creatures, levels and attacks (compatible stick input API).");
		}

		internal static bool IsMob(GameObject prefab)
		{
			if (Object.op_Implicit((Object)(object)prefab) && Object.op_Implicit((Object)(object)prefab.GetComponent<Character>()) && !Object.op_Implicit((Object)(object)prefab.GetComponent<Player>()))
			{
				return Object.op_Implicit((Object)(object)prefab.GetComponent<BaseAI>());
			}
			return false;
		}

		private static List<string> Options()
		{
			List<string> list = new List<string> { "exit", "attacks", "help" };
			if (Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				list.AddRange(from n in (from p in ZNetScene.instance.m_prefabs.Where(IsMob)
						select ((Object)p).name).Distinct()
					orderby n
					select n);
			}
			return list;
		}

		internal static object Execute(ConsoleEventArgs args)
		{
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			if (!CommandOptions.TryParse(args.Args, out var options, out var error))
			{
				return Reply(args, error, result: false);
			}
			if (options.Help)
			{
				return Reply(args, "playasmob <prefab> [poziom=1] | exit | attacks\nPrzyklad: playasmob troll 2 = troll z 1 gwiazdka. Tab podpowiada nazwy.\nAtak / silny atak / blok uruchamiaja ataki moba. Exit oddaje moba AI.");
			}
			if (options.Exit)
			{
				if (Current == null)
				{
					return Reply(args, "Nie sterujesz mobem.");
				}
				End("Wracasz do swojej postaci. Mob jest teraz sterowany przez AI.");
				return true;
			}
			if (options.Attacks)
			{
				if (Current?.Attacks == null)
				{
					return Reply(args, "Brak aktywnego moba lub jego ataki jeszcze sie inicjalizuja.", result: false);
				}
				return Reply(args, "Atak: " + Current.Attacks.Describe(0) + "\nSilny atak: " + Current.Attacks.Describe(1) + "\nBlok: " + Current.Attacks.Describe(2));
			}
			if (!Object.op_Implicit((Object)(object)_instance) || !((Behaviour)_instance).isActiveAndEnabled)
			{
				return Reply(args, "Plugin PlayAsMob jest wylaczony.", result: false);
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)GameCamera.instance))
			{
				return Reply(args, "Najpierw wejdz do swiata.", result: false);
			}
			if (((Character)localPlayer).IsDead() || ((Character)localPlayer).GetHealth() <= 0f || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).InAttack() || ((Character)localPlayer).InDodge())
			{
				return Reply(args, "Zaczekaj do konca ataku, teleportacji lub sceny; zejdz z wierzchowca/pojazdu.", result: false);
			}
			GameObject val = ((IEnumerable<GameObject>)ZNetScene.instance.m_prefabs).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => Object.op_Implicit((Object)(object)p) && string.Equals(((Object)p).name, options.Name, StringComparison.OrdinalIgnoreCase)));
			if (!IsMob(val))
			{
				return Reply(args, "Nie znaleziono moba: " + options.Name + ". Uzyj Tab, aby wybrac nazwe prefabu.", result: false);
			}
			Vector3 position = ((Component)GameCamera.instance).transform.position;
			Quaternion rotation = ((Component)GameCamera.instance).transform.rotation;
			if (!ZNetScene.instance.IsAreaReady(position))
			{
				return Reply(args, "Obszar przy kamerze nie jest jeszcze zaladowany.", result: false);
			}
			GameObject val2 = null;
			try
			{
				val2 = Object.Instantiate<GameObject>(val, position, Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f));
				Character component = val2.GetComponent<Character>();
				ZNetView component2 = val2.GetComponent<ZNetView>();
				if (!Object.op_Implicit((Object)(object)component2) || !component2.IsValid() || !component2.IsOwner())
				{
					throw new InvalidOperationException("Brak kontroli sieciowej nad nowym mobem.");
				}
				component.SetLevel(options.Level);
				component.SetHealth(component.GetMaxHealth());
				End(null);
				Current = new Possession(localPlayer, component, ((Object)val).name, rotation);
				Current.Begin();
				PublicMapPosition.SetPossessing(active: true);
				ZNet.instance.SetReferencePosition(position);
				return Reply(args, "Sterujesz " + ((Object)val).name + " (poziom " + options.Level + ", gwiazdki " + (options.Level - 1) + "). Powrot: playasmob exit");
			}
			catch (Exception ex)
			{
				End(null);
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)ZNetScene.instance))
				{
					ZNetScene.instance.Destroy(val2);
				}
				Log.LogError((object)ex);
				return Reply(args, "Nie udalo sie przejac moba: " + ex.Message, result: false);
			}
		}

		private static bool Reply(ConsoleEventArgs args, string message, bool result = true)
		{
			args.Context.AddString(message);
			return result;
		}

		internal static void End(string message)
		{
			Possession current = Current;
			Current = null;
			PublicMapPosition.SetPossessing(active: false);
			if (current == null)
			{
				return;
			}
			try
			{
				current.Release();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Release failed: " + ex));
			}
			if (message != null)
			{
				Log.LogInfo((object)message);
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					((Character)Player.m_localPlayer).Message((MessageType)1, message, 0, (Sprite)null, false);
				}
				if (Object.op_Implicit((Object)(object)Console.instance))
				{
					((Terminal)Console.instance).AddString(message);
				}
			}
		}

		private void Update()
		{
			if (Current == null)
			{
				return;
			}
			try
			{
				if (!Current.CheckValid(out var reason))
				{
					End(reason);
				}
				else
				{
					Current.ReadInput();
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex);
				End("Sterowanie przerwane po bledzie; przywrocono postac gracza.");
			}
		}

		private void FixedUpdate()
		{
			if (Current == null)
			{
				return;
			}
			try
			{
				if (!Current.CheckValid(out var reason))
				{
					End(reason);
				}
				else
				{
					Current.Tick(Time.fixedDeltaTime);
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex);
				End("Sterowanie przerwane po bledzie; przywrocono postac gracza.");
			}
		}

		private void OnGUI()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0073: Expected O, but got Unknown
			//IL_0078: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			Possession current = Current;
			if (_showHud.Value && current != null && Object.op_Implicit((Object)(object)current.Mob) && !Console.IsVisible() && !Menu.IsVisible())
			{
				if (_hudStyle == null)
				{
					_hudStyle = new GUIStyle(GUI.skin.box)
					{
						alignment = (TextAnchor)0,
						fontSize = 15,
						wordWrap = true,
						padding = new RectOffset(12, 12, 10, 10)
					};
				}
				string text = current.Prefab + "  |  poziom " + current.Mob.GetLevel() + "  |  HP " + Mathf.CeilToInt(current.Mob.GetHealth()) + "/" + Mathf.CeilToInt(current.Mob.GetMaxHealth());
				if (current.Attacks != null)
				{
					text = text + "\nAtak: " + current.Attacks.Describe(0) + "\nSilny atak: " + current.Attacks.Describe(1) + "\nBlok: " + current.Attacks.Describe(2);
				}
				text += "\nPowrot: playasmob exit";
				float num = Mathf.Min(620f, (float)Screen.width - 30f);
				float num2 = _hudStyle.CalcHeight(new GUIContent(text), num);
				GUI.Box(new Rect(((float)Screen.width - num) / 2f, (float)Screen.height - num2 - 35f, num, num2), text, _hudStyle);
			}
		}

		private void OnDisable()
		{
			End(null);
		}

		private void OnDestroy()
		{
			End(null);
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal sealed class Possession
	{
		internal readonly Player Player;

		internal readonly Character Mob;

		internal readonly Vector3 Anchor;

		internal readonly string Prefab;

		internal AttackSlots Attacks;

		private readonly BaseAI[] _ais;

		private readonly bool[] _aiEnabled;

		private readonly Rigidbody _playerBody;

		private readonly RigidbodyConstraints _constraints;

		private readonly PlayerController _controller;

		private readonly bool _controllerEnabled;

		private readonly ZNetView _view;

		private readonly bool _canFly;

		private readonly Quaternion _bodyRotation;

		private readonly RaycastHit[] _aimHits = (RaycastHit[])(object)new RaycastHit[64];

		private float _yaw;

		private float _pitch;

		private float _distance;

		private bool _ready;

		private bool _released;

		private bool _jumpPending;

		private bool _run;

		private bool _runPressed;

		private Vector3 _movement;

		private int _attackSlot = -1;

		private int _frame;

		private static readonly Action<MonsterAI> Wake = AccessTools.MethodDelegate<Action<MonsterAI>>(AccessTools.Method(typeof(MonsterAI), "Wakeup", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Action<BaseAI, float> Regenerate = AccessTools.MethodDelegate<Action<BaseAI, float>>(AccessTools.Method(typeof(BaseAI), "UpdateRegeneration", (Type[])null, (Type[])null), (object)null, true);

		internal Quaternion ViewRotation => Quaternion.Euler(_pitch, _yaw, 0f);

		internal Possession(Player player, Character mob, string prefab, Quaternion cameraRotation)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			Player = player;
			Mob = mob;
			Prefab = prefab;
			Anchor = ((Component)player).transform.position;
			_bodyRotation = ((Component)player).transform.rotation;
			_playerBody = ((Component)player).GetComponent<Rigidbody>();
			_constraints = _playerBody.constraints;
			_controller = ((Component)player).GetComponent<PlayerController>();
			_controllerEnabled = Object.op_Implicit((Object)(object)_controller) && ((Behaviour)_controller).enabled;
			_view = ((Component)mob).GetComponent<ZNetView>();
			_ais = ((Component)mob).GetComponents<BaseAI>();
			_aiEnabled = _ais.Select((BaseAI ai) => ((Behaviour)ai).enabled).ToArray();
			_canFly = mob.m_flying || _ais.Any((BaseAI ai) => ai.m_randomFly);
			_yaw = ((Quaternion)(ref cameraRotation)).eulerAngles.y;
			_pitch = Mathf.DeltaAngle(0f, ((Quaternion)(ref cameraRotation)).eulerAngles.x);
			_distance = Mathf.Clamp(mob.GetRadius() * 3f + mob.GetHeight(), 3f, 25f);
			_frame = Time.frameCount;
		}

		internal void Begin()
		{
			//IL_0012: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			Player.m_autoRun = false;
			Player.SetControls(Vector3.zero, false, false, false, false, false, false, false, false, false, false, false);
			if (Object.op_Implicit((Object)(object)_controller))
			{
				((Behaviour)_controller).enabled = false;
			}
			_playerBody.linearVelocity = Vector3.zero;
			_playerBody.angularVelocity = Vector3.zero;
			_playerBody.constraints = (RigidbodyConstraints)126;
			BaseAI[] ais = _ais;
			foreach (BaseAI obj in ais)
			{
				MonsterAI val = (MonsterAI)(object)((obj is MonsterAI) ? obj : null);
				if (val != null)
				{
					Wake(val);
				}
				((Behaviour)obj).enabled = false;
			}
			if (GameCamera.InFreeFly())
			{
				GameCamera.instance.ToggleFreeFly();
			}
			Mob.SetMoveDir(Vector3.zero);
			Mob.SetRun(false);
			Mob.SetWalk(false);
		}

		internal bool CheckValid(out string reason)
		{
			reason = null;
			if (!Object.op_Implicit((Object)(object)Player) || (Object)(object)Player != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)ZNet.instance))
			{
				reason = "Zakonczono sesje sterowania.";
			}
			else if (((Character)Player).IsDead() || ((Character)Player).GetHealth() <= 0f || ((Character)Player).IsTeleporting())
			{
				reason = "Powrot: postac gracza zginela lub rozpoczela teleportacje.";
			}
			else if (!Object.op_Implicit((Object)(object)Mob) || Mob.IsDead() || Mob.GetHealth() <= 0f)
			{
				reason = "Mob zginal. Wracasz do swojej postaci.";
			}
			else if (!Object.op_Implicit((Object)(object)_view) || !_view.IsValid() || !_view.IsOwner())
			{
				reason = "Powrot: utracono sieciowa kontrole nad mobem.";
			}
			return reason == null;
		}

		internal static bool InputAllowed()
		{
			if (!Console.IsVisible() && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Menu.IsVisible() && !TextInput.IsVisible() && !InventoryGui.IsVisible() && !StoreGui.IsVisible() && !Minimap.IsOpen() && !Hud.IsPieceSelectionVisible() && !Hud.InRadial())
			{
				return !UnifiedPopup.IsVisible();
			}
			return false;
		}

		internal void ReadInput()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: 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_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: 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_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			if (!_ready && Time.frameCount > _frame)
			{
				Attacks = new AttackSlots(Mob);
				_ready = true;
				PlayAsMobPlugin.Log.LogInfo((object)(Prefab + ": Attack=" + Attacks.Describe(0) + "; Secondary=" + Attacks.Describe(1) + "; Block=" + Attacks.Describe(2)));
			}
			if (!InputAllowed())
			{
				_movement = Vector3.zero;
				_attackSlot = -1;
				_jumpPending = false;
				_run = false;
				return;
			}
			Vector2 val;
			if (ZInput.IsMouseActive())
			{
				val = ZInput.GetMouseDelta() * PlayerController.m_mouseSens;
				if (PlayerController.m_invertMouse)
				{
					val.y = 0f - val.y;
				}
			}
			else
			{
				val = new Vector2(InputAxes.RightX(), 0f - InputAxes.RightY()) * (110f * Time.deltaTime * PlayerController.m_gamepadSens);
				if (PlayerController.m_invertCameraX)
				{
					val.x = 0f - val.x;
				}
				if (PlayerController.m_invertCameraY)
				{
					val.y = 0f - val.y;
				}
			}
			_yaw = Mathf.Repeat(_yaw + val.x, 360f);
			_pitch = Mathf.Clamp(_pitch - val.y, -85f, 85f);
			_distance = Mathf.Clamp(_distance - ZInput.GetMouseScrollWheel() * 20f, 1f, 40f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(InputAxes.LeftX(), 0f, 0f - InputAxes.LeftY());
			if (ZInput.GetButton("Forward"))
			{
				val2.z += 1f;
			}
			if (ZInput.GetButton("Backward"))
			{
				val2.z -= 1f;
			}
			if (ZInput.GetButton("Right"))
			{
				val2.x += 1f;
			}
			if (ZInput.GetButton("Left"))
			{
				val2.x -= 1f;
			}
			val2 = Vector3.ClampMagnitude(val2, 1f);
			_movement = Quaternion.Euler(0f, _yaw, 0f) * val2;
			bool flag = Button("Jump");
			bool flag2 = Button("Crouch");
			if (_canFly && (Mob.IsFlying() || flag))
			{
				if (!Mob.IsFlying())
				{
					Mob.TakeOff();
				}
				_movement.y = (flag ? 1f : (flag2 ? (-1f) : 0f));
				_movement = Vector3.ClampMagnitude(_movement, 1f);
			}
			else if (ZInput.GetButtonDown("Jump") || ZInput.GetButtonDown("JoyJump"))
			{
				_jumpPending = true;
			}
			bool flag3 = Button("Run");
			_run = (ZInput.ToggleRun ? (_run ^ (flag3 && !_runPressed)) : flag3);
			_runPressed = flag3;
			_attackSlot = (PlayerController.HasInputDelay ? (-1) : (Button("Block") ? 2 : (Button("SecondaryAttack") ? 1 : ((!Button("Attack")) ? (-1) : 0))));
		}

		private static bool Button(string name)
		{
			if (!ZInput.GetButton(name))
			{
				return ZInput.GetButton("Joy" + name);
			}
			return true;
		}

		internal void Tick(float dt)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			_playerBody.position = Anchor;
			_playerBody.rotation = _bodyRotation;
			_playerBody.linearVelocity = Vector3.zero;
			_playerBody.angularVelocity = Vector3.zero;
			ApplyControls(_movement, _run, _jumpPending, _attackSlot);
			_jumpPending = false;
			BaseAI[] ais = _ais;
			foreach (BaseAI val in ais)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Regenerate(val, dt);
				}
			}
		}

		internal void ApplyControls(Vector3 movement, bool run, bool jump, int attackSlot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Mob.SetLookDir(ViewRotation * Vector3.forward, 0f);
			Mob.SetMoveDir(movement);
			Mob.SetRun(run);
			if (jump && !Mob.IsFlying())
			{
				Mob.Jump(false);
			}
			Attacks?.UpdateHeldSlot(attackSlot);
			if (attackSlot >= 0)
			{
				Attacks?.TryAttack(attackSlot);
			}
		}

		internal Vector3 AimDirection(Vector3 from)
		{
			//IL_000b: 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_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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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)
			Transform transform = ((Component)GameCamera.instance).transform;
			Vector3 val = transform.position + ViewRotation * Vector3.forward * 200f;
			Vector3 val2 = ViewRotation * Vector3.forward;
			int num = Physics.RaycastNonAlloc(transform.position, val2, _aimHits, 200f, -5, (QueryTriggerInteraction)1);
			float num2 = 200f;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val3 = _aimHits[i];
				if (!(((RaycastHit)(ref val3)).distance >= num2) && !((Component)((RaycastHit)(ref val3)).collider).transform.IsChildOf(((Component)Mob).transform) && !((Component)((RaycastHit)(ref val3)).collider).transform.IsChildOf(((Component)Player).transform))
				{
					num2 = ((RaycastHit)(ref val3)).distance;
					val = ((RaycastHit)(ref val3)).point;
				}
			}
			Vector3 val4 = val - from;
			return ((Vector3)(ref val4)).normalized;
		}

		internal void UpdateCamera(GameCamera camera)
		{
			//IL_0006: 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_002d: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			Vector3 centerPoint = Mob.GetCenterPoint();
			float num = Mob.GetHeight() * ((Component)Mob).transform.lossyScale.y;
			Vector3 val = centerPoint + Vector3.up * Mathf.Clamp(num * 0.25f, 0.3f, 3f);
			Vector3 val2 = ViewRotation * Vector3.back;
			float num2 = _distance;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.SphereCast(val, 0.25f, val2, ref val3, num2, LayerMask.op_Implicit(camera.m_blockCameraMask), (QueryTriggerInteraction)1))
			{
				num2 = Mathf.Max(0.05f, ((RaycastHit)(ref val3)).distance - 0.15f);
			}
			((Component)camera).transform.SetPositionAndRotation(val + val2 * num2, ViewRotation);
		}

		internal void Release()
		{
			//IL_0024: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			if (_released)
			{
				return;
			}
			_released = true;
			if (Object.op_Implicit((Object)(object)_playerBody))
			{
				_playerBody.constraints = _constraints;
				_playerBody.linearVelocity = Vector3.zero;
				_playerBody.angularVelocity = Vector3.zero;
			}
			if (Object.op_Implicit((Object)(object)_controller))
			{
				((Behaviour)_controller).enabled = _controllerEnabled;
			}
			for (int i = 0; i < _ais.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)_ais[i]))
				{
					((Behaviour)_ais[i]).enabled = _aiEnabled[i];
				}
			}
			Attacks?.UpdateHeldSlot(-1);
			if (Object.op_Implicit((Object)(object)Mob) && Object.op_Implicit((Object)(object)_view) && _view.IsValid() && _view.IsOwner())
			{
				Mob.SetMoveDir(Vector3.zero);
				Mob.SetRun(false);
			}
			if (Object.op_Implicit((Object)(object)Player) && Object.op_Implicit((Object)(object)ZNet.instance))
			{
				ZNet.instance.SetReferencePosition(((Component)Player).transform.position);
			}
			PlayerController.SetTakeInputDelay(0.25f);
		}
	}
	[HarmonyPatch(typeof(ZNet), "UpdatePlayerList")]
	internal static class PublicMapPosition
	{
		internal const string PossessingKey = "com.tenzly.playasmob.possessing";

		internal static void SetPossessing(bool active)
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				if (active)
				{
					ZNet.instance.m_serverSyncedPlayerData["com.tenzly.playasmob.possessing"] = "1";
				}
				else
				{
					ZNet.instance.m_serverSyncedPlayerData.Remove("com.tenzly.playasmob.possessing");
				}
			}
		}

		internal static void Postfix(ZNet __instance)
		{
			//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_001c: 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_0034: 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_0045: 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)
			if (!__instance.IsServer())
			{
				return;
			}
			List<PlayerInfo> playerList = __instance.GetPlayerList();
			for (int i = 0; i < playerList.Count; i++)
			{
				PlayerInfo val = playerList[i];
				if (val.m_publicPosition && !((ZDOID)(ref val.m_characterID)).IsNone() && TryGetBodyPosition(__instance, val.m_characterID, out var position))
				{
					val.m_position = position;
					playerList[i] = val;
				}
			}
		}

		private static bool TryGetBodyPosition(ZNet net, ZDOID characterId, out Vector3 position)
		{
			//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			position = default(Vector3);
			Possession current = PlayAsMobPlugin.Current;
			if (characterId == net.LocalPlayerCharacterID && current != null)
			{
				position = current.Anchor;
				return true;
			}
			if (ZDOMan.instance == null)
			{
				return false;
			}
			foreach (ZNetPeer peer in net.GetPeers())
			{
				if (peer.IsReady() && !(peer.m_characterID != characterId) && peer.m_serverSyncedPlayerData.TryGetValue("com.tenzly.playasmob.possessing", out var value) && !(value != "1"))
				{
					ZDO zDO = ZDOMan.instance.GetZDO(characterId);
					if (zDO == null)
					{
						return false;
					}
					position = zDO.GetPosition();
					return true;
				}
			}
			return false;
		}
	}
}