using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AIGraph;
using API;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using Enemies;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Runtime.InteropServices;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using MindControl.API;
using MindControl.BepInEx;
using Player;
using ReplayRecorder;
using ReplayRecorder.API.Attributes;
using ReplayRecorder.Net;
using SNetwork;
using StateMachines;
using UnityEngine;
using UnityEngine.AI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MindControl")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8baf03d82fdb545d3f993fb4ecd001a7d22a9c7d")]
[assembly: AssemblyProduct("MindControl")]
[assembly: AssemblyTitle("MindControl")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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]
[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;
}
}
}
namespace API
{
internal static class APILogger
{
private static readonly ManualLogSource logger;
static APILogger()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
logger = new ManualLogSource("Rand-API");
Logger.Sources.Add((ILogSource)(object)logger);
}
private static string Format(string module, object msg)
{
return $"[{module}]: {msg}";
}
public static void Info(string module, object data)
{
logger.LogMessage((object)Format(module, data));
}
public static void Verbose(string module, object data)
{
}
public static void Log(object data)
{
logger.LogDebug((object)Format("MindControl", data));
}
public static void Debug(object data)
{
if (ConfigManager.Debug)
{
Log(data);
}
}
public static void Warn(object data)
{
logger.LogWarning((object)Format("MindControl", data));
}
public static void Error(object data)
{
logger.LogError((object)Format("MindControl", data));
}
}
}
namespace MindControl
{
[HarmonyPatch]
public class EnemyController : MonoBehaviour
{
[HarmonyPatch]
internal static class Patches
{
public static bool DontRecurse = false;
private static bool patch = true;
[HarmonyPatch(typeof(EnemySync), "OnSpawn")]
[HarmonyPostfix]
private static void Postfix_OnSpawn(EnemySync __instance, pEnemySpawnData spawnData)
{
if (SNet.IsMaster)
{
EnemyAgent agent = __instance.m_agent;
if (!((Object)(object)((Component)agent).GetComponent<PouncerBehaviour>() != (Object)null) && !agent.EnemyBehaviorData.IsFlyer)
{
((Component)agent).gameObject.AddComponent<EnemyController>().AssignAgent(agent);
}
}
}
[HarmonyPatch(typeof(EnemyBehaviour), "UpdateState")]
[HarmonyPrefix]
private static void Prefix_UpdateState(EnemyBehaviour __instance)
{
if (!DontRecurse && !(__instance.m_updatebehaviour >= Clock.Time) && controllers.TryGetValue(((Agent)__instance.m_ai.m_enemyAgent).GlobalID, out EnemyController value))
{
value.UpdateBehaviour();
}
}
[HarmonyPatch(typeof(EB_InCombat_MoveToPoint), "UpdateBehaviour")]
[HarmonyPrefix]
private static bool Prefix_UpdateBehaviour(EB_InCombat_MoveToPoint __instance)
{
if (!SNet.IsMaster)
{
return true;
}
EnemyAI ai = ((EB_StateBase)__instance).m_ai;
if (!controllers.TryGetValue(((Agent)ai.m_enemyAgent).GlobalID, out EnemyController value) || !value.IsControlled)
{
return true;
}
if (value.commandBuffer.Peek().type == Command.Type.Attack)
{
return true;
}
return false;
}
[HarmonyPatch(typeof(EnemyCourseNavigation), "UpdateTracking")]
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void UpdateTracking(EnemyCourseNavigation __instance)
{
if (!patch || !SNet.IsMaster)
{
return;
}
EnemyAI aI = __instance.m_owner.AI;
if (controllers.TryGetValue(((Agent)aI.m_enemyAgent).GlobalID, out EnemyController value) && value.IsControlled)
{
Command command = value.commandBuffer.Peek();
if (command.type == Command.Type.Attack && (Object)(object)command.target != (Object)null)
{
patch = false;
((AgentAI)aI).SetTarget((Agent)(object)command.target);
patch = true;
}
else if (command.type == Command.Type.MoveAttack && (Object)(object)value.currentTarget != (Object)null)
{
patch = false;
((AgentAI)aI).SetTarget((Agent)(object)value.currentTarget);
patch = true;
}
}
}
[HarmonyPatch(typeof(EB_InCombat), "TryAttacks")]
[HarmonyPrefix]
private static bool Prefix_TryAttacks(EB_InCombat __instance, ref bool __result)
{
if (!SNet.IsMaster)
{
return true;
}
EnemyAI ai = ((EB_StateBase)__instance).m_ai;
if (!controllers.TryGetValue(((Agent)ai.m_enemyAgent).GlobalID, out EnemyController value) || !value.IsControlled)
{
return true;
}
Command.Type type = value.commandBuffer.Peek().type;
if ((uint)(type - 1) <= 1u)
{
return true;
}
__result = false;
return false;
}
[HarmonyPatch(typeof(EB_InCombat), "TryStrafe")]
[HarmonyPrefix]
private static bool Prefix_TryStrafe(EB_InCombat __instance, ref bool __result)
{
if (!SNet.IsMaster)
{
return true;
}
EnemyAI ai = ((EB_StateBase)__instance).m_ai;
if (!controllers.TryGetValue(((Agent)ai.m_enemyAgent).GlobalID, out EnemyController value) || !value.IsControlled)
{
return true;
}
if (value.commandBuffer.Peek().type == Command.Type.Attack)
{
if ((((AgentAI)ai).Abilities.HasAbility((AgentAbility)1) && !((AgentAI)ai).Abilities.IsAbilityReady((AgentAbility)1, 0)) || (((AgentAI)ai).Abilities.HasAbility((AgentAbility)2) && !((AgentAI)ai).Abilities.IsAbilityReady((AgentAbility)2, 0)))
{
return true;
}
__result = false;
return false;
}
__result = false;
return false;
}
[HarmonyPatch(typeof(EB_InCombat), "TryScream")]
[HarmonyPrefix]
private static bool Prefix_TryScream(EB_InCombat __instance, ref bool __result)
{
if (!SNet.IsMaster)
{
return true;
}
EnemyAI ai = ((EB_StateBase)__instance).m_ai;
if (!controllers.TryGetValue(((Agent)ai.m_enemyAgent).GlobalID, out EnemyController value) || !value.IsControlled)
{
return true;
}
__result = false;
return false;
}
[HarmonyPatch(typeof(EB_InCombat), "TryUpdateNavigation")]
[HarmonyPrefix]
private static bool Prefix_TryUpdateNavigation(EB_InCombat __instance, out bool __result, EnemyCourseNavigationMode currentExpectedMode)
{
__result = false;
if (!controllers.TryGetValue(((Agent)((EB_StateBase)__instance).m_ai.m_enemyAgent).GlobalID, out EnemyController value) || !value.IsControlled)
{
return true;
}
return false;
}
[HarmonyPatch(typeof(EB_InCombat_MoveToPoint), "UpdateBehaviourStuckingCheck")]
[HarmonyPrefix]
private static bool Prefix_UpdateBehaviourStuckingCheck(EB_InCombat_MoveToPoint __instance)
{
if (!controllers.TryGetValue(((Agent)((EB_StateBase)__instance).m_ai.m_enemyAgent).GlobalID, out EnemyController value) || !value.IsControlled)
{
return true;
}
return false;
}
}
public class Command
{
public enum Type
{
Move,
Attack,
MoveAttack
}
public Type type;
public PlayerAgent? target;
public Vector3 position;
public Command(Vector3 pos)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
type = Type.Move;
position = pos;
}
public Command(PlayerAgent target)
{
type = Type.Attack;
this.target = target;
}
}
private class NavData
{
public Dictionary<int, int> nodeDistanceMap = new Dictionary<int, int>();
}
public static Dictionary<int, EnemyController> controllers = new Dictionary<int, EnemyController>();
private int globalId;
private EnemyAgent agent;
private EnemyAI ai;
private EnemyLocomotion locomotion;
private EnemyBehaviour behaviour;
private EnemyBehaviourData behaviourData;
private EB_InCombat EBInCombat;
public Queue<Command> commandBuffer = new Queue<Command>();
private PlayerAgent? currentTarget;
private Vector3 destination;
private AIG_CourseNode? destinationCourseNode;
private AIG_CoursePortal? targetPortal;
private Vector3 towardsPortalPosition;
private Vector3 throughPortalPosition;
private static Dictionary<int, NavData> navDataMap = new Dictionary<int, NavData>();
public bool IsControlled
{
get
{
if (agent.m_alive)
{
return commandBuffer.Count > 0;
}
return false;
}
}
public void AssignAgent(EnemyAgent agent)
{
this.agent = agent;
globalId = ((Agent)this.agent).GlobalID;
locomotion = agent.Locomotion;
ai = agent.AI;
behaviour = ai.m_behaviour;
EBInCombat = ((Il2CppObjectBase)((StateMachine<EB_StateBase>)(object)behaviour).m_states[5]).Cast<EB_InCombat>();
behaviourData = ai.m_behaviourData;
controllers.Add(globalId, this);
}
private void OnDestroy()
{
controllers.Remove(globalId);
}
public void AddPosition(Vector3 pos)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
commandBuffer.Enqueue(new Command(pos));
}
public void AddAttackPosition(Vector3 pos)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
Command command = new Command(pos);
command.type = Command.Type.MoveAttack;
commandBuffer.Enqueue(command);
}
public void AddTarget(PlayerAgent target)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
if (target.m_alive)
{
commandBuffer.Enqueue(new Command(target));
}
else
{
commandBuffer.Enqueue(new Command(((Agent)target).m_position));
}
}
public void ClearCommands()
{
if (commandBuffer.Count > 0)
{
commandBuffer.Clear();
behaviourData.m_advanceTimer = 0f;
Patches.DontRecurse = true;
behaviour.ChangeState((EB_States)5);
behaviour.m_updatebehaviour = 0f;
((StateMachine<EB_StateBase>)(object)behaviour).UpdateState();
Patches.DontRecurse = false;
}
}
public void Suicide()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
agent.Damage.BulletDamage(100000f, (Agent)null, ((Component)localPlayerAgent).transform.position, ((Agent)localPlayerAgent).TargetLookDir, Vector3.up, true, 0, 100f, 100f, 0u);
}
public void UpdateBehaviour()
{
if (IsControlled)
{
Command command = commandBuffer.Peek();
switch (command.type)
{
case Command.Type.Move:
case Command.Type.MoveAttack:
MoveCommand(command);
break;
case Command.Type.Attack:
AttackCommand(command);
break;
}
}
}
private void AttackCommand(Command command)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
if ((int)((AgentAI)ai).Mode != 1)
{
((AgentAI)ai).Mode = (AgentMode)1;
((AgentAI)ai).ModeChange();
}
if (((Il2CppObjectBase)((StateMachine<EB_StateBase>)(object)behaviour).m_currentState).TryCast<EB_Hibernating>() != null)
{
locomotion.ChangeState((ES_StateEnum)2);
Patches.DontRecurse = true;
behaviour.ChangeState((EB_States)5);
Patches.DontRecurse = false;
}
behaviourData.m_advanceTimer = 0f;
if (!((Object)(object)command.target == (Object)null))
{
if (((AgentAI)ai).m_target == null || (Object)(object)((AgentAI)ai).m_target.m_agent == (Object)null || ((AgentAI)ai).m_target.m_agent.GlobalID != ((Agent)command.target).GlobalID)
{
((AgentAI)ai).SetTarget((Agent)(object)command.target);
}
if (!((Agent)command.target).Alive)
{
commandBuffer.Dequeue();
APILogger.Debug("Target dead!");
}
}
}
private void MoveCommand(Command command)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Invalid comparison between Unknown and I4
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Invalid comparison between Unknown and I4
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Invalid comparison between Unknown and I4
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Invalid comparison between Unknown and I4
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Invalid comparison between Unknown and I4
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Invalid comparison between Unknown and I4
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Invalid comparison between Unknown and I4
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0226: Invalid comparison between Unknown and I4
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Invalid comparison between Unknown and I4
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
//IL_0512: Unknown result type (might be due to invalid IL or missing references)
//IL_0312: Unknown result type (might be due to invalid IL or missing references)
//IL_0322: Unknown result type (might be due to invalid IL or missing references)
//IL_0386: Unknown result type (might be due to invalid IL or missing references)
//IL_038c: Unknown result type (might be due to invalid IL or missing references)
//IL_0391: Unknown result type (might be due to invalid IL or missing references)
//IL_0396: Unknown result type (might be due to invalid IL or missing references)
//IL_0401: Unknown result type (might be due to invalid IL or missing references)
//IL_0406: Unknown result type (might be due to invalid IL or missing references)
//IL_0417: Unknown result type (might be due to invalid IL or missing references)
//IL_041c: Unknown result type (might be due to invalid IL or missing references)
//IL_043f: Unknown result type (might be due to invalid IL or missing references)
//IL_0446: Invalid comparison between Unknown and I4
//IL_044d: Unknown result type (might be due to invalid IL or missing references)
//IL_0454: Invalid comparison between Unknown and I4
//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
//IL_045b: Unknown result type (might be due to invalid IL or missing references)
//IL_0462: Invalid comparison between Unknown and I4
//IL_0470: Unknown result type (might be due to invalid IL or missing references)
//IL_048f: Unknown result type (might be due to invalid IL or missing references)
//IL_0495: Unknown result type (might be due to invalid IL or missing references)
//IL_049a: Unknown result type (might be due to invalid IL or missing references)
//IL_049f: Unknown result type (might be due to invalid IL or missing references)
//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
ES_StateEnum val = (ES_StateEnum)((MachineState<ES_Base>)(object)((StateMachine<ES_Base>)(object)locomotion).m_currentState).ENUM_ID;
Vector3 val2;
if (command.type == Command.Type.MoveAttack)
{
if ((Object)(object)currentTarget != (Object)null)
{
float max = agent.EnemyBehaviorData.MeleeAttackDistance.Max;
float max2 = agent.EnemyBehaviorData.RangedAttackDistance.Max;
val2 = ((Agent)currentTarget).m_position - ((Agent)agent).m_position;
float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
if (((AgentAI)ai).Abilities.HasAbility((AgentAbility)1) && sqrMagnitude >= max && ((AgentAI)ai).Abilities.HasAbility((AgentAbility)2) && sqrMagnitude >= max2)
{
currentTarget = null;
}
}
if ((Object)(object)currentTarget == (Object)null)
{
float num = float.MaxValue;
Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
while (enumerator.MoveNext())
{
PlayerAgent current = enumerator.Current;
if (current.m_alive)
{
val2 = ((Agent)current).m_position - ((Agent)agent).m_position;
float sqrMagnitude2 = ((Vector3)(ref val2)).sqrMagnitude;
if (sqrMagnitude2 < num)
{
num = sqrMagnitude2;
currentTarget = current;
}
}
}
}
if ((Object)(object)currentTarget != (Object)null && currentTarget.m_alive)
{
((AgentAI)ai).SetTarget((Agent)(object)currentTarget);
if (EBInCombat.TryAttacks() || val - 18 <= 1 || (int)val == 23)
{
return;
}
}
}
if ((int)val <= 10)
{
if ((int)val == 7 || (int)val == 10)
{
return;
}
}
else if (val - 24 <= 1 || (int)val == 29)
{
return;
}
if ((int)((AgentAI)ai).Mode != 1)
{
((AgentAI)ai).Mode = (AgentMode)1;
((AgentAI)ai).ModeChange();
}
if (((AgentAI)ai).m_target == null || !((AgentAI)ai).m_target.m_hasLineOfSight)
{
EnemyAgent enemyAgent = ai.m_enemyAgent;
val2 = destination - ((Component)ai).transform.position;
((Agent)enemyAgent).TargetLookDir = ((Vector3)(ref val2)).normalized;
}
else
{
((Agent)ai.m_enemyAgent).TargetLookDir = ((AgentAI)ai).m_target.m_dir;
}
if ((int)val != 2)
{
locomotion.ChangeState((ES_StateEnum)2);
}
if (((MachineState<EB_StateBase>)(object)((StateMachine<EB_StateBase>)(object)behaviour).m_currentState).ENUM_ID != 6)
{
Patches.DontRecurse = true;
behaviour.ChangeState((EB_States)6);
behaviour.m_updatebehaviour = 0f;
((StateMachine<EB_StateBase>)(object)behaviour).UpdateState();
Patches.DontRecurse = false;
}
EBInCombat.UpdateAvoidance();
if (!((AgentAI)ai).m_navMeshAgent.isOnNavMesh)
{
return;
}
NavMeshHit val3 = default(NavMeshHit);
if (NavMesh.SamplePosition(command.position, ref val3, 1f, 1))
{
destination = ((NavMeshHit)(ref val3)).position;
}
else
{
destination = command.position;
}
destinationCourseNode = GetNode(destination);
if (destinationCourseNode != null)
{
AIG_CourseNode courseNode = ((Agent)agent).CourseNode;
if (courseNode.NodeID != destinationCourseNode.NodeID && courseNode.m_dimension.DimensionIndex == destinationCourseNode.m_dimension.DimensionIndex)
{
NavData navData = GetNavData(destinationCourseNode);
int num2 = int.MaxValue;
float num3 = float.MaxValue;
AIG_CoursePortal val4 = null;
Enumerator<AIG_CoursePortal> enumerator2 = courseNode.m_portals.GetEnumerator();
while (enumerator2.MoveNext())
{
AIG_CoursePortal current2 = enumerator2.Current;
AIG_CourseNode oppositeNode = current2.GetOppositeNode(courseNode);
int num4 = navData.nodeDistanceMap[oppositeNode.NodeID];
val2 = current2.m_position - destination;
float sqrMagnitude3 = ((Vector3)(ref val2)).sqrMagnitude;
if (val4 == null || num4 < num2 || (num4 == num2 && sqrMagnitude3 < num3))
{
val4 = current2;
num2 = num4;
num3 = sqrMagnitude3;
}
}
if (val4 != null)
{
if (targetPortal == null || ((Il2CppObjectBase)targetPortal).Pointer != ((Il2CppObjectBase)val4).Pointer)
{
targetPortal = val4;
towardsPortalPosition = val4.RandomPositionOn_TowardsNode(courseNode);
throughPortalPosition = val4.RandomPositionOn_TowardsNode(val4.GetOppositeNode(courseNode));
}
LG_Gate gate = val4.Gate;
iLG_Door_Core val5 = ((gate != null) ? gate.SpawnedDoor : null);
if (val5 != null)
{
if ((int)val5.LastStatus != 11 && (int)val5.LastStatus != 10 && (int)val5.LastStatus != 16)
{
((AgentAI)ai).m_navMeshAgent.destination = towardsPortalPosition;
if (EB_InCombat_MoveToNextNode_DestroyDoor.s_globalRetryTimer < Clock.Time)
{
val2 = ((Agent)agent).m_position - towardsPortalPosition;
if (((Vector3)(ref val2)).sqrMagnitude < 6.25f)
{
EB_InCombat_MoveToNextNode_DestroyDoor.s_globalRetryTimer = Clock.Time + Random.Range(0.5f, 1f);
val5.AttemptDamage((eDoorDamageType)0, ((Agent)agent).m_position, (Agent)(object)agent);
}
}
return;
}
if (num2 > 0)
{
((AgentAI)ai).m_navMeshAgent.destination = throughPortalPosition;
return;
}
}
}
}
else
{
targetPortal = null;
}
}
((AgentAI)ai).m_navMeshAgent.destination = command.position;
}
private AIG_CourseNode? GetNode(Vector3 position)
{
//IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references)
AIG_INode val = default(AIG_INode);
AIG_NodeCluster val2 = default(AIG_NodeCluster);
if (AIG_GeomorphNodeVolume.TryGetNode(0, Dimension.GetDimensionFromPos(position).DimensionIndex, position, ref val, false) && AIG_NodeCluster.TryGetNodeCluster(val.ClusterID, ref val2))
{
if (val2.CourseNode == null)
{
return null;
}
return val2.CourseNode;
}
return null;
}
private NavData GetNavData(AIG_CourseNode destination)
{
if (!navDataMap.ContainsKey(destination.NodeID))
{
NavData navData = new NavData();
AIG_SearchID.IncrementSearchID();
ushort searchID = AIG_SearchID.SearchID;
Queue<(AIG_CourseNode, int)> queue = new Queue<(AIG_CourseNode, int)>();
queue.Enqueue((destination, 0));
((AIG_CourseGraphMember)destination).m_searchID = searchID;
while (queue.Count > 0)
{
(AIG_CourseNode, int) tuple = queue.Dequeue();
AIG_CourseNode item = tuple.Item1;
int item2 = tuple.Item2;
Enumerator<AIG_CoursePortal> enumerator = item.m_portals.GetEnumerator();
while (enumerator.MoveNext())
{
AIG_CourseNode oppositeNode = enumerator.Current.GetOppositeNode(item);
if (((AIG_CourseGraphMember)oppositeNode).m_searchID != searchID)
{
((AIG_CourseGraphMember)oppositeNode).m_searchID = searchID;
queue.Enqueue((oppositeNode, item2 + 1));
}
}
navData.nodeDistanceMap.Add(item.NodeID, item2);
}
navDataMap.Add(destination.NodeID, navData);
}
return navDataMap[destination.NodeID];
}
public static bool ChangeStatePrefix(StateMachine<EB_StateBase> __instance, EB_StateBase newState)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Invalid comparison between Unknown and I4
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Invalid comparison between Unknown and I4
EnemyController component = ((Component)__instance).GetComponent<EnemyController>();
if ((Object)(object)component == (Object)null || !component.IsControlled)
{
return true;
}
Command command = component.commandBuffer.Peek();
EB_States val = (EB_States)((MachineState<EB_StateBase>)(object)newState).ENUM_ID;
switch (command.type)
{
case Command.Type.Move:
case Command.Type.MoveAttack:
if ((int)val == 8 || (int)val == 7)
{
return false;
}
break;
}
return true;
}
[ReplayInit]
private static void Init()
{
APILogger.Debug("Clear old nav data.");
navDataMap.Clear();
}
}
}
namespace MindControl.NativePatches
{
internal static class ChangeStatePatches
{
private unsafe delegate void d_ChangeStateFromQueue(IntPtr _this, Il2CppMethodInfo* methodInfo);
private static INativeDetour? ChangeStateDetour;
private static d_ChangeStateFromQueue? orig_ChangeStateFromQueue;
internal unsafe static void ApplyNativePatch()
{
NativePatchAPI.AddChangeStatePrefix(EnemyController.ChangeStatePrefix);
INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)Il2CppClassPointerStore<StateMachine<ES_Base>>.NativeClassPtr);
for (int i = 0; i < val.MethodCount; i++)
{
INativeMethodInfoStruct val2 = UnityVersionHandler.Wrap(val.Methods[i]);
if (Marshal.PtrToStringAnsi(val2.Name) == "ChangeStateFromQueue")
{
ChangeStateDetour = INativeDetour.CreateAndApply<d_ChangeStateFromQueue>(val2.MethodPointer, (d_ChangeStateFromQueue)ChangeStatePatch, ref orig_ChangeStateFromQueue);
break;
}
}
}
private unsafe static void ChangeStatePatch(IntPtr _this, Il2CppMethodInfo* methodInfo)
{
StateMachine<EB_StateBase> val = new StateMachine<EB_StateBase>(_this);
if (val.CurrentState == null)
{
orig_ChangeStateFromQueue(_this, methodInfo);
return;
}
EB_StateBase state = val.m_stateQueue.Peek();
bool flag = true;
try
{
flag = NativePatchAPI.RunChangeStatePrefix(val, state);
}
catch (Exception ex)
{
APILogger.Error("Error running ChangeStatePrefix: " + ex.StackTrace);
}
if (flag)
{
orig_ChangeStateFromQueue(_this, methodInfo);
}
else
{
val.m_stateQueue.Dequeue();
}
try
{
NativePatchAPI.RunChangeStatePostfix(val, state);
}
catch (Exception ex2)
{
APILogger.Error("Error running ChangeStatePostfix: " + ex2.StackTrace);
}
}
}
}
namespace MindControl.BepInEx
{
public static class Module
{
public const string GUID = "randomuserhi.MindControl";
public const string Name = "MindControl";
public const string Version = "0.0.3";
}
public static class ConfigManager
{
public static ConfigFile configFile;
private static ConfigEntry<bool> debug;
public static bool Debug
{
get
{
return debug.Value;
}
set
{
debug.Value = value;
}
}
static ConfigManager()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "MindControl.cfg"), true);
debug = configFile.Bind<bool>("Debug", "enable", false, "Enables debug messages when true.");
}
}
[BepInPlugin("randomuserhi.MindControl", "MindControl", "0.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BasePlugin
{
private enum CommandType
{
MindControlPosition,
MindControlClear,
MindControlAttack,
MindControlAttackPosition,
MindControlKill
}
private static Harmony? harmony;
public override void Load()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
APILogger.Log("Plugin is loaded!");
harmony = new Harmony("randomuserhi.MindControl");
harmony.PatchAll();
ClassInjector.RegisterTypeInIl2Cpp<EnemyController>();
APILogger.Log("Debug is " + (ConfigManager.Debug ? "Enabled" : "Disabled"));
VNet.Register("MindControl", (Action<ulong, ArraySegment<byte>>)OnMindControlCommand);
VNet.Register("MindControl.SpawnEnemy", (Action<ulong, ArraySegment<byte>>)OnMindControlSpawnCommand);
}
private static AIG_CourseNode? GetNode(Vector3 position)
{
//IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references)
AIG_INode val = default(AIG_INode);
AIG_NodeCluster val2 = default(AIG_NodeCluster);
if (AIG_GeomorphNodeVolume.TryGetNode(0, Dimension.GetDimensionFromPos(position).DimensionIndex, position, ref val, false) && AIG_NodeCluster.TryGetNodeCluster(val.ClusterID, ref val2))
{
if (val2.CourseNode == null)
{
return null;
}
return val2.CourseNode;
}
return null;
}
private static void OnMindControlSpawnCommand(ulong from, ArraySegment<byte> buffer)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (!SNet.IsMaster)
{
return;
}
int num = 0;
Vector3 pos = BitHelper.ReadHalfVector3(buffer, ref num);
Quaternion rot = Quaternion.identity;
uint id = BitHelper.ReadUInt(buffer, ref num);
MainThread.Run((Action)delegate
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
AIG_CourseNode val = GetNode(pos);
if (val == null)
{
val = ((Agent)PlayerManager.GetLocalPlayerAgent()).CourseNode;
}
EnemyAllocator.Current.SpawnEnemy(id, val, (AgentMode)4, pos, rot, (EnemyGroup)null, -1);
});
}
private static void OnMindControlCommand(ulong from, ArraySegment<byte> buffer)
{
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
if (!SNet.IsMaster)
{
return;
}
int index = 0;
CommandType commandType = (CommandType)BitHelper.ReadUShort(buffer, ref index);
APILogger.Debug($"Received command of type '{commandType}'.");
switch (commandType)
{
case CommandType.MindControlClear:
{
int numEnemies5 = BitHelper.ReadInt(buffer, ref index);
APILogger.Debug($"Num Enemies '{numEnemies5}'.");
MainThread.Run((Action)delegate
{
for (int i = 0; i < numEnemies5; i++)
{
ushort key = BitHelper.ReadUShort(buffer, ref index);
if (EnemyController.controllers.TryGetValue(key, out EnemyController value) && value.commandBuffer.Count > 0)
{
value.ClearCommands();
}
}
});
break;
}
case CommandType.MindControlPosition:
{
Vector3 pos2 = BitHelper.ReadHalfVector3(buffer, ref index);
int numEnemies4 = BitHelper.ReadInt(buffer, ref index);
APILogger.Debug($"Num Enemies '{numEnemies4}'.");
MainThread.Run((Action)delegate
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < numEnemies4; i++)
{
ushort key = BitHelper.ReadUShort(buffer, ref index);
if (EnemyController.controllers.TryGetValue(key, out EnemyController value))
{
if (value.commandBuffer.Count > 0)
{
EnemyController.Command.Type type = value.commandBuffer.Peek().type;
if (type == EnemyController.Command.Type.Move || type == EnemyController.Command.Type.MoveAttack)
{
value.commandBuffer.Clear();
}
else
{
value.ClearCommands();
}
}
value.AddPosition(pos2);
}
}
});
break;
}
case CommandType.MindControlAttackPosition:
{
Vector3 pos = BitHelper.ReadHalfVector3(buffer, ref index);
int numEnemies3 = BitHelper.ReadInt(buffer, ref index);
APILogger.Debug($"Num Enemies '{numEnemies3}'.");
MainThread.Run((Action)delegate
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < numEnemies3; i++)
{
ushort key = BitHelper.ReadUShort(buffer, ref index);
if (EnemyController.controllers.TryGetValue(key, out EnemyController value))
{
if (value.commandBuffer.Count > 0)
{
EnemyController.Command.Type type = value.commandBuffer.Peek().type;
if (type == EnemyController.Command.Type.Move || type == EnemyController.Command.Type.MoveAttack)
{
value.commandBuffer.Clear();
}
else
{
value.ClearCommands();
}
}
value.AddAttackPosition(pos);
}
}
});
break;
}
case CommandType.MindControlAttack:
{
byte slot = BitHelper.ReadByte(buffer, ref index);
int numEnemies2 = BitHelper.ReadInt(buffer, ref index);
APILogger.Debug($"Num Enemies '{numEnemies2}'.");
MainThread.Run((Action)delegate
{
if (slot < ((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots).Length)
{
PlayerAgent val = ((Il2CppObjectBase)((Il2CppArrayBase<SNet_Slot>)(object)SNet.Slots.PlayerSlots)[(int)slot].player.m_playerAgent).TryCast<PlayerAgent>();
if ((Object)(object)val != (Object)null)
{
for (int i = 0; i < numEnemies2; i++)
{
ushort key = BitHelper.ReadUShort(buffer, ref index);
if (EnemyController.controllers.TryGetValue(key, out EnemyController value))
{
if (value.commandBuffer.Count > 0)
{
if (value.commandBuffer.Peek().type == EnemyController.Command.Type.Attack)
{
value.commandBuffer.Clear();
}
else
{
value.ClearCommands();
}
}
value.AddTarget(val);
}
}
}
}
});
break;
}
case CommandType.MindControlKill:
{
int numEnemies = BitHelper.ReadInt(buffer, ref index);
APILogger.Debug($"Num Enemies '{numEnemies}'.");
MainThread.Run((Action)delegate
{
for (int i = 0; i < numEnemies; i++)
{
ushort key = BitHelper.ReadUShort(buffer, ref index);
if (EnemyController.controllers.TryGetValue(key, out EnemyController value))
{
value.Suicide();
}
}
});
break;
}
default:
APILogger.Error($"No command defined for message of type '{commandType}'");
break;
}
}
}
}
namespace MindControl.API
{
public static class NativePatchAPI
{
public delegate bool ChangeStatePrefix(StateMachine<EB_StateBase> __instance, EB_StateBase state);
public delegate void ChangeStatePostfix(StateMachine<EB_StateBase> __instance, EB_StateBase state);
private static readonly List<ChangeStatePrefix> s_changePrefix = new List<ChangeStatePrefix>();
private static readonly List<ChangeStatePostfix> s_changePostfix = new List<ChangeStatePostfix>();
public static void AddChangeStatePrefix(ChangeStatePrefix detectPrefix)
{
s_changePrefix.Add(detectPrefix);
}
public static void AddChangeStatePostfix(ChangeStatePostfix detectPostfix)
{
s_changePostfix.Add(detectPostfix);
}
internal static bool RunChangeStatePrefix(StateMachine<EB_StateBase> __instance, EB_StateBase state)
{
bool flag = true;
foreach (ChangeStatePrefix item in s_changePrefix)
{
flag &= item(__instance, state);
}
return flag;
}
internal static void RunChangeStatePostfix(StateMachine<EB_StateBase> __instance, EB_StateBase state)
{
foreach (ChangeStatePostfix item in s_changePostfix)
{
item(__instance, state);
}
}
}
}