Decompiled source of PossessInUC v1.0.0

PossessInUC.dll

Decompiled 15 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InControl;
using Landfall.TABS;
using Landfall.TABS.AI;
using Landfall.TABS.UnitEditor;
using Landfall.TABS_Input;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace EditorPossess;

internal class EditorPossessController : MonoBehaviour
{
	private static readonly FieldInfo SpawnedTestUnitField = AccessTools.Field(typeof(UnitEditorManager), "spawnedTestUnit");

	private UnitEditorManager _manager;

	private Unit _unit;

	private Camera _camera;

	private UnitEditorFreeCamera _freeCamera;

	private CameraSpinner _spinner;

	private GeneralInput _input;

	private UnitAPI _api;

	private WeaponHandler _weapons;

	private Transform _savedParent;

	private Vector3 _savedPosition;

	private Quaternion _savedRotation;

	private bool _savedFreeCamera;

	private bool _savedSpinner;

	private bool _combatPressedOnce;

	private float _yaw;

	private float _pitch;

	private bool _possessing;

	private bool _firstPerson;

	private float _nextScan;

	private float _lookSyncUntil;

	private string _lastAction = "none yet";

	private int _pressed;

	private int _entered;

	private int _failed;

	private Vector3 _originalOffset = new Vector3(0.6f, 0.6f, -1f);

	private bool _originalOffsetFound;

	private GUIStyle _style;

	private GUIStyle _center;

	private Texture2D _plate;

	private Unit _highlighted;

	private CameraAbilityPossessUI _hud;

	private Texture2D _pie;

	private int _pieStep = -1;

	private void Update()
	{
		if (!Plugin.CfgEnabled.Value)
		{
			return;
		}
		try
		{
			if (Time.unscaledTime >= _nextScan)
			{
				_nextScan = Time.unscaledTime + 0.5f;
				if ((Object)(object)_manager == (Object)null)
				{
					_manager = Object.FindObjectOfType<UnitEditorManager>();
				}
			}
			if ((Object)(object)_manager == (Object)null || !UnitEditorManager.isTestingUnit)
			{
				if (_possessing)
				{
					Exit("test ended", restoreCamera: false);
				}
				SyncMouseLookWhileSettling();
			}
			else if (PossessPressed())
			{
				_pressed++;
				if (_possessing)
				{
					Exit("key pressed again");
				}
				else
				{
					Enter();
				}
			}
		}
		catch (Exception ex)
		{
			_failed++;
			_lastAction = "error: " + ex.GetType().Name + ": " + ex.Message;
			Plugin.LogWarn("[possess] " + ex);
		}
	}

	private void LateUpdate()
	{
		if (!_possessing)
		{
			return;
		}
		try
		{
			if (!UnitEditorManager.isTestingUnit)
			{
				Exit("test ended", restoreCamera: false);
			}
			else
			{
				Drive();
			}
		}
		catch (Exception ex)
		{
			Exit("driving failed: " + ex.Message);
		}
	}

	private void Enter()
	{
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: 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)
		if ((Object)(object)_manager == (Object)null)
		{
			return;
		}
		_camera = _manager.m_Camera;
		_freeCamera = _manager.m_FreeCamera;
		_spinner = _manager.m_CameraSpinner;
		Unit val = UnitNearScreenCenter();
		if ((Object)(object)val == (Object)null)
		{
			val = FindTestUnit();
		}
		_unit = val;
		if ((Object)(object)_unit == (Object)null)
		{
			_lastAction = "no unit to control";
			Plugin.LogInfo("[possess] " + _lastAction);
			return;
		}
		if ((Object)(object)_camera == (Object)null)
		{
			_lastAction = "the editor camera is missing";
			Plugin.LogInfo("[possess] " + _lastAction);
			return;
		}
		LoadOriginalCameraOffsets();
		_savedParent = ((Component)_camera).transform.parent;
		_savedPosition = ((Component)_camera).transform.position;
		_savedRotation = ((Component)_camera).transform.rotation;
		_savedFreeCamera = (Object)(object)_freeCamera != (Object)null && ((Behaviour)_freeCamera).enabled;
		_api = ((Component)_unit).GetComponent<UnitAPI>();
		if ((Object)(object)_api != (Object)null)
		{
			_api.SetActive(false, (bool?)true);
		}
		_input = ((Component)_unit).GetComponentInChildren<GeneralInput>();
		if ((Object)(object)_input != (Object)null)
		{
			_input.hasControl = true;
			PlayerActions instance = PlayerActions.Instance;
			if (instance != null)
			{
				_input.SetPlayerActions(instance);
			}
		}
		_weapons = ((Component)_unit).GetComponentInChildren<WeaponHandler>();
		if ((Object)(object)_weapons != (Object)null)
		{
			if ((Object)(object)_weapons.leftWeapon != (Object)null)
			{
				_weapons.leftWeapon.randomCooldown = false;
			}
			if ((Object)(object)_weapons.rightWeapon != (Object)null)
			{
				_weapons.rightWeapon.randomCooldown = false;
			}
		}
		_savedSpinner = (Object)(object)_spinner != (Object)null && ((Behaviour)_spinner).enabled;
		if ((Object)(object)_freeCamera != (Object)null)
		{
			((Behaviour)_freeCamera).enabled = false;
		}
		if ((Object)(object)_spinner != (Object)null)
		{
			((Behaviour)_spinner).enabled = false;
		}
		if ((Object)(object)_freeCamera != (Object)null && (Object)(object)_freeCamera.mouseLook != (Object)null)
		{
			try
			{
				_freeCamera.mouseLook.AlowInput(false);
			}
			catch
			{
			}
		}
		_yaw = ((Component)_camera).transform.eulerAngles.y;
		_pitch = 0f;
		_possessing = true;
		_entered++;
		SetupHud();
		StartHud();
		_lastAction = "possessing '" + ((Object)_unit).name + "'";
		Plugin.LogInfo("[possess] " + _lastAction);
	}

	private void Exit(string reason)
	{
		Exit(reason, restoreCamera: true);
	}

	private void Exit(string reason, bool restoreCamera)
	{
		//IL_008a: 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_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		_possessing = false;
		try
		{
			if ((Object)(object)_api != (Object)null)
			{
				_api.SetActive(true, (bool?)true);
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)_input != (Object)null)
			{
				_input.hasControl = false;
			}
		}
		catch
		{
		}
		if (restoreCamera)
		{
			try
			{
				if ((Object)(object)_camera != (Object)null && (Object)(object)_freeCamera != (Object)null)
				{
					((Component)_freeCamera).transform.position = ((Component)_camera).transform.position;
					((Component)_freeCamera).transform.rotation = ((Component)_camera).transform.rotation;
					Transform val = (((Object)(object)_freeCamera.camParent != (Object)null) ? _freeCamera.camParent : ((Component)_camera).transform.parent);
					if ((Object)(object)val != (Object)null)
					{
						((Component)_camera).transform.parent = val;
					}
					((Component)_camera).transform.localPosition = Vector3.zero;
					((Component)_camera).transform.localRotation = Quaternion.identity;
					if ((Object)(object)_freeCamera.mouseLook != (Object)null)
					{
						_freeCamera.mouseLook.SetRotationToCurrent();
					}
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)_freeCamera != (Object)null)
				{
					((Behaviour)_freeCamera).enabled = _savedFreeCamera;
				}
				if ((Object)(object)_spinner != (Object)null)
				{
					((Behaviour)_spinner).enabled = _savedSpinner;
				}
			}
			catch
			{
			}
		}
		else
		{
			_lookSyncUntil = Time.unscaledTime + 1f;
			try
			{
				if ((Object)(object)_freeCamera != (Object)null)
				{
					((Behaviour)_freeCamera).enabled = false;
					if ((Object)(object)_freeCamera.mouseLook != (Object)null)
					{
						_freeCamera.mouseLook.SetRotationToCurrent();
						_freeCamera.mouseLook.AlowInput(false);
					}
				}
				if ((Object)(object)_spinner != (Object)null)
				{
					((Behaviour)_spinner).enabled = true;
					if ((Object)(object)_camera != (Object)null)
					{
						((Component)_camera).transform.parent = ((Component)_spinner).transform;
						((Component)_camera).transform.localRotation = Quaternion.identity;
					}
				}
			}
			catch
			{
			}
		}
		_unit = null;
		_input = null;
		_api = null;
		_weapons = null;
		StopHud();
		_lastAction = "released control (" + reason + ")";
		Plugin.LogInfo("[possess] " + _lastAction);
	}

	private void SyncMouseLookWhileSettling()
	{
		if (Time.unscaledTime > _lookSyncUntil)
		{
			return;
		}
		try
		{
			if ((Object)(object)_freeCamera != (Object)null && (Object)(object)_freeCamera.mouseLook != (Object)null)
			{
				_freeCamera.mouseLook.SetRotationToCurrent();
				_freeCamera.mouseLook.AlowInput(false);
			}
		}
		catch
		{
		}
	}

	private void Drive()
	{
		//IL_0028: 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_004e: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_unit == (Object)null || (Object)(object)_camera == (Object)null)
		{
			Exit("unit or camera disappeared");
			return;
		}
		Vector2 val = Aim();
		float num = ((Plugin.CfgLookSensitivity != null) ? Plugin.CfgLookSensitivity.Value : 2.5f);
		_yaw += val.x * num;
		_pitch = Mathf.Clamp(_pitch - val.y * num, -80f, 80f);
		Quaternion rotation = Quaternion.Euler(_pitch, _yaw, 0f);
		((Component)_camera).transform.rotation = rotation;
		((Component)_camera).transform.position = CameraTarget(rotation);
		if ((Object)(object)_input != (Object)null)
		{
			_input.SetRotation(Quaternion.Euler(0f, _yaw, 0f));
		}
		UpdateHud();
		if (FirstPersonToggled())
		{
			_firstPerson = !_firstPerson;
			_lastAction = (_firstPerson ? "first person view" : "third person view");
		}
		PlayerActions instance = PlayerActions.Instance;
		if (instance == null)
		{
			return;
		}
		if ((Object)(object)_weapons == (Object)null)
		{
			UpdateCombatMove(instance);
			return;
		}
		Vector3 forward = ((Component)_camera).transform.forward;
		Vector3 position = ((Component)_camera).transform.position;
		float num2 = 3f;
		if (instance.m_possessAttack2 != null && ((OneAxisInputControl)instance.m_possessAttack2).WasPressed)
		{
			if ((Object)(object)_weapons.rightWeapon != (Object)null)
			{
				num2 = _weapons.rightWeapon.maxRange;
			}
			_weapons.Attack(position + forward * num2, (Rigidbody)null, forward, (ForceWeapon)2);
		}
		if (instance.m_possessAttack1 != null && ((OneAxisInputControl)instance.m_possessAttack1).WasPressed)
		{
			if ((Object)(object)_weapons.leftWeapon != (Object)null)
			{
				num2 = _weapons.leftWeapon.maxRange;
			}
			_weapons.Attack(position + forward * num2, (Rigidbody)null, forward, (ForceWeapon)1);
		}
		UpdateCombatMove(instance);
	}

	private void UpdateCombatMove(PlayerActions actions)
	{
		if ((Object)(object)_unit == (Object)null)
		{
			return;
		}
		bool flag = actions.m_possessAttack3 != null && ((OneAxisInputControl)actions.m_possessAttack3).IsPressed;
		bool flag2 = actions.m_possessAttack3 != null && ((OneAxisInputControl)actions.m_possessAttack3).WasPressed;
		ConditionalEvent[] componentsInChildren;
		try
		{
			componentsInChildren = ((Component)_unit).GetComponentsInChildren<ConditionalEvent>();
		}
		catch
		{
			return;
		}
		if (componentsInChildren == null)
		{
			return;
		}
		foreach (ConditionalEvent val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null || !val.controllableByPlayer)
			{
				continue;
			}
			try
			{
				if (flag2)
				{
					val.CheckConditionsUpdate(false);
				}
				else if (!flag)
				{
					val.CheckConditionsUpdate(true);
				}
			}
			catch
			{
			}
		}
		if (flag2 && !_combatPressedOnce)
		{
			_combatPressedOnce = true;
			_lastAction = "used the unit's ability";
			Plugin.LogInfo("[possess] " + _lastAction);
		}
		if (!flag)
		{
			_combatPressedOnce = false;
		}
	}

	private Vector3 CameraTarget(Quaternion rotation)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: 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_00d2: 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_00e4: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: 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_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: 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_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		Transform val = null;
		Rigidbody val2 = null;
		Transform val3 = null;
		float num = 1f;
		try
		{
			if ((Object)(object)_unit.data != (Object)null)
			{
				val = _unit.data.head;
				val2 = _unit.data.mainRig;
				val3 = _unit.data.characterForwardObject;
			}
			num = ((Component)_unit).transform.root.localScale.x;
		}
		catch
		{
		}
		if (num <= 0.01f)
		{
			num = 1f;
		}
		Vector3 val4 = (((Object)(object)val != (Object)null) ? val.position : (((Component)_unit).transform.position + Vector3.up * 1.5f));
		if (_firstPerson)
		{
			Vector3 val5 = val4 + Vector3.up * (0.22f * num);
			return Vector3.Lerp(((Component)_camera).transform.position, val5 + rotation * new Vector3(0.08f, 0.02f, 0.12f) * num, 0.6f);
		}
		Vector3 val6;
		if (_originalOffsetFound)
		{
			Vector3 originalOffset = _originalOffset;
			val6 = num * (rotation * Vector3.forward * originalOffset.z + Vector3.up * originalOffset.y + (((Object)(object)val3 != (Object)null) ? val3.right : Vector3.right) * originalOffset.x);
		}
		else
		{
			float num2 = ((Plugin.CfgCameraDistance != null) ? Plugin.CfgCameraDistance.Value : 3f);
			float num3 = ((Plugin.CfgCameraHeight != null) ? Plugin.CfgCameraHeight.Value : 0.9f);
			float num4 = ((Plugin.CfgCameraSide != null) ? Plugin.CfgCameraSide.Value : 0.6f);
			val6 = num * (rotation * Vector3.forward * (0f - num2) + Vector3.up * num3 + (((Object)(object)val3 != (Object)null) ? val3.right : Vector3.right) * num4);
		}
		Vector3 val7 = (((Object)(object)val2 != (Object)null) ? val2.position : val4) + val6;
		return Vector3.Lerp(((Component)_camera).transform.position, val7, Mathf.Clamp(Time.deltaTime, 0f, 0.03f) * 20f);
	}

	private unsafe void LoadOriginalCameraOffsets()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: 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_004a: 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_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		if (_originalOffsetFound)
		{
			return;
		}
		try
		{
			PossesionCamera[] array = Resources.FindObjectsOfTypeAll<PossesionCamera>();
			foreach (PossesionCamera val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 thirdPersonOffset = val.thirdPersonOffset;
					if (!(((Vector3)(ref thirdPersonOffset)).sqrMagnitude < 0.01f))
					{
						_originalOffset = thirdPersonOffset;
						_originalOffsetFound = true;
						Vector3 val2 = thirdPersonOffset;
						_lastAction = "original camera offset " + ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString();
						val2 = thirdPersonOffset;
						Plugin.LogInfo("[possess] using the game's third person offset " + ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString());
						return;
					}
				}
			}
		}
		catch
		{
		}
		Plugin.LogInfo("[possess] possession camera not loaded - using the configured camera offsets");
	}

	private Unit UnitNearScreenCenter()
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: 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_00d7: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)_camera == (Object)null)
			{
				return null;
			}
			Unit[] array = Object.FindObjectsOfType<Unit>();
			if (array == null || array.Length == 0)
			{
				return null;
			}
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
			Unit result = null;
			float num = float.MaxValue;
			foreach (Unit val2 in array)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Vector3 val3 = _camera.WorldToScreenPoint(FocusPoint(val2));
				if (!(val3.z <= 0f) && !(val3.x < 0f) && !(val3.y < 0f) && !(val3.x > (float)Screen.width) && !(val3.y > (float)Screen.height))
				{
					Vector2 val4 = new Vector2(val3.x, val3.y) - val;
					float sqrMagnitude = ((Vector2)(ref val4)).sqrMagnitude;
					if (!(sqrMagnitude >= num))
					{
						result = val2;
						num = sqrMagnitude;
					}
				}
			}
			return result;
		}
		catch
		{
			return null;
		}
	}

	private static Vector3 FocusPoint(Unit unit)
	{
		//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_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)unit.data != (Object)null && (Object)(object)unit.data.mainRig != (Object)null)
			{
				return unit.data.mainRig.position + Vector3.up * 0.35f;
			}
		}
		catch
		{
		}
		try
		{
			Renderer[] componentsInChildren = ((Component)unit).GetComponentsInChildren<Renderer>();
			if (componentsInChildren != null && componentsInChildren.Length != 0)
			{
				Bounds bounds = componentsInChildren[0].bounds;
				for (int i = 1; i < componentsInChildren.Length; i++)
				{
					((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds);
				}
				return ((Bounds)(ref bounds)).center;
			}
		}
		catch
		{
		}
		return ((Component)unit).transform.position + Vector3.up * 1f;
	}

	private static bool FirstPersonToggled()
	{
		try
		{
			PlayerActions instance = PlayerActions.Instance;
			if (instance != null && instance.m_possessToggleCamera != null && ((OneAxisInputControl)instance.m_possessToggleCamera).WasPressed)
			{
				return true;
			}
		}
		catch
		{
		}
		return Input.GetKeyDown((KeyCode)99);
	}

	private static Vector2 Aim()
	{
		//IL_0065: 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_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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)
		try
		{
			PlayerActions instance = PlayerActions.Instance;
			if (instance != null && instance.m_aim != null)
			{
				Vector2 result = default(Vector2);
				((Vector2)(ref result))..ctor(((TwoAxisInputControl)instance.m_aim).X, ((TwoAxisInputControl)instance.m_aim).Y);
				if (((Vector2)(ref result)).sqrMagnitude > 0.0001f)
				{
					return result;
				}
			}
		}
		catch
		{
		}
		try
		{
			return new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
		}
		catch
		{
		}
		return Vector2.zero;
	}

	private static Vector3 HeadOf(Unit unit)
	{
		//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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)unit.data != (Object)null && (Object)(object)unit.data.head != (Object)null)
			{
				return unit.data.head.position;
			}
		}
		catch
		{
		}
		return ((Component)unit).transform.position + Vector3.up * 1.5f;
	}

	private Unit FindTestUnit()
	{
		if ((Object)(object)_manager == (Object)null || SpawnedTestUnitField == null)
		{
			return null;
		}
		try
		{
			if (!(SpawnedTestUnitField.GetValue(_manager) is Array array))
			{
				return null;
			}
			for (int i = 0; i < array.Length; i++)
			{
				object? value = array.GetValue(i);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if (!((Object)(object)val == (Object)null))
				{
					Unit val2 = val.GetComponentInChildren<Unit>();
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = val.GetComponentInParent<Unit>();
					}
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
			}
		}
		catch (Exception ex)
		{
			_lastAction = "could not read the test unit: " + ex.Message;
			Plugin.LogWarn("[possess] " + _lastAction);
		}
		return null;
	}

	private static bool PossessPressed()
	{
		try
		{
			PlayerActions instance = PlayerActions.Instance;
			if (instance != null && instance.m_possessToggle != null && ((OneAxisInputControl)instance.m_possessToggle).WasPressed)
			{
				return true;
			}
		}
		catch
		{
		}
		return Input.GetKeyDown((KeyCode)102);
	}

	private void SetupHud()
	{
		//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_00d5: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_hud != (Object)null)
		{
			return;
		}
		try
		{
			CameraAbilityPossessUI[] array = Resources.FindObjectsOfTypeAll<CameraAbilityPossessUI>();
			CameraAbilityPossessUI val = null;
			foreach (CameraAbilityPossessUI val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					Scene scene = ((Component)val2).gameObject.scene;
					if (!((Scene)(ref scene)).IsValid())
					{
						val = val2;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				_lastAction = "possession HUD prefab not found - using the drawn HUD";
				Plugin.LogWarn("[possess] " + _lastAction);
				return;
			}
			GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject);
			((Object)val3).name = "EditorPossessHud";
			Canvas val4 = Object.FindObjectOfType<Canvas>();
			if ((Object)(object)val4 != (Object)null)
			{
				val3.transform.SetParent(((Component)val4).transform, false);
				Transform transform = val3.transform;
				RectTransform val5 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val5 != (Object)null)
				{
					val5.anchorMin = Vector2.zero;
					val5.anchorMax = Vector2.one;
					val5.pivot = new Vector2(0.5f, 0.5f);
					val5.offsetMin = Vector2.zero;
					val5.offsetMax = Vector2.zero;
				}
			}
			val3.SetActive(true);
			_hud = val3.GetComponent<CameraAbilityPossessUI>();
			if ((Object)(object)_hud == (Object)null)
			{
				_hud = val3.GetComponentInChildren<CameraAbilityPossessUI>(true);
			}
			Plugin.LogInfo("[possess] cloned the game's possession HUD (" + ((Object)val).name + ")");
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[possess] could not clone the possession HUD: " + ex.Message);
			_hud = null;
		}
	}

	private void StartHud()
	{
		if ((Object)(object)_hud == (Object)null)
		{
			return;
		}
		try
		{
			_hud.SetPlayerActions(PlayerActions.Instance);
			Weapon val = (((Object)(object)_weapons != (Object)null) ? _weapons.leftWeapon : null);
			Weapon val2 = (((Object)(object)_weapons != (Object)null) ? _weapons.rightWeapon : null);
			bool flag = (Object)(object)val2 != (Object)null && val2.internalCooldown < 100f;
			bool flag2 = (Object)(object)val != (Object)null && val.internalCooldown < 100f;
			bool flag3 = false;
			try
			{
				ConditionalEvent[] componentsInChildren = ((Component)_unit).GetComponentsInChildren<ConditionalEvent>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if ((Object)(object)componentsInChildren[i] != (Object)null && componentsInChildren[i].controllableByPlayer)
					{
						flag3 = true;
						break;
					}
				}
			}
			catch
			{
			}
			_hud.StartPossess((WeaponCooldownType)(flag ? 1 : 0), (WeaponCooldownType)(flag2 ? 1 : 0), (WeaponCooldownType)(flag3 ? 1 : 0));
			if ((Object)(object)_hud.UI != (Object)null)
			{
				_hud.UI.SetActive(true);
			}
			if ((Object)(object)_hud.Dot != (Object)null)
			{
				_hud.Dot.SetActive(true);
			}
		}
		catch (Exception ex)
		{
			Plugin.LogWarn("[possess] could not start the HUD: " + ex.Message);
		}
	}

	private void UpdateHud()
	{
		if ((Object)(object)_hud == (Object)null)
		{
			return;
		}
		try
		{
			float num = 1f;
			if ((Object)(object)_unit != (Object)null && (Object)(object)_unit.data != (Object)null && _unit.data.maxHealth > 0f)
			{
				num = Mathf.Clamp01(_unit.data.health / _unit.data.maxHealth);
			}
			_hud.UpdateHealth(num);
			Weapon val = (((Object)(object)_weapons != (Object)null) ? _weapons.leftWeapon : null);
			Weapon val2 = (((Object)(object)_weapons != (Object)null) ? _weapons.rightWeapon : null);
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			float num5 = 0f;
			if ((Object)(object)val2 != (Object)null && (Object)(object)val == (Object)null)
			{
				num4 = Mathf.Min(val2.internalCounter, val2.internalCooldown);
				num5 = val2.internalCooldown;
			}
			else
			{
				if ((Object)(object)val != (Object)null)
				{
					num2 = Mathf.Min(val.internalCounter, val.internalCooldown);
					num3 = val.internalCooldown;
				}
				if ((Object)(object)val2 != (Object)null)
				{
					num4 = Mathf.Min(val2.internalCounter, val2.internalCooldown);
					num5 = val2.internalCooldown;
				}
			}
			float num6 = 1f;
			float num7 = 1f;
			bool flag = false;
			ConditionalEvent[] array = null;
			try
			{
				array = ((Component)_unit).GetComponentsInChildren<ConditionalEvent>();
			}
			catch
			{
			}
			if (array != null)
			{
				foreach (ConditionalEvent val3 in array)
				{
					if ((Object)(object)val3 == (Object)null || !val3.controllableByPlayer)
					{
						continue;
					}
					Array events = val3.events;
					if (events == null)
					{
						continue;
					}
					for (int j = 0; j < events.Length; j++)
					{
						object value = events.GetValue(j);
						if (value == null)
						{
							continue;
						}
						FieldInfo field = value.GetType().GetField("conditions");
						Array array2 = ((field != null) ? (field.GetValue(value) as Array) : null);
						if (array2 == null)
						{
							continue;
						}
						for (int k = 0; k < array2.Length; k++)
						{
							object value2 = array2.GetValue(k);
							if (value2 == null)
							{
								continue;
							}
							Type type = value2.GetType();
							FieldInfo field2 = type.GetField("conditionType");
							FieldInfo field3 = type.GetField("value");
							FieldInfo field4 = type.GetField("counter");
							if (!(field2 == null) && !(field2.GetValue(value2).ToString() != "Cooldown"))
							{
								if (field3 != null)
								{
									num7 = Convert.ToSingle(field3.GetValue(value2));
								}
								if (field4 != null)
								{
									num6 = Convert.ToSingle(field4.GetValue(value2));
								}
							}
						}
					}
					flag = true;
				}
			}
			if (num7 <= 0f)
			{
				num6 = 1f;
				num7 = 1f;
			}
			_hud.UpdateCooldowns(num2, num3, num4, num5, num6, num7, flag, (Object)(object)val != (Object)null, (Object)(object)val2 != (Object)null);
		}
		catch
		{
		}
	}

	private void StopHud()
	{
		if ((Object)(object)_hud == (Object)null)
		{
			return;
		}
		try
		{
			if ((Object)(object)_hud.Dot != (Object)null)
			{
				_hud.Dot.SetActive(false);
			}
			_hud.EndPossess();
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)((Component)_hud).gameObject != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_hud).gameObject);
			}
		}
		catch
		{
		}
		_hud = null;
	}

	private void OnGUI()
	{
		if (!Plugin.CfgEnabled.Value)
		{
			return;
		}
		try
		{
			EnsureGui();
			GUI.depth = -10000;
			if (_possessing && (Object)(object)_hud == (Object)null && (Plugin.CfgShowHud == null || Plugin.CfgShowHud.Value))
			{
				DrawHud();
			}
		}
		catch
		{
		}
	}

	private void EnsureGui()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		//IL_0095: 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_00b0: Expected O, but got Unknown
		if ((Object)(object)_plate == (Object)null)
		{
			_plate = new Texture2D(1, 1);
			_plate.SetPixel(0, 0, Color.white);
			_plate.Apply();
			((Object)_plate).hideFlags = (HideFlags)61;
		}
		if (_style == null)
		{
			_style = new GUIStyle(GUI.skin.label);
			_style.fontSize = 13;
			_style.richText = false;
			_style.wordWrap = false;
			_style.normal.textColor = Color.white;
			_center = new GUIStyle(_style);
			_center.alignment = (TextAnchor)4;
			_center.fontSize = 16;
			_center.fontStyle = (FontStyle)1;
		}
	}

	private void Plate(Rect rect, Color color, float radius)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		GUI.DrawTexture(rect, (Texture)(object)_plate, (ScaleMode)0, true, 0f, color, 0f, Mathf.Max(0f, radius));
	}

	private void DrawHud()
	{
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0438: Unknown result type (might be due to invalid IL or missing references)
		//IL_0442: Unknown result type (might be due to invalid IL or missing references)
		//IL_045c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0475: Unknown result type (might be due to invalid IL or missing references)
		//IL_0482: Unknown result type (might be due to invalid IL or missing references)
		//IL_0492: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp((float)Screen.height / 1080f, 0.5f, 3f);
		float num2 = Mathf.Min((float)Screen.width - 80f * num, 760f * num);
		float num3 = 118f * num;
		Rect rect = default(Rect);
		((Rect)(ref rect))..ctor(((float)Screen.width - num2) * 0.5f, (float)Screen.height - num3 - 16f * num, num2, num3);
		Plate(rect, new Color(0.08f, 0.09f, 0.12f, 0.55f), 2f * num);
		float num4 = 1f;
		try
		{
			if ((Object)(object)_unit != (Object)null && (Object)(object)_unit.data != (Object)null && _unit.data.maxHealth > 0f)
			{
				num4 = Mathf.Clamp01(_unit.data.health / _unit.data.maxHealth);
			}
		}
		catch
		{
		}
		float num5 = ((Rect)(ref rect)).y + 47f * num;
		Rect rect2 = default(Rect);
		((Rect)(ref rect2))..ctor(((Rect)(ref rect)).x + 18f * num, num5, ((Rect)(ref rect)).width - 36f * num, 3f * num);
		Plate(rect2, new Color(1f, 1f, 1f, 0.14f), 1f * num);
		Plate(new Rect(((Rect)(ref rect2)).x, ((Rect)(ref rect2)).y, ((Rect)(ref rect2)).width * num4, ((Rect)(ref rect2)).height), new Color(1f, 1f, 1f, 0.95f), 1f * num);
		WeaponHandler val = _weapons;
		if ((Object)(object)val == (Object)null && (Object)(object)_unit != (Object)null)
		{
			val = ((Component)_unit).GetComponentInChildren<WeaponHandler>();
		}
		Weapon val2 = (((Object)(object)val != (Object)null) ? val.leftWeapon : null);
		Weapon val3 = (((Object)(object)val != (Object)null) ? val.rightWeapon : null);
		ReadCooldowns(val2, val3, out var leftCounter, out var leftMax, out var rightCounter, out var rightMax, out var moveCounter, out var moveMax);
		float num6 = 58f * num;
		float num7 = num5 + 1.5f * num - num6 * 0.5f;
		float num8 = 190f * num;
		PlayerActions instance = PlayerActions.Instance;
		string label = BindOf(instance?.m_possessAttack1, "LMB");
		string label2 = BindOf(instance?.m_possessAttack2, "RMB");
		string label3 = BindOf(instance?.m_possessAttack3, "Space");
		DrawCooldownBox(new Rect(((Rect)(ref rect)).center.x - num8 - num6 * 0.5f, num7, num6, num6), leftCounter, leftMax, (Object)(object)val2 != (Object)null, num, label);
		DrawCooldownBox(new Rect(((Rect)(ref rect)).center.x + num8 - num6 * 0.5f, num7, num6, num6), rightCounter, rightMax, (Object)(object)val3 != (Object)null, num, label2);
		bool flag = HasControllableAbility();
		float counter = ((!flag) ? 0f : ((moveMax > 0f) ? moveCounter : 1f));
		float max = ((!flag) ? 0f : ((moveMax > 0f) ? moveMax : 1f));
		float num9 = 58f * num;
		DrawCooldownBox(new Rect(((Rect)(ref rect)).center.x - num9 * 0.5f, num5 + 1.5f * num - num9 * 0.5f, num9, num9), counter, max, flag, num, label3);
		_center.fontSize = Mathf.RoundToInt(20f * num);
		_center.normal.textColor = new Color(1f, 1f, 1f, 0.95f);
		GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + num3 - 34f * num, ((Rect)(ref rect)).width, 28f * num), "Leave [F] - Toggle FPS [C]", _center);
		float num10 = 4f * num;
		Vector2 val4 = default(Vector2);
		((Vector2)(ref val4))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
		Plate(new Rect(val4.x - num10, val4.y - num10, num10 * 2f, num10 * 2f), new Color(0f, 0f, 0f, 0.5f), num10);
		Plate(new Rect(val4.x - num10 * 0.6f, val4.y - num10 * 0.6f, num10 * 1.2f, num10 * 1.2f), new Color(1f, 1f, 1f, 0.95f), num10 * 0.6f);
	}

	private bool HasControllableAbility()
	{
		try
		{
			if ((Object)(object)_unit == (Object)null)
			{
				return false;
			}
			ConditionalEvent[] componentsInChildren = ((Component)_unit).GetComponentsInChildren<ConditionalEvent>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && componentsInChildren[i].controllableByPlayer)
				{
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static string BindOf(PlayerAction action, string fallback)
	{
		if (action == null)
		{
			return fallback;
		}
		try
		{
			return Shorten(PlayerActions.GetCurrentBinds(action), fallback);
		}
		catch
		{
			return fallback;
		}
	}

	private static string Shorten(string text, string fallback)
	{
		if (string.IsNullOrEmpty(text))
		{
			return fallback;
		}
		string text2 = text.ToLowerInvariant();
		bool flag = text2.Contains("mouse") || text2.Contains("button") || text2.Contains("btn") || text2.Contains("鼠标") || text2.Contains("键");
		if (text2.Contains("middle") || text2.Contains("中"))
		{
			return "MMB";
		}
		if (text2.Contains("left") || text2.Contains("左"))
		{
			if (!flag && !text2.Contains("左"))
			{
				return "Left";
			}
			return "LMB";
		}
		if (text2.Contains("right") || text2.Contains("右"))
		{
			if (!flag && !text2.Contains("右"))
			{
				return "Right";
			}
			return "RMB";
		}
		if (text2.Contains("space") || text2.Contains("空格"))
		{
			return "Space";
		}
		if (text2.Contains("mouse") && text2.Contains("1"))
		{
			return "LMB";
		}
		if (text2.Contains("mouse") && text2.Contains("0"))
		{
			return "LMB";
		}
		StringBuilder stringBuilder = new StringBuilder(8);
		for (int i = 0; i < text.Length; i++)
		{
			if (stringBuilder.Length >= 5)
			{
				break;
			}
			char c = text[i];
			if (char.IsLetterOrDigit(c))
			{
				stringBuilder.Append(c);
			}
		}
		if (stringBuilder.Length <= 0)
		{
			return fallback;
		}
		return stringBuilder.ToString();
	}

	private void DrawFittedLabel(Rect rect, string text, float maxFontSize)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		_center.fontSize = Mathf.Max(8, Mathf.RoundToInt(maxFontSize));
		float x = _center.CalcSize(new GUIContent(text)).x;
		while (x > ((Rect)(ref rect)).width - 8f && _center.fontSize > 8)
		{
			GUIStyle center = _center;
			int fontSize = center.fontSize;
			center.fontSize = fontSize - 1;
			x = _center.CalcSize(new GUIContent(text)).x;
		}
		GUI.Label(rect, text, _center);
	}

	private void DrawCooldownBox(Rect rect, float counter, float max, bool has, float s, string label)
	{
		//IL_0001: 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_005f: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: 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_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		Plate(rect, new Color(0.08f, 0.09f, 0.14f, 0.92f), 1f * s);
		if (has && max > 0.01f)
		{
			float num = Mathf.Clamp01(counter / max);
			if (num > 0.005f)
			{
				GUI.color = new Color(1f, 1f, 1f, 0.9f);
				GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 2f * s, ((Rect)(ref rect)).y + 2f * s, ((Rect)(ref rect)).width - 4f * s, ((Rect)(ref rect)).height - 4f * s), (Texture)(object)PieTexture(num), (ScaleMode)0, true);
				GUI.color = Color.white;
			}
		}
		bool flag = has && max > 0.01f && counter >= max - 0.01f;
		if (has && !flag)
		{
			_center.normal.textColor = Color.black;
			DrawFittedLabel(rect, Mathf.RoundToInt(counter).ToString(), ((Rect)(ref rect)).height * 0.46f);
		}
		else
		{
			_center.normal.textColor = (Color)(has ? Color.black : new Color(1f, 1f, 1f, 0.4f));
			DrawFittedLabel(rect, label, ((Rect)(ref rect)).height * 0.34f);
		}
		float num2 = 2f * s;
		Color color = (Color)(has ? Color.white : new Color(1f, 1f, 1f, 0.4f));
		Plate(new Rect(((Rect)(ref rect)).x - num2, ((Rect)(ref rect)).y - num2, ((Rect)(ref rect)).width + num2 * 2f, num2), color, 0f);
		Plate(new Rect(((Rect)(ref rect)).x - num2, ((Rect)(ref rect)).yMax, ((Rect)(ref rect)).width + num2 * 2f, num2), color, 0f);
		Plate(new Rect(((Rect)(ref rect)).x - num2, ((Rect)(ref rect)).y, num2, ((Rect)(ref rect)).height), color, 0f);
		Plate(new Rect(((Rect)(ref rect)).xMax, ((Rect)(ref rect)).y, num2, ((Rect)(ref rect)).height), color, 0f);
	}

	private Texture2D PieTexture(float fill)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		//IL_008f: 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_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: 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_014a: Unknown result type (might be due to invalid IL or missing references)
		int num = Mathf.Clamp(Mathf.RoundToInt(fill * 100f), 0, 100);
		if ((Object)(object)_pie == (Object)null)
		{
			_pie = new Texture2D(64, 64, (TextureFormat)4, false);
		}
		if (num == _pieStep)
		{
			return _pie;
		}
		_pieStep = num;
		float num2 = (float)num / 100f * (float)Math.PI * 2f;
		Color[] array = (Color[])(object)new Color[4096];
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(31.5f, 31.5f);
		for (int i = 0; i < 64; i++)
		{
			for (int j = 0; j < 64; j++)
			{
				float num3 = (float)j - val.x;
				float num4 = (float)i - val.y;
				if (Mathf.Sqrt(num3 * num3 + num4 * num4) / 32f > 1f)
				{
					array[i * 64 + j] = new Color(1f, 1f, 1f, 0f);
					continue;
				}
				float num5 = Mathf.Atan2(num3, num4);
				if (num5 < 0f)
				{
					num5 += (float)Math.PI * 2f;
				}
				array[i * 64 + j] = ((num5 <= num2) ? new Color(1f, 1f, 1f, 0.95f) : new Color(1f, 1f, 1f, 0.06f));
			}
		}
		_pie.SetPixels(array);
		_pie.Apply();
		((Object)_pie).hideFlags = (HideFlags)61;
		return _pie;
	}

	private void ReadCooldowns(Weapon left, Weapon right, out float leftCounter, out float leftMax, out float rightCounter, out float rightMax, out float moveCounter, out float moveMax)
	{
		leftCounter = 0f;
		leftMax = 0f;
		rightCounter = 0f;
		rightMax = 0f;
		moveCounter = 0f;
		moveMax = 0f;
		try
		{
			if ((Object)(object)left != (Object)null)
			{
				leftMax = left.internalCooldown;
				leftCounter = Mathf.Clamp(left.internalCounter, 0f, leftMax);
			}
			if ((Object)(object)right != (Object)null)
			{
				rightMax = right.internalCooldown;
				rightCounter = Mathf.Clamp(right.internalCounter, 0f, rightMax);
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)_unit != (Object)null)
			{
				ConditionalEvent[] componentsInChildren = ((Component)_unit).GetComponentsInChildren<ConditionalEvent>();
				foreach (ConditionalEvent val in componentsInChildren)
				{
					if ((Object)(object)val == (Object)null || !val.controllableByPlayer)
					{
						continue;
					}
					Array events = val.events;
					if (events == null)
					{
						continue;
					}
					for (int j = 0; j < events.Length; j++)
					{
						object value = events.GetValue(j);
						if (value == null)
						{
							continue;
						}
						FieldInfo field = value.GetType().GetField("conditions");
						Array array = ((field != null) ? (field.GetValue(value) as Array) : null);
						if (array == null)
						{
							continue;
						}
						for (int k = 0; k < array.Length; k++)
						{
							object value2 = array.GetValue(k);
							if (value2 == null)
							{
								continue;
							}
							Type type = value2.GetType();
							FieldInfo field2 = type.GetField("conditionType");
							if (!(field2 == null) && !(field2.GetValue(value2).ToString() != "Cooldown"))
							{
								FieldInfo field3 = type.GetField("value");
								FieldInfo field4 = type.GetField("counter");
								if (field3 != null)
								{
									moveMax = Convert.ToSingle(field3.GetValue(value2));
								}
								if (field4 != null)
								{
									moveCounter = Convert.ToSingle(field4.GetValue(value2));
								}
							}
						}
					}
					if (moveMax > 0f)
					{
						break;
					}
				}
			}
		}
		catch
		{
		}
		if (moveMax > 0f)
		{
			moveCounter = Mathf.Clamp(moveCounter, 0f, moveMax);
		}
	}

	private void DrawBox(Rect rect, float counter, float max, bool has, string label, float s)
	{
		//IL_0001: 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_0120: 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_00da: 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_00a3: 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_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: 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_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		Plate(rect, new Color(0f, 0f, 0f, 0.78f), 2f * s);
		float num = ((has && max > 0.01f) ? Mathf.Clamp01(counter / max) : 0f);
		if (has && num > 0f)
		{
			float num2 = ((Rect)(ref rect)).height - 4f * s;
			Rect rect2 = default(Rect);
			((Rect)(ref rect2))..ctor(((Rect)(ref rect)).x + 2f * s, ((Rect)(ref rect)).yMax - 2f * s - num2 * num, ((Rect)(ref rect)).width - 4f * s, num2 * num);
			Plate(rect2, new Color(1f, 1f, 1f, 0.85f), 1f * s);
		}
		if (has)
		{
			_center.normal.textColor = Color.black;
			GUI.Label(rect, Mathf.RoundToInt(counter).ToString(), _center);
		}
		else
		{
			_center.normal.textColor = new Color(1f, 1f, 1f, 0.3f);
			GUI.Label(rect, label, _center);
		}
		float num3 = 1.5f * s;
		Color color = (has ? new Color(1f, 1f, 1f, 0.9f) : new Color(1f, 1f, 1f, 0.3f));
		Plate(new Rect(((Rect)(ref rect)).x - num3, ((Rect)(ref rect)).y - num3, ((Rect)(ref rect)).width + num3 * 2f, num3), color, 0f);
		Plate(new Rect(((Rect)(ref rect)).x - num3, ((Rect)(ref rect)).yMax, ((Rect)(ref rect)).width + num3 * 2f, num3), color, 0f);
		Plate(new Rect(((Rect)(ref rect)).x - num3, ((Rect)(ref rect)).y, num3, ((Rect)(ref rect)).height), color, 0f);
		Plate(new Rect(((Rect)(ref rect)).xMax, ((Rect)(ref rect)).y, num3, ((Rect)(ref rect)).height), color, 0f);
	}

	private void UpdateAimHighlight()
	{
		//IL_001b: 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_009a: Unknown result type (might be due to invalid IL or missing references)
		Unit val = null;
		try
		{
			RaycastHit val2 = default(RaycastHit);
			if ((Object)(object)_camera != (Object)null && Physics.Raycast(((Component)_camera).transform.position, ((Component)_camera).transform.forward, ref val2, 60f, -1, (QueryTriggerInteraction)2) && (Object)(object)((RaycastHit)(ref val2)).collider != (Object)null)
			{
				val = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Unit>();
			}
		}
		catch
		{
		}
		if ((Object)(object)val == (Object)(object)_highlighted)
		{
			return;
		}
		try
		{
			if ((Object)(object)_highlighted != (Object)null)
			{
				_highlighted.RemoveHighlight();
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)val != (Object)null)
			{
				val.SetHighlight(Color.white);
			}
		}
		catch
		{
		}
		_highlighted = val;
	}

	private void ClearAimHighlight()
	{
		try
		{
			if ((Object)(object)_highlighted != (Object)null)
			{
				_highlighted.RemoveHighlight();
			}
		}
		catch
		{
		}
		_highlighted = null;
	}
}
[BepInPlugin("saucein.tabs.editorpossess", "Editor Possess", "4.6.0")]
[BepInProcess("TotallyAccurateBattleSimulator.exe")]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "saucein.tabs.editorpossess";

	public const string PluginName = "Editor Possess";

	public const string PluginVersion = "4.6.0";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> CfgEnabled;

	internal static ConfigEntry<bool> CfgUseGameHud;

	internal static ConfigEntry<bool> CfgShowHud;

	internal static ConfigEntry<float> CfgLookSensitivity;

	internal static ConfigEntry<float> CfgCameraDistance;

	internal static ConfigEntry<float> CfgCameraHeight;

	internal static ConfigEntry<float> CfgCameraSide;

	internal static ConfigEntry<bool> CfgVerbose;

	private void Awake()
	{
		//IL_0120: 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_012b: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Allow controlling the unit you are testing in the Unit Creator.");
		CfgShowHud = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowHud", true, "Draw the possession HUD (health bar, weapon cooldowns, key hints, aim dot).");
		CfgUseGameHud = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseGameHud", false, "Use the game's own possession HUD prefab instead of the drawn one. Off by default because that prefab assumes the battle UI layout and stacks its boxes when reused here.");
		CfgLookSensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LookSensitivity", 2.5f, "Mouse look speed while controlling the test unit.");
		CfgCameraDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CameraDistance", 3f, "How far the third person camera sits behind the unit (scaled by the unit size).");
		CfgCameraHeight = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CameraHeight", 0.9f, "How high the third person camera sits above the unit.");
		CfgCameraSide = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CameraSide", 0.6f, "How far the third person camera sits to the side (over the shoulder offset).");
		CfgVerbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", true, "Log what happens when the possess key is pressed (useful when reporting a problem).");
		GameObject val = new GameObject("EditorPossess");
		Object.DontDestroyOnLoad((Object)val);
		val.AddComponent<EditorPossessController>();
		LogInfo("Editor Possess 4.6.0 loaded.");
	}

	internal static string StatusFile()
	{
		try
		{
			string text = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (string.IsNullOrEmpty(text))
			{
				text = ".";
			}
			return Path.Combine(text, "EditorPossess_status.txt");
		}
		catch
		{
			return "EditorPossess_status.txt";
		}
	}

	internal static void LogInfo(string message)
	{
		if (Log != null)
		{
			if (CfgVerbose != null && !CfgVerbose.Value)
			{
				Log.LogDebug((object)message);
			}
			else
			{
				Log.LogInfo((object)message);
			}
		}
	}

	internal static void LogWarn(string message)
	{
		if (Log != null)
		{
			Log.LogWarning((object)message);
		}
	}
}