Decompiled source of Hero Toy v1.1.0

HeroToy.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using P2.Game.Unit;
using P2.Game.Unit.CharaParam;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("HeroToy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Hero Toy")]
[assembly: AssemblyTitle("HeroToy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HeroToy
{
	[BepInPlugin("ninja.nairobi.herotoy", "Hero Toy", "1.0.0")]
	[BepInProcess("PATAPON12_REPLAY.exe")]
	public class Plugin : BasePlugin
	{
		public enum AutokillMode
		{
			Dont,
			MissionStart,
			HeroMode,
			Always
		}

		public enum AutokillModeNH
		{
			Dont,
			MissionStart,
			Always
		}

		public enum AutokillType
		{
			Kill,
			Permakill,
			InstantPermakill
		}

		public enum UnitType
		{
			Yumi = 2,
			Tate = 3,
			Yari = 4,
			Kiba = 6,
			Deka = 9,
			Mega = 10,
			Maho = 11,
			Robo = 12
		}

		private static Plugin _instance;

		public static ConfigEntry<AutokillMode> KillHeroMode { get; private set; }

		public static ConfigEntry<AutokillType> KillHeroType { get; private set; }

		public static ConfigEntry<bool> DisableRespawn { get; private set; }

		public static ConfigEntry<bool> DisableHeroMode { get; private set; }

		public static ConfigEntry<AutokillMode> KillPonsMode { get; private set; }

		public static ConfigEntry<bool> ForceHeroMode { get; private set; }

		public static ConfigEntry<string> ToriponizePons { get; private set; }

		public static ConfigEntry<AutokillModeNH> Kill7BillionPeopleMode { get; private set; }

		public static ConfigEntry<string> ToriponizeOther { get; private set; }

		public override void Load()
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			_instance = this;
			KillHeroMode = ((BasePlugin)this).Config.Bind<AutokillMode>("Hero", "Autokill", AutokillMode.Dont, "When to kill the hero.");
			KillHeroType = ((BasePlugin)this).Config.Bind<AutokillType>("Hero", "AutokillType", AutokillType.Permakill, "The method of the execution, if it shall be carried out.");
			DisableRespawn = ((BasePlugin)this).Config.Bind<bool>("Hero", "DisableRespawn", false, "Whether to trap the hero's soul should he die normally.");
			DisableHeroMode = ((BasePlugin)this).Config.Bind<bool>("Hero", "DisableHeroMode", false, "Whether to unhero the hero.");
			KillPonsMode = ((BasePlugin)this).Config.Bind<AutokillMode>("Pons", "Autokill", AutokillMode.Dont, "When to massacre regular pons.");
			ForceHeroMode = ((BasePlugin)this).Config.Bind<bool>("Pons", "ForceHeroMode", false, "Whether to turn normal pons into faux heroes ඞ.");
			ToriponizePons = ((BasePlugin)this).Config.Bind<string>("Pons", "Toriponize", "", "Whether to send certain pons flying. Example: \"yari, kiba, mega\". Also affects the hero.");
			Kill7BillionPeopleMode = ((BasePlugin)this).Config.Bind<AutokillModeNH>("Other", "Autokill", AutokillModeNH.Dont, "When to massacre enemies.");
			ToriponizeOther = ((BasePlugin)this).Config.Bind<string>("Other", "Toriponize", "", "Whether to send certain enemies flying. Example: \"yari, kiba, mega\".");
			Harmony val = new Harmony("ninja.nairobi.herotoy");
			val.PatchAll();
		}

		public static void Print(object message)
		{
			((BasePlugin)_instance).Log.LogInfo(message);
		}
	}
	[HarmonyPatch]
	public static class MurderHero
	{
		private static bool _isInit;

		private static float _startTime;

		private static float _killTime;

		private static readonly float INIT_TIMEOUT = 0.5f;

		private static readonly float KILL_TIMEOUT = 5f;

		private static int GetSquadId(UnitSquad squad)
		{
			try
			{
				UnitBase unitTail = squad.getUnitTail(false);
				object value = AccessTools.FirstProperty(typeof(UnitBase), (Func<PropertyInfo, bool>)((PropertyInfo pi) => pi.Name == "info_")).GetValue(unitTail);
				return (int)AccessTools.Property(value.GetType(), "uniqueId").GetValue(value);
			}
			catch (Exception)
			{
				return -1;
			}
		}

		private static void EnableHeroMode(UnitSquad squad, bool value)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			SquadInfo obj = (SquadInfo)AccessTools.Property(typeof(UnitSquad), "squadInfo_").GetValue(squad);
			PropertyInfo propertyInfo = AccessTools.Property(typeof(SquadInfo), "isHero");
			if ((bool)propertyInfo.GetValue(obj) != value)
			{
				Plugin.Print($"Toggling hero mode for squad {GetSquadId(squad)} to {value}");
				propertyInfo.SetValue(obj, value);
				PropertyInfo propertyInfo2 = AccessTools.Property(typeof(SquadInfo), "charaType");
				Plugin.Print($"charaType={(int)propertyInfo2.GetValue(obj)}");
			}
		}

		private static void KillUnit0(UnitSquad squad, bool force)
		{
			if (GetSquadId(squad) != 0)
			{
				return;
			}
			if (Plugin.KillHeroType.Value != Plugin.AutokillType.InstantPermakill)
			{
				_killTime = Time.timeSinceLevelLoad;
			}
			else
			{
				force = true;
			}
			UnitBase unitTail = squad.getUnitTail(false);
			if (force)
			{
				_killTime = 0f;
				if (Plugin.KillHeroType.Value != 0)
				{
					Plugin.Print("Destroying the hero");
					unitTail.deleteUnit();
				}
			}
			else
			{
				unitTail.kill();
			}
		}

		private static void KillOtherUnit(UnitSquad squad, bool racism)
		{
			try
			{
				bool flag = GetEthnicGroup(squad) == 0;
				int squadId = GetSquadId(squad);
				if (squadId != 0 && (flag ^ racism))
				{
					squad.kill();
				}
			}
			catch (Exception)
			{
			}
		}

		private static BaseParam GetParam(UnitSquad squad)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			Info obj = (Info)AccessTools.FirstProperty(typeof(UnitBase), (Func<PropertyInfo, bool>)((PropertyInfo p) => p.Name == "info_")).GetValue(squad.getUnitTail(true));
			return (BaseParam)AccessTools.Property(typeof(Info), "charaParam").GetValue(obj);
		}

		private static int GetEthnicGroup(UnitSquad squad)
		{
			BaseParam param = GetParam(squad);
			return (int)AccessTools.Property(((object)param).GetType(), "ethnicGroupId").GetValue(param);
		}

		private static int GetTroopType(UnitSquad squad)
		{
			BaseParam param = GetParam(squad);
			return (int)AccessTools.Property(((object)param).GetType(), "charaType").GetValue(param);
		}

		private static void SendFlying(UnitSquad squad)
		{
			try
			{
				int troopType = GetTroopType(squad);
				if (!Enum.IsDefined(typeof(Plugin.UnitType), troopType))
				{
					return;
				}
				string text = ((GetEthnicGroup(squad) == 0) ? Plugin.ToriponizePons.Value : Plugin.ToriponizeOther.Value);
				string text2 = text.ToLower();
				Plugin.UnitType unitType = (Plugin.UnitType)troopType;
				if (!text2.Contains(unitType.ToString().ToLower()))
				{
					return;
				}
				PropertyInfo propertyInfo = AccessTools.FirstProperty(typeof(UnitBase), (Func<PropertyInfo, bool>)((PropertyInfo p) => p.Name == "info_"));
				for (int i = 0; i < 6; i++)
				{
					UnitBase unit_LineIndex = squad.getUnit_LineIndex(i);
					if (unit_LineIndex != null)
					{
						AccessTools.Property(typeof(Info), "isFly").SetValue(propertyInfo.GetValue(unit_LineIndex), true);
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private static void ExecIntro(UnitSquad squad)
		{
			SendFlying(squad);
			if (Plugin.ForceHeroMode.Value && GetSquadId(squad) > 0 && GetEthnicGroup(squad) == 0)
			{
				EnableHeroMode(squad, value: true);
			}
			if (Plugin.DisableHeroMode.Value && GetSquadId(squad) == 0)
			{
				EnableHeroMode(squad, value: false);
			}
			if (Plugin.KillHeroMode.Value == Plugin.AutokillMode.MissionStart)
			{
				KillUnit0(squad, force: false);
			}
			if (Plugin.KillPonsMode.Value == Plugin.AutokillMode.MissionStart)
			{
				KillOtherUnit(squad, racism: false);
			}
			if (Plugin.Kill7BillionPeopleMode.Value == Plugin.AutokillModeNH.MissionStart)
			{
				KillOtherUnit(squad, racism: true);
			}
			if (Time.timeSinceLevelLoad - _startTime > INIT_TIMEOUT)
			{
				_isInit = false;
			}
		}

		private static void ExecLoop(UnitSquad squad)
		{
			if (Plugin.DisableRespawn.Value && GetSquadId(squad) == 0)
			{
				UnitBase unitTail = squad.getUnitTail(false);
				if ((bool)AccessTools.Property(typeof(UnitBase), "isDead_").GetValue(unitTail))
				{
					Plugin.Print("Obliterating the hero");
					unitTail.deleteUnit();
				}
			}
			if (Plugin.KillHeroMode.Value == Plugin.AutokillMode.Always)
			{
				KillUnit0(squad, force: false);
			}
			if (Plugin.KillPonsMode.Value == Plugin.AutokillMode.Always)
			{
				KillOtherUnit(squad, racism: false);
			}
			if (Plugin.Kill7BillionPeopleMode.Value == Plugin.AutokillModeNH.Always)
			{
				KillOtherUnit(squad, racism: true);
			}
			if (_killTime != 0f && Time.timeSinceLevelLoad - _killTime > KILL_TIMEOUT)
			{
				KillUnit0(squad, force: true);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UnitSquad), "initialize")]
		public static void Initialize()
		{
			_isInit = true;
			_startTime = Time.timeSinceLevelLoad;
			_killTime = 0f;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UnitSquad), "update")]
		public static void Update(UnitSquad __instance)
		{
			if (_isInit)
			{
				ExecIntro(__instance);
			}
			else
			{
				ExecLoop(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UnitSquad), "checkHeroMode")]
		public static void CheckHeroMode(UnitSquad __instance, bool __result)
		{
			if (__result)
			{
				if (Plugin.KillHeroMode.Value == Plugin.AutokillMode.HeroMode)
				{
					KillUnit0(__instance, force: false);
				}
				if (Plugin.KillPonsMode.Value == Plugin.AutokillMode.HeroMode)
				{
					KillOtherUnit(__instance, racism: false);
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "HeroToy";

		public const string PLUGIN_NAME = "Hero Toy";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}