Decompiled source of ConfigurableScoutmaster v1.0.0

plugins/com.github.GABRlEL.ConfigurableScoutmaster.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.GABRlEL.ConfigurableScoutmaster")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("com.github.GABRlEL.ConfigurableScoutmaster")]
[assembly: AssemblyTitle("ConfigurableScoutmaster")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace ConfigurableScoutmaster
{
	[BepInPlugin("com.github.GABRlEL.ConfigurableScoutmaster", "ConfigurableScoutmaster", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal enum DamageTypeOverride
		{
			Vanilla = -1,
			Injury,
			Hunger,
			Cold,
			Poison,
			Crab,
			Curse,
			Drowsy,
			Weight,
			Hot,
			Thorns,
			Spores,
			Web
		}

		private sealed class ScoutmasterOriginals
		{
			public float AttackHeightDelta;

			public float MaxAggroHeight;
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_LookForTarget
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "LookForTarget", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Expected O, but got Unknown
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Expected O, but got Unknown
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Expected O, but got Unknown
				//IL_0156: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetTargetIntervalSeconds", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetChancePerCheck", (Type[])null, (Type[])null);
				bool flag = false;
				bool flag2 = false;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					int value;
					if (!flag && val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 30f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						flag = true;
					}
					else if (!flag2 && val.opcode == OpCodes.Ldc_R4 && val.operand is float a2 && Approximately(a2, 0.1f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
						flag2 = true;
					}
					else if (!flag && TryGetInt32Constant(val, out value) && value == 30 && i + 1 < list.Count && list[i + 1].opcode == OpCodes.Conv_R4)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						list[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						flag = true;
					}
				}
				if (!flag)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] LookForTarget: did not find 30f constant to replace (target interval).");
					}
				}
				if (!flag2)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[ConfigurableScoutmaster] LookForTarget: did not find 0.1f constant to replace (chance per check).");
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_VerifyTarget
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "VerifyTarget", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Expected O, but got Unknown
				//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Expected O, but got Unknown
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetMinIsolationDistance", (Type[])null, (Type[])null);
				bool flag = false;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					int value;
					if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 15f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						flag = true;
					}
					else if (TryGetInt32Constant(val, out value) && value == 15 && i + 1 < list.Count && list[i + 1].opcode == OpCodes.Conv_R4)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						list[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						flag = true;
					}
				}
				if (!flag)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] VerifyTarget: did not find 15f constant to replace (min isolation distance).");
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_CalcVars
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "CalcVars", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Expected O, but got Unknown
				//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fb: Expected O, but got Unknown
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Expected O, but got Unknown
				//IL_0191: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Expected O, but got Unknown
				//IL_0265: Unknown result type (might be due to invalid IL or missing references)
				//IL_026f: Expected O, but got Unknown
				//IL_0298: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a2: Expected O, but got Unknown
				//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d2: Expected O, but got Unknown
				//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0302: Expected O, but got Unknown
				List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetCloseDistance", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetTargetLookAwayAngle", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(Plugin), "GetSeenGainRate_1", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(Plugin), "GetSeenGainRate_03", (Type[])null, (Type[])null);
				MethodInfo methodInfo5 = AccessTools.Method(typeof(Plugin), "GetSeenGainRate_015", (Type[])null, (Type[])null);
				MethodInfo methodInfo6 = AccessTools.Method(typeof(Plugin), "GetSeenDecayRate_01", (Type[])null, (Type[])null);
				bool flag = false;
				bool flag2 = false;
				bool flag3 = false;
				bool flag4 = false;
				bool flag5 = false;
				bool flag6 = false;
				for (int i = 0; i < codes.Count; i++)
				{
					CodeInstruction val = codes[i];
					int value;
					if (!flag && val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 10f))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						flag = true;
					}
					else if (!flag && TryGetInt32Constant(val, out value) && value == 10 && i + 1 < codes.Count && codes[i + 1].opcode == OpCodes.Conv_R4)
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						codes[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						flag = true;
					}
					else if (!flag2 && val.opcode == OpCodes.Ldc_R4 && val.operand is float a2 && Approximately(a2, 70f))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
						flag2 = true;
					}
					else if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a3 && StoresSeenCounterSoon(i))
					{
						if (!flag3 && Approximately(a3, 1f))
						{
							codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo3);
							flag3 = true;
						}
						else if (!flag4 && Approximately(a3, 0.3f))
						{
							codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo4);
							flag4 = true;
						}
						else if (!flag5 && Approximately(a3, 0.15f))
						{
							codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo5);
							flag5 = true;
						}
						else if (!flag6 && Approximately(a3, 0.1f))
						{
							codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo6);
							flag6 = true;
						}
					}
				}
				if (!flag)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] CalcVars: did not find 10f constant to replace (close distance).");
					}
				}
				if (!flag2)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[ConfigurableScoutmaster] CalcVars: did not find 70f constant to replace (target look-away angle).");
					}
				}
				if (!flag3 || !flag4 || !flag5 || !flag6)
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogWarning((object)("[ConfigurableScoutmaster] CalcVars: did not replace all seen rates (1.0/0.3/0.15/0.1). " + $"Replaced: 1.0={flag3}, 0.3={flag4}, 0.15={flag5}, 0.1={flag6}."));
					}
				}
				return codes;
				bool StoresSeenCounterSoon(int idx)
				{
					for (int j = idx; j < Mathf.Min(codes.Count, idx + 16); j++)
					{
						if (codes[j].opcode == OpCodes.Stfld && codes[j].operand is FieldInfo fieldInfo && fieldInfo.Name.IndexOf("targetHasSeenMeCounter", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return true;
						}
					}
					return false;
				}
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_AnyoneCanSeePos
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "AnyoneCanSeePos", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Expected O, but got Unknown
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Expected O, but got Unknown
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetAnyoneCanSeeAngle", (Type[])null, (Type[])null);
				bool flag = false;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					int value;
					if (!flag && val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 80f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						flag = true;
					}
					else if (!flag && TryGetInt32Constant(val, out value) && value == 80 && i + 1 < list.Count && list[i + 1].opcode == OpCodes.Conv_R4)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						list[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						flag = true;
					}
				}
				if (!flag)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] AnyoneCanSeePos: did not find 80f constant to replace (anyone-can-see angle).");
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_Chase
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "Chase", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Expected O, but got Unknown
				//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cd: Expected O, but got Unknown
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Expected O, but got Unknown
				//IL_023d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0247: Expected O, but got Unknown
				//IL_0257: Unknown result type (might be due to invalid IL or missing references)
				//IL_0261: Expected O, but got Unknown
				//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c2: Expected O, but got Unknown
				//IL_0335: Unknown result type (might be due to invalid IL or missing references)
				//IL_033f: Expected O, but got Unknown
				//IL_034f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0359: Expected O, but got Unknown
				List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetSeenCounterToEnableSprint", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetWalkTowardTargetDistance", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(Plugin), "GetSprintIfDistance", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(Plugin), "GetLoseTargetAfterTeleportChance", (Type[])null, (Type[])null);
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				int num4 = 0;
				for (int i = 0; i < codes.Count; i++)
				{
					CodeInstruction val = codes[i];
					int value;
					int value2;
					if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 1f) && i - 1 >= 0 && codes[i - 1].opcode == OpCodes.Ldfld && codes[i - 1].operand is FieldInfo fieldInfo && fieldInfo.Name.IndexOf("targetHasSeenMeCounter", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						num++;
					}
					else if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a2 && Approximately(a2, 5f) && RecentDistanceCompute(i) && !RecentLoadsField(i, "tpCounter"))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
						num2++;
					}
					else if (TryGetInt32Constant(val, out value) && value == 5 && i + 1 < codes.Count && codes[i + 1].opcode == OpCodes.Conv_R4 && RecentDistanceCompute(i) && !RecentLoadsField(i, "tpCounter"))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
						codes[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						num2++;
					}
					else if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a3 && Approximately(a3, 15f) && RecentDistanceCompute(i))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo3);
						num3++;
					}
					else if (TryGetInt32Constant(val, out value2) && value2 == 15 && i + 1 < codes.Count && codes[i + 1].opcode == OpCodes.Conv_R4 && RecentDistanceCompute(i))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo3);
						codes[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						num3++;
					}
					else if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a4 && Approximately(a4, 0.1f) && RecentRandomValue(i))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo4);
						num4++;
					}
				}
				if (num == 0)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] Chase: did not find targetHasSeenMeCounter > 1f threshold to replace.");
					}
				}
				else if (num < 2)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)string.Format("[{0}] Chase: replaced {1} seen-threshold occurrences (expected 2).", "ConfigurableScoutmaster", num));
					}
				}
				if (num2 == 0)
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogWarning((object)"[ConfigurableScoutmaster] Chase: did not find 5f walk-toward-target distance to replace (pattern may have changed).");
					}
				}
				if (num3 == 0)
				{
					ManualLogSource log4 = Log;
					if (log4 != null)
					{
						log4.LogWarning((object)"[ConfigurableScoutmaster] Chase: did not find 15f sprint-if-distance threshold to replace (pattern may have changed).");
					}
				}
				if (num4 == 0)
				{
					ManualLogSource log5 = Log;
					if (log5 != null)
					{
						log5.LogWarning((object)"[ConfigurableScoutmaster] Chase: did not find 0.1f lose-target-after-teleport chance to replace (pattern may have changed).");
					}
				}
				return codes;
				bool RecentDistanceCompute(int idx, int lookback = 10)
				{
					int num7 = idx - 1;
					while (num7 >= 0 && num7 >= idx - lookback)
					{
						OpCode opcode2 = codes[num7].opcode;
						if ((opcode2 == OpCodes.Call || opcode2 == OpCodes.Callvirt) && codes[num7].operand is MethodInfo methodInfo6)
						{
							Type declaringType2 = methodInfo6.DeclaringType;
							if (declaringType2 != null && declaringType2.FullName == "UnityEngine.Vector3" && (methodInfo6.Name == "Distance" || methodInfo6.Name == "get_magnitude" || methodInfo6.Name == "get_sqrMagnitude"))
							{
								return true;
							}
							if (methodInfo6.Name.IndexOf("Distance", StringComparison.OrdinalIgnoreCase) >= 0)
							{
								return true;
							}
						}
						num7--;
					}
					return false;
				}
				bool RecentLoadsField(int idx, string fieldNamePart, int lookback = 3)
				{
					int num6 = idx - 1;
					while (num6 >= 0 && num6 >= idx - lookback)
					{
						if (codes[num6].opcode == OpCodes.Ldfld && codes[num6].operand is FieldInfo fieldInfo2 && fieldInfo2.Name.IndexOf(fieldNamePart, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							return true;
						}
						num6--;
					}
					return false;
				}
				bool RecentRandomValue(int idx, int lookback = 8)
				{
					int num5 = idx - 1;
					while (num5 >= 0 && num5 >= idx - lookback)
					{
						OpCode opcode = codes[num5].opcode;
						if ((opcode == OpCodes.Call || opcode == OpCodes.Callvirt) && codes[num5].operand is MethodInfo methodInfo5)
						{
							Type declaringType = methodInfo5.DeclaringType;
							if (declaringType != null && declaringType.FullName == "UnityEngine.Random" && methodInfo5.Name == "get_value")
							{
								return true;
							}
							if (methodInfo5.Name.IndexOf("Random", StringComparison.OrdinalIgnoreCase) >= 0 && methodInfo5.Name.IndexOf("value", StringComparison.OrdinalIgnoreCase) >= 0)
							{
								return true;
							}
						}
						num5--;
					}
					return false;
				}
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_Update
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "Update", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Expected O, but got Unknown
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Expected O, but got Unknown
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Expected O, but got Unknown
				List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetTeleportInsteadOfChaseDistance", (Type[])null, (Type[])null);
				int num = 0;
				for (int i = 0; i < codes.Count; i++)
				{
					CodeInstruction val = codes[i];
					int value;
					if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 80f) && RecentDistanceCompute(i))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						num++;
					}
					else if (TryGetInt32Constant(val, out value) && value == 80 && i + 1 < codes.Count && codes[i + 1].opcode == OpCodes.Conv_R4 && RecentDistanceCompute(i))
					{
						codes[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						codes[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						num++;
					}
				}
				if (num == 0)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] Update: did not find teleport-instead-of-chase distance (80f) to replace (pattern may have changed).");
					}
				}
				return codes;
				bool RecentDistanceCompute(int idx, int lookback = 10)
				{
					int num2 = idx - 1;
					while (num2 >= 0 && num2 >= idx - lookback)
					{
						OpCode opcode = codes[num2].opcode;
						if ((opcode == OpCodes.Call || opcode == OpCodes.Callvirt) && codes[num2].operand is MethodInfo methodInfo2)
						{
							Type declaringType = methodInfo2.DeclaringType;
							if (declaringType != null && declaringType.FullName == "UnityEngine.Vector3" && (methodInfo2.Name == "Distance" || methodInfo2.Name == "get_magnitude" || methodInfo2.Name == "get_sqrMagnitude"))
							{
								return true;
							}
							if (methodInfo2.Name.IndexOf("Distance", StringComparison.OrdinalIgnoreCase) >= 0)
							{
								return true;
							}
						}
						num2--;
					}
					return false;
				}
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_Teleport
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (type == null)
				{
					return null;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (string.Equals(methodInfo.Name, "Teleport", StringComparison.Ordinal))
					{
						ParameterInfo[] parameters = methodInfo.GetParameters();
						if (parameters.Length == 4 && !(parameters[1].ParameterType != typeof(float)) && !(parameters[2].ParameterType != typeof(float)) && !(parameters[3].ParameterType != typeof(float)) && string.Equals(parameters[0].ParameterType.Name, "Character", StringComparison.Ordinal))
						{
							return methodInfo;
						}
					}
				}
				return null;
			}

			private static void Prefix(ref float minDistanceToTarget, ref float maxDistanceToTarget, ref float maxHeightDifference)
			{
				if (Approximately(minDistanceToTarget, 50f) && Approximately(maxDistanceToTarget, 70f))
				{
					float num = TeleportCloseMinDistanceMult?.Value ?? 1f;
					float num2 = TeleportCloseMaxDistanceMult?.Value ?? 1f;
					minDistanceToTarget = Mathf.Max(0f, minDistanceToTarget * num);
					maxDistanceToTarget = Mathf.Max(0f, maxDistanceToTarget * num2);
					if (maxDistanceToTarget < minDistanceToTarget + 0.01f)
					{
						maxDistanceToTarget = minDistanceToTarget + 0.01f;
					}
				}
				else
				{
					float num3 = TeleportSamplingMaxDistanceMult?.Value ?? 1f;
					maxDistanceToTarget = Mathf.Max(0.01f, maxDistanceToTarget * num3);
				}
				float num4 = TeleportSamplingMaxHeightDifferenceMult?.Value ?? 1f;
				maxHeightDifference = Mathf.Max(0.01f, maxHeightDifference * num4);
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Expected O, but got Unknown
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetTeleportSamplingSamples", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetTeleportCloseCooldownSeconds", (Type[])null, (Type[])null);
				int num = 0;
				int num2 = 0;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					int value;
					if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 5f) && i - 1 >= 0 && list[i - 1].opcode == OpCodes.Ldfld && list[i - 1].operand is FieldInfo fieldInfo && fieldInfo.Name.IndexOf("tpCounter", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
						num2++;
					}
					else if (num == 0 && TryGetInt32Constant(val, out value) && value == 50)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						num++;
					}
				}
				if (num2 == 0)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] Teleport: did not find tpCounter < 5f gate to replace (pattern may have changed).");
					}
				}
				if (num == 0)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[ConfigurableScoutmaster] Teleport: did not find int 50 constant to replace (attempt-loop count).");
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_EvasiveBehaviour
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "EvasiveBehaviour", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetTeleportFarSeenTimeSeconds", (Type[])null, (Type[])null);
				int num = 0;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 0.5f) && i - 1 >= 0 && list[i - 1].opcode == OpCodes.Ldfld && list[i - 1].operand is FieldInfo fieldInfo && fieldInfo.Name.IndexOf("sinceAnyoneCanSeeMe", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						num++;
					}
				}
				if (num == 0)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] EvasiveBehaviour: did not find sinceAnyoneCanSeeMe > 0.5f threshold to replace.");
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_TeleportFarAway
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "TeleportFarAway", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Expected O, but got Unknown
				//IL_028c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0296: Expected O, but got Unknown
				//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ab: Expected O, but got Unknown
				//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c0: Expected O, but got Unknown
				//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d3: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetTeleportFarCooldownSeconds", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetTeleportFarPosition", (Type[])null, (Type[])null);
				ConstructorInfo constructorInfo = AccessTools.Constructor(typeof(Vector3), new Type[3]
				{
					typeof(float),
					typeof(float),
					typeof(float)
				}, false);
				int num = 0;
				int num2 = 0;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					if (val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 5f) && i - 1 >= 0 && list[i - 1].opcode == OpCodes.Ldfld && list[i - 1].operand is FieldInfo fieldInfo && fieldInfo.Name.IndexOf("tpCounter", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						num++;
					}
					else if (constructorInfo != null && val.opcode == OpCodes.Newobj && val.operand is ConstructorInfo constructorInfo2 && constructorInfo2 == constructorInfo && i >= 3 && list[i - 3].opcode == OpCodes.Ldc_R4 && list[i - 3].operand is float a2 && Approximately(a2, 0f) && list[i - 2].opcode == OpCodes.Ldc_R4 && list[i - 2].operand is float a3 && Approximately(a3, 0f) && list[i - 1].opcode == OpCodes.Ldc_R4 && list[i - 1].operand is float a4 && Approximately(a4, 5000f))
					{
						list[i - 3] = new CodeInstruction(OpCodes.Nop, (object)null);
						list[i - 2] = new CodeInstruction(OpCodes.Nop, (object)null);
						list[i - 1] = new CodeInstruction(OpCodes.Nop, (object)null);
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
						num2++;
					}
				}
				if (num == 0)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] TeleportFarAway: did not find tpCounter < 5f gate to replace.");
					}
				}
				if (num2 == 0)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[ConfigurableScoutmaster] TeleportFarAway: did not find new Vector3(0,0,5000) to replace.");
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_IThrow
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (type == null)
				{
					return null;
				}
				MethodInfo methodInfo = AccessTools.Method(type, "IThrow", (Type[])null, (Type[])null);
				if (!(methodInfo == null))
				{
					return AccessTools.EnumeratorMoveNext((MethodBase)methodInfo);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e1: Expected O, but got Unknown
				//IL_0433: Unknown result type (might be due to invalid IL or missing references)
				//IL_043d: Expected O, but got Unknown
				//IL_048f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0499: Expected O, but got Unknown
				//IL_031d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0327: Expected O, but got Unknown
				//IL_0332: Unknown result type (might be due to invalid IL or missing references)
				//IL_033c: Expected O, but got Unknown
				//IL_0551: Unknown result type (might be due to invalid IL or missing references)
				//IL_055b: Expected O, but got Unknown
				//IL_0369: Unknown result type (might be due to invalid IL or missing references)
				//IL_0373: Expected O, but got Unknown
				//IL_037f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0389: Expected O, but got Unknown
				//IL_0746: Unknown result type (might be due to invalid IL or missing references)
				//IL_0750: Expected O, but got Unknown
				//IL_061f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0629: Expected O, but got Unknown
				//IL_067f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0689: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetThrowWindupSeconds", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetThrowLocalShakeAmplitude", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(Plugin), "GetThrowLocalShakeDuration", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(Plugin), "GetThrowGlobalShakeAmplitude", (Type[])null, (Type[])null);
				MethodInfo methodInfo5 = AccessTools.Method(typeof(Plugin), "GetThrowGlobalShakeDuration", (Type[])null, (Type[])null);
				MethodInfo methodInfo6 = AccessTools.Method(typeof(Plugin), "GetThrowUpwardBias", (Type[])null, (Type[])null);
				MethodInfo methodInfo7 = AccessTools.Method(typeof(Plugin), "GetThrowForce", (Type[])null, (Type[])null);
				MethodInfo methodInfo8 = AccessTools.Method(typeof(Plugin), "GetThrowDuration", (Type[])null, (Type[])null);
				MethodInfo methodInfo9 = AccessTools.Method(typeof(Plugin), "GetThrowInjuryAmount", (Type[])null, (Type[])null);
				MethodInfo methodInfo10 = AccessTools.Method(typeof(Plugin), "GetThrowStatusTypeValue", (Type[])null, (Type[])null);
				MethodInfo methodInfo11 = AccessTools.Method(typeof(Plugin), "GetThrowPostChillSeconds", (Type[])null, (Type[])null);
				MethodInfo methodInfo12 = null;
				Type type = AccessTools.TypeByName("GamefeelHandler");
				if (type != null)
				{
					methodInfo12 = AccessTools.Method(type, "AddPerlinShake", new Type[2]
					{
						typeof(float),
						typeof(float)
					}, (Type[])null);
				}
				MethodInfo methodInfo13 = null;
				Type type2 = AccessTools.TypeByName("CharacterGrabbing");
				if (type2 != null)
				{
					methodInfo13 = AccessTools.Method(type2, "Throw", new Type[2]
					{
						typeof(Vector3),
						typeof(float)
					}, (Type[])null);
				}
				MethodInfo methodInfo14 = null;
				Type type3 = AccessTools.TypeByName("CharacterAfflictions");
				if (type3 != null)
				{
					methodInfo14 = AccessTools.Method(type3, "AddStatus", (Type[])null, (Type[])null);
				}
				FieldInfo fieldInfo = null;
				Type type4 = AccessTools.TypeByName("Scoutmaster");
				if (type4 != null)
				{
					fieldInfo = AccessTools.Field(type4, "chillForSeconds");
				}
				bool flag = false;
				bool flag2 = false;
				bool flag3 = false;
				bool flag4 = false;
				bool flag5 = false;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					if (methodInfo12 != null && (val.opcode == OpCodes.Callvirt || val.opcode == OpCodes.Call) && val.operand is MethodInfo methodInfo15 && methodInfo15 == methodInfo12 && i >= 2 && list[i - 2].opcode == OpCodes.Ldc_R4 && list[i - 2].operand is float a && list[i - 1].opcode == OpCodes.Ldc_R4 && list[i - 1].operand is float a2)
					{
						if (Approximately(a, 15f) && Approximately(a2, 0.5f))
						{
							list[i - 2] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
							list[i - 1] = new CodeInstruction(OpCodes.Call, (object)methodInfo3);
							continue;
						}
						if (Approximately(a, 3f) && Approximately(a2, 3f))
						{
							list[i - 2] = new CodeInstruction(OpCodes.Call, (object)methodInfo4);
							list[i - 1] = new CodeInstruction(OpCodes.Call, (object)methodInfo5);
							continue;
						}
					}
					if (!flag && val.opcode == OpCodes.Ldc_R4 && val.operand is float a3 && Approximately(a3, 3.2f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						flag = true;
						continue;
					}
					if (!flag2 && val.opcode == OpCodes.Ldc_R4 && val.operand is float a4 && Approximately(a4, 0.3f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo6);
						flag2 = true;
						continue;
					}
					if (!flag3 && val.opcode == OpCodes.Ldc_R4 && val.operand is float a5 && Approximately(a5, 1500f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo7);
						flag3 = true;
						continue;
					}
					if (methodInfo13 != null && (val.opcode == OpCodes.Callvirt || val.opcode == OpCodes.Call) && val.operand is MethodInfo methodInfo16 && methodInfo16 == methodInfo13 && i >= 1 && list[i - 1].opcode == OpCodes.Ldc_R4 && list[i - 1].operand is float a6 && Approximately(a6, 3f))
					{
						list[i - 1] = new CodeInstruction(OpCodes.Call, (object)methodInfo8);
						continue;
					}
					if (methodInfo14 != null && (val.opcode == OpCodes.Callvirt || val.opcode == OpCodes.Call) && val.operand is MethodInfo methodInfo17 && methodInfo17 == methodInfo14 && i >= 3)
					{
						int num = -1;
						for (int j = 1; j <= 6 && i - j >= 0; j++)
						{
							CodeInstruction val2 = list[i - j];
							if (val2.opcode == OpCodes.Ldc_R4 && val2.operand is float a7 && Approximately(a7, 0.25f))
							{
								list[i - j] = new CodeInstruction(OpCodes.Call, (object)methodInfo9);
								num = i - j;
								break;
							}
						}
						if (!flag5 && num >= 0 && methodInfo10 != null)
						{
							int num2 = num - 1;
							while (num2 >= 0 && num2 >= num - 10)
							{
								if (TryGetInt32Constant(list[num2], out var value) && value == 0)
								{
									list[num2] = new CodeInstruction(OpCodes.Call, (object)methodInfo10);
									flag5 = true;
									break;
								}
								num2--;
							}
						}
					}
					if (!flag4 && fieldInfo != null && val.opcode == OpCodes.Stfld && val.operand is FieldInfo fieldInfo2 && fieldInfo2 == fieldInfo && i >= 1 && list[i - 1].opcode == OpCodes.Ldc_R4 && list[i - 1].operand is float a8 && Approximately(a8, 2f))
					{
						list[i - 1] = new CodeInstruction(OpCodes.Call, (object)methodInfo11);
						flag4 = true;
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_RotateToMostEvilThrowDirection
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "RotateToMostEvilThrowDirection", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Expected O, but got Unknown
				//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01dd: Expected O, but got Unknown
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetThrowDirectionSamples", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetThrowDirectionSampleRadius", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(Plugin), "GetThrowDirectionDownRayLength", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = null;
				Type type = AccessTools.TypeByName("HelperFunctions");
				if (type != null)
				{
					methodInfo4 = AccessTools.Method(type, "GetCircularDirections", new Type[1] { typeof(int) }, (Type[])null);
				}
				bool flag = false;
				bool flag2 = false;
				bool flag3 = false;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					if (methodInfo4 != null && (val.opcode == OpCodes.Call || val.opcode == OpCodes.Callvirt) && val.operand is MethodInfo methodInfo5 && methodInfo5 == methodInfo4)
					{
						if (i >= 1 && TryGetInt32Constant(list[i - 1], out var value) && value == 10)
						{
							list[i - 1] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
						}
						flag = true;
					}
					else if (flag && !flag2 && val.opcode == OpCodes.Ldc_R4 && val.operand is float a && Approximately(a, 10f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
						flag2 = true;
					}
					else if (flag && !flag3 && val.opcode == OpCodes.Ldc_R4 && val.operand is float a2 && Approximately(a2, 1000f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo3);
						flag3 = true;
					}
				}
				return list;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_DoVisuals
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "DoVisuals", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c5: Expected O, but got Unknown
				//IL_0332: Unknown result type (might be due to invalid IL or missing references)
				//IL_033c: Expected O, but got Unknown
				//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f7: Expected O, but got Unknown
				//IL_025d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0267: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "GetVisualStrengthFarDistance", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "GetVisualStrengthNearDistance", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(Plugin), "GetVisualStrengthLerpSpeed", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(Plugin), "ApplyGrainMultiplier", (Type[])null, (Type[])null);
				MethodInfo methodInfo5 = AccessTools.Method(typeof(Material), "SetFloat", new Type[2]
				{
					typeof(int),
					typeof(float)
				}, (Type[])null);
				MethodInfo methodInfo6 = AccessTools.Method(typeof(Mathf), "InverseLerp", new Type[3]
				{
					typeof(float),
					typeof(float),
					typeof(float)
				}, (Type[])null);
				FieldInfo grainField = null;
				FieldInfo strengthField = null;
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (type != null)
				{
					grainField = AccessTools.Field(type, "GRAINMULTID");
					strengthField = AccessTools.Field(type, "STRENGTHID");
				}
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				int num4 = 0;
				for (int i = 0; i < list.Count; i++)
				{
					CodeInstruction val = list[i];
					if (methodInfo6 != null && (val.opcode == OpCodes.Call || val.opcode == OpCodes.Callvirt) && val.operand is MethodInfo methodInfo7 && methodInfo7 == methodInfo6 && i >= 3)
					{
						if (list[i - 3].opcode == OpCodes.Ldc_R4 && list[i - 3].operand is float a && Approximately(a, 50f))
						{
							list[i - 3] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
							num++;
						}
						if (list[i - 2].opcode == OpCodes.Ldc_R4 && list[i - 2].operand is float a2 && Approximately(a2, 5f))
						{
							list[i - 2] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
							num2++;
						}
					}
					else if (num3 == 0 && val.opcode == OpCodes.Ldc_R4 && val.operand is float a3 && Approximately(a3, 0.5f))
					{
						list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo3);
						num3++;
					}
					else if (methodInfo5 != null && (val.opcode == OpCodes.Callvirt || val.opcode == OpCodes.Call) && val.operand is MethodInfo methodInfo8 && methodInfo8 == methodInfo5 && IsNearestIdField(list, i, grainField, strengthField))
					{
						list.Insert(i, new CodeInstruction(OpCodes.Call, (object)methodInfo4));
						i++;
						num4++;
					}
				}
				if (num == 0 || num2 == 0)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)string.Format("[{0}] DoVisuals: did not replace both InverseLerp endpoints (50f/5f). Replaced: far={1}, near={2}.", "ConfigurableScoutmaster", num, num2));
					}
				}
				if (num3 == 0)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[ConfigurableScoutmaster] DoVisuals: did not replace 0.5f lerp speed constant.");
					}
				}
				if (num4 == 0)
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogWarning((object)"[ConfigurableScoutmaster] DoVisuals: did not insert grain multiplier before SetFloat(GRAINMULTID, ...).");
					}
				}
				return list;
			}

			private static bool IsNearestIdField(List<CodeInstruction> codes, int callIndex, FieldInfo? grainField, FieldInfo? strengthField)
			{
				int num = callIndex - 1;
				while (num >= 0 && num >= callIndex - 12)
				{
					if ((codes[num].opcode == OpCodes.Ldfld || codes[num].opcode == OpCodes.Ldsfld) && codes[num].operand is FieldInfo fieldInfo && (!(codes[num].opcode == OpCodes.Ldfld) || (num - 1 >= 0 && !(codes[num - 1].opcode != OpCodes.Ldarg_0))))
					{
						if (grainField != null && fieldInfo == grainField)
						{
							return true;
						}
						if (strengthField != null && fieldInfo == strengthField)
						{
							return false;
						}
					}
					num--;
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class Patch_Scoutmaster_Start
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("Scoutmaster");
				if (!(type == null))
				{
					return AccessTools.Method(type, "Start", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static void Postfix(object __instance)
			{
				try
				{
					Type type = __instance.GetType();
					FieldInfo fieldInfo = AccessTools.Field(type, "attackHeightDelta");
					FieldInfo fieldInfo2 = AccessTools.Field(type, "maxAggroHeight");
					if (fieldInfo == null || fieldInfo2 == null)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogWarning((object)"[ConfigurableScoutmaster] Start: could not access fields attackHeightDelta/maxAggroHeight (names may have changed).");
						}
						return;
					}
					if (!ScoutmasterOriginalsByInstance.TryGetValue(__instance, out ScoutmasterOriginals value))
					{
						value = new ScoutmasterOriginals
						{
							AttackHeightDelta = SafeGetFloat(fieldInfo, __instance),
							MaxAggroHeight = SafeGetFloat(fieldInfo2, __instance)
						};
						ScoutmasterOriginalsByInstance.Add(__instance, value);
					}
					float num = Mathf.Max(0f, GetAttackHeightDeltaMultiplier());
					float num2 = Mathf.Max(0f, GetMaxAggroHeightMultiplier());
					fieldInfo.SetValue(__instance, value.AttackHeightDelta * num);
					fieldInfo2.SetValue(__instance, value.MaxAggroHeight * num2);
				}
				catch (Exception arg)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogError((object)string.Format("[{0}] Start postfix error: {1}", "ConfigurableScoutmaster", arg));
					}
				}
			}
		}

		[HarmonyPatch]
		private static class Patch_CharacterAfflictions_AddStatus
		{
			private static MethodBase? TargetMethod()
			{
				Type type = AccessTools.TypeByName("CharacterAfflictions");
				if (!(type == null))
				{
					return AccessTools.Method(type, "AddStatus", (Type[])null, (Type[])null);
				}
				return null;
			}

			private static void Prefix(object __instance, object statusType, ref float amount, bool fromRPC, bool playEffects)
			{
				ConfigEntry<bool> disableScoutmasterStatusImmunity = DisableScoutmasterStatusImmunity;
				if (disableScoutmasterStatusImmunity == null || !disableScoutmasterStatusImmunity.Value || fromRPC)
				{
					return;
				}
				object value = Traverse.Create(__instance).Field("character").GetValue();
				if (value == null || !Traverse.Create(value).Field("isScoutmaster").GetValue<bool>())
				{
					return;
				}
				string a = statusType?.ToString() ?? string.Empty;
				if (string.Equals(a, "Injury", StringComparison.Ordinal))
				{
					float num = ScoutmasterInjuryDamageMultiplier?.Value ?? 0f;
					if (num <= 0f)
					{
						amount = 0f;
						return;
					}
					amount *= num;
					if (amount < 0f)
					{
						amount = 0f;
					}
					return;
				}
				float num2 = ScoutmasterOtherStatusDamageMultiplier?.Value ?? 1f;
				if (Approximately(num2, 1f))
				{
					return;
				}
				if (num2 <= 0f)
				{
					amount = 0f;
					return;
				}
				amount *= num2;
				if (amount < 0f)
				{
					amount = 0f;
				}
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				Type type = AccessTools.TypeByName("Character");
				FieldInfo fieldInfo = null;
				if (type != null)
				{
					fieldInfo = AccessTools.Field(type, "isScoutmaster");
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "ShouldBlockScoutmasterStatus", new Type[1] { typeof(bool) }, (Type[])null);
				if (fieldInfo == null || methodInfo == null)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[ConfigurableScoutmaster] AddStatus: could not find Character.isScoutmaster field or helper; leaving vanilla.");
					}
					return list;
				}
				bool flag = false;
				for (int i = 0; i < list.Count - 1; i++)
				{
					CodeInstruction val = list[i];
					if (val.opcode == OpCodes.Ldfld && val.operand is FieldInfo fieldInfo2 && fieldInfo2 == fieldInfo)
					{
						CodeInstruction val2 = list[i + 1];
						if (val2.opcode == OpCodes.Brfalse || val2.opcode == OpCodes.Brfalse_S)
						{
							list.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)methodInfo));
							flag = true;
							i++;
						}
					}
				}
				if (!flag)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[ConfigurableScoutmaster] AddStatus: did not find scoutmaster immunity check to patch.");
					}
				}
				return list;
			}
		}

		private const string LogTag = "ConfigurableScoutmaster";

		private Harmony? _harmony;

		private static readonly ConditionalWeakTable<object, ScoutmasterOriginals> ScoutmasterOriginalsByInstance = new ConditionalWeakTable<object, ScoutmasterOriginals>();

		public const string Id = "com.github.GABRlEL.ConfigurableScoutmaster";

		internal static ManualLogSource Log { get; private set; } = null;


		internal static ConfigEntry<float> TargetIntervalMult { get; private set; } = null;


		internal static ConfigEntry<float> ChancePerCheckMult { get; private set; } = null;


		internal static ConfigEntry<float> AttackHeightDeltaMult { get; private set; } = null;


		internal static ConfigEntry<float> MaxAggroHeightMult { get; private set; } = null;


		internal static ConfigEntry<float> MinIsolationDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> CloseDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> TargetLookAwayAngleMult { get; private set; } = null;


		internal static ConfigEntry<float> AnyoneCanSeeAngleMult { get; private set; } = null;


		internal static ConfigEntry<float> SeenGainRatesMult { get; private set; } = null;


		internal static ConfigEntry<float> SeenCounterToEnableSprintMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportInsteadOfChaseDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> WalkTowardTargetDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> SprintIfDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> LoseTargetAfterTeleportChanceMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportCloseCooldownMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportCloseMinDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportCloseMaxDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportSamplingMaxDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportSamplingMaxHeightDifferenceMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportSamplingSamplesMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportFarSeenTimeMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportFarCooldownMult { get; private set; } = null;


		internal static ConfigEntry<float> TeleportFarPositionX { get; private set; } = null;


		internal static ConfigEntry<float> TeleportFarPositionY { get; private set; } = null;


		internal static ConfigEntry<float> TeleportFarPositionZ { get; private set; } = null;


		internal static ConfigEntry<float> ThrowWindupMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowLocalShakeAmplitudeMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowLocalShakeDurationMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowGlobalShakeAmplitudeMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowGlobalShakeDurationMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowUpwardBiasMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowForceMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowDurationMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowInjuryAmountMult { get; private set; } = null;


		internal static ConfigEntry<DamageTypeOverride> ThrowDamageType { get; private set; } = null;


		internal static ConfigEntry<float> ThrowPostChillSecondsMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowDirectionSamplesMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowDirectionSampleRadiusMult { get; private set; } = null;


		internal static ConfigEntry<float> ThrowDirectionDownRayLengthMult { get; private set; } = null;


		internal static ConfigEntry<float> VisualStrengthFarDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> VisualStrengthNearDistanceMult { get; private set; } = null;


		internal static ConfigEntry<float> VisualStrengthLerpSpeedMult { get; private set; } = null;


		internal static ConfigEntry<float> VisualGrainMultiplierMult { get; private set; } = null;


		internal static ConfigEntry<bool> DisableScoutmasterStatusImmunity { get; private set; } = null;


		internal static ConfigEntry<float> ScoutmasterInjuryDamageMultiplier { get; private set; } = null;


		internal static ConfigEntry<float> ScoutmasterOtherStatusDamageMultiplier { get; private set; } = null;


		public static string Name => "ConfigurableScoutmaster";

		public static string Version => "0.1.0";

		private void Awake()
		{
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			string text = "Scoutmaster.Targeting";
			TargetIntervalMult = ((BaseUnityPlugin)this).Config.Bind<float>(text, "TargetIntervalMultiplier", 1f, "Multiplier for Scoutmaster target interval (base game: 30 seconds). 1.0 = vanilla.");
			ChancePerCheckMult = ((BaseUnityPlugin)this).Config.Bind<float>(text, "ChancePerCheckMultiplier", 1f, "Multiplier for Scoutmaster chance per check (base game: 0.10). Clamped to [0,1]. 1.0 = vanilla.");
			AttackHeightDeltaMult = ((BaseUnityPlugin)this).Config.Bind<float>(text, "AttackHeightDeltaMultiplier", 1f, "Multiplier for Scoutmaster attackHeightDelta (base game: 100). 1.0 = vanilla.");
			MaxAggroHeightMult = ((BaseUnityPlugin)this).Config.Bind<float>(text, "MaxAggroHeightMultiplier", 1f, "Multiplier for Scoutmaster maxAggroHeight (base game: 825). 1.0 = vanilla.");
			MinIsolationDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text, "MinIsolationDistanceMultiplier", 1f, "Multiplier for Scoutmaster minIsolationDistance (base game: 15). 1.0 = vanilla.");
			string text2 = "Scoutmaster.Perception";
			CloseDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text2, "CloseDistanceMultiplier", 1f, "Multiplier for Scoutmaster close distance check (base game: 10). 1.0 = vanilla.");
			TargetLookAwayAngleMult = ((BaseUnityPlugin)this).Config.Bind<float>(text2, "TargetLookAwayAngleMultiplier", 1f, "Multiplier for target look-away angle (degrees) used in perception (base game: 70). 1.0 = vanilla.");
			AnyoneCanSeeAngleMult = ((BaseUnityPlugin)this).Config.Bind<float>(text2, "AnyoneCanSeeAngleMultiplier", 1f, "Multiplier for anyone-can-see angle (degrees) used in perception (base game: 80). 1.0 = vanilla.");
			SeenGainRatesMult = ((BaseUnityPlugin)this).Config.Bind<float>(text2, "SeenGainRatesMultiplier", 1f, "Multiplier applied to all seen gain/decay rates (base game rates: 1.0 / 0.3 / 0.15 gains, 0.1 decay). 1.0 = vanilla.");
			SeenCounterToEnableSprintMult = ((BaseUnityPlugin)this).Config.Bind<float>(text2, "SeenCounterToEnableSprintMultiplier", 1f, "Multiplier for seenCounter threshold enabling sprint logic (base game: 1.0). 1.0 = vanilla.");
			string text3 = "Scoutmaster.Movement";
			TeleportInsteadOfChaseDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text3, "TeleportInsteadOfChaseDistanceMultiplier", 1f, "Multiplier for distance at which Scoutmaster teleports instead of chasing (base game: 80). 1.0 = vanilla.");
			WalkTowardTargetDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text3, "WalkTowardTargetDistanceMultiplier", 1f, "Multiplier for distance threshold to walk toward target (base game: 5). 1.0 = vanilla.");
			SprintIfDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text3, "SprintIfDistanceMultiplier", 1f, "Multiplier for distance threshold to sprint toward target (base game: 15). 1.0 = vanilla.");
			LoseTargetAfterTeleportChanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text3, "LoseTargetAfterTeleportChanceMultiplier", 1f, "Multiplier for chance to lose target after teleport (base game: 0.10). Clamped to [0,1]. 1.0 = vanilla.");
			string text4 = "Scoutmaster.TeleportClose";
			TeleportCloseCooldownMult = ((BaseUnityPlugin)this).Config.Bind<float>(text4, "TeleportCloseCooldownMultiplier", 1f, "Multiplier for teleport-close cooldown gate (base game: 5 seconds). 1.0 = vanilla.");
			TeleportCloseMinDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text4, "TeleportCloseMinDistanceMultiplier", 1f, "Multiplier for teleport-close MIN distance to target (base game: 50). 1.0 = vanilla.");
			TeleportCloseMaxDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text4, "TeleportCloseMaxDistanceMultiplier", 1f, "Multiplier for teleport-close MAX distance to target (base game: 70). 1.0 = vanilla.");
			string text5 = "Scoutmaster.TeleportSampling";
			TeleportSamplingMaxDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text5, "TeleportSamplingMaxDistanceMultiplier", 1f, "Multiplier for generic teleport sampling maxDistanceToTarget (base game: 45). 1.0 = vanilla.");
			TeleportSamplingMaxHeightDifferenceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text5, "TeleportSamplingMaxHeightDifferenceMultiplier", 1f, "Multiplier for generic teleport sampling maxHeightDifference (base game: 15). 1.0 = vanilla.");
			TeleportSamplingSamplesMult = ((BaseUnityPlugin)this).Config.Bind<float>(text5, "TeleportSamplingSamplesMultiplier", 1f, "Multiplier for generic teleport sampling raycast samples (base game: 50). Rounded, clamped to >= 1. 1.0 = vanilla.");
			string text6 = "Scoutmaster.TeleportFar";
			TeleportFarSeenTimeMult = ((BaseUnityPlugin)this).Config.Bind<float>(text6, "TeleportFarSeenTimeMultiplier", 1f, "Multiplier for time being seen before triggering far teleport (base game: 0.5 seconds). 1.0 = vanilla.");
			TeleportFarCooldownMult = ((BaseUnityPlugin)this).Config.Bind<float>(text6, "TeleportFarCooldownMultiplier", 1f, "Multiplier for far teleport cooldown gate (base game: 5 seconds). 1.0 = vanilla.");
			TeleportFarPositionX = ((BaseUnityPlugin)this).Config.Bind<float>(text6, "TeleportFarPositionX", 0f, "Absolute X position for far teleport (base game: 0).");
			TeleportFarPositionY = ((BaseUnityPlugin)this).Config.Bind<float>(text6, "TeleportFarPositionY", 0f, "Absolute Y position for far teleport (base game: 0).");
			TeleportFarPositionZ = ((BaseUnityPlugin)this).Config.Bind<float>(text6, "TeleportFarPositionZ", 5000f, "Absolute Z position for far teleport (base game: 5000).");
			string text7 = "Scoutmaster.Throw";
			ThrowWindupMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowWindupMultiplier", 1f, "Multiplier for throw windup (base game: 3.2 seconds). 1.0 = vanilla.");
			ThrowLocalShakeAmplitudeMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowLocalShakeAmplitudeMultiplier", 1f, "Multiplier for local (victim) perlin shake amplitude during throw windup (base game: 15). 1.0 = vanilla.");
			ThrowLocalShakeDurationMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowLocalShakeDurationMultiplier", 1f, "Multiplier for local (victim) perlin shake duration during throw windup (base game: 0.5). 1.0 = vanilla.");
			ThrowGlobalShakeAmplitudeMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowGlobalShakeAmplitudeMultiplier", 1f, "Multiplier for global perlin shake amplitude during throw windup (base game: 3). 1.0 = vanilla.");
			ThrowGlobalShakeDurationMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowGlobalShakeDurationMultiplier", 1f, "Multiplier for global perlin shake duration during throw windup (base game: 3). 1.0 = vanilla.");
			ThrowUpwardBiasMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowUpwardBiasMultiplier", 1f, "Multiplier for throw upward bias (base game: 0.3). 1.0 = vanilla.");
			ThrowForceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowForceMultiplier", 1f, "Multiplier for throw force (base game: 1500). 1.0 = vanilla.");
			ThrowDurationMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowDurationMultiplier", 1f, "Multiplier for throw duration/param passed to grabbing.Throw (base game: 3). 1.0 = vanilla.");
			ThrowInjuryAmountMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowInjuryAmountMultiplier", 1f, "Multiplier for injury amount applied on throw (base game: 0.25). 1.0 = vanilla.");
			ThrowDamageType = ((BaseUnityPlugin)this).Config.Bind<DamageTypeOverride>(text7, "DamageType", DamageTypeOverride.Vanilla, "Controls the status/damage type applied to the victim when Scoutmaster throws them. Vanilla keeps the game's original setting.\nCold = freeze, Hot = burn, Spores = shroom.");
			ThrowPostChillSecondsMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowPostChillSecondsMultiplier", 1f, "Multiplier for post-throw chill duration (base game: 2 seconds). 1.0 = vanilla.");
			ThrowDirectionSamplesMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowDirectionSamplesMultiplier", 1f, "Multiplier for throw direction sample count used by RotateToMostEvilThrowDirection (base game: 10). 1.0 = vanilla.");
			ThrowDirectionSampleRadiusMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowDirectionSampleRadiusMultiplier", 1f, "Multiplier for throw direction sample radius used by RotateToMostEvilThrowDirection (base game: 10). 1.0 = vanilla.");
			ThrowDirectionDownRayLengthMult = ((BaseUnityPlugin)this).Config.Bind<float>(text7, "ThrowDirectionDownRayLengthMultiplier", 1f, "Multiplier for down-ray length used by RotateToMostEvilThrowDirection (base game: 1000). 1.0 = vanilla.");
			string text8 = "Scoutmaster.Visuals";
			VisualStrengthFarDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text8, "StrengthDistanceFarMultiplier", 1f, "Multiplier for the far distance used in Scoutmaster visual strength mapping (base game: 50). 1.0 = vanilla.");
			VisualStrengthNearDistanceMult = ((BaseUnityPlugin)this).Config.Bind<float>(text8, "StrengthDistanceNearMultiplier", 1f, "Multiplier for the near distance used in Scoutmaster visual strength mapping (base game: 5). 1.0 = vanilla.");
			VisualStrengthLerpSpeedMult = ((BaseUnityPlugin)this).Config.Bind<float>(text8, "StrengthLerpSpeedMultiplier", 1f, "Multiplier for the visual strength lerp speed (base game: 0.5). 1.0 = vanilla.");
			VisualGrainMultiplierMult = ((BaseUnityPlugin)this).Config.Bind<float>(text8, "GrainMultiplier", 1f, "Multiplier applied to the grain strength when photosensitivity is off (base game: 1). 1.0 = vanilla.");
			string text9 = "Scoutmaster.Rules";
			DisableScoutmasterStatusImmunity = ((BaseUnityPlugin)this).Config.Bind<bool>(text9, "DisableStatusImmunity", false, "When true, the Scoutmaster is no longer immune to status effects (vanilla: immune). Default false preserves vanilla.");
			ScoutmasterInjuryDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>(text9, "ScoutmasterInjuryDamageMultiplier", 0f, "Multiplier applied to Injury status amounts the Scoutmaster receives when DisableStatusImmunity is true. Default 0 prevents spawn fall-damage from making the Scoutmaster go limp. 1.0 = vanilla injury amounts.");
			ScoutmasterOtherStatusDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>(text9, "ScoutmasterOtherStatusDamageMultiplier", 1f, "Multiplier applied to ALL non-Injury status amounts the Scoutmaster receives when DisableStatusImmunity is true. Default 1.0 keeps vanilla status amounts (when immunity is disabled).");
			try
			{
				_harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				_harmony.PatchAll();
				Log.LogInfo((object)$"Plugin {((BaseUnityPlugin)this).Info.Metadata.Name} ({((BaseUnityPlugin)this).Info.Metadata.Version}) is loaded and patched.");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to apply Harmony patches ({((BaseUnityPlugin)this).Info.Metadata.Version}): {arg}");
			}
		}

		internal static bool ShouldBlockScoutmasterStatus(bool isScoutmaster)
		{
			if (!isScoutmaster)
			{
				return false;
			}
			bool flag = DisableScoutmasterStatusImmunity?.Value ?? false;
			return !flag;
		}

		internal static float GetTargetIntervalSeconds()
		{
			float num = TargetIntervalMult?.Value ?? 1f;
			return Mathf.Max(0.01f, 30f * num);
		}

		internal static float GetChancePerCheck()
		{
			float num = ChancePerCheckMult?.Value ?? 1f;
			return Mathf.Clamp01(0.1f * num);
		}

		internal static float GetMinIsolationDistance()
		{
			float num = MinIsolationDistanceMult?.Value ?? 1f;
			return Mathf.Max(0f, 15f * num);
		}

		internal static float GetAttackHeightDeltaMultiplier()
		{
			return AttackHeightDeltaMult?.Value ?? 1f;
		}

		internal static float GetMaxAggroHeightMultiplier()
		{
			return MaxAggroHeightMult?.Value ?? 1f;
		}

		internal static float GetCloseDistance()
		{
			float num = CloseDistanceMult?.Value ?? 1f;
			return Mathf.Max(0f, 10f * num);
		}

		internal static float GetTargetLookAwayAngle()
		{
			float num = TargetLookAwayAngleMult?.Value ?? 1f;
			return Mathf.Clamp(70f * num, 0f, 180f);
		}

		internal static float GetAnyoneCanSeeAngle()
		{
			float num = AnyoneCanSeeAngleMult?.Value ?? 1f;
			return Mathf.Clamp(80f * num, 0f, 180f);
		}

		internal static float GetSeenGainRate_1()
		{
			float num = SeenGainRatesMult?.Value ?? 1f;
			return Mathf.Max(0f, 1f * num);
		}

		internal static float GetSeenGainRate_03()
		{
			float num = SeenGainRatesMult?.Value ?? 1f;
			return Mathf.Max(0f, 0.3f * num);
		}

		internal static float GetSeenGainRate_015()
		{
			float num = SeenGainRatesMult?.Value ?? 1f;
			return Mathf.Max(0f, 0.15f * num);
		}

		internal static float GetSeenDecayRate_01()
		{
			float num = SeenGainRatesMult?.Value ?? 1f;
			return Mathf.Max(0f, 0.1f * num);
		}

		internal static float GetSeenCounterToEnableSprint()
		{
			float num = SeenCounterToEnableSprintMult?.Value ?? 1f;
			return Mathf.Max(0f, 1f * num);
		}

		internal static float GetTeleportInsteadOfChaseDistance()
		{
			float num = TeleportInsteadOfChaseDistanceMult?.Value ?? 1f;
			return Mathf.Max(0f, 80f * num);
		}

		internal static float GetWalkTowardTargetDistance()
		{
			float num = WalkTowardTargetDistanceMult?.Value ?? 1f;
			return Mathf.Max(0f, 5f * num);
		}

		internal static float GetSprintIfDistance()
		{
			float num = SprintIfDistanceMult?.Value ?? 1f;
			return Mathf.Max(0f, 15f * num);
		}

		internal static float GetLoseTargetAfterTeleportChance()
		{
			float num = LoseTargetAfterTeleportChanceMult?.Value ?? 1f;
			return Mathf.Clamp01(0.1f * num);
		}

		internal static float GetTeleportCloseCooldownSeconds()
		{
			float num = TeleportCloseCooldownMult?.Value ?? 1f;
			return Mathf.Max(0.01f, 5f * num);
		}

		internal static float GetTeleportFarCooldownSeconds()
		{
			float num = TeleportFarCooldownMult?.Value ?? 1f;
			return Mathf.Max(0.01f, 5f * num);
		}

		internal static float GetTeleportFarSeenTimeSeconds()
		{
			float num = TeleportFarSeenTimeMult?.Value ?? 1f;
			return Mathf.Max(0f, 0.5f * num);
		}

		internal static Vector3 GetTeleportFarPosition()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			float num = TeleportFarPositionX?.Value ?? 0f;
			float num2 = TeleportFarPositionY?.Value ?? 0f;
			float num3 = TeleportFarPositionZ?.Value ?? 5000f;
			return new Vector3(num, num2, num3);
		}

		internal static int GetTeleportSamplingSamples()
		{
			float num = TeleportSamplingSamplesMult?.Value ?? 1f;
			int num2 = Mathf.RoundToInt(50f * num);
			return Mathf.Clamp(num2, 1, 512);
		}

		internal static float GetThrowWindupSeconds()
		{
			float num = ThrowWindupMult?.Value ?? 1f;
			return Mathf.Max(0f, 3.2f * num);
		}

		internal static float GetThrowLocalShakeAmplitude()
		{
			float num = ThrowLocalShakeAmplitudeMult?.Value ?? 1f;
			return Mathf.Max(0f, 15f * num);
		}

		internal static float GetThrowLocalShakeDuration()
		{
			float num = ThrowLocalShakeDurationMult?.Value ?? 1f;
			return Mathf.Max(0f, 0.5f * num);
		}

		internal static float GetThrowGlobalShakeAmplitude()
		{
			float num = ThrowGlobalShakeAmplitudeMult?.Value ?? 1f;
			return Mathf.Max(0f, 3f * num);
		}

		internal static float GetThrowGlobalShakeDuration()
		{
			float num = ThrowGlobalShakeDurationMult?.Value ?? 1f;
			return Mathf.Max(0f, 3f * num);
		}

		internal static float GetThrowUpwardBias()
		{
			float num = ThrowUpwardBiasMult?.Value ?? 1f;
			return 0.3f * num;
		}

		internal static float GetThrowForce()
		{
			float num = ThrowForceMult?.Value ?? 1f;
			return Mathf.Max(0f, 1500f * num);
		}

		internal static float GetThrowDuration()
		{
			float num = ThrowDurationMult?.Value ?? 1f;
			return Mathf.Max(0f, 3f * num);
		}

		internal static float GetThrowInjuryAmount()
		{
			float num = ThrowInjuryAmountMult?.Value ?? 1f;
			return Mathf.Max(0f, 0.25f * num);
		}

		internal static int GetThrowStatusTypeValue()
		{
			DamageTypeOverride damageTypeOverride = ThrowDamageType?.Value ?? DamageTypeOverride.Vanilla;
			if (damageTypeOverride == DamageTypeOverride.Vanilla)
			{
				return 0;
			}
			return (int)damageTypeOverride;
		}

		internal static float GetThrowPostChillSeconds()
		{
			float num = ThrowPostChillSecondsMult?.Value ?? 1f;
			return Mathf.Max(0f, 2f * num);
		}

		internal static int GetThrowDirectionSamples()
		{
			float num = ThrowDirectionSamplesMult?.Value ?? 1f;
			int num2 = Mathf.RoundToInt(10f * num);
			return Mathf.Clamp(num2, 1, 512);
		}

		internal static float GetThrowDirectionSampleRadius()
		{
			float num = ThrowDirectionSampleRadiusMult?.Value ?? 1f;
			return Mathf.Max(0f, 10f * num);
		}

		internal static float GetThrowDirectionDownRayLength()
		{
			float num = ThrowDirectionDownRayLengthMult?.Value ?? 1f;
			return Mathf.Max(0f, 1000f * num);
		}

		internal static float GetVisualStrengthFarDistance()
		{
			float num = VisualStrengthFarDistanceMult?.Value ?? 1f;
			return Mathf.Max(0f, 50f * num);
		}

		internal static float GetVisualStrengthNearDistance()
		{
			float num = VisualStrengthNearDistanceMult?.Value ?? 1f;
			return Mathf.Max(0f, 5f * num);
		}

		internal static float GetVisualStrengthLerpSpeed()
		{
			float num = VisualStrengthLerpSpeedMult?.Value ?? 1f;
			return Mathf.Max(0f, 0.5f * num);
		}

		internal static float ApplyGrainMultiplier(float baseGrain)
		{
			float num = VisualGrainMultiplierMult?.Value ?? 1f;
			return baseGrain * Mathf.Max(0f, num);
		}

		private static float SafeGetFloat(FieldInfo fi, object instance)
		{
			object value = fi.GetValue(instance);
			if (value is float)
			{
				return (float)value;
			}
			if (value is double num)
			{
				return (float)num;
			}
			if (value is int num2)
			{
				return num2;
			}
			return 0f;
		}

		private static bool Approximately(float a, float b)
		{
			return Mathf.Abs(a - b) < 0.0001f;
		}

		private static bool TryGetInt32Constant(CodeInstruction ci, out int value)
		{
			OpCode opcode = ci.opcode;
			if (opcode == OpCodes.Ldc_I4_M1)
			{
				value = -1;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_0)
			{
				value = 0;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_1)
			{
				value = 1;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_2)
			{
				value = 2;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_3)
			{
				value = 3;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_4)
			{
				value = 4;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_5)
			{
				value = 5;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_6)
			{
				value = 6;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_7)
			{
				value = 7;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_8)
			{
				value = 8;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4 && ci.operand is int num)
			{
				value = num;
				return true;
			}
			if (opcode == OpCodes.Ldc_I4_S)
			{
				if (ci.operand is sbyte b)
				{
					value = b;
					return true;
				}
				if (ci.operand is byte b2)
				{
					value = b2;
					return true;
				}
				if (ci.operand is int num2)
				{
					value = num2;
					return true;
				}
			}
			value = 0;
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}