using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using IL.RoR2.CharacterAI;
using IL.RoR2.Items;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using On.RoR2.CharacterAI;
using RoR2;
using RoR2.CharacterAI;
using RoR2.UI;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MinionsChargeTeleporter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+617a243477cf88f76182892d1ea1b95373ac6df3")]
[assembly: AssemblyProduct("MinionsChargeTeleporter")]
[assembly: AssemblyTitle("MinionsChargeTeleporter")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace MinionsChargeTeleporter;
public class Items
{
public static ItemDef MinionLeash2 => new ItemDef
{
name = "MinionLeash2",
tier = (ItemTier)5
};
}
[BepInPlugin("com.woodyscales.minionschargeteleporter", "Minions Charge Teleporter", "1.0.0")]
public class MinionsChargeTeleporterMod : BaseUnityPlugin
{
private readonly Dictionary<HoldoutZoneController, HashSet<CharacterBody>> bodiesInZones = new Dictionary<HoldoutZoneController, HashSet<CharacterBody>>();
public void Awake()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
HoldoutZoneController.CountPlayersInRadius += new hook_CountPlayersInRadius(HoldoutZoneController_CountPlayersInRadius);
ChargeHoldoutZoneObjectiveTracker.ShouldBeFlashing += new hook_ShouldBeFlashing(ChargeHoldoutZoneObjectiveTracker_ShouldBeFlashing);
MinionLeashBodyBehavior.FixedUpdate += new Manipulator(MinionLeashBodyBehavior_FixedUpdate);
BaseAI.EvaluateSingleSkillDriver += new hook_EvaluateSingleSkillDriver(BaseAI_EvaluateSingleSkillDriver);
CombatDirector.PickPlayerAsSpawnTarget += new hook_PickPlayerAsSpawnTarget(CombatDirector_PickPlayerAsSpawnTarget);
BaseAI.FindEnemyHurtBox += new Manipulator(BaseAI_FindEnemyHurtBox);
ItemStealController.GetStolenInventoryInfo += new hook_GetStolenInventoryInfo(ItemStealController_GetStolenInventoryInfo);
}
private static StolenInventoryInfo ItemStealController_GetStolenInventoryInfo(orig_GetStolenInventoryInfo orig, ItemStealController self, Inventory victimInventory)
{
return self.stolenInventoryInfos?.FirstOrDefault((Func<StolenInventoryInfo, bool>)((StolenInventoryInfo x) => (Object)(object)x.victimInventory == (Object)(object)victimInventory));
}
private static bool ChargeHoldoutZoneObjectiveTracker_ShouldBeFlashing(orig_ShouldBeFlashing orig, ChargeHoldoutZoneObjectiveTracker self)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(((ObjectiveTracker)self).sourceDescriptor.master.teamIndex);
return teamMembers.Count((TeamComponent teamComponent) => self.holdoutZoneController.IsBodyInChargingRadius(teamComponent.body)) < teamMembers.Count((TeamComponent teamComponent) => teamComponent.body.isPlayerControlled);
}
private static void BaseAI_FindEnemyHurtBox(ILContext il)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
ILCursor val = new ILCursor(il);
val.GotoNext(new Func<Instruction, bool>[3]
{
(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
(Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "RoR2.CharacterAI.BaseAI", "enemySearch"),
(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, "RoR2.BullseyeSearch", "GetResults")
});
val.Index += 3;
val.GotoNext(Array.Empty<Func<Instruction, bool>>());
val.RemoveRange(2);
val.EmitDelegate<Func<IEnumerable<HurtBox>, IEnumerable<HurtBox>>>((Func<IEnumerable<HurtBox>, IEnumerable<HurtBox>>)FastSort);
}
private static IEnumerable<HurtBox> FastSort(IEnumerable<HurtBox> input)
{
Utils.SetHoldoutZones();
return input.OrderByDescending(delegate(HurtBox h)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
Vector3? position;
if (h == null)
{
position = null;
}
else
{
Transform transform = ((Component)h).transform;
position = ((transform != null) ? new Vector3?(transform.position) : null);
}
return Utils.IsInHoldoutZone(position);
}).ToArray();
}
private static SkillDriverEvaluation? BaseAI_EvaluateSingleSkillDriver(orig_EvaluateSingleSkillDriver orig, BaseAI self, ref SkillDriverEvaluation currentSkillDriverEvaluation, AISkillDriver aiSkillDriver, float myHealthFraction)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
if (Utils.WantsToStayInZone(self.master) && (int)aiSkillDriver.moveTargetType == 2)
{
return null;
}
return orig.Invoke(self, ref currentSkillDriverEvaluation, aiSkillDriver, myHealthFraction);
}
private static void MinionLeashBodyBehavior_FixedUpdate(ILContext il)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
ILCursor val = new ILCursor(il);
val.GotoNext(new Func<Instruction, bool>[4]
{
(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
(Instruction x) => ILPatternMatchingExt.MatchCall(x, "RoR2.Items.BaseItemBodyBehavior", "get_body"),
(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, "RoR2.CharacterBody", "get_master"),
(Instruction x) => ILPatternMatchingExt.MatchStloc(x, 0)
});
val.Index += 3;
val.EmitDelegate<Func<CharacterMaster, CharacterMaster>>((Func<CharacterMaster, CharacterMaster>)((CharacterMaster master) => (!Utils.WantsToStayInZone(master)) ? master : null));
}
private int HoldoutZoneController_CountPlayersInRadius(orig_CountPlayersInRadius orig, HoldoutZoneController holdoutZoneController, Vector3 origin, float chargingRadiusSqr, TeamIndex teamIndex)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
//IL_0014: 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_000a: Unknown result type (might be due to invalid IL or missing references)
if ((int)teamIndex != 1)
{
return orig.Invoke(holdoutZoneController, origin, chargingRadiusSqr, teamIndex);
}
return CountPlayersAndAlliesInRadius(holdoutZoneController, teamIndex);
}
private int CountPlayersAndAlliesInRadius(HoldoutZoneController holdoutZoneController, TeamIndex teamIndex)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
HashSet<CharacterBody> bodiesInHoldoutZone = Utils.GetBodiesInHoldoutZone(holdoutZoneController, teamIndex);
if (!bodiesInZones.TryGetValue(holdoutZoneController, out var value))
{
value = new HashSet<CharacterBody>();
}
bodiesInZones[holdoutZoneController] = bodiesInHoldoutZone;
CharacterBody[] array = bodiesInHoldoutZone.Except(value).ToArray();
CharacterBody[] array2 = value.Except(bodiesInHoldoutZone).ToArray();
CharacterBody[] array3 = array;
foreach (CharacterBody val in array3)
{
((BaseUnityPlugin)this).Logger.LogDebug((object)(((val != null) ? val.GetDisplayName() : null) + " entered zone '" + ((holdoutZoneController != null) ? ((Object)holdoutZoneController).name : null) + "', following AIs " + Utils.GetListOfAIsRunningBody(val) + "."));
}
array3 = array2;
foreach (CharacterBody val2 in array3)
{
((BaseUnityPlugin)this).Logger.LogDebug((object)(((val2 != null) ? val2.GetDisplayName() : null) + " left zone '" + ((holdoutZoneController != null) ? ((Object)holdoutZoneController).name : null) + "', following AIs " + Utils.GetListOfAIsRunningBody(val2) + "."));
}
return Math.Min(bodiesInHoldoutZone.Count, Utils.GetTotalNumberOfPlayers(teamIndex));
}
private void CombatDirector_PickPlayerAsSpawnTarget(orig_PickPlayerAsSpawnTarget orig, CombatDirector self)
{
Utils.SetHoldoutZones();
IEnumerable<CharacterMaster> enumerable = CharacterMaster.instancesList.Where((CharacterMaster master) => isEnemy(master.teamIndex) && master.hasBody);
List<CharacterMaster> list = new List<CharacterMaster>();
List<CharacterMaster> list2 = new List<CharacterMaster>();
foreach (CharacterMaster item in enumerable)
{
if (Utils.IsInHoldoutZone(item))
{
list.Add(item);
}
else
{
list2.Add(item);
}
}
if (list.Count > 0)
{
self.currentSpawnTarget = self.rng.NextElementUniform<CharacterMaster>(list).GetBodyObject();
}
else if (list2.Count > 0)
{
self.currentSpawnTarget = self.rng.NextElementUniform<CharacterMaster>(list2).GetBodyObject();
}
bool isEnemy(TeamIndex teamIndex)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
if ((int)teamIndex != 0)
{
return teamIndex != self.teamIndex;
}
return false;
}
}
}
internal static class Utils
{
public static List<HoldoutZoneController> HoldoutZones { get; private set; }
public static void SetHoldoutZones()
{
HoldoutZones = InstanceTracker.GetInstancesList<HoldoutZoneController>();
}
internal static bool IsInHoldoutZone(CharacterMaster master)
{
GameObject val = ((master != null) ? master.bodyInstanceObject : null);
CharacterBody body;
try
{
body = ((val != null) ? val.GetComponent<CharacterBody>() : null);
}
catch
{
return false;
}
if (body == null)
{
return false;
}
return HoldoutZones.Any((HoldoutZoneController z) => z.IsBodyInChargingRadius(body));
}
internal static bool IsInHoldoutZone(Vector3? position)
{
if (!position.HasValue)
{
return false;
}
return HoldoutZones.Any((HoldoutZoneController z) => ((BaseZoneBehavior)z).IsInBounds(position.Value));
}
internal static bool WantsToStayInZone(CharacterMaster master)
{
if (master == null)
{
return false;
}
if (master.aiComponents.Any((BaseAI ai) => ai.isHealer))
{
return false;
}
SetHoldoutZones();
if (!IsInHoldoutZone(master))
{
return false;
}
if (IsInHoldoutZone(GetMinionMaster(master)))
{
return false;
}
return true;
}
internal static CharacterMaster GetMinionMaster(CharacterMaster master)
{
if (!Object.op_Implicit((Object)(object)master))
{
return null;
}
return master.minionOwnership.ownerMaster;
}
internal static string GetListOfAIsRunningBody(CharacterBody body)
{
BaseAI[] array = ((body == null) ? null : body.master?.aiComponents);
if (array == null)
{
return string.Empty;
}
return string.Join(", ", from x in array
select x?.skillDriverEvaluation.dominantSkillDriver?.customName into x
where x != null
select x);
}
internal static int GetTotalNumberOfPlayers(TeamIndex teamIndex)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return TeamComponent.GetTeamMembers(teamIndex).Count(delegate(TeamComponent teamComponent)
{
CharacterBody body = teamComponent.body;
return body != null && body.isPlayerControlled;
});
}
internal static HashSet<CharacterBody> GetBodiesInHoldoutZone(HoldoutZoneController holdoutZoneController, TeamIndex teamIndex)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
return (from tc in TeamComponent.GetTeamMembers(teamIndex)
select tc.body into body
where holdoutZoneController.IsBodyInChargingRadius(body)
select body).ToHashSet();
}
}