Decompiled source of ShadowChildEnhancements v1.0.0

ShadowChildEnhancements.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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("REPOJP")]
[assembly: AssemblyTitle("REPOJP")]
[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.ShadowChildEnhancements
{
	[BepInPlugin("REPOJP.ShadowChildEnhancements", "ShadowChildEnhancements", "1.0.0")]
	public sealed class ShadowChildEnhancementsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "REPOJP.ShadowChildEnhancements";

		public const string PluginName = "ShadowChildEnhancements";

		public const string PluginVersion = "1.0.0";

		internal static ShadowChildEnhancementsPlugin Instance;

		internal static ConfigEntry<float> CfgEyeContactSeconds;

		internal static ConfigEntry<float> CfgKnockbackMultiplier;

		internal static ConfigEntry<int> CfgDamage;

		internal static ConfigEntry<float> CfgLookAwayGraceSeconds;

		internal static ConfigEntry<bool> CfgSolidarityAttack;

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			Instance = this;
			CfgEyeContactSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("ShadowChild", "EyeContactSeconds", 3f, new ConfigDescription("Seconds required before attack.攻撃までに必要な目合わせ秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			CfgKnockbackMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("ShadowChild", "KnockbackMultiplier", 10f, new ConfigDescription("Knockback multiplier toward the enemy.敵方向へ引き寄せるノックバック倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			CfgDamage = ((BaseUnityPlugin)this).Config.Bind<int>("ShadowChild", "Damage", 50, new ConfigDescription("Damage amount.ダメージ量", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			CfgLookAwayGraceSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("ShadowChild", "LookAwayGraceSeconds", 0f, new ConfigDescription("Grace seconds after looking away.目を外した直後の猶予秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			CfgSolidarityAttack = ((BaseUnityPlugin)this).Config.Bind<bool>("ShadowChild", "SolidarityAttack", true, "Attack all players who entered sight at least once.一瞬でも視界に入ったプレイヤー全員を攻撃対象に含める");
			Harmony val = new Harmony("REPOJP.ShadowChildEnhancements");
			val.PatchAll(typeof(ShadowChildEnhancementsPatches));
		}
	}
	internal static class ShadowChildEnhancementsPatches
	{
		private sealed class RuntimeState
		{
			public float LastOnScreenTime = -99999f;

			public readonly HashSet<int> AccumulatedViewIds = new HashSet<int>();

			public float BaseHitForce;

			public float BaseTumbleForce;

			public float BaseTumbleTorque;

			public bool BaseForceCached;
		}

		private const float FixedLookAwayDecayMultiplier = 0f;

		private const float ExpandedPaddingWidth = 0.35f;

		private const float ExpandedPaddingHeight = 0.35f;

		private const float FastOnScreenPollInterval = 0.02f;

		private static readonly ConditionalWeakTable<EnemyThinMan, RuntimeState> StateTable = new ConditionalWeakTable<EnemyThinMan, RuntimeState>();

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

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

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

		private static readonly MethodInfo M_EnemyThinMan_UpdateState = AccessTools.Method(typeof(EnemyThinMan), "UpdateState", new Type[1] { typeof(State) }, (Type[])null);

		private static readonly MethodInfo M_EnemyThinMan_SetTarget = AccessTools.Method(typeof(EnemyThinMan), "SetTarget", new Type[1] { typeof(PlayerAvatar) }, (Type[])null);

		private static readonly FieldRef<Enemy, EnemyOnScreen> F_Enemy_OnScreen = AccessTools.FieldRefAccess<Enemy, EnemyOnScreen>("OnScreen");

		private static readonly FieldInfo FI_EnemyOnScreen_OnScreenTimer = AccessTools.Field(typeof(EnemyOnScreen), "OnScreenTimer");

		private static readonly FieldRef<PlayerAvatar, bool> F_PlayerAvatar_isDisabled = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");

		private static readonly FieldRef<PlayerAvatar, bool> F_PlayerAvatar_deadSet = AccessTools.FieldRefAccess<PlayerAvatar, bool>("deadSet");

		private static readonly FieldRef<PlayerHealth, int> F_PlayerHealth_health = AccessTools.FieldRefAccess<PlayerHealth, int>("health");

		private static readonly FieldRef<PlayerTumble, bool> F_PlayerTumble_isTumbling = AccessTools.FieldRefAccess<PlayerTumble, bool>("isTumbling");

		private static bool IsMasterOrSingle()
		{
			if (!SemiFunc.IsMultiplayer())
			{
				return true;
			}
			return PhotonNetwork.IsMasterClient;
		}

		private static RuntimeState GetState(EnemyThinMan thinMan)
		{
			return StateTable.GetOrCreateValue(thinMan);
		}

		private static Enemy GetEnemy(EnemyThinMan thinMan)
		{
			try
			{
				return F_EnemyThinMan_enemy.Invoke(thinMan);
			}
			catch
			{
				return null;
			}
		}

		private static PlayerAvatar GetTarget(EnemyThinMan thinMan)
		{
			try
			{
				return F_EnemyThinMan_playerTarget.Invoke(thinMan);
			}
			catch
			{
				return null;
			}
		}

		private static void SetTarget(EnemyThinMan thinMan, PlayerAvatar target)
		{
			if ((Object)(object)thinMan == (Object)null || M_EnemyThinMan_SetTarget == null)
			{
				return;
			}
			try
			{
				M_EnemyThinMan_SetTarget.Invoke(thinMan, new object[1] { target });
			}
			catch
			{
			}
		}

		private static void UpdateState(EnemyThinMan thinMan, State state)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)thinMan == (Object)null || M_EnemyThinMan_UpdateState == null)
			{
				return;
			}
			try
			{
				M_EnemyThinMan_UpdateState.Invoke(thinMan, new object[1] { state });
			}
			catch
			{
			}
		}

		private static bool HasConfigKey(string section, string key)
		{
			try
			{
				string path = Path.Combine(Paths.ConfigPath, "REPOJP.ShadowChildEnhancements.cfg");
				if (!File.Exists(path))
				{
					return false;
				}
				bool flag = false;
				string[] array = File.ReadAllLines(path);
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (text.Length == 0 || text.StartsWith("#", StringComparison.Ordinal) || text.StartsWith("//", StringComparison.Ordinal))
					{
						continue;
					}
					if (text.StartsWith("[", StringComparison.Ordinal) && text.EndsWith("]", StringComparison.Ordinal))
					{
						string a = text.Substring(1, text.Length - 2);
						flag = string.Equals(a, section, StringComparison.OrdinalIgnoreCase);
					}
					else
					{
						if (!flag)
						{
							continue;
						}
						int num = text.IndexOf('=');
						if (num > 0)
						{
							string a2 = text.Substring(0, num).Trim();
							if (string.Equals(a2, key, StringComparison.OrdinalIgnoreCase))
							{
								return true;
							}
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static void TuneOnScreenComponent(EnemyThinMan thinMan)
		{
			Enemy enemy = GetEnemy(thinMan);
			if ((Object)(object)enemy == (Object)null)
			{
				return;
			}
			EnemyOnScreen val = null;
			try
			{
				val = F_Enemy_OnScreen.Invoke(enemy);
			}
			catch
			{
				val = null;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				val.paddingWidth = 0.35f;
				val.paddingHeight = 0.35f;
			}
			catch
			{
			}
			try
			{
				if (FI_EnemyOnScreen_OnScreenTimer != null)
				{
					FI_EnemyOnScreen_OnScreenTimer.SetValue(val, 0.02f);
				}
			}
			catch
			{
			}
		}

		private static void CacheBaseForces(EnemyThinMan thinMan)
		{
			RuntimeState state = GetState(thinMan);
			if (!state.BaseForceCached && !((Object)(object)thinMan == (Object)null) && !((Object)(object)thinMan.hurtCollider == (Object)null))
			{
				HurtCollider component = thinMan.hurtCollider.GetComponent<HurtCollider>();
				if (!((Object)(object)component == (Object)null))
				{
					state.BaseHitForce = component.playerHitForce;
					state.BaseTumbleForce = component.playerTumbleForce;
					state.BaseTumbleTorque = component.playerTumbleTorque;
					state.BaseForceCached = true;
				}
			}
		}

		private static bool IsAttackable(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null)
			{
				return false;
			}
			if ((Object)(object)avatar.photonView == (Object)null)
			{
				return false;
			}
			bool flag = false;
			bool flag2 = false;
			try
			{
				flag = F_PlayerAvatar_isDisabled.Invoke(avatar);
			}
			catch
			{
				flag = false;
			}
			try
			{
				flag2 = F_PlayerAvatar_deadSet.Invoke(avatar);
			}
			catch
			{
				flag2 = false;
			}
			if (flag || flag2)
			{
				return false;
			}
			if ((Object)(object)avatar.playerHealth == (Object)null)
			{
				return false;
			}
			int num = 1;
			try
			{
				num = F_PlayerHealth_health.Invoke(avatar.playerHealth);
			}
			catch
			{
				num = 1;
			}
			return num > 0;
		}

		private static List<PlayerAvatar> GetVisiblePlayers(EnemyThinMan thinMan)
		{
			List<PlayerAvatar> list = new List<PlayerAvatar>();
			Enemy enemy = GetEnemy(thinMan);
			if ((Object)(object)enemy == (Object)null)
			{
				return list;
			}
			EnemyOnScreen val = null;
			try
			{
				val = F_Enemy_OnScreen.Invoke(enemy);
			}
			catch
			{
				val = null;
			}
			if ((Object)(object)val == (Object)null || (Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null)
			{
				return list;
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (IsAttackable(player))
				{
					bool flag = false;
					try
					{
						flag = val.GetOnScreen(player);
					}
					catch
					{
						flag = false;
					}
					if (flag)
					{
						list.Add(player);
					}
				}
			}
			return list;
		}

		private static bool ContainsPlayer(List<PlayerAvatar> players, PlayerAvatar target)
		{
			if (players == null || (Object)(object)target == (Object)null)
			{
				return false;
			}
			for (int i = 0; i < players.Count; i++)
			{
				if ((Object)(object)players[i] == (Object)(object)target)
				{
					return true;
				}
			}
			return false;
		}

		private static void TrackVisiblePlayers(EnemyThinMan thinMan, List<PlayerAvatar> visiblePlayers)
		{
			if ((Object)(object)thinMan == (Object)null || visiblePlayers == null || visiblePlayers.Count == 0)
			{
				return;
			}
			RuntimeState state = GetState(thinMan);
			for (int i = 0; i < visiblePlayers.Count; i++)
			{
				PlayerAvatar val = visiblePlayers[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.photonView == (Object)null))
				{
					int viewID = val.photonView.ViewID;
					if (viewID > 0)
					{
						state.AccumulatedViewIds.Add(viewID);
					}
				}
			}
		}

		private static List<PlayerAvatar> CollectVictims(EnemyThinMan thinMan, PlayerAvatar primary)
		{
			List<PlayerAvatar> list = new List<PlayerAvatar>();
			if (!ShadowChildEnhancementsPlugin.CfgSolidarityAttack.Value)
			{
				if (IsAttackable(primary))
				{
					list.Add(primary);
				}
				else
				{
					RuntimeState state = GetState(thinMan);
					foreach (int accumulatedViewId in state.AccumulatedViewIds)
					{
						PhotonView val = null;
						try
						{
							val = PhotonView.Find(accumulatedViewId);
						}
						catch
						{
							val = null;
						}
						if (!((Object)(object)val == (Object)null))
						{
							PlayerAvatar component = ((Component)val).GetComponent<PlayerAvatar>();
							if (IsAttackable(component))
							{
								list.Add(component);
								break;
							}
						}
					}
				}
				return list;
			}
			RuntimeState state2 = GetState(thinMan);
			foreach (int accumulatedViewId2 in state2.AccumulatedViewIds)
			{
				PhotonView val2 = null;
				try
				{
					val2 = PhotonView.Find(accumulatedViewId2);
				}
				catch
				{
					val2 = null;
				}
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				PlayerAvatar component2 = ((Component)val2).GetComponent<PlayerAvatar>();
				if (!IsAttackable(component2))
				{
					continue;
				}
				bool flag = false;
				for (int i = 0; i < list.Count; i++)
				{
					if ((Object)(object)list[i] == (Object)(object)component2)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					list.Add(component2);
				}
			}
			if (IsAttackable(primary) && !ContainsPlayer(list, primary))
			{
				list.Insert(0, primary);
			}
			return list;
		}

		private static void ApplyKnockback(PlayerAvatar playerAvatar, Vector3 enemyPosition, float hitForce, float tumbleForce, float tumbleTorque)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)playerAvatar == (Object)null)
			{
				return;
			}
			Vector3 val = enemyPosition - ((Component)playerAvatar).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f)
			{
				val = Vector3.forward;
			}
			((Vector3)(ref val)).Normalize();
			bool flag = false;
			try
			{
				if ((Object)(object)playerAvatar.tumble != (Object)null)
				{
					flag = F_PlayerTumble_isTumbling.Invoke(playerAvatar.tumble);
				}
			}
			catch
			{
				flag = false;
			}
			if (flag && (Object)(object)playerAvatar.tumble != (Object)null)
			{
				if (tumbleForce > 0f)
				{
					try
					{
						playerAvatar.tumble.TumbleForce(val * tumbleForce);
					}
					catch
					{
					}
				}
				if (tumbleTorque > 0f)
				{
					try
					{
						playerAvatar.tumble.TumbleTorque(Vector3.up * tumbleTorque);
					}
					catch
					{
					}
				}
			}
			else if (hitForce > 0f)
			{
				try
				{
					playerAvatar.ForceImpulse(val * hitForce);
				}
				catch
				{
				}
			}
		}

		[HarmonyPatch(typeof(EnemyThinMan), "OnSpawn")]
		[HarmonyPostfix]
		private static void EnemyThinMan_OnSpawn_Postfix(EnemyThinMan __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				RuntimeState state = GetState(__instance);
				state.LastOnScreenTime = -99999f;
				state.AccumulatedViewIds.Clear();
				CacheBaseForces(__instance);
				TuneOnScreenComponent(__instance);
			}
		}

		[HarmonyPatch(typeof(EnemyThinMan), "Awake")]
		[HarmonyPostfix]
		private static void EnemyThinMan_Awake_Postfix(EnemyThinMan __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			TuneOnScreenComponent(__instance);
			CacheBaseForces(__instance);
			if (!IsMasterOrSingle() || HasConfigKey("ShadowChild", "EyeContactSeconds"))
			{
				return;
			}
			try
			{
				if (!((Object)(object)__instance.anim != (Object)null))
				{
					return;
				}
				float tentacleSpeed = __instance.anim.tentacleSpeed;
				if (tentacleSpeed > 0.0001f)
				{
					ShadowChildEnhancementsPlugin.CfgEyeContactSeconds.Value = Mathf.Clamp(1f / tentacleSpeed, 0f, 20f);
					if ((Object)(object)ShadowChildEnhancementsPlugin.Instance != (Object)null)
					{
						((BaseUnityPlugin)ShadowChildEnhancementsPlugin.Instance).Config.Save();
					}
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(EnemyThinMan), "StateStand")]
		[HarmonyPostfix]
		private static void EnemyThinMan_StateStand_Postfix(EnemyThinMan __instance)
		{
			if (IsMasterOrSingle() && !((Object)(object)__instance == (Object)null))
			{
				List<PlayerAvatar> visiblePlayers = GetVisiblePlayers(__instance);
				if (visiblePlayers.Count > 0)
				{
					TrackVisiblePlayers(__instance, visiblePlayers);
				}
			}
		}

		[HarmonyPatch(typeof(EnemyThinMan), "StateOnScreen")]
		[HarmonyPrefix]
		private static bool EnemyThinMan_StateOnScreen_Prefix(EnemyThinMan __instance)
		{
			if (!IsMasterOrSingle() || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			TuneOnScreenComponent(__instance);
			List<PlayerAvatar> visiblePlayers = GetVisiblePlayers(__instance);
			if (visiblePlayers.Count > 0)
			{
				TrackVisiblePlayers(__instance, visiblePlayers);
				PlayerAvatar target = GetTarget(__instance);
				if ((Object)(object)target == (Object)null || !ContainsPlayer(visiblePlayers, target))
				{
					SetTarget(__instance, visiblePlayers[0]);
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(EnemyThinMan), "StateStunned")]
		[HarmonyPostfix]
		private static void EnemyThinMan_StateStunned_Postfix(EnemyThinMan __instance)
		{
			if (IsMasterOrSingle() && !((Object)(object)__instance == (Object)null))
			{
				RuntimeState state = GetState(__instance);
				state.LastOnScreenTime = -99999f;
				state.AccumulatedViewIds.Clear();
				__instance.tentacleLerp = 0f;
				SetTarget(__instance, null);
			}
		}

		[HarmonyPatch(typeof(EnemyThinMan), "TentacleLogic")]
		[HarmonyPrefix]
		private static bool EnemyThinMan_TentacleLogic_Prefix(EnemyThinMan __instance)
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Invalid comparison between Unknown and I4
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Invalid comparison between Unknown and I4
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Invalid comparison between Unknown and I4
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Invalid comparison between Unknown and I4
			if (!IsMasterOrSingle())
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return false;
			}
			RuntimeState state = GetState(__instance);
			List<PlayerAvatar> visiblePlayers = GetVisiblePlayers(__instance);
			bool flag = visiblePlayers.Count > 0;
			if (flag)
			{
				TrackVisiblePlayers(__instance, visiblePlayers);
				state.LastOnScreenTime = Time.time;
				PlayerAvatar target = GetTarget(__instance);
				if ((Object)(object)target == (Object)null || !ContainsPlayer(visiblePlayers, target))
				{
					SetTarget(__instance, visiblePlayers[0]);
				}
			}
			float num = Mathf.Clamp(ShadowChildEnhancementsPlugin.CfgEyeContactSeconds.Value, 0f, 20f);
			float num2 = Mathf.Clamp(ShadowChildEnhancementsPlugin.CfgLookAwayGraceSeconds.Value, 0f, 20f);
			float num3 = ((num <= 0.0001f) ? 9999f : (1f / num));
			float deltaTime = Time.deltaTime;
			float num4 = __instance.tentacleLerp;
			if ((int)__instance.currentState == 1)
			{
				if (flag)
				{
					num4 += num3 * deltaTime;
				}
				else
				{
					float num5 = Time.time - state.LastOnScreenTime;
					if (num5 > num2)
					{
						num4 -= num3 * 0.5f * 0f * deltaTime;
					}
				}
			}
			else if ((int)__instance.currentState != 3)
			{
				if ((int)__instance.currentState == 4)
				{
					num4 -= 10f * deltaTime;
				}
				else if ((int)__instance.currentState == 7)
				{
					num4 = 0f;
					state.AccumulatedViewIds.Clear();
					state.LastOnScreenTime = -99999f;
				}
				else
				{
					float num6 = Time.time - state.LastOnScreenTime;
					if (num6 > num2)
					{
						num4 -= num3 * 0.5f * 0f * deltaTime;
					}
				}
			}
			__instance.tentacleLerp = Mathf.Clamp(num4, 0f, 1f);
			return false;
		}

		[HarmonyPatch(typeof(EnemyThinMan), "StateDamage")]
		[HarmonyPrefix]
		private static bool EnemyThinMan_StateDamage_Prefix(EnemyThinMan __instance)
		{
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			if (!IsMasterOrSingle())
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return false;
			}
			bool flag = false;
			try
			{
				flag = F_EnemyThinMan_stateImpulse.Invoke(__instance);
			}
			catch
			{
				flag = false;
			}
			if (!flag)
			{
				return false;
			}
			try
			{
				F_EnemyThinMan_stateImpulse.Invoke(__instance) = false;
			}
			catch
			{
			}
			CacheBaseForces(__instance);
			RuntimeState state = GetState(__instance);
			PlayerAvatar target = GetTarget(__instance);
			List<PlayerAvatar> list = CollectVictims(__instance, target);
			if (list.Count == 0)
			{
				state.AccumulatedViewIds.Clear();
				state.LastOnScreenTime = -99999f;
				SetTarget(__instance, null);
				UpdateState(__instance, (State)6);
				return false;
			}
			int num = Mathf.Clamp(ShadowChildEnhancementsPlugin.CfgDamage.Value, 0, 100);
			float num2 = Mathf.Clamp(ShadowChildEnhancementsPlugin.CfgKnockbackMultiplier.Value, 0f, 50f);
			Enemy enemy = GetEnemy(__instance);
			int num3 = -1;
			if ((Object)(object)enemy != (Object)null)
			{
				try
				{
					num3 = SemiFunc.EnemyGetIndex(enemy);
				}
				catch
				{
					num3 = -1;
				}
			}
			Vector3 enemyPosition = (((Object)(object)__instance.rb != (Object)null) ? __instance.rb.position : ((Component)__instance).transform.position);
			for (int i = 0; i < list.Count; i++)
			{
				PlayerAvatar val = list[i];
				if (IsAttackable(val))
				{
					try
					{
						val.playerHealth.HurtOther(num, ((Component)val).transform.position, false, num3);
					}
					catch
					{
					}
					ApplyKnockback(val, enemyPosition, state.BaseHitForce * num2, state.BaseTumbleForce * num2, state.BaseTumbleTorque * num2);
				}
			}
			state.AccumulatedViewIds.Clear();
			state.LastOnScreenTime = -99999f;
			SetTarget(__instance, null);
			UpdateState(__instance, (State)6);
			return false;
		}
	}
}