Decompiled source of ClownBeamTrackingEnhancements v1.1.2

ClownBeamTrackingEnhancements.dll

Decompiled a day 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("zabu")]
[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", "Clown Beam Track", "1.1.1")]
	public sealed class ClownBeamTrackingEnhancements : BaseUnityPlugin
	{
		public const string PluginGuid = "REPOJP.ClownBeamTrackingEnhancements";

		public const string PluginName = "Clown Beam Track";

		public const string PluginVersion = "1.1.1";

		internal static ClownBeamTrackingEnhancements Instance;

		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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Expected O, but got Unknown
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Expected O, but got Unknown
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Expected O, but got Unknown
			Instance = this;
			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", 300, 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", 5, 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. ビームのノックバック倍率 HurtCollider.playerHitForce/playerTumbleForce へ倍率適用", (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", false, "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>()));
			Harmony val = new Harmony("REPOJP.ClownBeamTrackingEnhancements");
			val.PatchAll(typeof(ClownBeamTrackingEnhancements).Assembly);
		}
	}
	[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, 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, 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 Action<EnemyBeamer, State> CallUpdateState = AccessTools.MethodDelegate<Action<EnemyBeamer, State>>(AccessTools.Method(typeof(EnemyBeamer), "UpdateState", (Type[])null, (Type[])null), (object)null, true);

		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 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 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 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_0065: 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))
			{
				EnemyNavMeshAgent component = ((Component)beamer).GetComponent<EnemyNavMeshAgent>();
				if (!((Object)(object)component == (Object)null))
				{
					component.Stop(0f);
					component.SetDestination(((Component)target).transform.position);
				}
			}
		}

		private static void ApplyAttackRandomMove(EnemyBeamer beamer)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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_0151: 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)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_0195: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			if (!ClownBeamTrackingEnhancements.CfgAttackRandomMoveEnabled.Value || !IsMasterOrSolo() || (Object)(object)beamer == (Object)null || (Object)(object)beamer.enemy == (Object)null)
			{
				return;
			}
			EnemyNavMeshAgent component = ((Component)beamer).GetComponent<EnemyNavMeshAgent>();
			if ((Object)(object)component == (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);
				Vector3 val = (((Object)(object)beamer.enemy.Rigidbody != (Object)null) ? ((Component)beamer.enemy.Rigidbody).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;
				component.Stop(0f);
				component.SetDestination(destination);
			}
		}

		private static void PerformMeaninglessJumpNow(EnemyBeamer beamer, Vector3 horizontalDir)
		{
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			if (IsMasterOrSolo() && !((Object)(object)beamer == (Object)null) && !((Object)(object)beamer.enemy == (Object)null) && !((Object)(object)beamer.enemy.Rigidbody == (Object)null) && !((Object)(object)beamer.enemy.Rigidbody.rb == (Object)null) && !beamer.enemy.IsStunned() && !FR_EnemyRigidbody_Grabbed.Invoke(beamer.enemy.Rigidbody) && !(FR_EnemyRigidbody_TeleportedTimer.Invoke(beamer.enemy.Rigidbody) > 0f) && !((Object)(object)beamer.enemy.Grounded == (Object)null) && beamer.enemy.Grounded.grounded)
			{
				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;
				if ((Object)(object)beamer.enemy.Jump != (Object)null)
				{
					num = beamer.enemy.Jump.surfaceJumpForceUp;
					num2 = beamer.enemy.Jump.surfaceJumpForceSide;
				}
				beamer.enemy.Rigidbody.JumpImpulse();
				Vector3 val = horizontalDir * num2 + Vector3.up * num;
				beamer.enemy.Rigidbody.rb.AddForce(val, (ForceMode)1);
			}
		}

		private static void ApplyAttackRandomJump(EnemyBeamer beamer)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			if (!ClownBeamTrackingEnhancements.CfgAttackRandomJumpEnabled.Value || !IsMasterOrSolo() || (Object)(object)beamer == (Object)null || (Object)(object)beamer.enemy == (Object)null || (Object)(object)beamer.enemy.Rigidbody == (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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			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);
			Collider[] array = Physics.OverlapSphere(val, num, LayerMask.GetMask(new string[1] { "Player" }));
			if (array == null || array.Length == 0)
			{
				return;
			}
			PlayerAvatar val2 = null;
			List<PlayerAvatar> list = new List<PlayerAvatar>();
			for (int i = 0; i < array.Length; i++)
			{
				if (!((Object)(object)array[i] == (Object)null))
				{
					PlayerAvatar componentInParent = ((Component)array[i]).GetComponentInParent<PlayerAvatar>();
					if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.photonView == (Object)null) && (!((Object)(object)target != (Object)null) || !((Object)(object)componentInParent == (Object)(object)target)) && (runtime.LastTargetViewId == 0 || componentInParent.photonView.ViewID != runtime.LastTargetViewId))
					{
						list.Add(componentInParent);
					}
				}
			}
			if (list.Count == 0)
			{
				for (int j = 0; j < array.Length; j++)
				{
					if (!((Object)(object)array[j] == (Object)null))
					{
						PlayerAvatar componentInParent2 = ((Component)array[j]).GetComponentInParent<PlayerAvatar>();
						if (!((Object)(object)componentInParent2 == (Object)null) && !((Object)(object)componentInParent2.photonView == (Object)null) && (!((Object)(object)target != (Object)null) || !((Object)(object)componentInParent2 == (Object)(object)target)))
						{
							list.Add(componentInParent2);
						}
					}
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			val2 = list[Random.Range(0, list.Count)];
			if (!((Object)(object)val2 == (Object)null))
			{
				FR_PlayerTarget.Invoke(beamer) = val2;
				beamer.playerTarget = val2;
				runtime.LastTargetViewId = val2.photonView.ViewID;
				if (GameManager.Multiplayer())
				{
					beamer.photonView.RPC("UpdatePlayerTargetRPC", (RpcTarget)0, new object[1] { val2.photonView.ViewID });
				}
			}
		}

		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)
		{
			if ((Object)(object)beamer == (Object)null || (Object)(object)beamer.enemy == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)beamer).GetInstanceID();
			if (!SenseOriginals.TryGetValue(instanceID, out SenseOriginal value))
			{
				value = new SenseOriginal();
				if ((Object)(object)beamer.enemy.Vision != (Object)null)
				{
					value.VisionDistance = beamer.enemy.Vision.VisionDistance;
					value.VisionDistanceClose = beamer.enemy.Vision.VisionDistanceClose;
					value.VisionDistanceCloseCrouch = beamer.enemy.Vision.VisionDistanceCloseCrouch;
					value.VisionDotStanding = beamer.enemy.Vision.VisionDotStanding;
					value.VisionDotCrouch = beamer.enemy.Vision.VisionDotCrouch;
					value.VisionDotCrawl = beamer.enemy.Vision.VisionDotCrawl;
					value.PhysObjectVisionDot = beamer.enemy.Vision.PhysObjectVisionDot;
				}
				if ((Object)(object)beamer.enemy.StateInvestigate != (Object)null)
				{
					value.HearingRangeMultiplier = beamer.enemy.StateInvestigate.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)beamer.enemy.Vision != (Object)null)
			{
				beamer.enemy.Vision.VisionDistance = value.VisionDistance * num2;
				beamer.enemy.Vision.VisionDistanceClose = value.VisionDistanceClose * num2;
				beamer.enemy.Vision.VisionDistanceCloseCrouch = value.VisionDistanceCloseCrouch * num2;
				float num4 = 1f / num;
				beamer.enemy.Vision.VisionDotStanding = Mathf.Clamp(value.VisionDotStanding * num4, -1f, 1f);
				beamer.enemy.Vision.VisionDotCrouch = Mathf.Clamp(value.VisionDotCrouch * num4, -1f, 1f);
				beamer.enemy.Vision.VisionDotCrawl = Mathf.Clamp(value.VisionDotCrawl * num4, -1f, 1f);
				beamer.enemy.Vision.PhysObjectVisionDot = Mathf.Clamp(value.PhysObjectVisionDot * num4, -1f, 1f);
			}
			if ((Object)(object)beamer.enemy.StateInvestigate != (Object)null)
			{
				beamer.enemy.StateInvestigate.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), "OnVision")]
		[HarmonyPrefix]
		private static bool OnVision_Prefix(EnemyBeamer __instance)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Invalid comparison between Unknown and I4
			//IL_00c1: 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)
			if (!ClownBeamTrackingEnhancements.CfgDisableKickAttack.Value)
			{
				return true;
			}
			if ((Object)(object)__instance.enemy != (Object)null && (Object)(object)__instance.enemy.Jump != (Object)null && __instance.enemy.Jump.jumping)
			{
				return false;
			}
			State currentState = __instance.currentState;
			if ((int)currentState != 2 && (int)currentState != 1 && (int)currentState != 9 && (int)currentState != 10 && (int)currentState != 3)
			{
				if (((int)currentState == 4 || (int)currentState == 5 || (int)currentState == 6) && (Object)(object)__instance.playerTarget == (Object)(object)__instance.enemy.Vision.onVisionTriggeredPlayer)
				{
					__instance.seekDestination = ((Component)__instance.playerTarget).transform.position;
				}
				return false;
			}
			if ((Object)(object)__instance.playerTarget != (Object)(object)__instance.enemy.Vision.onVisionTriggeredPlayer)
			{
				__instance.playerTarget = __instance.enemy.Vision.onVisionTriggeredPlayer;
				if (GameManager.Multiplayer())
				{
					__instance.photonView.RPC("UpdatePlayerTargetRPC", (RpcTarget)0, new object[1] { __instance.playerTarget.photonView.ViewID });
				}
			}
			if (FR_LaserCooldown.Invoke(__instance) <= 0f)
			{
				CallUpdateState(__instance, (State)4);
				return false;
			}
			__instance.seekDestination = ((Component)__instance.playerTarget).transform.position;
			CallUpdateState(__instance, (State)9);
			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_010c: 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);
				}
				if ((Object)(object)__instance.enemy != (Object)null && (Object)(object)__instance.enemy.NavMeshAgent != (Object)null && (Object)(object)__instance.enemy.Rigidbody != (Object)null)
				{
					__instance.enemy.NavMeshAgent.Warp(((Component)__instance.enemy.Rigidbody).transform.position, false);
					__instance.enemy.NavMeshAgent.ResetPath();
				}
			}
			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_012d: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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_016b: 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_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_0198: 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_01b2: 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_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: 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)
			//IL_021e: 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)
			{
				return false;
			}
			if ((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_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_00ce: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Invalid comparison between Unknown and I4
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Invalid comparison between Unknown and I4
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Invalid comparison between Unknown and I4
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Invalid comparison between Unknown and I4
			Quaternion val = Quaternion.identity;
			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
			{
				EnemyNavMeshAgent component = ((Component)__instance).GetComponent<EnemyNavMeshAgent>();
				if ((Object)(object)component != (Object)null)
				{
					Vector3 agentVelocity = component.AgentVelocity;
					Vector3 normalized = ((Vector3)(ref agentVelocity)).normalized;
					if (((Vector3)(ref normalized)).magnitude > 0.1f)
					{
						val = Quaternion.LookRotation(((Vector3)(ref agentVelocity)).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;
			}
			((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))
			{
				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;
			}
		}
	}
}