Decompiled source of ClownBeamTrackingEnhancements v4.0.0

ClownBeamTrackingEnhancements.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 HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 REPOJP.ClownBeamTrackingEnhancements
{
	[BepInPlugin("REPOJP.ClownBeamTrackingEnhancements", "ClownBeamTrackingEnhancements", "1.2.0")]
	public sealed class ClownBeamTrackingEnhancements : BaseUnityPlugin
	{
		public const string PluginGuid = "REPOJP.ClownBeamTrackingEnhancements";

		public const string PluginName = "ClownBeamTrackingEnhancements";

		public const string PluginVersion = "1.2.0";

		internal static ClownBeamTrackingEnhancements Instance;

		private Harmony harmony;

		internal static ConfigEntry<int> CfgAttackTrackSpeed;

		internal static ConfigEntry<int> CfgLaserRange;

		internal static ConfigEntry<bool> CfgAttackWalkEnabled;

		internal static ConfigEntry<bool> CfgZeroAttackStartDelay;

		internal static ConfigEntry<int> CfgBeamDurationMin;

		internal static ConfigEntry<int> CfgBeamDurationMax;

		internal static ConfigEntry<bool> CfgDisableKickAttack;

		internal static ConfigEntry<float> CfgKnockbackMultiplier;

		internal static ConfigEntry<bool> CfgAttackRandomMoveEnabled;

		internal static ConfigEntry<bool> CfgAttackRandomJumpEnabled;

		internal static ConfigEntry<bool> CfgAttackRandomTargetSwitchEnabled;

		internal static ConfigEntry<float> CfgVisionAngleMultiplier;

		internal static ConfigEntry<float> CfgVisionDistanceMultiplier;

		internal static ConfigEntry<float> CfgHearingMultiplier;

		internal static ConfigEntry<int> CfgAttackSpinChancePercent;

		internal static ConfigEntry<int> CfgAttackSpinSpeedDegPerSec;

		private void Awake()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			Instance = this;
			try
			{
				((Component)this).transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Plugin persistence setup failed. プラグイン永続化設定失敗\n" + ex));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"\n█████████████████████████████████████████████████████████████████████████████████████████████████████████████\n ▄▄▄▄▄▄▄ ▄▄                     ▄▄▄▄▄▄▄                       ▄▄▄▄▄▄▄▄▄\n███▀▀▀▀▀ ██                     ███▀▀███▄                     ▀▀▀███▀▀▀                ▄▄     ▀▀\n███      ██ ▄███▄ ██   ██ ████▄ ███▄▄███▀ ▄█▀█▄  ▀▀█▄ ███▄███▄   ███ ████▄  ▀▀█▄ ▄████ ██ ▄█▀ ██  ████▄ ▄████\n███      ██ ██ ██ ██ █ ██ ██ ██ ███  ███▄ ██▄█▀ ▄█▀██ ██ ██ ██   ███ ██ ▀▀ ▄█▀██ ██    ████   ██  ██ ██ ██ ██\n▀███████ ██ ▀███▀  ██▀██  ██ ██ ████████▀ ▀█▄▄▄ ▀█▄██ ██ ██ ██   ███ ██    ▀█▄██ ▀████ ██ ▀█▄ ██▄ ██ ██ ▀████\n                                                                                                           ██\n                                                                                                         ▀▀▀\n█████████████████████████████████████████████████████████████████████████████████████████████████████████████\n");
			BindConfigs();
			try
			{
				harmony = new Harmony("REPOJP.ClownBeamTrackingEnhancements");
				harmony.PatchAll(typeof(ClownBeamTrackingEnhancements).Assembly);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Harmony patches applied. Harmony Patch適用完了");
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Harmony patch failed. Harmony Patch失敗\n" + ex2));
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Harmony cleanup failed. Harmony解除失敗\n" + ex));
			}
		}

		private void BindConfigs()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Expected O, but got Unknown
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Expected O, but got Unknown
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Expected O, but got Unknown
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Expected O, but got Unknown
			CfgAttackTrackSpeed = ((BaseUnityPlugin)this).Config.Bind<int>("Clown", "AttackTrackSpeed", 15, new ConfigDescription("Horizontal tracking speed while attacking (AttackStart/Attack/AttackEnd) SpringQuaternion.speed. 攻撃中(AttackStart/Attack/AttackEnd)の水平追従速度 SpringQuaternion.speed", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 300), Array.Empty<object>()));
			CfgLaserRange = ((BaseUnityPlugin)this).Config.Bind<int>("Clown", "BeamRange", 10, new ConfigDescription("Beam range distance EnemyBeamer.laserRange. ビーム射程距離 EnemyBeamer.laserRange", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 300), Array.Empty<object>()));
			CfgAttackWalkEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Clown", "AttackWalkEnabled", true, "Allow walking during attack. true = walk while beaming, false = mostly stationary. 攻撃中の歩行許可 true=歩行しながらビーム false=停止寄り");
			CfgZeroAttackStartDelay = ((BaseUnityPlugin)this).Config.Bind<bool>("Clown", "ZeroAttackStartDelay", false, "Set AttackStart wait time to 0. true = immediately transition to Attack. AttackStartの待機時間を0にする true=即Attackへ遷移");
			CfgBeamDurationMin = ((BaseUnityPlugin)this).Config.Bind<int>("Clown", "BeamDurationMinSeconds", 1, new ConfigDescription("Minimum beam attack duration in seconds (Attack state duration). ビーム攻撃時間の最小秒数 Attack状態の継続時間", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 300), Array.Empty<object>()));
			CfgBeamDurationMax = ((BaseUnityPlugin)this).Config.Bind<int>("Clown", "BeamDurationMaxSeconds", 2, new ConfigDescription("Maximum beam attack duration in seconds (Attack state duration). ビーム攻撃時間の最大秒数 Attack状態の継続時間", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 300), Array.Empty<object>()));
			CfgDisableKickAttack = ((BaseUnityPlugin)this).Config.Bind<bool>("Clown", "DisableKickAttack", false, "Never perform kick (Melee) attack. true = disabled, false = vanilla. キック攻撃(Melee)を絶対に行わない true=無効 false=原作通り");
			CfgKnockbackMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Clown", "KnockbackMultiplier", 1.5f, new ConfigDescription("Beam knockback multiplier applied to HurtCollider.playerHitForce/playerTumbleForce/playerTumbleTorque. ビームのノックバック倍率 HurtCollider.playerHitForce/playerTumbleForce/playerTumbleTorqueへ倍率適用", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			CfgAttackRandomMoveEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Clown", "AttackRandomMoveEnabled", true, "Randomly move forward/back/left/right during attack. true = enabled, false = disabled. 攻撃中に前後左右へランダム移動する true=有効 false=無効");
			CfgAttackRandomJumpEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Clown", "AttackRandomJumpEnabled", true, "Randomly perform meaningless jumps during attack. true = enabled, false = disabled. 攻撃中にランダムで無意味ジャンプする true=有効 false=無効");
			CfgAttackRandomTargetSwitchEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Clown", "AttackRandomTargetSwitchEnabled", true, "If multiple players are in attackable range, randomly switch target instantly during attack. true = enabled, false = disabled. 攻撃可能範囲内に複数プレイヤーがいる場合 攻撃中にランダムでターゲットを瞬時に切替 true=有効 false=無効");
			CfgVisionAngleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Clown", "VisionAngleMultiplier", 1.5f, new ConfigDescription("Vision angle multiplier: adjust VisionDot (dot threshold) by 1/multiplier (1.5 widens). 視野角拡張倍率 VisionDot(判定ドット)を1/倍率に調整 1.5=広がる", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			CfgVisionDistanceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Clown", "VisionDistanceMultiplier", 1.5f, new ConfigDescription("Vision distance multiplier applied to VisionDistance/VisionDistanceClose/VisionDistanceCloseCrouch. 視野距離拡張倍率 VisionDistance/VisionDistanceClose/VisionDistanceCloseCrouchへ倍率適用", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			CfgHearingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Clown", "HearingMultiplier", 1.5f, new ConfigDescription("Hearing (investigate range) multiplier applied to EnemyStateInvestigate.rangeMultiplier. 聴覚(Investigate範囲)倍率 EnemyStateInvestigate.rangeMultiplierへ倍率適用", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			CfgAttackSpinChancePercent = ((BaseUnityPlugin)this).Config.Bind<int>("Clown", "AttackSpinChancePercent", 10, new ConfigDescription("Chance (%) to always perform a spin-sweep during attack (like a grab-escape spin). 0=disabled 100=always. 攻撃中に掴み逃れ回転のような回転スイープを無条件で行う発生率(%) 0=無効 100=常時", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			CfgAttackSpinSpeedDegPerSec = ((BaseUnityPlugin)this).Config.Bind<int>("Clown", "AttackSpinSpeedDegPerSec", 300, new ConfigDescription("Spin sweep speed during attack (deg/sec). Random variance is applied. 攻撃中の回転スイープ速度(度/秒) 実際はランダムばらけ適用", (AcceptableValueBase)(object)new AcceptableValueRange<int>(90, 3000), Array.Empty<object>()));
		}
	}
	[HarmonyPatch]
	internal static class EnemyBeamerPatches
	{
		private sealed class SenseOriginal
		{
			public float VisionDistance;

			public float VisionDistanceClose;

			public float VisionDistanceCloseCrouch;

			public float VisionDotStanding;

			public float VisionDotCrouch;

			public float VisionDotCrawl;

			public float PhysObjectVisionDot;

			public float HearingRangeMultiplier;
		}

		private sealed class AttackRuntime
		{
			public float NextMoveTimer;

			public float NextJumpTimer;

			public float NextTargetSwitchTimer;

			public int LastTargetViewId;

			public float NextSpinCheckTimer;

			public bool Spinning;

			public float SpinTimer;

			public float SpinYaw;

			public float SpinSpeedDegPerSec;
		}

		private static readonly FieldRef<EnemyBeamer, Enemy> FR_Enemy = AccessTools.FieldRefAccess<EnemyBeamer, Enemy>("enemy");

		private static readonly FieldRef<EnemyBeamer, PhotonView> FR_PhotonView = AccessTools.FieldRefAccess<EnemyBeamer, PhotonView>("photonView");

		private static readonly FieldRef<EnemyBeamer, Quaternion> FR_AimHorizontalTarget = AccessTools.FieldRefAccess<EnemyBeamer, Quaternion>("aimHorizontalTarget");

		private static readonly FieldRef<EnemyBeamer, float> FR_AimHorizontalResult = AccessTools.FieldRefAccess<EnemyBeamer, float>("aimHorizontalResult");

		private static readonly FieldRef<EnemyBeamer, float> FR_AimHorizontalLerp = AccessTools.FieldRefAccess<EnemyBeamer, float>("aimHorizontalLerp");

		private static readonly FieldRef<EnemyBeamer, Quaternion> FR_AimVerticalTarget = AccessTools.FieldRefAccess<EnemyBeamer, Quaternion>("aimVerticalTarget");

		private static readonly FieldRef<EnemyBeamer, bool> FR_StateImpulse = AccessTools.FieldRefAccess<EnemyBeamer, bool>("stateImpulse");

		private static readonly FieldRef<EnemyBeamer, float> FR_StateTimer = AccessTools.FieldRefAccess<EnemyBeamer, float>("stateTimer");

		private static readonly FieldRef<EnemyBeamer, float> FR_LaserRange = AccessTools.FieldRefAccess<EnemyBeamer, float>("laserRange");

		private static readonly FieldRef<EnemyBeamer, PlayerAvatar> FR_PlayerTarget = AccessTools.FieldRefAccess<EnemyBeamer, PlayerAvatar>("playerTarget");

		private static readonly FieldRef<EnemyBeamer, float> FR_LaserCooldown = AccessTools.FieldRefAccess<EnemyBeamer, float>("laserCooldown");

		private static readonly FieldRef<EnemyBeamer, Vector3> FR_SeekDestination = AccessTools.FieldRefAccess<EnemyBeamer, Vector3>("seekDestination");

		private static readonly FieldRef<EnemyBeamer, Vector3> FR_MeleeTarget = AccessTools.FieldRefAccess<EnemyBeamer, Vector3>("meleeTarget");

		private static readonly FieldRef<EnemyBeamer, bool> FR_MeleePlayer = AccessTools.FieldRefAccess<EnemyBeamer, bool>("meleePlayer");

		private static readonly FieldRef<EnemyBeamer, Quaternion> FR_HorizontalRotationTarget = AccessTools.FieldRefAccess<EnemyBeamer, Quaternion>("horizontalRotationTarget");

		private static readonly FieldRef<EnemyVision, PlayerAvatar> FR_VisionTriggeredPlayer = AccessTools.FieldRefAccess<EnemyVision, PlayerAvatar>("onVisionTriggeredPlayer");

		private static readonly FieldRef<EnemyJump, bool> FR_EnemyJump_Jumping = AccessTools.FieldRefAccess<EnemyJump, bool>("jumping");

		private static readonly FieldRef<EnemyGrounded, bool> FR_EnemyGrounded_Grounded = AccessTools.FieldRefAccess<EnemyGrounded, bool>("grounded");

		private static readonly FieldRef<EnemyRigidbody, bool> FR_EnemyRigidbody_Grabbed = AccessTools.FieldRefAccess<EnemyRigidbody, bool>("grabbed");

		private static readonly FieldRef<EnemyRigidbody, float> FR_EnemyRigidbody_TeleportedTimer = AccessTools.FieldRefAccess<EnemyRigidbody, float>("teleportedTimer");

		private static readonly FieldRef<EnemyRigidbody, Rigidbody> FR_EnemyRigidbody_Rigidbody = AccessTools.FieldRefAccess<EnemyRigidbody, Rigidbody>("rb");

		private static readonly FieldRef<EnemyNavMeshAgent, Vector3> FR_EnemyNavMeshAgent_AgentVelocity = AccessTools.FieldRefAccess<EnemyNavMeshAgent, Vector3>("AgentVelocity");

		private static readonly Action<EnemyBeamer, State> CallUpdateState = AccessTools.MethodDelegate<Action<EnemyBeamer, State>>(AccessTools.Method(typeof(EnemyBeamer), "UpdateState", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Dictionary<int, SenseOriginal> SenseOriginals = new Dictionary<int, SenseOriginal>();

		private static readonly Dictionary<int, AttackRuntime> AttackRuntimes = new Dictionary<int, AttackRuntime>();

		private static bool IsMasterOrSolo()
		{
			return SemiFunc.IsMasterClientOrSingleplayer();
		}

		private static Enemy GetEnemy(EnemyBeamer beamer)
		{
			if ((Object)(object)beamer == (Object)null)
			{
				return null;
			}
			Enemy val = FR_Enemy.Invoke(beamer);
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)beamer).GetComponent<Enemy>();
				if ((Object)(object)val != (Object)null)
				{
					FR_Enemy.Invoke(beamer) = val;
				}
			}
			return val;
		}

		private static PhotonView GetPhotonView(EnemyBeamer beamer)
		{
			if ((Object)(object)beamer == (Object)null)
			{
				return null;
			}
			PhotonView val = FR_PhotonView.Invoke(beamer);
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)beamer).GetComponent<PhotonView>();
				if ((Object)(object)val != (Object)null)
				{
					FR_PhotonView.Invoke(beamer) = val;
				}
			}
			return val;
		}

		private static EnemyVision GetEnemyVision(Enemy enemy)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				return null;
			}
			return ((Component)enemy).GetComponent<EnemyVision>();
		}

		private static EnemyStateInvestigate GetEnemyStateInvestigate(Enemy enemy)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				return null;
			}
			return ((Component)enemy).GetComponent<EnemyStateInvestigate>();
		}

		private static EnemyRigidbody GetEnemyRigidbody(Enemy enemy, EnemyBeamer beamer)
		{
			if ((Object)(object)enemy != (Object)null)
			{
				EnemyRigidbody component = ((Component)enemy).GetComponent<EnemyRigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
			}
			if ((Object)(object)beamer != (Object)null)
			{
				return ((Component)beamer).GetComponent<EnemyRigidbody>();
			}
			return null;
		}

		private static EnemyNavMeshAgent GetEnemyNavMeshAgent(Enemy enemy, EnemyBeamer beamer)
		{
			if ((Object)(object)enemy != (Object)null)
			{
				EnemyNavMeshAgent component = ((Component)enemy).GetComponent<EnemyNavMeshAgent>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
			}
			if ((Object)(object)beamer != (Object)null)
			{
				return ((Component)beamer).GetComponent<EnemyNavMeshAgent>();
			}
			return null;
		}

		private static EnemyJump GetEnemyJump(Enemy enemy, EnemyBeamer beamer)
		{
			if ((Object)(object)enemy != (Object)null)
			{
				EnemyJump component = ((Component)enemy).GetComponent<EnemyJump>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
			}
			if ((Object)(object)beamer != (Object)null)
			{
				return ((Component)beamer).GetComponent<EnemyJump>();
			}
			return null;
		}

		private static EnemyGrounded GetEnemyGrounded(Enemy enemy, EnemyBeamer beamer)
		{
			if ((Object)(object)enemy != (Object)null)
			{
				EnemyGrounded component = ((Component)enemy).GetComponent<EnemyGrounded>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
			}
			if ((Object)(object)beamer != (Object)null)
			{
				return ((Component)beamer).GetComponent<EnemyGrounded>();
			}
			return null;
		}

		private static PlayerAvatar GetTarget(EnemyBeamer beamer)
		{
			if ((Object)(object)beamer == (Object)null)
			{
				return null;
			}
			return FR_PlayerTarget.Invoke(beamer);
		}

		private static AttackRuntime GetRuntime(EnemyBeamer beamer)
		{
			if ((Object)(object)beamer == (Object)null)
			{
				return null;
			}
			int instanceID = ((Object)beamer).GetInstanceID();
			if (!AttackRuntimes.TryGetValue(instanceID, out AttackRuntime value))
			{
				value = new AttackRuntime();
				value.NextMoveTimer = Random.Range(0.15f, 0.55f);
				value.NextJumpTimer = Random.Range(0.45f, 1.35f);
				value.NextTargetSwitchTimer = Random.Range(0.05f, 0.25f);
				value.NextSpinCheckTimer = Random.Range(0.35f, 1.1f);
				value.LastTargetViewId = 0;
				value.Spinning = false;
				value.SpinTimer = 0f;
				value.SpinYaw = 0f;
				value.SpinSpeedDegPerSec = 0f;
				AttackRuntimes[instanceID] = value;
			}
			return value;
		}

		private static void SetTargetAndSync(EnemyBeamer beamer, PlayerAvatar target)
		{
			if ((Object)(object)beamer == (Object)null || (Object)(object)target == (Object)null || (Object)(object)target.photonView == (Object)null)
			{
				return;
			}
			FR_PlayerTarget.Invoke(beamer) = target;
			if (GameManager.Multiplayer())
			{
				PhotonView photonView = GetPhotonView(beamer);
				if ((Object)(object)photonView != (Object)null)
				{
					photonView.RPC("UpdatePlayerTargetRPC", (RpcTarget)0, new object[1] { target.photonView.ViewID });
				}
			}
		}

		private static void UpdateAimHorizontalToTarget(EnemyBeamer beamer)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_0097: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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)
			AttackRuntime runtime = GetRuntime(beamer);
			if (runtime != null && runtime.Spinning)
			{
				return;
			}
			PlayerAvatar target = GetTarget(beamer);
			if (!((Object)(object)target == (Object)null) && !((Object)(object)target.PlayerVisionTarget == (Object)null) && !((Object)(object)target.PlayerVisionTarget.VisionTransform == (Object)null))
			{
				Vector3 val = (((Object)(object)beamer.bottomTransform != (Object)null) ? beamer.bottomTransform.position : ((Component)beamer).transform.position);
				Vector3 position = target.PlayerVisionTarget.VisionTransform.position;
				Vector3 val2 = position - val;
				if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f))
				{
					Quaternion val3 = Quaternion.LookRotation(val2);
					val3 = Quaternion.Euler(0f, ((Quaternion)(ref val3)).eulerAngles.y, 0f);
					FR_AimHorizontalTarget.Invoke(beamer) = val3;
					FR_AimHorizontalResult.Invoke(beamer) = 0f;
				}
			}
		}

		private static void ApplyAttackWalkForward(EnemyBeamer beamer)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!ClownBeamTrackingEnhancements.CfgAttackWalkEnabled.Value || !IsMasterOrSolo())
			{
				return;
			}
			PlayerAvatar target = GetTarget(beamer);
			if (!((Object)(object)target == (Object)null))
			{
				Enemy enemy = GetEnemy(beamer);
				EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(enemy, beamer);
				if (!((Object)(object)enemyNavMeshAgent == (Object)null))
				{
					enemyNavMeshAgent.Stop(0f);
					enemyNavMeshAgent.SetDestination(((Component)target).transform.position);
				}
			}
		}

		private static void ApplyAttackRandomMove(EnemyBeamer beamer)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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_0164: Unknown result type (might be due to invalid IL or missing references)
			if (!ClownBeamTrackingEnhancements.CfgAttackRandomMoveEnabled.Value || !IsMasterOrSolo())
			{
				return;
			}
			Enemy enemy = GetEnemy(beamer);
			if ((Object)(object)beamer == (Object)null || (Object)(object)enemy == (Object)null)
			{
				return;
			}
			EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(enemy, beamer);
			if ((Object)(object)enemyNavMeshAgent == (Object)null)
			{
				return;
			}
			AttackRuntime runtime = GetRuntime(beamer);
			if (runtime == null)
			{
				return;
			}
			runtime.NextMoveTimer -= Time.deltaTime;
			if (!(runtime.NextMoveTimer > 0f))
			{
				runtime.NextMoveTimer = Random.Range(0.18f, 0.75f);
				EnemyRigidbody enemyRigidbody = GetEnemyRigidbody(enemy, beamer);
				Vector3 val = (((Object)(object)enemyRigidbody != (Object)null) ? ((Component)enemyRigidbody).transform.position : ((Component)beamer).transform.position);
				Vector3 right = ((Component)beamer).transform.right;
				Vector3 forward = ((Component)beamer).transform.forward;
				float num = Random.Range(-1f, 1f);
				float num2 = Random.Range(-1f, 1f);
				float num3 = Random.Range(0.8f, 2.2f);
				Vector3 val2 = right * num + forward * num2;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
				{
					val2 = forward;
				}
				val2.y = 0f;
				((Vector3)(ref val2)).Normalize();
				Vector3 destination = val + val2 * num3;
				enemyNavMeshAgent.Stop(0f);
				enemyNavMeshAgent.SetDestination(destination);
			}
		}

		private static void PerformMeaninglessJumpNow(EnemyBeamer beamer, Vector3 horizontalDir)
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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)
			if (!IsMasterOrSolo())
			{
				return;
			}
			Enemy enemy = GetEnemy(beamer);
			EnemyRigidbody enemyRigidbody = GetEnemyRigidbody(enemy, beamer);
			Rigidbody val = (((Object)(object)enemyRigidbody != (Object)null) ? FR_EnemyRigidbody_Rigidbody.Invoke(enemyRigidbody) : null);
			if ((Object)(object)beamer == (Object)null || (Object)(object)enemy == (Object)null || (Object)(object)enemyRigidbody == (Object)null || (Object)(object)val == (Object)null || enemy.IsStunned() || FR_EnemyRigidbody_Grabbed.Invoke(enemyRigidbody) || FR_EnemyRigidbody_TeleportedTimer.Invoke(enemyRigidbody) > 0f)
			{
				return;
			}
			EnemyGrounded enemyGrounded = GetEnemyGrounded(enemy, beamer);
			if (!((Object)(object)enemyGrounded == (Object)null) && FR_EnemyGrounded_Grounded.Invoke(enemyGrounded))
			{
				horizontalDir.y = 0f;
				if (((Vector3)(ref horizontalDir)).sqrMagnitude < 0.001f)
				{
					horizontalDir = ((Component)beamer).transform.forward;
					horizontalDir.y = 0f;
				}
				((Vector3)(ref horizontalDir)).Normalize();
				float num = 5f;
				float num2 = 2f;
				EnemyJump enemyJump = GetEnemyJump(enemy, beamer);
				if ((Object)(object)enemyJump != (Object)null)
				{
					num = enemyJump.surfaceJumpForceUp;
					num2 = enemyJump.surfaceJumpForceSide;
				}
				enemyRigidbody.JumpImpulse();
				Vector3 val2 = horizontalDir * num2 + Vector3.up * num;
				val.AddForce(val2, (ForceMode)1);
			}
		}

		private static void ApplyAttackRandomJump(EnemyBeamer beamer)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00f0: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			if (!ClownBeamTrackingEnhancements.CfgAttackRandomJumpEnabled.Value || !IsMasterOrSolo())
			{
				return;
			}
			Enemy enemy = GetEnemy(beamer);
			EnemyRigidbody enemyRigidbody = GetEnemyRigidbody(enemy, beamer);
			if ((Object)(object)beamer == (Object)null || (Object)(object)enemy == (Object)null || (Object)(object)enemyRigidbody == (Object)null)
			{
				return;
			}
			AttackRuntime runtime = GetRuntime(beamer);
			if (runtime == null)
			{
				return;
			}
			runtime.NextJumpTimer -= Time.deltaTime;
			if (!(runtime.NextJumpTimer > 0f))
			{
				runtime.NextJumpTimer = Random.Range(0.35f, 2.1f);
				Vector3 horizontalDir = ((Component)beamer).transform.right * Random.Range(-1f, 1f) + ((Component)beamer).transform.forward * Random.Range(-1f, 1f);
				if (((Vector3)(ref horizontalDir)).sqrMagnitude < 0.001f)
				{
					horizontalDir = ((Component)beamer).transform.forward;
				}
				PerformMeaninglessJumpNow(beamer, horizontalDir);
			}
		}

		private static void ApplyAttackRandomTargetSwitch(EnemyBeamer beamer)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			if (!ClownBeamTrackingEnhancements.CfgAttackRandomTargetSwitchEnabled.Value || !IsMasterOrSolo() || (Object)(object)beamer == (Object)null)
			{
				return;
			}
			AttackRuntime runtime = GetRuntime(beamer);
			if (runtime == null)
			{
				return;
			}
			runtime.NextTargetSwitchTimer -= Time.deltaTime;
			if (runtime.NextTargetSwitchTimer > 0f)
			{
				return;
			}
			runtime.NextTargetSwitchTimer = Random.Range(0.1f, 0.8f);
			PlayerAvatar target = GetTarget(beamer);
			float num = Mathf.Clamp((float)ClownBeamTrackingEnhancements.CfgLaserRange.Value, 1f, 300f);
			Vector3 val = (((Object)(object)beamer.laserStartTransform != (Object)null) ? beamer.laserStartTransform.position : ((Component)beamer).transform.position);
			List<PlayerAvatar> list = SemiFunc.PlayerGetList();
			if (list == null || list.Count == 0)
			{
				return;
			}
			List<PlayerAvatar> list2 = new List<PlayerAvatar>();
			for (int i = 0; i < list.Count; i++)
			{
				PlayerAvatar val2 = list[i];
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.photonView == (Object)null) && !((Object)(object)val2.PlayerVisionTarget == (Object)null) && !((Object)(object)val2.PlayerVisionTarget.VisionTransform == (Object)null) && (!((Object)(object)target != (Object)null) || !((Object)(object)val2 == (Object)(object)target)) && (runtime.LastTargetViewId == 0 || val2.photonView.ViewID != runtime.LastTargetViewId) && !(Vector3.Distance(val, val2.PlayerVisionTarget.VisionTransform.position) > num))
				{
					list2.Add(val2);
				}
			}
			if (list2.Count == 0)
			{
				for (int j = 0; j < list.Count; j++)
				{
					PlayerAvatar val3 = list[j];
					if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.photonView == (Object)null) && !((Object)(object)val3.PlayerVisionTarget == (Object)null) && !((Object)(object)val3.PlayerVisionTarget.VisionTransform == (Object)null) && (!((Object)(object)target != (Object)null) || !((Object)(object)val3 == (Object)(object)target)) && !(Vector3.Distance(val, val3.PlayerVisionTarget.VisionTransform.position) > num))
					{
						list2.Add(val3);
					}
				}
			}
			if (list2.Count != 0)
			{
				PlayerAvatar val4 = list2[Random.Range(0, list2.Count)];
				if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4.photonView == (Object)null))
				{
					SetTargetAndSync(beamer, val4);
					runtime.LastTargetViewId = val4.photonView.ViewID;
					UpdateAimHorizontalToTarget(beamer);
				}
			}
		}

		private static void ProcessAttackSpinSweep(EnemyBeamer beamer)
		{
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			if (!IsMasterOrSolo())
			{
				return;
			}
			AttackRuntime runtime = GetRuntime(beamer);
			if (runtime == null)
			{
				return;
			}
			if (runtime.Spinning)
			{
				runtime.SpinTimer -= Time.deltaTime;
				runtime.SpinYaw += runtime.SpinSpeedDegPerSec * Time.deltaTime;
				if (runtime.SpinTimer <= 0f)
				{
					runtime.Spinning = false;
					runtime.SpinTimer = 0f;
					runtime.SpinSpeedDegPerSec = 0f;
					runtime.NextSpinCheckTimer = Random.Range(0.35f, 1.45f);
				}
				return;
			}
			int num = Mathf.Clamp(ClownBeamTrackingEnhancements.CfgAttackSpinChancePercent.Value, 0, 100);
			if (num <= 0)
			{
				return;
			}
			runtime.NextSpinCheckTimer -= Time.deltaTime;
			if (!(runtime.NextSpinCheckTimer > 0f))
			{
				runtime.NextSpinCheckTimer = Random.Range(0.35f, 1.45f);
				int num2 = Random.Range(0, 100);
				if (num2 < num)
				{
					runtime.Spinning = true;
					runtime.SpinTimer = Random.Range(0.55f, 1.2f);
					float num3 = Mathf.Clamp((float)ClownBeamTrackingEnhancements.CfgAttackSpinSpeedDegPerSec.Value, 90f, 3000f);
					runtime.SpinSpeedDegPerSec = Random.Range(num3 * 0.75f, num3 * 1.25f);
					Quaternion rotation = ((Component)beamer).transform.rotation;
					float y = ((Quaternion)(ref rotation)).eulerAngles.y;
					runtime.SpinYaw = y + Random.Range(-30f, 30f);
				}
			}
		}

		private static void GetBeamDuration(out float min, out float max)
		{
			min = Mathf.Max(0.05f, (float)ClownBeamTrackingEnhancements.CfgBeamDurationMin.Value);
			max = Mathf.Max(0.05f, (float)ClownBeamTrackingEnhancements.CfgBeamDurationMax.Value);
			if (min > max)
			{
				float num = min;
				min = max;
				max = num;
			}
		}

		private static void ApplySenseMultipliers(EnemyBeamer beamer)
		{
			Enemy enemy = GetEnemy(beamer);
			if ((Object)(object)beamer == (Object)null || (Object)(object)enemy == (Object)null)
			{
				return;
			}
			EnemyVision enemyVision = GetEnemyVision(enemy);
			EnemyStateInvestigate enemyStateInvestigate = GetEnemyStateInvestigate(enemy);
			if ((Object)(object)enemyVision == (Object)null && (Object)(object)enemyStateInvestigate == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)beamer).GetInstanceID();
			if (!SenseOriginals.TryGetValue(instanceID, out SenseOriginal value))
			{
				value = new SenseOriginal();
				if ((Object)(object)enemyVision != (Object)null)
				{
					value.VisionDistance = enemyVision.VisionDistance;
					value.VisionDistanceClose = enemyVision.VisionDistanceClose;
					value.VisionDistanceCloseCrouch = enemyVision.VisionDistanceCloseCrouch;
					value.VisionDotStanding = enemyVision.VisionDotStanding;
					value.VisionDotCrouch = enemyVision.VisionDotCrouch;
					value.VisionDotCrawl = enemyVision.VisionDotCrawl;
					value.PhysObjectVisionDot = enemyVision.PhysObjectVisionDot;
				}
				if ((Object)(object)enemyStateInvestigate != (Object)null)
				{
					value.HearingRangeMultiplier = enemyStateInvestigate.rangeMultiplier;
				}
				SenseOriginals[instanceID] = value;
			}
			float num = Mathf.Clamp(ClownBeamTrackingEnhancements.CfgVisionAngleMultiplier.Value, 1f, 10f);
			float num2 = Mathf.Clamp(ClownBeamTrackingEnhancements.CfgVisionDistanceMultiplier.Value, 1f, 10f);
			float num3 = Mathf.Clamp(ClownBeamTrackingEnhancements.CfgHearingMultiplier.Value, 1f, 10f);
			if ((Object)(object)enemyVision != (Object)null)
			{
				enemyVision.VisionDistance = value.VisionDistance * num2;
				enemyVision.VisionDistanceClose = value.VisionDistanceClose * num2;
				enemyVision.VisionDistanceCloseCrouch = value.VisionDistanceCloseCrouch * num2;
				float num4 = 1f / num;
				enemyVision.VisionDotStanding = Mathf.Clamp(value.VisionDotStanding * num4, -1f, 1f);
				enemyVision.VisionDotCrouch = Mathf.Clamp(value.VisionDotCrouch * num4, -1f, 1f);
				enemyVision.VisionDotCrawl = Mathf.Clamp(value.VisionDotCrawl * num4, -1f, 1f);
				enemyVision.PhysObjectVisionDot = Mathf.Clamp(value.PhysObjectVisionDot * num4, -1f, 1f);
			}
			if ((Object)(object)enemyStateInvestigate != (Object)null)
			{
				enemyStateInvestigate.rangeMultiplier = Mathf.Max(0.01f, value.HearingRangeMultiplier * num3);
			}
		}

		[HarmonyPatch(typeof(EnemyBeamer), "Awake")]
		[HarmonyPostfix]
		private static void Awake_Postfix(EnemyBeamer __instance)
		{
			ApplySenseMultipliers(__instance);
		}

		[HarmonyPatch(typeof(EnemyBeamer), "OnSpawn")]
		[HarmonyPostfix]
		private static void OnSpawn_Postfix(EnemyBeamer __instance)
		{
			ApplySenseMultipliers(__instance);
		}

		[HarmonyPatch(typeof(EnemyBeamer), "OnVision")]
		[HarmonyPrefix]
		private static bool OnVision_Prefix(EnemyBeamer __instance)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Invalid comparison between Unknown and I4
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Invalid comparison between Unknown and I4
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Invalid comparison between Unknown and I4
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Invalid comparison between Unknown and I4
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Invalid comparison between Unknown and I4
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Invalid comparison between Unknown and I4
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Invalid comparison between Unknown and I4
			//IL_01ba: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			if (!ClownBeamTrackingEnhancements.CfgDisableKickAttack.Value)
			{
				return true;
			}
			if (!IsMasterOrSolo())
			{
				return false;
			}
			Enemy enemy = GetEnemy(__instance);
			if ((Object)(object)enemy == (Object)null)
			{
				return false;
			}
			EnemyJump enemyJump = GetEnemyJump(enemy, __instance);
			if ((Object)(object)enemyJump != (Object)null && FR_EnemyJump_Jumping.Invoke(enemyJump))
			{
				return false;
			}
			EnemyVision enemyVision = GetEnemyVision(enemy);
			PlayerAvatar val = (((Object)(object)enemyVision != (Object)null) ? FR_VisionTriggeredPlayer.Invoke(enemyVision) : null);
			PlayerAvatar val2 = GetTarget(__instance);
			State currentState = __instance.currentState;
			if ((int)currentState == 2 || (int)currentState == 1 || (int)currentState == 9 || (int)currentState == 10 || (int)currentState == 3)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)(object)val)
				{
					SetTargetAndSync(__instance, val);
					val2 = val;
				}
				if (FR_LaserCooldown.Invoke(__instance) <= 0f)
				{
					CallUpdateState(__instance, (State)4);
					return false;
				}
				if ((Object)(object)val2 != (Object)null)
				{
					FR_SeekDestination.Invoke(__instance) = ((Component)val2).transform.position;
					CallUpdateState(__instance, (State)9);
				}
				return false;
			}
			if (((int)currentState == 4 || (int)currentState == 5 || (int)currentState == 6) && (Object)(object)val2 != (Object)null && (Object)(object)val2 == (Object)(object)val)
			{
				FR_SeekDestination.Invoke(__instance) = ((Component)val2).transform.position;
			}
			return false;
		}

		[HarmonyPatch(typeof(EnemyBeamer), "StateAttackStart")]
		[HarmonyPrefix]
		private static bool StateAttackStart_Prefix(EnemyBeamer __instance)
		{
			if (!ClownBeamTrackingEnhancements.CfgZeroAttackStartDelay.Value)
			{
				return true;
			}
			if (!FR_StateImpulse.Invoke(__instance))
			{
				return true;
			}
			CallUpdateState(__instance, (State)5);
			return false;
		}

		[HarmonyPatch(typeof(EnemyBeamer), "StateAttackStart")]
		[HarmonyPostfix]
		private static void StateAttackStart_Postfix(EnemyBeamer __instance)
		{
			ProcessAttackSpinSweep(__instance);
			UpdateAimHorizontalToTarget(__instance);
			ApplyAttackWalkForward(__instance);
			ApplyAttackRandomMove(__instance);
			ApplyAttackRandomJump(__instance);
			ApplyAttackRandomTargetSwitch(__instance);
		}

		[HarmonyPatch(typeof(EnemyBeamer), "StateAttack")]
		[HarmonyPrefix]
		private static bool StateAttack_Prefix(EnemyBeamer __instance)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			if (FR_StateImpulse.Invoke(__instance))
			{
				FR_StateImpulse.Invoke(__instance) = false;
				GetBeamDuration(out var min, out var max);
				float num = ((min == max) ? min : Random.Range(min, max));
				FR_StateTimer.Invoke(__instance) = num;
				AttackRuntime runtime = GetRuntime(__instance);
				if (runtime != null)
				{
					runtime.NextTargetSwitchTimer = Random.Range(0.05f, 0.25f);
					runtime.NextSpinCheckTimer = Random.Range(0.35f, 1.1f);
					runtime.NextJumpTimer = Random.Range(0.35f, 1.1f);
					runtime.NextMoveTimer = Random.Range(0.15f, 0.55f);
					runtime.Spinning = false;
					runtime.SpinTimer = 0f;
				}
				Enemy enemy = GetEnemy(__instance);
				EnemyRigidbody enemyRigidbody = GetEnemyRigidbody(enemy, __instance);
				EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(enemy, __instance);
				if ((Object)(object)enemyRigidbody != (Object)null && (Object)(object)enemyNavMeshAgent != (Object)null)
				{
					enemyNavMeshAgent.Warp(((Component)enemyRigidbody).transform.position, false);
					enemyNavMeshAgent.ResetPath();
				}
				FR_AimHorizontalLerp.Invoke(__instance) = 0f;
			}
			ProcessAttackSpinSweep(__instance);
			UpdateAimHorizontalToTarget(__instance);
			ApplyAttackWalkForward(__instance);
			ApplyAttackRandomMove(__instance);
			ApplyAttackRandomJump(__instance);
			ApplyAttackRandomTargetSwitch(__instance);
			FR_StateTimer.Invoke(__instance) -= Time.deltaTime;
			if (FR_StateTimer.Invoke(__instance) <= 0f)
			{
				CallUpdateState(__instance, (State)6);
			}
			return false;
		}

		[HarmonyPatch(typeof(EnemyBeamer), "StateAttackEnd")]
		[HarmonyPostfix]
		private static void StateAttackEnd_Postfix(EnemyBeamer __instance)
		{
			ProcessAttackSpinSweep(__instance);
			UpdateAimHorizontalToTarget(__instance);
			ApplyAttackWalkForward(__instance);
			ApplyAttackRandomMove(__instance);
			ApplyAttackRandomJump(__instance);
			ApplyAttackRandomTargetSwitch(__instance);
		}

		[HarmonyPatch(typeof(EnemyBeamer), "LaserLogic")]
		[HarmonyPrefix]
		private static void LaserLogic_Prefix(EnemyBeamer __instance)
		{
			float num = Mathf.Clamp((float)ClownBeamTrackingEnhancements.CfgLaserRange.Value, 1f, 300f);
			FR_LaserRange.Invoke(__instance) = num;
		}

		[HarmonyPatch(typeof(EnemyBeamer), "VerticalAimLogic")]
		[HarmonyPrefix]
		private static bool VerticalAimLogic_Prefix(EnemyBeamer __instance)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: 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_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: 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_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			if ((int)__instance.currentState != 4 && (int)__instance.currentState != 5 && (int)__instance.currentState != 6)
			{
				FR_AimVerticalTarget.Invoke(__instance) = Quaternion.identity;
				if ((Object)(object)__instance.aimVerticalTransform != (Object)null)
				{
					__instance.aimVerticalTransform.localRotation = Quaternion.Lerp(__instance.aimVerticalTransform.localRotation, FR_AimVerticalTarget.Invoke(__instance), 20f * Time.deltaTime);
				}
				if ((Object)(object)__instance.laserRayTransform != (Object)null)
				{
					__instance.laserRayTransform.localRotation = FR_AimVerticalTarget.Invoke(__instance);
				}
				return false;
			}
			PlayerAvatar target = GetTarget(__instance);
			if ((Object)(object)target == (Object)null || (Object)(object)target.PlayerVisionTarget == (Object)null || (Object)(object)target.PlayerVisionTarget.VisionTransform == (Object)null || (Object)(object)__instance.laserRayTransform == (Object)null)
			{
				return false;
			}
			Quaternion val = Quaternion.LookRotation(target.PlayerVisionTarget.VisionTransform.position - __instance.laserRayTransform.position);
			Quaternion val2 = FR_AimVerticalTarget.Invoke(__instance);
			val2 = ((!(val2 == Quaternion.identity)) ? Quaternion.Lerp(val2, val, 2f * Time.deltaTime) : val);
			Quaternion rotation = __instance.laserRayTransform.rotation;
			__instance.laserRayTransform.rotation = val2;
			Quaternion localRotation = __instance.laserRayTransform.localRotation;
			localRotation = Quaternion.Euler(__instance.laserRayTransform.eulerAngles.x, 0f, 0f);
			__instance.laserRayTransform.rotation = rotation;
			FR_AimVerticalTarget.Invoke(__instance) = localRotation;
			if ((Object)(object)__instance.aimVerticalTransform != (Object)null)
			{
				__instance.aimVerticalTransform.localRotation = Quaternion.Lerp(__instance.aimVerticalTransform.localRotation, localRotation, 20f * Time.deltaTime);
			}
			__instance.laserRayTransform.localRotation = localRotation;
			return false;
		}

		[HarmonyPatch(typeof(EnemyBeamer), "RotationLogic")]
		[HarmonyPrefix]
		private static bool RotationLogic_Prefix(EnemyBeamer __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Invalid comparison between Unknown and I4
			//IL_00f2: 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_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00ab: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Invalid comparison between Unknown and I4
			//IL_0135: 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_0139: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Invalid comparison between Unknown and I4
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Invalid comparison between Unknown and I4
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Invalid comparison between Unknown and I4
			Quaternion val = FR_HorizontalRotationTarget.Invoke(__instance);
			bool flag = (int)__instance.currentState == 4 || (int)__instance.currentState == 5 || (int)__instance.currentState == 6;
			if (flag)
			{
				AttackRuntime runtime = GetRuntime(__instance);
				if (runtime != null && runtime.Spinning)
				{
					val = Quaternion.Euler(0f, runtime.SpinYaw, 0f);
				}
				else
				{
					Quaternion val2 = FR_AimHorizontalTarget.Invoke(__instance);
					float num = FR_AimHorizontalResult.Invoke(__instance);
					val = Quaternion.Euler(((Quaternion)(ref val2)).eulerAngles.x, ((Quaternion)(ref val2)).eulerAngles.y + num, ((Quaternion)(ref val2)).eulerAngles.z);
				}
			}
			else if ((int)__instance.currentState == 7)
			{
				Enemy enemy = GetEnemy(__instance);
				EnemyRigidbody enemyRigidbody = GetEnemyRigidbody(enemy, __instance);
				Vector3 val3 = FR_MeleeTarget.Invoke(__instance);
				Vector3 val4 = (((Object)(object)enemyRigidbody != (Object)null) ? ((Component)enemyRigidbody).transform.position : ((Component)__instance).transform.position);
				if (Vector3.Distance(val3, val4) > 0.1f)
				{
					val = Quaternion.LookRotation(val3 - val4);
					((Quaternion)(ref val)).eulerAngles = new Vector3(0f, ((Quaternion)(ref val)).eulerAngles.y, 0f);
				}
			}
			else
			{
				Enemy enemy2 = GetEnemy(__instance);
				EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(enemy2, __instance);
				if ((Object)(object)enemyNavMeshAgent != (Object)null)
				{
					Vector3 val5 = FR_EnemyNavMeshAgent_AgentVelocity.Invoke(enemyNavMeshAgent);
					Vector3 normalized = ((Vector3)(ref val5)).normalized;
					if (((Vector3)(ref normalized)).magnitude > 0.1f)
					{
						val = Quaternion.LookRotation(((Vector3)(ref val5)).normalized);
						((Quaternion)(ref val)).eulerAngles = new Vector3(0f, ((Quaternion)(ref val)).eulerAngles.y, 0f);
					}
				}
			}
			if ((int)__instance.currentState == 0 || (int)__instance.currentState == 1 || (int)__instance.currentState == 2 || (int)__instance.currentState == 3 || (int)__instance.currentState == 10)
			{
				__instance.horizontalRotationSpring.speed = 5f;
				__instance.horizontalRotationSpring.damping = 0.7f;
			}
			else if (flag)
			{
				__instance.horizontalRotationSpring.speed = Mathf.Clamp((float)ClownBeamTrackingEnhancements.CfgAttackTrackSpeed.Value, 1f, 300f);
				__instance.horizontalRotationSpring.damping = 0.8f;
			}
			else
			{
				__instance.horizontalRotationSpring.speed = 10f;
				__instance.horizontalRotationSpring.damping = 0.8f;
			}
			FR_HorizontalRotationTarget.Invoke(__instance) = val;
			((Component)__instance).transform.rotation = SemiFunc.SpringQuaternionGet(__instance.horizontalRotationSpring, val, -1f);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class SemiLaserPatches
	{
		private sealed class KnockbackOriginal
		{
			public float PlayerHitForce;

			public float PlayerTumbleForce;

			public float PlayerTumbleTorque;
		}

		private static readonly FieldRef<SemiLaser, HurtCollider> FR_HurtCollider = AccessTools.FieldRefAccess<SemiLaser, HurtCollider>("hurtCollider");

		private static readonly Dictionary<int, KnockbackOriginal> KnockbackOriginals = new Dictionary<int, KnockbackOriginal>();

		[HarmonyPatch(typeof(SemiLaser), "Start")]
		[HarmonyPostfix]
		private static void Start_Postfix(SemiLaser __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			HurtCollider val = FR_HurtCollider.Invoke(__instance);
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance).GetComponentInChildren<HurtCollider>(true);
				if ((Object)(object)val != (Object)null)
				{
					FR_HurtCollider.Invoke(__instance) = val;
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				int instanceID = ((Object)__instance).GetInstanceID();
				if (!KnockbackOriginals.TryGetValue(instanceID, out KnockbackOriginal value))
				{
					value = new KnockbackOriginal();
					value.PlayerHitForce = val.playerHitForce;
					value.PlayerTumbleForce = val.playerTumbleForce;
					value.PlayerTumbleTorque = val.playerTumbleTorque;
					KnockbackOriginals[instanceID] = value;
				}
				float num = Mathf.Clamp(ClownBeamTrackingEnhancements.CfgKnockbackMultiplier.Value, 1f, 10f);
				val.playerHitForce = value.PlayerHitForce * num;
				val.playerTumbleForce = value.PlayerTumbleForce * num;
				val.playerTumbleTorque = value.PlayerTumbleTorque * num;
			}
		}
	}
}