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)
{
}
}
}