Decompiled source of Minions Charge Teleporter v1.0.1

MinionsChargeTeleporter/MinionsChargeTeleporter.dll

Decompiled a month ago
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();
	}
}