Decompiled source of ReversibleBatteryDrone v1.0.2

ReversibleBatteryDrone.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Osmar Briones")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+a54cb48e762962b53d962abce86c78c2c658dbd9")]
[assembly: AssemblyProduct("ReversibleBatteryDrone")]
[assembly: AssemblyTitle("ReversibleBatteryDrone")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ReversibleBatteryDrone
{
	internal static class ConfigurationController
	{
		private static ConfigFile? ConfigFile { get; set; }

		internal static ConfigEntry<bool>? Enabled { get; private set; }

		internal static ConfigEntry<int>? TargetBatteryDrainPercentPerSecond { get; private set; }

		internal static ConfigEntry<int>? MonsterDamageFlatHpPerTick { get; private set; }

		internal static ConfigEntry<int>? PlayerDamageFlatHpPerTick { get; private set; }

		internal static ConfigEntry<int>? DroneBatteryGainPercentPerTick { get; private set; }

		internal static ConfigEntry<float>? LeechTickIntervalSeconds { get; private set; }

		internal static ConfigEntry<bool>? AllowTargetingMonsters { get; private set; }

		internal static ConfigEntry<bool>? AllowTargetingPlayers { get; private set; }

		internal static ConfigEntry<bool>? AlertEnemyOnAttach { get; private set; }

		internal static ConfigEntry<bool>? AlertEnemyOnDetach { get; private set; }

		internal static ConfigEntry<int>? AlertEnemyDetectionRange { get; private set; }

		internal static void Initialize(ConfigFile config)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			ConfigFile = config;
			Enabled = ConfigFile.Bind<bool>("General", "Enabled", true, "Enable or disable the ReversibleBatteryDrone mod entirely.");
			TargetBatteryDrainPercentPerSecond = ConfigFile.Bind<int>("ItemSiphoning", "TargetBatteryDrainPercentPerSecond", 5, new ConfigDescription("Percentage of battery (1% to 100%) drained from the targeted item per second and transferred directly into the drone's battery. At 5% (default, matches game's native recharge rate), an item with 100% battery drains in 20 seconds. Can be set up to 100% for instant 1-second drain.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			MonsterDamageFlatHpPerTick = ConfigFile.Bind<int>("LifeLeech", "MonsterDamageFlatHpPerTick", 1, new ConfigDescription("Flat health points (HP) of damage dealt to the targeted monster on every tick (1 to 100 HP).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			PlayerDamageFlatHpPerTick = ConfigFile.Bind<int>("LifeLeech", "PlayerDamageFlatHpPerTick", 10, new ConfigDescription("Flat health points (HP) of damage dealt to the targeted player/teammate on every tick (1 to 100 HP).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			DroneBatteryGainPercentPerTick = ConfigFile.Bind<int>("LifeLeech", "DroneBatteryGainPercentPerTick", 1, new ConfigDescription("Percentage of battery charge (1% to 100%) added to the drone on every tick while leeching life from a monster or player.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			LeechTickIntervalSeconds = ConfigFile.Bind<float>("LifeLeech", "LeechTickIntervalSeconds", 0.5f, new ConfigDescription("Time in seconds between each damage and battery gain tick when leeching life from a living target (0.1s to 5.0s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			AllowTargetingMonsters = ConfigFile.Bind<bool>("LifeLeech", "AllowTargetingMonsters", true, "Whether the drone in Drain mode is allowed to latch onto monsters and leech their health.");
			AllowTargetingPlayers = ConfigFile.Bind<bool>("LifeLeech", "AllowTargetingPlayers", true, "Whether the drone in Drain mode is allowed to latch onto other players and leech their health (PvP friendly-fire toggle).");
			AlertEnemyOnAttach = ConfigFile.Bind<bool>("LifeLeech", "AlertEnemyOnAttach", true, "Whether attaching the drone in Drain mode to an enemy alerts them and initiates a direct chase toward the player.");
			AlertEnemyOnDetach = ConfigFile.Bind<bool>("LifeLeech", "AlertEnemyOnDetach", true, "Whether detaching the drone in Drain mode from an enemy alerts them and initiates a direct chase toward the player.");
			AlertEnemyDetectionRange = ConfigFile.Bind<int>("LifeLeech", "AlertEnemyDetectionRange", 6, new ConfigDescription("Maximum distance in meters (1 to 20 meters, integer) between the player and the enemy for the enemy to detect and chase the player on attach/detach. If no player is within this range, or if the drone detaches naturally on full battery, the enemy is not alerted.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			ConfigFile.Save();
		}

		internal static void Reload()
		{
			ConfigFile? configFile = ConfigFile;
			if (configFile != null)
			{
				configFile.Reload();
			}
			ConfigFile? configFile2 = ConfigFile;
			if (configFile2 != null)
			{
				configFile2.Save();
			}
		}
	}
	internal enum DroneMode
	{
		Charge,
		Drain
	}
	[BepInPlugin("com.osmar.ReversibleBatteryDrone", "ReversibleBatteryDrone", "1.0.2")]
	public class ReversibleBatteryDronePlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.osmar.ReversibleBatteryDrone";

		public const string PluginName = "ReversibleBatteryDrone";

		public const string PluginVersion = "1.0.2";

		internal Harmony? Harmony { get; set; }

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			ConfigurationController.Initialize(((BaseUnityPlugin)this).Config);
			Harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
			Harmony.PatchAll();
			Logger.LogInfo((object)"ReversibleBatteryDrone 1.0.2 loaded!");
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal class ReversibleDroneController : MonoBehaviour
	{
		private ItemDrone itemDrone;

		private ItemDroneBattery itemDroneBattery;

		private ItemBattery itemBattery;

		private ItemToggle itemToggle;

		private PhysGrabObject physGrabObject;

		private PhotonView photonView;

		private Color originalDroneColor;

		private Color originalBeamColor;

		private bool colorsCached;

		private float tickTimer;

		private EnemyParent? activeEnemyTarget;

		private bool naturalFullChargeDetach;

		private bool distanceBreakDetach;

		private float lastPlayerInteractTime = -999f;

		private bool previousToggleState;

		public DroneMode CurrentMode { get; private set; }

		public DroneMode NextActivationMode { get; private set; }

		public int DroneCycleState
		{
			get
			{
				if (!((Object)(object)itemToggle != (Object)null) || !itemToggle.toggleState)
				{
					return 0;
				}
				if (CurrentMode != DroneMode.Drain)
				{
					return 1;
				}
				return 2;
			}
		}

		private void Awake()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			itemDrone = ((Component)this).GetComponent<ItemDrone>();
			itemDroneBattery = ((Component)this).GetComponent<ItemDroneBattery>();
			itemBattery = ((Component)this).GetComponent<ItemBattery>();
			itemToggle = ((Component)this).GetComponent<ItemToggle>();
			physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
			photonView = ((Component)this).GetComponent<PhotonView>();
			if ((Object)(object)photonView != (Object)null)
			{
				photonView.RefreshRpcMonoBehaviourCache();
			}
			if ((Object)(object)itemBattery != (Object)null)
			{
				itemBattery.isUnchargable = false;
			}
			if ((Object)(object)itemToggle != (Object)null)
			{
				itemToggle.onToggle.AddListener(new UnityAction(OnItemToggled));
			}
			ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
			if (logger != null)
			{
				PhotonView obj = photonView;
				logger.LogInfo((object)$"[ReversibleBatteryDrone] Controller Awake on ViewID: {((obj != null) ? new int?(obj.ViewID) : ((int?)null))}, isMaster: {SemiFunc.IsMasterClientOrSingleplayer()}");
			}
		}

		private void Start()
		{
			CacheOriginalColors();
			UpdateVisuals();
		}

		private void CacheOriginalColors()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!colorsCached && (Object)(object)itemDrone != (Object)null)
			{
				originalDroneColor = itemDrone.droneColor;
				originalBeamColor = itemDrone.beamColor;
				if (originalDroneColor != default(Color))
				{
					colorsCached = true;
				}
			}
		}

		private void Update()
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Invalid comparison between Unknown and I4
			if (!colorsCached)
			{
				CacheOriginalColors();
			}
			if ((Object)(object)itemToggle != (Object)null && previousToggleState != itemToggle.toggleState)
			{
				HandleToggleStateChange(itemToggle.toggleState);
			}
			if (CurrentMode == DroneMode.Drain && (Object)(object)itemBattery != (Object)null && itemBattery.batteryLife <= 0.05f)
			{
				itemBattery.batteryLife = 0.001f;
			}
			if ((Object)(object)itemDrone != (Object)null && itemDrone.itemActivated)
			{
				if (CurrentMode == DroneMode.Drain)
				{
					itemDrone.targetValuables = true;
					itemDrone.targetNonValuables = true;
					itemDrone.targetEnemies = ConfigurationController.AllowTargetingMonsters?.Value ?? true;
					itemDrone.targetPlayers = ConfigurationController.AllowTargetingPlayers?.Value ?? true;
				}
				else
				{
					itemDrone.targetEnemies = false;
					itemDrone.targetPlayers = false;
				}
			}
			if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)activeEnemyTarget != (Object)null && (!((Object)(object)itemDrone != (Object)null) || (int)itemDrone.currentState != 2 || !itemDrone.targetIsEnemy || !((Object)(object)itemDrone.enemyTarget == (Object)(object)activeEnemyTarget) || !((Object)(object)itemToggle != (Object)null) || !itemToggle.toggleState || CurrentMode != DroneMode.Drain))
			{
				EnemyParent ep = activeEnemyTarget;
				activeEnemyTarget = null;
				bool num = naturalFullChargeDetach || distanceBreakDetach;
				naturalFullChargeDetach = false;
				distanceBreakDetach = false;
				if (!num)
				{
					NotifyEnemyOfPlayer(ep, isAttach: false);
				}
			}
		}

		private void OnDestroy()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if ((Object)(object)itemToggle != (Object)null)
			{
				itemToggle.onToggle.RemoveListener(new UnityAction(OnItemToggled));
			}
			if ((Object)(object)activeEnemyTarget != (Object)null)
			{
				bool num = naturalFullChargeDetach || distanceBreakDetach;
				naturalFullChargeDetach = false;
				distanceBreakDetach = false;
				if (!num)
				{
					NotifyEnemyOfPlayer(activeEnemyTarget, isAttach: false);
				}
				activeEnemyTarget = null;
			}
		}

		private void OnItemToggled()
		{
			if (!((Object)(object)itemToggle == (Object)null))
			{
				HandleToggleStateChange(itemToggle.toggleState);
			}
		}

		private void HandleToggleStateChange(bool newState)
		{
			if (previousToggleState == newState)
			{
				return;
			}
			previousToggleState = newState;
			if (newState)
			{
				bool num = (Object)(object)itemBattery != (Object)null && itemBattery.batteryLife > 0.05f;
				bool flag = (Object)(object)itemBattery != (Object)null && itemBattery.batteryLife >= 99f;
				DroneMode droneMode;
				if (!num)
				{
					droneMode = DroneMode.Drain;
					NextActivationMode = DroneMode.Charge;
				}
				else if (flag)
				{
					droneMode = DroneMode.Charge;
					NextActivationMode = DroneMode.Drain;
				}
				else
				{
					droneMode = NextActivationMode;
					NextActivationMode = ((droneMode == DroneMode.Charge) ? DroneMode.Drain : DroneMode.Charge);
				}
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
					if (logger != null)
					{
						object[] array = new object[4];
						PhotonView obj = photonView;
						array[0] = ((obj != null) ? new int?(obj.ViewID) : ((int?)null));
						array[1] = droneMode;
						array[2] = NextActivationMode;
						array[3] = itemBattery?.batteryLife;
						logger.LogInfo((object)string.Format("[ReversibleBatteryDrone] Drone turned ON on ViewID: {0}. Mode: {1}, NextActivationMode: {2}, Battery: {3:F1}%", array));
					}
					SetMode(droneMode);
				}
			}
			else
			{
				ManualLogSource logger2 = ReversibleBatteryDronePlugin.Logger;
				if (logger2 != null)
				{
					PhotonView obj2 = photonView;
					logger2.LogInfo((object)$"[ReversibleBatteryDrone] Drone turned OFF on ViewID: {((obj2 != null) ? new int?(obj2.ViewID) : ((int?)null))}. Was Mode: {CurrentMode}, NextActivationMode: {NextActivationMode}");
				}
				if (CurrentMode == DroneMode.Drain && (Object)(object)itemBattery != (Object)null && itemBattery.batteryLife <= 0.05f)
				{
					itemBattery.batteryLife = 0f;
				}
				CurrentMode = DroneMode.Charge;
				UpdateVisuals();
			}
		}

		public DroneMode GetAnticipatedActivationMode()
		{
			bool num = (Object)(object)itemBattery != (Object)null && itemBattery.batteryLife > 0.05f;
			bool flag = (Object)(object)itemBattery != (Object)null && itemBattery.batteryLife >= 99f;
			if (!num)
			{
				return DroneMode.Drain;
			}
			if (flag)
			{
				return DroneMode.Charge;
			}
			return NextActivationMode;
		}

		public DroneMode GetEffectiveModeForDisplay()
		{
			if ((Object)(object)itemToggle != (Object)null && itemToggle.toggleState)
			{
				return CurrentMode;
			}
			return GetAnticipatedActivationMode();
		}

		public void HandleInteractPress()
		{
			lastPlayerInteractTime = Time.time;
			int num = SemiFunc.PhotonViewIDPlayerAvatarLocal();
			if (!((Object)(object)itemToggle == (Object)null))
			{
				bool flag = !itemToggle.toggleState;
				ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
				if (logger != null)
				{
					PhotonView obj = photonView;
					logger.LogInfo((object)$"[ReversibleBatteryDrone] HandleInteractPress on ViewID: {((obj != null) ? new int?(obj.ViewID) : ((int?)null))}. Toggling state to: {flag}");
				}
				itemToggle.ToggleItem(flag, num);
			}
		}

		public void SetMode(DroneMode mode)
		{
			ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
			if (logger != null)
			{
				object arg = mode;
				PhotonView obj = photonView;
				logger.LogInfo((object)$"[ReversibleBatteryDrone] SetMode({arg}) called on ViewID: {((obj != null) ? new int?(obj.ViewID) : ((int?)null))}. Multiplayer: {GameManager.Multiplayer()}");
			}
			if (GameManager.Multiplayer() && (Object)(object)photonView != (Object)null && photonView.ViewID != 0)
			{
				photonView.RPC("SetModeRPC", (RpcTarget)0, new object[1] { (int)mode });
			}
			else
			{
				SetModeRPC((int)mode);
			}
		}

		[PunRPC]
		public void SetModeRPC(int mode)
		{
			//IL_01c7: 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_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Invalid comparison between Unknown and I4
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Invalid comparison between Unknown and I4
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Invalid comparison between Unknown and I4
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Invalid comparison between Unknown and I4
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Invalid comparison between Unknown and I4
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Invalid comparison between Unknown and I4
			CurrentMode = (DroneMode)mode;
			lastPlayerInteractTime = Time.time;
			ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
			if (logger != null)
			{
				object arg = (DroneMode)mode;
				PhotonView obj = photonView;
				logger.LogInfo((object)$"[ReversibleBatteryDrone] SetModeRPC({arg}) received on ViewID: {((obj != null) ? new int?(obj.ViewID) : ((int?)null))}. isMaster: {SemiFunc.IsMasterClientOrSingleplayer()}");
			}
			if (CurrentMode == DroneMode.Drain)
			{
				if ((Object)(object)itemBattery != (Object)null && itemBattery.batteryLife <= 0.05f)
				{
					itemBattery.batteryLife = 0.001f;
				}
				if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)itemToggle != (Object)null && itemToggle.toggleState)
				{
					if ((Object)(object)itemDrone != (Object)null && ((int)itemDrone.currentState == 0 || (int)itemDrone.currentState == 4))
					{
						itemDrone.StateSet((State)1);
					}
					else if ((Object)(object)itemDrone != (Object)null && ((int)itemDrone.currentState == 2 || (int)itemDrone.currentState == 3))
					{
						if (itemDrone.magnetActive)
						{
							itemDrone.MagnetActiveToggle(false);
						}
						itemDrone.StateSet((State)1);
					}
				}
				PlayModeSwitchSound();
			}
			else
			{
				if ((Object)(object)itemBattery != (Object)null && itemBattery.batteryLife <= 0.05f)
				{
					itemBattery.batteryLife = 0f;
				}
				if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)itemToggle != (Object)null && itemToggle.toggleState)
				{
					if ((Object)(object)itemDrone != (Object)null && ((int)itemDrone.currentState == 0 || (int)itemDrone.currentState == 4))
					{
						if ((Object)(object)itemBattery != (Object)null && itemBattery.batteryLife > 0.05f)
						{
							itemDrone.StateSet((State)1);
						}
					}
					else if ((Object)(object)itemDrone != (Object)null && ((int)itemDrone.currentState == 2 || (int)itemDrone.currentState == 3))
					{
						if (itemDrone.magnetActive)
						{
							itemDrone.MagnetActiveToggle(false);
						}
						itemDrone.StateSet((State)1);
					}
				}
			}
			UpdateVisuals();
		}

		public void UpdateVisuals()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0267: 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_0187: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)itemDrone == (Object)null)
			{
				return;
			}
			Color val = ((CurrentMode == DroneMode.Drain) ? Color.red : ((originalDroneColor != default(Color)) ? originalDroneColor : itemDrone.droneColor));
			Color val2 = (Color)((CurrentMode == DroneMode.Drain) ? new Color(1f, 0.15f, 0.15f, 1f) : ((originalBeamColor != default(Color)) ? originalBeamColor : itemDrone.beamColor));
			itemDrone.droneColor = val;
			itemDrone.beamColor = val2;
			if ((Object)(object)itemDrone.lineBetweenTwoPoints != (Object)null)
			{
				itemDrone.lineBetweenTwoPoints.SetColor(val2);
			}
			if ((Object)(object)itemDrone.onSwitchTransform != (Object)null)
			{
				Renderer component = ((Component)itemDrone.onSwitchTransform).GetComponent<Renderer>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.material != (Object)null)
				{
					component.material.SetColor("_EmissionColor", val);
				}
			}
			if (itemDrone.dronePyramidTransforms != null)
			{
				foreach (Transform dronePyramidTransform in itemDrone.dronePyramidTransforms)
				{
					if ((Object)(object)dronePyramidTransform != (Object)null)
					{
						Renderer component2 = ((Component)dronePyramidTransform).GetComponent<Renderer>();
						if ((Object)(object)component2 != (Object)null && (Object)(object)component2.material != (Object)null)
						{
							component2.material.SetColor("_EmissionColor", val);
						}
					}
				}
			}
			if ((Object)(object)itemDrone.droneTransform != (Object)null)
			{
				Renderer component3 = ((Component)itemDrone.droneTransform).GetComponent<Renderer>();
				if ((Object)(object)component3 != (Object)null && (Object)(object)component3.material != (Object)null)
				{
					component3.material.SetColor("_EmissionColor", val);
				}
			}
			Transform val3 = ((Component)this).transform.Find("Drone Icon");
			if ((Object)(object)val3 != (Object)null)
			{
				Renderer component4 = ((Component)val3).GetComponent<Renderer>();
				if ((Object)(object)component4 != (Object)null && (Object)(object)component4.material != (Object)null)
				{
					component4.material.SetColor("_EmissionColor", val);
				}
			}
			ItemLight componentInChildren = ((Component)this).GetComponentInChildren<ItemLight>();
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.itemLight != (Object)null)
			{
				componentInChildren.itemLight.color = val;
			}
			ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
			if (logger != null)
			{
				PhotonView obj = photonView;
				logger.LogInfo((object)string.Format("[ReversibleBatteryDrone] UpdateVisuals on ViewID: {0}. Mode: {1}, activeBeam: {2}", (obj != null) ? new int?(obj.ViewID) : ((int?)null), CurrentMode, (CurrentMode == DroneMode.Drain) ? "RED" : "YELLOW"));
			}
		}

		private void PlayModeSwitchSound()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)itemDrone != (Object)null && (Object)(object)itemDrone.itemDroneSounds != (Object)null && itemDrone.itemDroneSounds.DroneStart != null)
			{
				itemDrone.itemDroneSounds.DroneStart.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
			}
		}

		public bool CustomTargetingCondition(GameObject target)
		{
			if ((Object)(object)target == (Object)null || (Object)(object)itemBattery == (Object)null)
			{
				return false;
			}
			if (itemBattery.batteryLife >= 99f)
			{
				return false;
			}
			ItemBattery component = target.GetComponent<ItemBattery>();
			if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)itemBattery)
			{
				if (component.isUnchargable)
				{
					return false;
				}
				ItemAttributes val = target.GetComponent<ItemAttributes>() ?? target.GetComponentInParent<ItemAttributes>();
				if ((Object)(object)val != (Object)null && val.shopItem)
				{
					return false;
				}
				return component.batteryLife > 0f;
			}
			ConfigEntry<bool>? allowTargetingMonsters = ConfigurationController.AllowTargetingMonsters;
			if (allowTargetingMonsters == null || allowTargetingMonsters.Value)
			{
				EnemyParent val2 = target.GetComponentInParent<EnemyParent>() ?? target.GetComponent<EnemyParent>();
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.Enemy != (Object)null && (Object)(object)val2.Enemy.Health != (Object)null)
				{
					if (!val2.Enemy.Health.dead)
					{
						return val2.Enemy.Health.healthCurrent > 0;
					}
					return false;
				}
			}
			ConfigEntry<bool>? allowTargetingPlayers = ConfigurationController.AllowTargetingPlayers;
			if (allowTargetingPlayers == null || allowTargetingPlayers.Value)
			{
				PlayerAvatar val3 = target.GetComponentInParent<PlayerAvatar>() ?? target.GetComponent<PlayerAvatar>();
				if ((Object)(object)val3 != (Object)null && !val3.deadSet && (Object)(object)val3.playerHealth != (Object)null)
				{
					return val3.playerHealth.health > 0;
				}
			}
			return false;
		}

		public void CustomStateSearching()
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (itemDrone.stateStart)
			{
				itemDrone.stateTimerMax = 0.5f;
				itemDrone.stateTimer = 0f;
				itemDrone.BatteryToggle(false);
				itemDrone.lerpAnimationProgress = 0f;
				itemDrone.itemActivated = true;
				if ((Object)(object)itemDrone.physGrabObject != (Object)null && (Object)(object)itemDrone.physGrabObject.impactDetector != (Object)null)
				{
					itemDrone.physGrabObject.impactDetector.canHurtLogic = false;
				}
				if ((Object)(object)itemDrone.onSwitchTransform != (Object)null)
				{
					Renderer component = ((Component)itemDrone.onSwitchTransform).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.material != (Object)null)
					{
						component.material.SetColor("_EmissionColor", itemDrone.droneColor);
					}
				}
				if ((Object)(object)itemDrone.itemDroneSounds != (Object)null && itemDrone.itemDroneSounds.DroneStart != null)
				{
					itemDrone.itemDroneSounds.DroneStart.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
				itemDrone.droneOwner = SemiFunc.PlayerAvatarGetFromPhotonID(itemToggle.playerTogglePhotonID);
				itemDrone.stateStart = false;
			}
			itemDrone.soundDroneLoop.PlayLoop(true, 2f, 2f, 1f, 1f);
			itemDrone.AnimateDrone();
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if (!itemToggle.toggleState)
			{
				itemDrone.StateSet((State)0);
				return;
			}
			ItemDrone obj = itemDrone;
			obj.stateTimer += Time.deltaTime;
			if (!(itemDrone.stateTimer < itemDrone.stateTimerMax))
			{
				itemDrone.stateTimer = 0f;
				itemDrone.playerTumbleTarget = null;
				itemDrone.playerAvatarTarget = null;
				itemDrone.targetIsPlayer = false;
				itemDrone.targetIsEnemy = false;
				itemDrone.targetIsLocalPlayer = false;
				if (FindDrainTarget())
				{
					itemDrone.hadTarget = true;
					itemDrone.ActivateMagnet();
					itemDrone.StateSet((State)2);
				}
			}
		}

		private bool FindDrainTarget()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_09d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0f: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0704: Unknown result type (might be due to invalid IL or missing references)
			//IL_070e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0713: Unknown result type (might be due to invalid IL or missing references)
			//IL_0718: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0785: Unknown result type (might be due to invalid IL or missing references)
			//IL_078a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0838: Unknown result type (might be due to invalid IL or missing references)
			//IL_084b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0850: Unknown result type (might be due to invalid IL or missing references)
			//IL_0887: Unknown result type (might be due to invalid IL or missing references)
			//IL_088c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0871: Unknown result type (might be due to invalid IL or missing references)
			//IL_0876: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)itemBattery == (Object)null || itemBattery.batteryLife >= 99f)
			{
				return false;
			}
			float num = 3.5f;
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, num);
			float num2 = float.MaxValue;
			GameObject val = null;
			float num3 = float.MaxValue;
			GameObject val2 = null;
			float num4 = float.MaxValue;
			GameObject val3 = null;
			PlayerAvatar val4 = null;
			if ((Object)(object)physGrabObject != (Object)null && physGrabObject.playerGrabbing.Count > 0)
			{
				val4 = physGrabObject.playerGrabbing[0].playerAvatar;
			}
			Collider[] array2 = array;
			foreach (Collider val5 in array2)
			{
				if ((Object)(object)val5 == (Object)null || (Object)(object)((Component)val5).gameObject == (Object)(object)((Component)this).gameObject || ((Component)val5).transform.IsChildOf(((Component)this).transform))
				{
					continue;
				}
				ItemBattery val6 = ((Component)val5).GetComponent<ItemBattery>() ?? ((Component)val5).GetComponentInParent<ItemBattery>() ?? ((Component)val5).GetComponentInChildren<ItemBattery>();
				if ((Object)(object)val6 != (Object)null && (Object)(object)val6 != (Object)(object)itemBattery && val6.batteryLife > 0.05f && !val6.isUnchargable)
				{
					ItemAttributes val7 = ((Component)val6).GetComponent<ItemAttributes>() ?? ((Component)val6).GetComponentInParent<ItemAttributes>();
					if ((Object)(object)val7 == (Object)null || !val7.shopItem)
					{
						float num5 = Vector3.Distance(((Component)this).transform.position, ((Component)val6).transform.position);
						if (num5 < num2)
						{
							num2 = num5;
							val = ((Component)val6).gameObject;
						}
					}
				}
				ConfigEntry<bool>? allowTargetingMonsters = ConfigurationController.AllowTargetingMonsters;
				if (allowTargetingMonsters == null || allowTargetingMonsters.Value)
				{
					EnemyParent val8 = ((Component)val5).GetComponentInParent<EnemyParent>() ?? ((Component)val5).GetComponent<EnemyParent>();
					if ((Object)(object)val8 != (Object)null && (Object)(object)val8.Enemy != (Object)null && (Object)(object)val8.Enemy.Health != (Object)null && !val8.Enemy.Health.dead && val8.Enemy.Health.healthCurrent > 0)
					{
						Transform val9 = (((Object)(object)val8.Enemy.CenterTransform != (Object)null) ? val8.Enemy.CenterTransform : ((Component)val8).transform);
						float num6 = Vector3.Distance(((Component)this).transform.position, val9.position);
						if (num6 < num3)
						{
							num3 = num6;
							val2 = ((Component)val8).gameObject;
						}
					}
				}
				ConfigEntry<bool>? allowTargetingPlayers = ConfigurationController.AllowTargetingPlayers;
				if (allowTargetingPlayers != null && !allowTargetingPlayers.Value)
				{
					continue;
				}
				PlayerAvatar val10 = ((Component)val5).GetComponentInParent<PlayerAvatar>() ?? ((Component)val5).GetComponent<PlayerAvatar>();
				if ((Object)(object)val10 != (Object)null && (Object)(object)val10 != (Object)(object)val4 && !val10.deadSet && (Object)(object)val10.playerHealth != (Object)null && val10.playerHealth.health > 0)
				{
					Transform val11 = (((Object)(object)val10.PlayerVisionTarget != (Object)null && (Object)(object)val10.PlayerVisionTarget.VisionTransform != (Object)null) ? val10.PlayerVisionTarget.VisionTransform : ((Component)val10).transform);
					float num7 = Vector3.Distance(((Component)this).transform.position, val11.position);
					if (num7 < num4)
					{
						num4 = num7;
						val3 = ((Component)val10).gameObject;
					}
				}
			}
			GameObject val12 = null;
			int num8 = 0;
			if ((Object)(object)val != (Object)null)
			{
				val12 = val;
				num8 = 1;
			}
			else if ((Object)(object)val2 != (Object)null)
			{
				val12 = val2;
				num8 = 2;
			}
			else if ((Object)(object)val3 != (Object)null)
			{
				val12 = val3;
				num8 = 3;
			}
			if ((Object)(object)val12 == (Object)null)
			{
				return false;
			}
			if (num8 != 2 && (Object)(object)activeEnemyTarget != (Object)null)
			{
				EnemyParent ep = activeEnemyTarget;
				activeEnemyTarget = null;
				NotifyEnemyOfPlayer(ep, isAttach: false);
			}
			switch (num8)
			{
			case 1:
			{
				ItemBattery val21 = val12.GetComponent<ItemBattery>() ?? val12.GetComponentInParent<ItemBattery>() ?? val12.GetComponentInChildren<ItemBattery>();
				itemDrone.targetIsEnemy = false;
				itemDrone.targetIsPlayer = false;
				itemDrone.targetIsLocalPlayer = false;
				itemDrone.enemyTarget = null;
				itemDrone.playerAvatarTarget = null;
				itemDrone.playerTumbleTarget = null;
				PhysGrabObject val22 = ((Component)val21).GetComponent<PhysGrabObject>() ?? ((Component)val21).GetComponentInParent<PhysGrabObject>() ?? ((Component)val21).GetComponentInChildren<PhysGrabObject>();
				Transform val23 = (((Object)(object)val22 != (Object)null) ? ((Component)val22).transform : ((Component)val21).transform);
				int num11 = -1;
				Vector3 position2 = val23.position;
				if ((Object)(object)val22 != (Object)null && val22.colliders != null && val22.colliders.Count > 0 && (Object)(object)val22.colliders[0] != (Object)null)
				{
					PhysGrabObjectCollider component2 = ((Component)val22.colliders[0]).GetComponent<PhysGrabObjectCollider>();
					if ((Object)(object)component2 != (Object)null)
					{
						num11 = component2.colliderID;
						position2 = val22.colliders[0].position;
					}
				}
				itemDrone.magnetTarget = ((num11 != -1 && (Object)(object)val22 != (Object)null && val22.colliders != null && val22.colliders.Count > 0) ? val22.colliders[0] : val23);
				itemDrone.magnetTargetPhysGrabObject = val22;
				itemDrone.magnetTargetRigidbody = ((Component)val23).GetComponent<Rigidbody>();
				PhotonView val24 = (((Object)(object)val22 != (Object)null && (Object)(object)val22.photonView != (Object)null) ? val22.photonView : ((Component)val21).GetComponent<PhotonView>());
				int num12 = (((Object)(object)val24 != (Object)null) ? val24.ViewID : 0);
				itemDrone.NewRayHitPoint(position2, num12, num11, val23);
				if (itemDrone.rayHitPosition == Vector3.zero)
				{
					itemDrone.rayHitPosition = new Vector3(0f, 0.05f, 0f);
				}
				itemDrone.attachPoint = itemDrone.rayHitPosition;
				return true;
			}
			case 2:
			{
				EnemyParent val15 = val12.GetComponentInParent<EnemyParent>() ?? val12.GetComponent<EnemyParent>();
				itemDrone.enemyTarget = val15;
				itemDrone.targetIsEnemy = true;
				itemDrone.targetIsPlayer = false;
				itemDrone.targetIsLocalPlayer = false;
				itemDrone.playerAvatarTarget = null;
				itemDrone.playerTumbleTarget = null;
				Transform val16 = (((Object)(object)val15.Enemy.CenterTransform != (Object)null) ? val15.Enemy.CenterTransform : ((Component)val15).transform);
				PhysGrabObject val17 = (((Object)(object)val15.Enemy.Rigidbody != (Object)null) ? val15.Enemy.Rigidbody.physGrabObject : ((Component)val15).GetComponent<PhysGrabObject>());
				itemDrone.magnetTargetPhysGrabObject = val17;
				itemDrone.magnetTargetRigidbody = (((Object)(object)val15.Enemy.Rigidbody != (Object)null) ? val15.Enemy.Rigidbody.rb : ((Component)val15).GetComponent<Rigidbody>());
				Transform val18 = (((Object)(object)val17 != (Object)null) ? ((Component)val17).transform : val16);
				int num9 = -1;
				Vector3 val19 = val16.position + Vector3.up * 0.1f;
				if ((Object)(object)val17 != (Object)null && val17.colliders != null && val17.colliders.Count > 0 && (Object)(object)val17.colliders[0] != (Object)null)
				{
					PhysGrabObjectCollider component = ((Component)val17.colliders[0]).GetComponent<PhysGrabObjectCollider>();
					if ((Object)(object)component != (Object)null)
					{
						num9 = component.colliderID;
						val19 = val17.colliders[0].position;
					}
				}
				itemDrone.magnetTarget = ((num9 != -1 && (Object)(object)val17 != (Object)null && val17.colliders != null && val17.colliders.Count > 0) ? val17.colliders[0] : val16);
				PhotonView val20 = (((Object)(object)val17 != (Object)null && (Object)(object)val17.photonView != (Object)null) ? val17.photonView : (((Object)(object)val15.Enemy.PhotonView != (Object)null) ? val15.Enemy.PhotonView : ((Component)val15).GetComponent<PhotonView>()));
				int num10 = (((Object)(object)val20 != (Object)null) ? val20.ViewID : 0);
				itemDrone.NewRayHitPoint(val19, num10, num9, val18);
				if (itemDrone.rayHitPosition == Vector3.zero)
				{
					itemDrone.rayHitPosition = new Vector3(0f, 0.05f, 0f);
				}
				itemDrone.attachPoint = itemDrone.rayHitPosition;
				if ((Object)(object)activeEnemyTarget != (Object)null && (Object)(object)activeEnemyTarget != (Object)(object)val15)
				{
					EnemyParent ep2 = activeEnemyTarget;
					activeEnemyTarget = null;
					NotifyEnemyOfPlayer(ep2, isAttach: false);
				}
				activeEnemyTarget = val15;
				NotifyEnemyOfPlayer(val15, isAttach: true);
				return true;
			}
			case 3:
			{
				PlayerAvatar val13 = val12.GetComponentInParent<PlayerAvatar>() ?? val12.GetComponent<PlayerAvatar>();
				itemDrone.playerAvatarTarget = val13;
				itemDrone.targetIsPlayer = true;
				itemDrone.targetIsEnemy = false;
				itemDrone.targetIsLocalPlayer = val13.isLocal;
				itemDrone.enemyTarget = null;
				itemDrone.playerTumbleTarget = null;
				Transform val14 = (((Object)(object)val13.PlayerVisionTarget != (Object)null && (Object)(object)val13.PlayerVisionTarget.VisionTransform != (Object)null) ? val13.PlayerVisionTarget.VisionTransform : ((Component)val13).transform);
				itemDrone.magnetTarget = val14;
				itemDrone.magnetTargetPhysGrabObject = null;
				itemDrone.magnetTargetRigidbody = null;
				Vector3 position = val14.position;
				itemDrone.NewRayHitPoint(position, val13.photonView.ViewID, -1, val14);
				if (itemDrone.rayHitPosition == Vector3.zero)
				{
					itemDrone.rayHitPosition = new Vector3(0f, 0.05f, 0f);
				}
				itemDrone.attachPoint = itemDrone.rayHitPosition;
				return true;
			}
			default:
				return false;
			}
		}

		public void ExecuteDrain()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if ((Object)(object)itemBattery == (Object)null || itemBattery.batteryLife >= 99.9f)
			{
				naturalFullChargeDetach = true;
				itemDrone.MagnetActiveToggle(false);
				return;
			}
			if ((Object)(object)itemDrone.magnetTarget != (Object)null && Vector3.Distance(((Component)this).transform.position, itemDrone.magnetTarget.position) > 8f)
			{
				distanceBreakDetach = true;
				itemDrone.MagnetActiveToggle(false);
				return;
			}
			ItemBattery val = null;
			if ((Object)(object)itemDrone.magnetTargetPhysGrabObject != (Object)null)
			{
				val = ((Component)itemDrone.magnetTargetPhysGrabObject).GetComponent<ItemBattery>();
			}
			if ((Object)(object)val == (Object)null && (Object)(object)itemDrone.magnetTarget != (Object)null)
			{
				val = ((Component)itemDrone.magnetTarget).GetComponent<ItemBattery>() ?? ((Component)itemDrone.magnetTarget).GetComponentInParent<ItemBattery>();
			}
			if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)itemBattery)
			{
				val.OverrideBatteryShow(0.25f);
				BatteryVisualLogic componentInChildren = ((Component)val).GetComponentInChildren<BatteryVisualLogic>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.OverrideBatteryDrain(0.25f);
				}
				itemBattery.OverrideBatteryShow(0.25f);
				BatteryVisualLogic componentInChildren2 = ((Component)itemBattery).GetComponentInChildren<BatteryVisualLogic>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.OverrideBatteryCharge(0.25f);
				}
				float num = ((float?)ConfigurationController.TargetBatteryDrainPercentPerSecond?.Value) ?? 5f;
				val.Drain(num);
				itemBattery.ChargeBattery(((Component)val).gameObject, num);
				if (val.batteryLife <= 0.05f)
				{
					val.batteryLife = 0f;
					val.SetBatteryLife(0);
					itemDrone.MagnetActiveToggle(false);
				}
				else if (itemBattery.batteryLife >= 99f)
				{
					itemBattery.batteryLife = 100f;
					naturalFullChargeDetach = true;
					itemDrone.MagnetActiveToggle(false);
				}
				return;
			}
			EnemyParent val2 = itemDrone.enemyTarget;
			if ((Object)(object)val2 == (Object)null && (Object)(object)itemDrone.magnetTargetPhysGrabObject != (Object)null)
			{
				val2 = ((Component)itemDrone.magnetTargetPhysGrabObject).GetComponentInParent<EnemyParent>();
			}
			if ((Object)(object)val2 == (Object)null && (Object)(object)itemDrone.magnetTarget != (Object)null)
			{
				val2 = ((Component)itemDrone.magnetTarget).GetComponentInParent<EnemyParent>() ?? ((Component)itemDrone.magnetTarget).GetComponent<EnemyParent>();
			}
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.Enemy != (Object)null && (Object)(object)val2.Enemy.Health != (Object)null)
			{
				EnemyHealth health = val2.Enemy.Health;
				if (health.dead || health.healthCurrent <= 0)
				{
					itemDrone.MagnetActiveToggle(false);
					return;
				}
				itemBattery.OverrideBatteryShow(0.25f);
				BatteryVisualLogic componentInChildren3 = ((Component)itemBattery).GetComponentInChildren<BatteryVisualLogic>();
				if ((Object)(object)componentInChildren3 != (Object)null)
				{
					componentInChildren3.OverrideBatteryCharge(0.25f);
				}
				tickTimer += Time.deltaTime;
				float num2 = ConfigurationController.LeechTickIntervalSeconds?.Value ?? 0.5f;
				if (!(tickTimer >= num2))
				{
					return;
				}
				tickTimer = 0f;
				int num3 = ConfigurationController.MonsterDamageFlatHpPerTick?.Value ?? 1;
				float num4 = ((float?)ConfigurationController.DroneBatteryGainPercentPerTick?.Value) ?? 1f;
				health.Hurt(num3, Vector3.up * 0.1f);
				itemBattery.ChargeBattery(((Component)val2).gameObject, num4 * (1f / Mathf.Max(0.01f, num2)));
				if (health.dead || health.healthCurrent <= 0 || itemBattery.batteryLife >= 99f)
				{
					if (itemBattery.batteryLife >= 99f)
					{
						naturalFullChargeDetach = true;
					}
					itemDrone.MagnetActiveToggle(false);
				}
				return;
			}
			PlayerAvatar val3 = itemDrone.playerAvatarTarget;
			if ((Object)(object)val3 == (Object)null && (Object)(object)itemDrone.playerTumbleTarget != (Object)null)
			{
				val3 = itemDrone.playerTumbleTarget.playerAvatar;
			}
			if (!((Object)(object)val3 != (Object)null))
			{
				return;
			}
			if (val3.deadSet || (Object)(object)val3.playerHealth == (Object)null || val3.playerHealth.health <= 0)
			{
				itemDrone.MagnetActiveToggle(false);
				return;
			}
			itemBattery.OverrideBatteryShow(0.25f);
			BatteryVisualLogic componentInChildren4 = ((Component)itemBattery).GetComponentInChildren<BatteryVisualLogic>();
			if ((Object)(object)componentInChildren4 != (Object)null)
			{
				componentInChildren4.OverrideBatteryCharge(0.25f);
			}
			tickTimer += Time.deltaTime;
			float num5 = ConfigurationController.LeechTickIntervalSeconds?.Value ?? 0.5f;
			if (!(tickTimer >= num5))
			{
				return;
			}
			tickTimer = 0f;
			int num6 = ConfigurationController.PlayerDamageFlatHpPerTick?.Value ?? 10;
			float num7 = ((float?)ConfigurationController.DroneBatteryGainPercentPerTick?.Value) ?? 1f;
			val3.playerHealth.HurtOther(num6, Vector3.zero, false, -1, false);
			itemBattery.ChargeBattery(((Component)val3).gameObject, num7 * (1f / Mathf.Max(0.01f, num5)));
			if (val3.deadSet || val3.playerHealth.health <= 0 || itemBattery.batteryLife >= 99f)
			{
				if (itemBattery.batteryLife >= 99f)
				{
					naturalFullChargeDetach = true;
				}
				itemDrone.MagnetActiveToggle(false);
			}
		}

		private PlayerAvatar? GetResponsiblePlayerNearEnemy(Vector3 enemyPos, float maxDistance)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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)
			if ((Object)(object)physGrabObject != (Object)null && physGrabObject.playerGrabbing.Count > 0)
			{
				PlayerAvatar playerAvatar = physGrabObject.playerGrabbing[0].playerAvatar;
				if ((Object)(object)playerAvatar != (Object)null && !playerAvatar.deadSet && !playerAvatar.isDisabled && Vector3.Distance(((Component)playerAvatar).transform.position, enemyPos) <= maxDistance + 2.5f)
				{
					return playerAvatar;
				}
			}
			if ((Object)(object)itemDrone != (Object)null && (Object)(object)itemDrone.droneOwner != (Object)null && !itemDrone.droneOwner.deadSet && !itemDrone.droneOwner.isDisabled && Vector3.Distance(((Component)itemDrone.droneOwner).transform.position, enemyPos) <= maxDistance)
			{
				return itemDrone.droneOwner;
			}
			PlayerAvatar result = null;
			float num = maxDistance;
			List<PlayerAvatar> list = SemiFunc.PlayerGetList();
			if (list != null)
			{
				foreach (PlayerAvatar item in list)
				{
					if ((Object)(object)item != (Object)null && !item.deadSet && !item.isDisabled)
					{
						float num2 = Vector3.Distance(enemyPos, ((Component)item).transform.position);
						if (num2 <= num)
						{
							num = num2;
							result = item;
						}
					}
				}
			}
			return result;
		}

		private void NotifyEnemyOfPlayer(EnemyParent? ep, bool isAttach)
		{
			//IL_00ef: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Invalid comparison between Unknown and I4
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Invalid comparison between Unknown and I4
			if (!SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)ep == (Object)null || (Object)(object)ep.Enemy == (Object)null || ((Object)(object)ep.Enemy.Health != (Object)null && (ep.Enemy.Health.dead || ep.Enemy.Health.healthCurrent <= 0)))
			{
				return;
			}
			bool value;
			if (!isAttach)
			{
				ConfigEntry<bool>? alertEnemyOnDetach = ConfigurationController.AlertEnemyOnDetach;
				if (alertEnemyOnDetach != null)
				{
					value = alertEnemyOnDetach.Value;
					goto IL_0080;
				}
			}
			else
			{
				ConfigEntry<bool>? alertEnemyOnAttach = ConfigurationController.AlertEnemyOnAttach;
				if (alertEnemyOnAttach != null)
				{
					value = alertEnemyOnAttach.Value;
					goto IL_0080;
				}
			}
			goto IL_0083;
			IL_0083:
			if (!isAttach)
			{
				bool num = (Object)(object)physGrabObject != (Object)null && physGrabObject.playerGrabbing.Count > 0;
				bool flag = Time.time - lastPlayerInteractTime < 1f;
				if (!num && !flag)
				{
					return;
				}
			}
			Vector3 enemyPos = (((Object)(object)ep.Enemy.CenterTransform != (Object)null) ? ep.Enemy.CenterTransform.position : ((Component)ep).transform.position);
			float maxDistance = ((float?)ConfigurationController.AlertEnemyDetectionRange?.Value) ?? 6f;
			PlayerAvatar responsiblePlayerNearEnemy = GetResponsiblePlayerNearEnemy(enemyPos, maxDistance);
			if (!((Object)(object)responsiblePlayerNearEnemy == (Object)null))
			{
				ep.Enemy.SetChaseTarget(responsiblePlayerNearEnemy);
				if (ep.Enemy.HasStateChase && ((int)ep.Enemy.CurrentState == 4 || (int)ep.Enemy.CurrentState == 3))
				{
					ep.Enemy.TargetPlayerViewID = responsiblePlayerNearEnemy.photonView.ViewID;
					ep.Enemy.TargetPlayerAvatar = responsiblePlayerNearEnemy;
				}
			}
			return;
			IL_0080:
			if (!value)
			{
				return;
			}
			goto IL_0083;
		}
	}
}
namespace ReversibleBatteryDrone.Patches
{
	[HarmonyPatch(typeof(EnemyDirector), "Start")]
	internal static class EnemyDirector_Start_Patch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if (SemiFunc.RunIsLevel())
			{
				ConfigurationController.Reload();
			}
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "ShowingInfo")]
	internal static class ItemAttributes_ShowingInfo_Patch
	{
		private static void Postfix(ItemAttributes __instance, ref string ___promptName)
		{
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if ((enabled != null && !enabled.Value) || (Object)(object)__instance == (Object)null || string.IsNullOrEmpty(___promptName))
			{
				return;
			}
			ReversibleDroneController component = ((Component)__instance).GetComponent<ReversibleDroneController>();
			if (!((Object)(object)component == (Object)null) && component.GetEffectiveModeForDisplay() == DroneMode.Drain)
			{
				if (___promptName.Contains("Recharge Droid"))
				{
					___promptName = ___promptName.Replace("Recharge Droid", "Drain Droid");
				}
				else if (___promptName.Contains("Dron de recarga"))
				{
					___promptName = ___promptName.Replace("Dron de recarga", "Dron de drenado");
				}
				else if (___promptName.Contains("Recharge"))
				{
					___promptName = ___promptName.Replace("Recharge", "Drain");
				}
				else if (___promptName.Contains("recarga"))
				{
					___promptName = ___promptName.Replace("recarga", "drenado");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemDroneBattery), "CustomTargetingCondition")]
	internal static class ItemDroneBattery_CustomTargetingCondition_Patch
	{
		private static bool Prefix(ItemDroneBattery __instance, GameObject target, ref bool __result)
		{
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if (enabled != null && !enabled.Value)
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null || (Object)(object)target == (Object)null)
			{
				return true;
			}
			ReversibleDroneController component = ((Component)__instance).GetComponent<ReversibleDroneController>();
			if ((Object)(object)component != (Object)null && component.CurrentMode == DroneMode.Drain)
			{
				__result = component.CustomTargetingCondition(target);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDroneBattery), "Start")]
	internal static class ItemDroneBattery_Start_Patch
	{
		private static void Postfix(ItemDroneBattery __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				if ((Object)(object)((Component)__instance).GetComponent<ReversibleDroneController>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<ReversibleDroneController>();
				}
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				if (component != null)
				{
					component.RefreshRpcMonoBehaviourCache();
				}
				ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"[ReversibleBatteryDrone] ItemDroneBattery.Start patched on GameObject {((Object)((Component)__instance).gameObject).name}, ViewID: {((component != null) ? new int?(component.ViewID) : ((int?)null))}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemDroneBattery), "Update")]
	internal static class ItemDroneBattery_Update_Patch
	{
		private static bool Prefix(ItemDroneBattery __instance)
		{
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if (enabled != null && !enabled.Value)
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			ReversibleDroneController component = ((Component)__instance).GetComponent<ReversibleDroneController>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (component.CurrentMode == DroneMode.Drain)
			{
				ItemEquippable component2 = ((Component)__instance).GetComponent<ItemEquippable>();
				ItemDrone component3 = ((Component)__instance).GetComponent<ItemDrone>();
				PhysGrabObject component4 = ((Component)__instance).GetComponent<PhysGrabObject>();
				if ((Object)(object)component2 != (Object)null && component2.isEquipped)
				{
					return false;
				}
				if (!SemiFunc.IsMasterClientOrSingleplayer())
				{
					return false;
				}
				if ((Object)(object)component3 == (Object)null || !component3.itemActivated)
				{
					return false;
				}
				if ((Object)(object)component4 != (Object)null)
				{
					component4.OverrideZeroGravity(0.1f);
					component4.OverrideDrag(1f, 0.1f);
					component4.OverrideAngularDrag(10f, 0.1f);
				}
				if (component3.magnetActive)
				{
					component.ExecuteDrain();
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "CheckTargetDeath")]
	internal static class ItemDrone_CheckTargetDeath_Patch
	{
		private static bool Prefix(ItemDrone __instance)
		{
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if (enabled != null && !enabled.Value)
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			ReversibleDroneController component = ((Component)__instance).GetComponent<ReversibleDroneController>();
			if ((Object)(object)component != (Object)null && component.CurrentMode == DroneMode.Drain)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "Start")]
	internal static class ItemDrone_Start_Patch
	{
		private static void Postfix(ItemDrone __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponent<ItemDroneBattery>() == (Object)null))
			{
				if ((Object)(object)((Component)__instance).GetComponent<ReversibleDroneController>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<ReversibleDroneController>();
				}
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				if (component != null)
				{
					component.RefreshRpcMonoBehaviourCache();
				}
				ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"[ReversibleBatteryDrone] ItemDrone.Start patched on GameObject {((Object)((Component)__instance).gameObject).name}, ViewID: {((component != null) ? new int?(component.ViewID) : ((int?)null))}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "StateOff")]
	internal static class ItemDrone_StateOff_Patch
	{
		private static void Postfix(ItemDrone __instance)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if ((enabled != null && !enabled.Value) || (Object)(object)__instance == (Object)null || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			ReversibleDroneController component = ((Component)__instance).GetComponent<ReversibleDroneController>();
			if ((Object)(object)component != (Object)null && component.CurrentMode == DroneMode.Drain)
			{
				ItemToggle component2 = ((Component)__instance).GetComponent<ItemToggle>();
				if ((Object)(object)component2 != (Object)null && component2.toggleState && (int)__instance.currentState == 0)
				{
					__instance.StateSet((State)1);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "StateSearching")]
	internal static class ItemDrone_StateSearching_Patch
	{
		private static bool Prefix(ItemDrone __instance)
		{
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if (enabled != null && !enabled.Value)
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			ReversibleDroneController component = ((Component)__instance).GetComponent<ReversibleDroneController>();
			if ((Object)(object)component != (Object)null && component.CurrentMode == DroneMode.Drain)
			{
				component.CustomStateSearching();
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "StateSet")]
	internal static class ItemDrone_StateSet_Patch
	{
		private static bool Prefix(ItemDrone __instance, State newState)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if (enabled != null && !enabled.Value)
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((int)newState == 4)
			{
				ReversibleDroneController component = ((Component)__instance).GetComponent<ReversibleDroneController>();
				if ((Object)(object)component != (Object)null && component.CurrentMode == DroneMode.Drain)
				{
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemToggle), "Update")]
	internal static class ItemToggle_Update_Patch
	{
		private static bool Prefix(ItemToggle __instance)
		{
			ConfigEntry<bool>? enabled = ConfigurationController.Enabled;
			if (enabled != null && !enabled.Value)
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null || __instance.disabled)
			{
				return true;
			}
			ReversibleDroneController reversibleDroneController = ((Component)__instance).GetComponent<ReversibleDroneController>();
			if ((Object)(object)reversibleDroneController == (Object)null)
			{
				if (!((Object)(object)((Component)__instance).GetComponent<ItemDroneBattery>() != (Object)null) && !((Object)(object)((Component)__instance).GetComponent<ItemDrone>() != (Object)null))
				{
					return true;
				}
				reversibleDroneController = ((Component)__instance).gameObject.AddComponent<ReversibleDroneController>();
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				if (component != null)
				{
					component.RefreshRpcMonoBehaviourCache();
				}
				ManualLogSource logger = ReversibleBatteryDronePlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"[ReversibleBatteryDrone] Controller dynamically attached in ItemToggle_Update. ViewID: {((component != null) ? new int?(component.ViewID) : ((int?)null))}");
				}
			}
			PhysGrabObject component2 = ((Component)__instance).GetComponent<PhysGrabObject>();
			if ((Object)(object)component2 == (Object)null || !component2.heldByLocalPlayer)
			{
				return true;
			}
			if ((Object)(object)PlayerController.instance != (Object)null && PlayerController.instance.InputDisableTimer <= 0f && SemiFunc.InputDown((InputKey)2))
			{
				if ((Object)(object)TutorialDirector.instance != (Object)null)
				{
					TutorialDirector.instance.playerUsedToggle = true;
				}
				PhotonView component3 = ((Component)reversibleDroneController).GetComponent<PhotonView>();
				ManualLogSource logger2 = ReversibleBatteryDronePlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogInfo((object)$"[ReversibleBatteryDrone] [Input] Local player pressed E on ViewID: {((component3 != null) ? new int?(component3.ViewID) : ((int?)null))}. CurrentMode: {reversibleDroneController.CurrentMode}, ToggleState: {__instance.toggleState}");
				}
				reversibleDroneController.HandleInteractPress();
				return false;
			}
			return true;
		}
	}
}