using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using Gunshy;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.PuppetMasta;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;
using UnityEngine.AI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(GunshyMod), "Gunshy", "1.0.0", "Gunshy", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Gunshy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Gunshy")]
[assembly: AssemblyTitle("Gunshy")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Gunshy;
public class GunshyMod : MelonMod
{
private sealed class Panic
{
public BehaviourBaseNav behaviour;
public NavMeshAgent agent;
public float originalSpeed;
public float originalAccel;
public bool originalBraking;
public Vector3 awayFrom;
public Vector3 dest;
public float until;
public float repathAt;
}
internal static MelonPreferences_Entry<bool> Enabled;
internal static MelonPreferences_Entry<float> HearRadius;
internal static MelonPreferences_Entry<float> FleeSeconds;
internal static MelonPreferences_Entry<float> FleeSpeed;
private readonly Dictionary<int, Panic> panics = new Dictionary<int, Panic>();
private Harmony harmony;
private Action<Gun> gunHandler;
private Action unloadHandler;
private float nextLogTime;
private bool loggedDriveError;
private bool menuReady;
private static GunshyMod current;
private bool diagScareLogged;
private bool diagAgentLogged;
private bool diagPatchLogged;
private bool diagSetDestLogged;
private bool diagDumpLogged;
private static readonly string[] TargetFields = new string[5] { "cur_target", "targetTriggerRef", "targetProxy", "_target", "enemyTarget" };
public override void OnInitializeMelon()
{
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
MelonPreferences_Category obj = MelonPreferences.CreateCategory("Gunshy");
Enabled = obj.CreateEntry<bool>("Enabled", true, "Enabled", (string)null, false, false, (ValueValidator)null, (string)null);
HearRadius = obj.CreateEntry<float>("HearRadius", 22f, "Hearing radius (m)", (string)null, false, false, (ValueValidator)null, (string)null);
FleeSeconds = obj.CreateEntry<float>("FleeSeconds", 4.5f, "Flee time (s)", (string)null, false, false, (ValueValidator)null, (string)null);
FleeSpeed = obj.CreateEntry<float>("FleeSpeed", 6.5f, "Flee speed", (string)null, false, false, (ValueValidator)null, (string)null);
gunHandler = OnGunFired;
unloadHandler = ClearPanics;
Hooking.OnPostFireGun += gunHandler;
Hooking.OnLevelUnloaded += unloadHandler;
Hooking.OnMarrowGameStarted += CreateMenu;
current = this;
harmony = new Harmony("gunshy.flee");
TryPatchDriver();
CreateMenu();
((MelonBase)this).LoggerInstance.Msg("Gunshy loaded. Your gunshots make nearby NPCs run.");
}
public override void OnDeinitializeMelon()
{
if (gunHandler != null)
{
Hooking.OnPostFireGun -= gunHandler;
}
if (unloadHandler != null)
{
Hooking.OnLevelUnloaded -= unloadHandler;
}
Hooking.OnMarrowGameStarted -= CreateMenu;
if (harmony != null)
{
harmony.UnpatchSelf();
}
ClearPanics();
}
public override void OnLateUpdate()
{
if (panics.Count == 0)
{
return;
}
float time = Time.time;
List<int> list = null;
foreach (KeyValuePair<int, Panic> panic in panics)
{
Panic value = panic.Value;
if ((Object)(object)value.behaviour == (Object)null || time >= value.until)
{
Restore(value);
if (list == null)
{
list = new List<int>();
}
list.Add(panic.Key);
}
else
{
Drive(value, time);
}
}
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
panics.Remove(list[i]);
}
}
}
private void CreateMenu()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
if (!menuReady && Page.Root != null)
{
menuReady = true;
Page obj = Page.Root.CreatePage("Gunshy", new Color(0.84f, 1f, 0.25f), 0, true);
obj.CreateBool("Enabled", Color.white, Enabled.Value, (Action<bool>)delegate(bool value)
{
Enabled.Value = value;
});
obj.CreateFloat("Hearing radius", Color.white, HearRadius.Value, 1f, 4f, 60f, (Action<float>)delegate(float value)
{
HearRadius.Value = value;
});
obj.CreateFloat("Flee seconds", Color.white, FleeSeconds.Value, 0.5f, 1f, 12f, (Action<float>)delegate(float value)
{
FleeSeconds.Value = value;
});
obj.CreateFloat("Flee speed", Color.white, FleeSpeed.Value, 0.5f, 2f, 12f, (Action<float>)delegate(float value)
{
FleeSpeed.Value = value;
});
}
}
private void TryPatchDriver()
{
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(BehaviourBaseNav), "Update", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(BehaviourBaseNav), "OnUpdate", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(BehaviourBaseNav), "FixedUpdate", (Type[])null, (Type[])null);
if (methodInfo == null)
{
((MelonBase)this).LoggerInstance.Msg("No behaviour update to patch. LateUpdate still drives the flee.");
return;
}
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] Patching " + methodInfo.DeclaringType.Name + "." + methodInfo.Name);
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(GunshyMod), "RepathPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
public static void RepathPostfix(BehaviourBaseNav __instance)
{
GunshyMod gunshyMod = current;
if (gunshyMod != null && !gunshyMod.diagPatchLogged)
{
gunshyMod.diagPatchLogged = true;
((MelonBase)gunshyMod).LoggerInstance.Msg("[Gunshy][DIAG] RepathPostfix fired - Harmony patch is live.");
}
if (gunshyMod != null && !((Object)(object)__instance == (Object)null))
{
int instanceID = ((Object)__instance).GetInstanceID();
if (gunshyMod.panics.TryGetValue(instanceID, out var value) && !(Time.time >= value.until))
{
gunshyMod.ApplyDestination(value);
}
}
}
private void OnGunFired(Gun gun)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
if (Enabled == null || !Enabled.Value || !IsPlayerGun(gun))
{
return;
}
Vector3 val = (((Object)(object)gun.firePointTransform != (Object)null) ? gun.firePointTransform.position : ((Component)gun).transform.position);
AIBrain[] array = Il2CppArrayBase<AIBrain>.op_Implicit(Object.FindObjectsOfType<AIBrain>());
if (array == null)
{
return;
}
float value = HearRadius.Value;
float num = value * value;
int num2 = 0;
foreach (AIBrain val2 in array)
{
if ((Object)(object)val2 == (Object)null)
{
continue;
}
bool flag = false;
try
{
flag = val2.isDead;
}
catch
{
}
if (flag || ((Object)(object)Player.RigManager != (Object)null && ((Component)val2).transform.IsChildOf(((Component)Player.RigManager).transform)))
{
continue;
}
BehaviourBaseNav behaviour = val2.behaviour;
if (!((Object)(object)behaviour == (Object)null))
{
Vector3 val3 = ((Component)val2).transform.position - val;
if (!(((Vector3)(ref val3)).sqrMagnitude > num))
{
Scare(behaviour, val2, val);
num2++;
}
}
}
if (num2 > 0 && Time.time >= nextLogTime)
{
nextLogTime = Time.time + 1f;
((MelonBase)this).LoggerInstance.Msg("Spooked " + num2 + " NPC" + ((num2 == 1) ? "" : "s") + ".");
}
}
private void Scare(BehaviourBaseNav behaviour, AIBrain brain, Vector3 shot)
{
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
if (!diagScareLogged)
{
diagScareLogged = true;
NavMeshAgent val = FindAgent(behaviour, brain);
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] behaviour=" + ((object)behaviour).GetType().FullName);
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] FindAgent=" + (((Object)(object)val == (Object)null) ? "NULL" : (((Object)val).name + " active=" + ((Behaviour)val).isActiveAndEnabled + " onNav=" + val.isOnNavMesh)));
if ((Object)(object)val == (Object)null)
{
DumpBehaviourDiagnostics(behaviour, brain);
}
}
int instanceID = ((Object)behaviour).GetInstanceID();
float until = Time.time + FleeSeconds.Value;
if (!panics.TryGetValue(instanceID, out var value))
{
NavMeshAgent val2 = FindAgent(behaviour, brain);
value = new Panic
{
behaviour = behaviour,
agent = val2,
originalSpeed = (((Object)(object)val2 != (Object)null) ? val2.speed : 3.5f),
originalAccel = (((Object)(object)val2 != (Object)null) ? val2.acceleration : 8f),
originalBraking = ((Object)(object)val2 == (Object)null || val2.autoBraking),
awayFrom = shot,
until = until,
repathAt = 0f,
dest = ((Component)behaviour).transform.position
};
panics[instanceID] = value;
DropTarget(behaviour);
PushRoam(behaviour);
Shove(behaviour, ((Component)behaviour).transform.position - shot, 2.1f);
}
else
{
value.until = until;
value.awayFrom = shot;
value.repathAt = 0f;
if ((Object)(object)value.agent == (Object)null)
{
value.agent = FindAgent(behaviour, brain);
if ((Object)(object)value.agent != (Object)null)
{
value.originalSpeed = value.agent.speed;
value.originalAccel = value.agent.acceleration;
value.originalBraking = value.agent.autoBraking;
}
}
}
Drive(value, Time.time);
}
private void Drive(Panic panic, float now)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
PushRoam(panic.behaviour);
if (now >= panic.repathAt)
{
panic.dest = PickFleePoint(((Component)panic.behaviour).transform.position, panic.awayFrom);
panic.repathAt = now + 0.4f;
}
ApplyDestination(panic);
}
private void ApplyDestination(Panic panic)
{
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
NavMeshAgent agent = panic.agent;
if ((Object)(object)agent == (Object)null)
{
if (!diagAgentLogged)
{
diagAgentLogged = true;
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] ApplyDestination: agent is NULL.");
}
return;
}
if (!diagAgentLogged)
{
diagAgentLogged = true;
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] agent=" + ((Object)agent).name + " active=" + ((Behaviour)agent).isActiveAndEnabled + " onNav=" + agent.isOnNavMesh + " speed=" + agent.speed);
}
try
{
if (((Behaviour)agent).isActiveAndEnabled && agent.isOnNavMesh)
{
agent.speed = FleeSpeed.Value;
agent.acceleration = 40f;
agent.angularSpeed = 720f;
agent.autoBraking = false;
agent.stoppingDistance = 0.4f;
if (!agent.SetDestination(panic.dest) && !diagSetDestLogged)
{
diagSetDestLogged = true;
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] SetDestination returned FALSE.");
}
}
}
catch (Exception ex)
{
if (!loggedDriveError)
{
loggedDriveError = true;
((MelonBase)this).LoggerInstance.Warning("Could not drive a fleeing agent: " + ex.Message);
}
}
}
private static Vector3 PickFleePoint(Vector3 from, Vector3 threat)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = from - threat;
val.y = 0f;
if (((Vector3)(ref val)).sqrMagnitude < 0.04f)
{
((Vector3)(ref val))..ctor(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f));
}
((Vector3)(ref val)).Normalize();
float num = Random.Range(10f, 16f);
Vector3 result = from;
float num2 = -1f;
NavMeshHit val3 = default(NavMeshHit);
for (int i = 0; i < 9; i++)
{
float num3 = ((i % 2 == 0) ? 1f : (-1f));
float num4 = ((i == 0) ? 0f : (num3 * (15f * (float)((i + 1) / 2))));
Vector3 val2 = Quaternion.Euler(0f, num4, 0f) * val;
if (NavMesh.SamplePosition(from + val2 * num, ref val3, 7f, -1))
{
float num5 = Vector3.Dot(((NavMeshHit)(ref val3)).position - from, val);
if (num5 > num2)
{
num2 = num5;
result = ((NavMeshHit)(ref val3)).position;
}
}
}
return result;
}
private static NavMeshAgent FindAgent(BehaviourBaseNav behaviour, AIBrain brain)
{
if ((Object)(object)behaviour == (Object)null)
{
return null;
}
NavMeshAgent val = TryGetAgentMember(behaviour);
if ((Object)(object)val != (Object)null)
{
return val;
}
if ((Object)(object)brain != (Object)null)
{
val = TryGetAgentMember(brain);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
try
{
val = ((Component)behaviour).GetComponent<NavMeshAgent>();
if ((Object)(object)val != (Object)null)
{
return val;
}
}
catch
{
}
try
{
val = ((Component)behaviour).GetComponentInChildren<NavMeshAgent>(true);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
catch
{
}
try
{
val = ((Component)behaviour).GetComponentInChildren<NavMeshAgent>();
if ((Object)(object)val != (Object)null)
{
return val;
}
}
catch
{
}
try
{
Transform val2 = ((Component)behaviour).transform;
while ((Object)(object)val2 != (Object)null)
{
val = ((Component)val2).GetComponent<NavMeshAgent>();
if ((Object)(object)val != (Object)null)
{
return val;
}
try
{
val = ((Component)val2).GetComponentInChildren<NavMeshAgent>(true);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
catch
{
}
val2 = val2.parent;
}
}
catch
{
}
return null;
}
private static NavMeshAgent TryGetAgentMember(object obj)
{
if (obj == null)
{
return null;
}
Type type = obj.GetType();
int num = 0;
while (type != null && type != typeof(object) && num < 8)
{
try
{
FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (!typeof(NavMeshAgent).IsAssignableFrom(fieldInfo.FieldType))
{
continue;
}
try
{
object? value = fieldInfo.GetValue(obj);
NavMeshAgent val = (NavMeshAgent)((value is NavMeshAgent) ? value : null);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
catch
{
}
}
}
catch
{
}
try
{
PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in properties)
{
if (!typeof(NavMeshAgent).IsAssignableFrom(propertyInfo.PropertyType))
{
continue;
}
try
{
object? value2 = propertyInfo.GetValue(obj, null);
NavMeshAgent val2 = (NavMeshAgent)((value2 is NavMeshAgent) ? value2 : null);
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
catch
{
}
}
}
catch
{
}
type = type.BaseType;
num++;
}
return null;
}
private void DumpBehaviourDiagnostics(BehaviourBaseNav behaviour, AIBrain brain)
{
if (diagDumpLogged)
{
return;
}
diagDumpLogged = true;
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] ========= DUMP START =========");
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] === BehaviourBaseNav members ===");
DumpTypeMembers(((object)behaviour).GetType());
if ((Object)(object)brain != (Object)null)
{
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] === AIBrain members ===");
DumpTypeMembers(((object)brain).GetType());
}
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] === Scene NavMeshAgents ===");
try
{
NavMeshAgent[] array = Il2CppArrayBase<NavMeshAgent>.op_Implicit(Object.FindObjectsOfType<NavMeshAgent>());
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] count=" + ((array != null) ? array.Length : 0));
if (array != null)
{
int num = 0;
NavMeshAgent[] array2 = array;
foreach (NavMeshAgent val in array2)
{
if (!((Object)(object)val == (Object)null))
{
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] " + SafePath(((Component)val).transform) + " enabled=" + ((Behaviour)val).enabled + " onNav=" + val.isOnNavMesh);
num++;
if (num >= 25)
{
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] ...(more omitted)");
break;
}
}
}
}
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] scene scan failed: " + ex.Message);
}
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] ========= DUMP END =========");
}
private void DumpTypeMembers(Type t)
{
int num = 0;
while (t != null && t != typeof(object) && num < 6)
{
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] " + t.FullName);
try
{
FieldInfo[] fields = t.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
bool flag = fieldInfo.Name.IndexOf("agent", StringComparison.OrdinalIgnoreCase) >= 0 || fieldInfo.Name.IndexOf("nav", StringComparison.OrdinalIgnoreCase) >= 0;
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] " + (flag ? "** " : " ") + "F " + fieldInfo.FieldType.Name + " " + fieldInfo.Name);
}
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] (fields error: " + ex.GetType().Name + ")");
}
try
{
PropertyInfo[] properties = t.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in properties)
{
bool flag2 = propertyInfo.Name.IndexOf("agent", StringComparison.OrdinalIgnoreCase) >= 0 || propertyInfo.Name.IndexOf("nav", StringComparison.OrdinalIgnoreCase) >= 0;
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] " + (flag2 ? "** " : " ") + "P " + propertyInfo.PropertyType.Name + " " + propertyInfo.Name);
}
}
catch (Exception ex2)
{
((MelonBase)this).LoggerInstance.Msg("[Gunshy][DIAG] (props error: " + ex2.GetType().Name + ")");
}
t = t.BaseType;
num++;
}
}
private static string SafePath(Transform t)
{
if ((Object)(object)t == (Object)null)
{
return "<null>";
}
string text = ((Object)t).name;
int num = 0;
while ((Object)(object)t.parent != (Object)null && num < 6)
{
t = t.parent;
text = ((Object)t).name + "/" + text;
num++;
}
return text;
}
private static void PushRoam(BehaviourBaseNav behaviour)
{
if ((Object)(object)behaviour == (Object)null)
{
return;
}
try
{
MethodInfo methodInfo = AccessTools.Method(((object)behaviour).GetType(), "SetMentalState", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(BehaviourBaseNav), "SetMentalState", (Type[])null, (Type[])null);
if (methodInfo != null && TryInvokeState(methodInfo, behaviour))
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(((object)behaviour).GetType(), "mentalState") ?? AccessTools.Field(typeof(BehaviourBaseNav), "mentalState");
if (!(fieldInfo == null) && fieldInfo.FieldType.IsEnum)
{
object obj = FindRoam(fieldInfo.FieldType);
if (obj != null && !obj.Equals(fieldInfo.GetValue(behaviour)))
{
fieldInfo.SetValue(behaviour, obj);
}
}
}
catch
{
}
}
private static bool TryInvokeState(MethodInfo method, BehaviourBaseNav behaviour)
{
ParameterInfo[] parameters = method.GetParameters();
if (parameters.Length != 1 || !parameters[0].ParameterType.IsEnum)
{
return false;
}
object obj = FindRoam(parameters[0].ParameterType);
if (obj == null)
{
return false;
}
method.Invoke(behaviour, new object[1] { obj });
return true;
}
private static object FindRoam(Type enumType)
{
string[] names = Enum.GetNames(enumType);
for (int i = 0; i < names.Length; i++)
{
if (names[i].Equals("Roam", StringComparison.OrdinalIgnoreCase))
{
return Enum.Parse(enumType, names[i]);
}
}
for (int j = 0; j < names.Length; j++)
{
if (names[j].IndexOf("Roam", StringComparison.OrdinalIgnoreCase) >= 0)
{
return Enum.Parse(enumType, names[j]);
}
}
return null;
}
private static void DropTarget(BehaviourBaseNav behaviour)
{
for (int i = 0; i < TargetFields.Length; i++)
{
FieldInfo fieldInfo = AccessTools.Field(((object)behaviour).GetType(), TargetFields[i]) ?? AccessTools.Field(typeof(BehaviourBaseNav), TargetFields[i]);
if (!(fieldInfo == null))
{
try
{
fieldInfo.SetValue(behaviour, null);
}
catch
{
}
}
}
}
private static void Shove(BehaviourBaseNav behaviour, Vector3 away, float strength)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
away.y = 0f;
if (((Vector3)(ref away)).sqrMagnitude < 0.001f)
{
return;
}
((Vector3)(ref away)).Normalize();
Rigidbody[] array = Il2CppArrayBase<Rigidbody>.op_Implicit(((Component)behaviour).GetComponentsInChildren<Rigidbody>());
if (array == null)
{
return;
}
int num = 0;
foreach (Rigidbody val in array)
{
if (!((Object)(object)val == (Object)null) && !val.isKinematic)
{
val.AddForce(away * strength, (ForceMode)2);
num++;
if (num >= 8)
{
break;
}
}
}
}
private static void Restore(Panic panic)
{
NavMeshAgent agent = panic.agent;
if ((Object)(object)agent == (Object)null)
{
return;
}
try
{
agent.speed = panic.originalSpeed;
agent.acceleration = panic.originalAccel;
agent.autoBraking = panic.originalBraking;
}
catch
{
}
}
private void ClearPanics()
{
foreach (KeyValuePair<int, Panic> panic in panics)
{
Restore(panic.Value);
}
panics.Clear();
}
private static bool IsPlayerGun(Gun gun)
{
if ((Object)(object)gun == (Object)null || !Player.HandsExist)
{
return false;
}
Gun componentInHand = Player.GetComponentInHand<Gun>(Player.LeftHand);
if ((Object)(object)componentInHand != (Object)null && ((Object)componentInHand).GetInstanceID() == ((Object)gun).GetInstanceID())
{
return true;
}
Gun componentInHand2 = Player.GetComponentInHand<Gun>(Player.RightHand);
if ((Object)(object)componentInHand2 != (Object)null)
{
return ((Object)componentInHand2).GetInstanceID() == ((Object)gun).GetInstanceID();
}
return false;
}
}