Decompiled source of More FPS v1.3.0

TabsFPS.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Landfall;
using Landfall.TABC;
using Landfall.TABS;
using Landfall.TABS.AI.Systems;
using Landfall.TABS.RuntimeCleanup;
using TFBGames;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Tabs Poof Mod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Tabs Poof Mod")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8aad4f38-2ad4-4206-bf0b-7d28fb6d5c2e")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace myfpsmodd;

[BepInPlugin("bayturtleking.morefps", "More FPS", "1.3.0")]
public class Plugin : BaseUnityPlugin
{
	private void Awake()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		modconfiggg.bindddd(((BaseUnityPlugin)this).Config);
		safepatcherzzz.logzzz = ((BaseUnityPlugin)this).Logger;
		safepatcherzzz.patcheverythinggg(new Harmony("bayturtleking.morefps"));
	}
}
internal static class safepatcherzzz
{
	public static ManualLogSource logzzz;

	public static void patcheverythinggg(Harmony harmonyyy)
	{
		Type[] types;
		try
		{
			types = typeof(safepatcherzzz).Assembly.GetTypes();
		}
		catch (ReflectionTypeLoadException ex)
		{
			types = ex.Types;
		}
		foreach (Type type in types)
		{
			if (type == null || !type.IsDefined(typeof(HarmonyPatch), inherit: true))
			{
				continue;
			}
			try
			{
				harmonyyy.PatchAll(type);
			}
			catch (Exception ex2)
			{
				if (logzzz != null)
				{
					logzzz.LogError((object)("turtle's very cool mroe fps  optimization " + type.Name + " did nto work :( and got skipped like that one guy in regular show: " + ex2));
				}
			}
		}
	}
}
internal static class modconfiggg
{
	public static ConfigEntry<bool> feetgorayzzz;

	public static ConfigEntry<bool> barsgobrrr;

	public static ConfigEntry<bool> brainzzznap;

	public static ConfigEntry<bool> musclebatchhh;

	public static ConfigEntry<bool> eyesrestzzz;

	public static ConfigEntry<bool> targetsnooze;

	public static ConfigEntry<bool> corpsechillzzz;

	public static ConfigEntry<bool> crowdscaleeee;

	public static ConfigEntry<bool> shadowsnoozeeee;

	public static ConfigEntry<bool> deadforcesnooozee;

	public static ConfigEntry<bool> deadtorquesnoozeee;

	public static ConfigEntry<bool> effectmemoryyy;

	public static ConfigEntry<bool> boomcachehhh;

	public static ConfigEntry<bool> shieldcachezzz;

	public static ConfigEntry<bool> soundcapzzz;

	public static ConfigEntry<int> soundcapamountzzz;

	public static ConfigEntry<bool> shotsetupzzz;

	public static ConfigEntry<bool> trailbatchzzz;

	public static ConfigEntry<bool> gcgrowzzz;

	public static void bindddd(ConfigFile config)
	{
		feetgorayzzz = config.Bind<bool>("Performance", "Foot ik throttle", true, "far away units' feet update less often. Increases FPS in large battles.");
		barsgobrrr = config.Bind<bool>("Performance", "Healthbar slow", true, "far away healthbars update less often. Increases FPS in large battles.");
		brainzzznap = config.Bind<bool>("Performance", "Pathfinding slow", true, "units pathfind less often. Increases FPS in large battles but may make the AI worse.");
		musclebatchhh = config.Bind<bool>("Performance", "Force batch", true, "forces limb and torque updates into one loop instead of individual calls. Increases FPS in large battles.");
		eyesrestzzz = config.Bind<bool>("Performance", "Vision check throttle", true, "units check line of sight to target less often. Increases FPS in large battles.");
		targetsnooze = config.Bind<bool>("Performance", "Target search slow", true, "units attempt to search for new targets less often. Increases FPS in large battles but may make target switching slightly slower.");
		corpsechillzzz = config.Bind<bool>("Performance", "Corpses collision stuff", true, "corpses can't collide with other dead bodies");
		crowdscaleeee = config.Bind<bool>("Performance", "Dynamic optimize", true, "throttles harder depending on how big the battle is :)");
		shadowsnoozeeee = config.Bind<bool>("Performance", "Blob shadow throttle", true, "the little shadows under units skip their ground check when the unit has not moved, and far away shadows update less often. Increases FPS in large battles.");
		deadforcesnooozee = config.Bind<bool>("Performance", "Skip dead muscle force", true, "dead units stop running muscle force updates. Needs Force Batching. Increases FPS in long battles.");
		deadtorquesnoozeee = config.Bind<bool>("Performance", "Skip dead muscle torques", false, "same as above but for torques. needs force batching.");
		effectmemoryyy = config.Bind<bool>("Performance", "Effect look cache", true, "effect hits remember which effect a unit already has instead of searching the whole unit on every hit. increases FPS with lots of bullets/projectiles.");
		boomcachehhh = config.Bind<bool>("Performance", "explosion rewrite", true, "explosions cache the unit and healthh lookups of every limb they touch and skip a bunch of unneeded allocs. increases FPS with lots of explosions.");
		shieldcachezzz = config.Bind<bool>("Performance", "Projectile shield cache", true, "projectile hits check a by unit list of shields or blocking things instead of searching the limb every hit. a new shield can take up to half a second to be noticed. Increases FPS with many of projectiles.");
		soundcapzzz = config.Bind<bool>("Performance", "Hit sound spam cap", true, "caps how many copies of the same hit sound can start in a single frame. audio only. it stacks the same sound anyway. Increases FPS with many of projectiles.");
		soundcapamountzzz = config.Bind<int>("Performance", "Hit sound spam cap amount", 8, "how many clone of the same sound can start per frame when the cap is enablde. higher is closer to normal game / vanilla.");
		shotsetupzzz = config.Bind<bool>("Performance", "Shot set up cache", true, "weapons lok up the parts of a new projectile once per shot instead of searching the projectile again for every part. Increases FPS with lots of multi part projectiles.");
		trailbatchzzz = config.Bind<bool>("Performance", "Raycast trail batc", true, "all projectile ray cast check run as one batch job per frame instead of one job per projectile. the hits are still found one frame later like normal game. Increases FPS with tons of projectiles.");
		gcgrowzzz = config.Bind<bool>("Performance", "Spawn tracker growth", true, "the game lists of projectiles grows by doubling instead of by 100 which makes way less arra garbage garbage. reduces lag spikes with lots of projectiles.");
	}
}
internal static class cameraaaaaa
{
	private static Camera itiscached;

	private static int cachedcamframezzz = -1;

	public static Camera getmaincammm()
	{
		if (Time.frameCount != cachedcamframezzz)
		{
			itiscached = Camera.main;
			cachedcamframezzz = Time.frameCount;
		}
		return itiscached;
	}
}
internal static class battleweightstuff
{
	private const int refresheveryyyy = 30;

	private static int cachedcountzzz;

	private static int lastcheckedframezzz = -9999;

	private static TeamSystem cachedteamsystemzzz;

	private static TeamSystem gimmeteamsystemzzz()
	{
		if (cachedteamsystemzzz == null)
		{
			World active = World.Active;
			if (active == null)
			{
				return null;
			}
			cachedteamsystemzzz = active.GetOrCreateManager<TeamSystem>();
		}
		return cachedteamsystemzzz;
	}

	public static int howmanydudesrightnowzzz()
	{
		if (Time.frameCount - lastcheckedframezzz < 30)
		{
			return cachedcountzzz;
		}
		lastcheckedframezzz = Time.frameCount;
		TeamSystem val = gimmeteamsystemzzz();
		cachedcountzzz = ((val != null) ? val.GetAllUnits().Count : 0);
		return cachedcountzzz;
	}

	public static float getmultiplierrr()
	{
		if (!modconfiggg.crowdscaleeee.Value)
		{
			return 1f;
		}
		int num = howmanydudesrightnowzzz();
		if (num <= 100)
		{
			return 1f;
		}
		if (num <= 250)
		{
			return 1.5f;
		}
		if (num <= 400)
		{
			return 2f;
		}
		return 3f;
	}
}
internal static class skipmathhh
{
	public static int scaleitupppzzz(int baseskipzzz)
	{
		if (baseskipzzz <= 0)
		{
			return 0;
		}
		int num = Mathf.RoundToInt((float)baseskipzzz * battleweightstuff.getmultiplierrr());
		return Mathf.Max(baseskipzzz, num);
	}
}
[HarmonyPatch(typeof(IkLeg), "DoRayCast")]
public static class throttleyourfeett
{
	private sealed class excusecounter
	{
		public int lazyframe;
	}

	private const float closerangeeee = 15f;

	private const float midrangeeee = 35f;

	private const int midskipzzz = 1;

	private const int farskipzzz = 3;

	private static readonly ConditionalWeakTable<IkLeg, excusecounter> whosloggingthisss = new ConditionalWeakTable<IkLeg, excusecounter>();

	private static bool Prefix(IkLeg __instance)
	{
		//IL_0025: 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)
		if (!modconfiggg.feetgorayzzz.Value)
		{
			return true;
		}
		Camera val = cameraaaaaa.getmaincammm();
		if ((Object)(object)val == (Object)null)
		{
			return true;
		}
		float num = Vector3.Distance(((Component)val).transform.position, ((Component)__instance).transform.position);
		int num2 = 0;
		if (num > 35f)
		{
			num2 = skipmathhh.scaleitupppzzz(3);
		}
		else if (num > 15f)
		{
			num2 = skipmathhh.scaleitupppzzz(1);
		}
		if (num2 == 0)
		{
			return true;
		}
		excusecounter orCreateValue = whosloggingthisss.GetOrCreateValue(__instance);
		orCreateValue.lazyframe++;
		if (orCreateValue.lazyframe <= num2)
		{
			return false;
		}
		orCreateValue.lazyframe = 0;
		return true;
	}
}
[HarmonyPatch(typeof(TABCUnitUI), "LateUpdate")]
public static class healthbarrrelax
{
	private sealed class excusecounter
	{
		public int lazyframe;
	}

	private const float closerangeeee = 20f;

	private const float midrangeeee = 50f;

	private const int midskipzzz = 1;

	private const int farskipzzz = 4;

	private static readonly ConditionalWeakTable<TABCUnitUI, excusecounter> whosloggingthisss = new ConditionalWeakTable<TABCUnitUI, excusecounter>();

	private static bool Prefix(TABCUnitUI __instance)
	{
		//IL_0025: 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)
		if (!modconfiggg.barsgobrrr.Value)
		{
			return true;
		}
		Camera val = cameraaaaaa.getmaincammm();
		if ((Object)(object)val == (Object)null)
		{
			return true;
		}
		float num = Vector3.Distance(((Component)val).transform.position, ((Component)__instance).transform.position);
		int num2 = 0;
		if (num > 50f)
		{
			num2 = skipmathhh.scaleitupppzzz(4);
		}
		else if (num > 20f)
		{
			num2 = skipmathhh.scaleitupppzzz(1);
		}
		if (num2 == 0)
		{
			return true;
		}
		excusecounter orCreateValue = whosloggingthisss.GetOrCreateValue(__instance);
		orCreateValue.lazyframe++;
		if (orCreateValue.lazyframe <= num2)
		{
			return false;
		}
		orCreateValue.lazyframe = 0;
		return true;
	}
}
[HarmonyPatch(typeof(CalculateNavPathSystem), "OnUpdate")]
public static class pathpathpath
{
	private const int skipeveryyyy = 1;

	private static int ticktockzzz;

	private static bool Prefix()
	{
		if (!modconfiggg.brainzzznap.Value)
		{
			return true;
		}
		ticktockzzz++;
		if (ticktockzzz <= skipmathhh.scaleitupppzzz(1))
		{
			return false;
		}
		ticktockzzz = 0;
		return true;
	}
}
[HarmonyPatch(typeof(CanSeeSystem), "OnUpdate", new Type[] { typeof(JobHandle) })]
public static class visstuff
{
	private const int skipeveryyyy = 1;

	private static int ticktockzzz;

	private static bool Prefix(ref JobHandle __result, JobHandle inputDeps)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.eyesrestzzz.Value)
		{
			return true;
		}
		ticktockzzz++;
		if (ticktockzzz <= skipmathhh.scaleitupppzzz(1))
		{
			__result = inputDeps;
			return false;
		}
		ticktockzzz = 0;
		return true;
	}
}
[HarmonyPatch(typeof(FindEnemyTargetSystem), "OnUpdate", new Type[] { typeof(JobHandle) })]
public static class enemysnoozeee
{
	private const int skipeveryyyy = 2;

	private static int ticktockzzz;

	private static bool Prefix(ref JobHandle __result, JobHandle inputDeps)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.targetsnooze.Value)
		{
			return true;
		}
		ticktockzzz++;
		if (ticktockzzz <= skipmathhh.scaleitupppzzz(2))
		{
			__result = inputDeps;
			return false;
		}
		ticktockzzz = 0;
		return true;
	}
}
[HarmonyPatch(typeof(FindFriendlyTargetSystem), "OnUpdate", new Type[] { typeof(JobHandle) })]
public static class friendsnoozeee
{
	private const int skipeveryyyy = 2;

	private static int ticktockzzz;

	private static bool Prefix(ref JobHandle __result, JobHandle inputDeps)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.targetsnooze.Value)
		{
			return true;
		}
		ticktockzzz++;
		if (ticktockzzz <= skipmathhh.scaleitupppzzz(2))
		{
			__result = inputDeps;
			return false;
		}
		ticktockzzz = 0;
		return true;
	}
}
[HarmonyPatch(typeof(FindNearestFriendTargetSystem), "OnUpdate", new Type[] { typeof(JobHandle) })]
public static class nearestfriendsnoozeee
{
	private const int skipeveryyyy = 2;

	private static int ticktockzzz;

	private static bool Prefix(ref JobHandle __result, JobHandle inputDeps)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.targetsnooze.Value)
		{
			return true;
		}
		ticktockzzz++;
		if (ticktockzzz <= skipmathhh.scaleitupppzzz(2))
		{
			__result = inputDeps;
			return false;
		}
		ticktockzzz = 0;
		return true;
	}
}
[HarmonyPatch(typeof(FindFriendlyHighestPriceTargetSystem), "OnUpdate", new Type[] { typeof(JobHandle) })]
public static class highestpricesnoozeee
{
	private const int skipeveryyyy = 2;

	private static int ticktockzzz;

	private static bool Prefix(ref JobHandle __result, JobHandle inputDeps)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.targetsnooze.Value)
		{
			return true;
		}
		ticktockzzz++;
		if (ticktockzzz <= skipmathhh.scaleitupppzzz(2))
		{
			__result = inputDeps;
			return false;
		}
		ticktockzzz = 0;
		return true;
	}
}
internal static class stopcolondead
{
	private const int maxtrackedzzz = 120;

	private static readonly List<Collider> allcorpsecolliderzzz = new List<Collider>();

	private static readonly ConditionalWeakTable<DataHandler, object> whojoinedddd = new ConditionalWeakTable<DataHandler, object>();

	public static void jointheclubbb(HealthHandler deadonezzz, DataHandler datazzz)
	{
		if (allcorpsecolliderzzz.Count >= 120 || whojoinedddd.TryGetValue(datazzz, out var _))
		{
			return;
		}
		whojoinedddd.Add(datazzz, new object());
		Collider[] componentsInChildren = ((Component)deadonezzz).GetComponentsInChildren<Collider>();
		foreach (Collider val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			for (int j = 0; j < allcorpsecolliderzzz.Count; j++)
			{
				Collider val2 = allcorpsecolliderzzz[j];
				if (!((Object)(object)val2 == (Object)null))
				{
					Physics.IgnoreCollision(val, val2, true);
				}
			}
		}
		allcorpsecolliderzzz.AddRange(componentsInChildren);
	}

	public static void leavetheclubbb(DataHandler datazzz)
	{
		if (!whojoinedddd.TryGetValue(datazzz, out var _))
		{
			return;
		}
		whojoinedddd.Remove(datazzz);
		Collider[] theircolliderzzz = ((Component)datazzz).GetComponentsInChildren<Collider>();
		foreach (Collider val in theircolliderzzz)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			for (int j = 0; j < allcorpsecolliderzzz.Count; j++)
			{
				Collider val2 = allcorpsecolliderzzz[j];
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)val))
				{
					Physics.IgnoreCollision(val, val2, false);
				}
			}
		}
		allcorpsecolliderzzz.RemoveAll((Collider x) => (Object)(object)x == (Object)null || Array.IndexOf(theircolliderzzz, x) >= 0);
	}
}
[HarmonyPatch(typeof(HealthHandler), "Die", new Type[] { typeof(Unit) })]
public static class corpsenapzzz
{
	private sealed class oldrigstuff
	{
		public int solverrr;

		public int velocitysolverrr;

		public float sleeppp;
	}

	private const int lowsolverzzz = 1;

	private const float sleepythresholdzzz = 0.5f;

	private static readonly ConditionalWeakTable<Rigidbody, oldrigstuff> whatitwasbeforeee = new ConditionalWeakTable<Rigidbody, oldrigstuff>();

	private static void Postfix(HealthHandler __instance, bool __result)
	{
		if (!modconfiggg.corpsechillzzz.Value || !__result)
		{
			return;
		}
		DataHandler componentInParent = ((Component)__instance).GetComponentInParent<DataHandler>();
		if ((Object)(object)componentInParent == (Object)null || !componentInParent.Dead)
		{
			return;
		}
		RigidbodyHolder component = ((Component)__instance).GetComponent<RigidbodyHolder>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		Rigidbody[] allRigs = component.AllRigs;
		if (allRigs == null)
		{
			return;
		}
		foreach (Rigidbody val in allRigs)
		{
			if (!((Object)(object)val == (Object)null))
			{
				if (!whatitwasbeforeee.TryGetValue(val, out var _))
				{
					oldrigstuff oldrigstuff = new oldrigstuff();
					oldrigstuff.solverrr = val.solverIterations;
					oldrigstuff.velocitysolverrr = val.solverVelocityIterations;
					oldrigstuff.sleeppp = val.sleepThreshold;
					whatitwasbeforeee.Add(val, oldrigstuff);
				}
				val.solverIterations = 1;
				val.solverVelocityIterations = 1;
				val.sleepThreshold = Mathf.Max(val.sleepThreshold, 0.5f);
			}
		}
		stopcolondead.jointheclubbb(__instance, componentInParent);
	}

	public static void backtolifeee(DataHandler datazzz)
	{
		if ((Object)(object)datazzz.allRigs == (Object)null)
		{
			return;
		}
		Rigidbody[] allRigs = datazzz.allRigs.AllRigs;
		if (allRigs == null)
		{
			return;
		}
		foreach (Rigidbody val in allRigs)
		{
			if (!((Object)(object)val == (Object)null) && whatitwasbeforeee.TryGetValue(val, out var value))
			{
				val.solverIterations = value.solverrr;
				val.solverVelocityIterations = value.velocitysolverrr;
				val.sleepThreshold = value.sleeppp;
				whatitwasbeforeee.Remove(val);
			}
		}
	}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public static class revivedwatchhh
{
	private static void Postfix(DataHandler __instance, bool value)
	{
		if (!value)
		{
			corpsenapzzz.backtolifeee(__instance);
			stopcolondead.leavetheclubbb(__instance);
		}
	}
}
[HarmonyPatch(typeof(BlobShadowService), "Update")]
public static class shadowsnoozeee
{
	private sealed class shadowtrackerrr
	{
		public Vector3 lastposs;

		public bool hasposs;

		public int versionn;

		public int lazyframe;
	}

	private const float closerangeeee = 30f;

	private const int farskipzzz = 2;

	private const float tinymoveee = 0.0001f;

	private static int versionnn;

	private static bool lastshowwwww = true;

	private static readonly FieldInfo castersfieldd = AccessTools.Field(typeof(BlobShadowService), "shadowCasters");

	private static readonly FieldInfo showfieldd = AccessTools.Field(typeof(BlobShadowService), "showShadows");

	private static readonly FieldInfo distfieldd = AccessTools.Field(typeof(BlobShadowService), "castDistance");

	private static readonly FieldInfo offsetfieldd = AccessTools.Field(typeof(BlobShadowService), "offset");

	private static readonly FieldInfo layersfieldd = AccessTools.Field(typeof(BlobShadowService), "allowedLayers");

	private static readonly FieldInfo alignfieldd = AccessTools.Field(typeof(BlobShadowService), "forceAlignUp");

	private static readonly ConditionalWeakTable<Transform, shadowtrackerrr> whosloggingthisss = new ConditionalWeakTable<Transform, shadowtrackerrr>();

	private static bool Prefix(BlobShadowService __instance)
	{
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: 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_010e: 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_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: 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)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.shadowsnoozeeee.Value)
		{
			return true;
		}
		if (castersfieldd == null || showfieldd == null || distfieldd == null || offsetfieldd == null || layersfieldd == null || alignfieldd == null)
		{
			return true;
		}
		if (!(castersfieldd.GetValue(__instance) is Dictionary<Transform, GameObject> dictionary))
		{
			return true;
		}
		bool flag = (bool)showfieldd.GetValue(__instance);
		float num = (float)distfieldd.GetValue(__instance);
		float num2 = (float)offsetfieldd.GetValue(__instance);
		int num3 = LayerMask.op_Implicit((LayerMask)layersfieldd.GetValue(__instance));
		bool flag2 = (bool)alignfieldd.GetValue(__instance);
		if (flag != lastshowwwww)
		{
			lastshowwwww = flag;
			versionnn++;
		}
		Camera val = cameraaaaaa.getmaincammm();
		Vector3 val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : Vector3.zero);
		Dictionary<Transform, GameObject>.Enumerator enumerator = dictionary.GetEnumerator();
		RaycastHit val4 = default(RaycastHit);
		while (enumerator.MoveNext())
		{
			Transform key = enumerator.Current.Key;
			GameObject value = enumerator.Current.Value;
			if ((Object)(object)key == (Object)null || (Object)(object)value == (Object)null)
			{
				continue;
			}
			if (!flag)
			{
				value.SetActive(false);
				continue;
			}
			shadowtrackerrr orCreateValue = whosloggingthisss.GetOrCreateValue(key);
			Vector3 position = key.position;
			if (orCreateValue.hasposs && orCreateValue.versionn == versionnn)
			{
				Vector3 val3 = position - orCreateValue.lastposs;
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
				{
					continue;
				}
				if ((Object)(object)val != (Object)null && Vector3.Distance(val2, position) > 30f)
				{
					orCreateValue.lazyframe++;
					if (orCreateValue.lazyframe <= skipmathhh.scaleitupppzzz(2))
					{
						continue;
					}
					orCreateValue.lazyframe = 0;
				}
			}
			orCreateValue.lastposs = position;
			orCreateValue.hasposs = true;
			orCreateValue.versionn = versionnn;
			if (Physics.Raycast(position, Vector3.down, ref val4, num, num3))
			{
				value.SetActive(true);
				value.transform.position = new Vector3(position.x, ((RaycastHit)(ref val4)).point.y + num2, position.z);
				value.transform.up = (flag2 ? Vector3.up : (-((RaycastHit)(ref val4)).normal));
			}
			else
			{
				value.SetActive(false);
			}
		}
		return false;
	}
}
internal sealed class animberunnin : MonoBehaviour
{
	public static animberunnin onlyoneee;

	private void FixedUpdate()
	{
		animationbatchh.runbatch();
	}
}
internal static class animationbatchh
{
	private sealed class forceentryy
	{
		public AnimationForce whoo;

		public DataHandler dataaa;
	}

	private sealed class torqueentryy
	{
		public AnimationTorque whoo;

		public DataHandler dataaa;
	}

	private static readonly List<forceentryy> listofforce = new List<forceentryy>();

	private static readonly List<torqueentryy> listoftorque = new List<torqueentryy>();

	private static readonly Action<AnimationForce> callforceup = AccessTools.MethodDelegate<Action<AnimationForce>>(AccessTools.Method(typeof(AnimationForce), "FixedUpdate", (Type[])null, (Type[])null), (object)null, true);

	private static readonly Action<AnimationTorque> calltorquedog = AccessTools.MethodDelegate<Action<AnimationTorque>>(AccessTools.Method(typeof(AnimationTorque), "FixedUpdate", (Type[])null, (Type[])null), (object)null, true);

	public static void betterrun()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		if (!((Object)(object)animberunnin.onlyoneee != (Object)null))
		{
			GameObject val = new GameObject("animberunnin");
			Object.DontDestroyOnLoad((Object)val);
			animberunnin.onlyoneee = val.AddComponent<animberunnin>();
		}
	}

	public static void forcer(AnimationForce whoisit)
	{
		betterrun();
		forceentryy forceentryy = new forceentryy();
		forceentryy.whoo = whoisit;
		forceentryy.dataaa = ((Component)whoisit).GetComponentInParent<DataHandler>();
		listofforce.Add(forceentryy);
	}

	public static void torquer(AnimationTorque whoisit)
	{
		betterrun();
		torqueentryy torqueentryy = new torqueentryy();
		torqueentryy.whoo = whoisit;
		torqueentryy.dataaa = ((Component)whoisit).GetComponentInParent<DataHandler>();
		listoftorque.Add(torqueentryy);
	}

	public static void runbatch()
	{
		if (!modconfiggg.musclebatchhh.Value)
		{
			return;
		}
		bool value = modconfiggg.deadforcesnooozee.Value;
		bool value2 = modconfiggg.deadtorquesnoozeee.Value;
		for (int num = listofforce.Count - 1; num >= 0; num--)
		{
			forceentryy forceentryy = listofforce[num];
			if ((Object)(object)forceentryy.whoo == (Object)null)
			{
				listofforce.RemoveAt(num);
			}
			else if (!value || !((Object)(object)forceentryy.dataaa != (Object)null) || !forceentryy.dataaa.Dead)
			{
				callforceup(forceentryy.whoo);
			}
		}
		for (int num2 = listoftorque.Count - 1; num2 >= 0; num2--)
		{
			torqueentryy torqueentryy = listoftorque[num2];
			if ((Object)(object)torqueentryy.whoo == (Object)null)
			{
				listoftorque.RemoveAt(num2);
			}
			else if (!value2 || !((Object)(object)torqueentryy.dataaa != (Object)null) || !torqueentryy.dataaa.Dead)
			{
				calltorquedog(torqueentryy.whoo);
			}
		}
	}
}
[HarmonyPatch(typeof(AnimationForce), "Start")]
internal static class forcething
{
	private static void Postfix(AnimationForce __instance)
	{
		animationbatchh.forcer(__instance);
	}
}
[HarmonyPatch(typeof(AnimationForce), "FixedUpdate")]
internal static class skipitt
{
	private static bool Prefix()
	{
		return !modconfiggg.musclebatchhh.Value;
	}
}
[HarmonyPatch(typeof(AnimationTorque), "Start")]
internal static class torquestuff
{
	private static void Postfix(AnimationTorque __instance)
	{
		animationbatchh.torquer(__instance);
	}
}
[HarmonyPatch(typeof(AnimationTorque), "FixedUpdate")]
internal static class dontdotorquestuff
{
	private static bool Prefix()
	{
		return !modconfiggg.musclebatchhh.Value;
	}
}
[HarmonyPatch(typeof(UnitEffectBase), "AddEffectToTarget")]
public static class efflookz
{
	private sealed class slotzzz
	{
		public Type typeee;

		public int idddd;

		public UnitEffectBase effectzzz;
	}

	private sealed class slotlistzzz
	{
		public readonly List<slotzzz> slotsss = new List<slotzzz>();
	}

	private static readonly ConditionalWeakTable<Transform, slotlistzzz> rememberedddd = new ConditionalWeakTable<Transform, slotlistzzz>();

	private static bool hitthecacheee;

	private static bool Prefix(GameObject target, UnitEffectBase EffectPrefab, ref UnitEffectBase __result)
	{
		hitthecacheee = false;
		if (!modconfiggg.effectmemoryyy.Value)
		{
			return true;
		}
		if ((Object)(object)target == (Object)null || (Object)(object)EffectPrefab == (Object)null)
		{
			return true;
		}
		Transform root = target.transform.root;
		if (!rememberedddd.TryGetValue(root, out var value))
		{
			return true;
		}
		Type type = ((object)EffectPrefab).GetType();
		int effectID = EffectPrefab.effectID;
		for (int i = 0; i < value.slotsss.Count; i++)
		{
			slotzzz slotzzz = value.slotsss[i];
			if (!(slotzzz.typeee != type) && slotzzz.idddd == effectID)
			{
				UnitEffectBase effectzzz = slotzzz.effectzzz;
				if ((Object)(object)effectzzz != (Object)null && ((Component)effectzzz).gameObject.activeInHierarchy)
				{
					__result = effectzzz;
					hitthecacheee = true;
					return false;
				}
				value.slotsss.RemoveAt(i);
				return true;
			}
		}
		return true;
	}

	private static void Postfix(GameObject target, UnitEffectBase EffectPrefab, UnitEffectBase __result)
	{
		if (hitthecacheee)
		{
			hitthecacheee = false;
		}
		else
		{
			if (!modconfiggg.effectmemoryyy.Value || (Object)(object)__result == (Object)null || (Object)(object)target == (Object)null || (Object)(object)EffectPrefab == (Object)null)
			{
				return;
			}
			slotlistzzz orCreateValue = rememberedddd.GetOrCreateValue(target.transform.root);
			Type type = ((object)EffectPrefab).GetType();
			int effectID = EffectPrefab.effectID;
			for (int i = 0; i < orCreateValue.slotsss.Count; i++)
			{
				slotzzz slotzzz = orCreateValue.slotsss[i];
				if (slotzzz.typeee == type && slotzzz.idddd == effectID)
				{
					slotzzz.effectzzz = __result;
					return;
				}
			}
			slotzzz slotzzz2 = new slotzzz();
			slotzzz2.typeee = type;
			slotzzz2.idddd = effectID;
			slotzzz2.effectzzz = __result;
			orCreateValue.slotsss.Add(slotzzz2);
		}
	}
}
[HarmonyPatch(typeof(Explosion), "Explode")]
public static class boomreeew
{
	private sealed class limbmemoryzzz
	{
		public Transform rootzzz;

		public DataHandler dataaa;

		public Unit unitzzz;

		public Damagable damagableee;

		public DataHandler damagabledataaa;

		public float stampp = -999f;
	}

	private const float rememforz = 1f;

	private const int buffman = 2048;

	private static int depthhh;

	private static readonly ConditionalWeakTable<Rigidbody, limbmemoryzzz> limbmemoryyy = new ConditionalWeakTable<Rigidbody, limbmemoryzzz>();

	private static readonly Collider[] bufferrr = (Collider[])(object)new Collider[2048];

	private static readonly HashSet<Rigidbody> oncepereigzzz = new HashSet<Rigidbody>();

	private static readonly HashSet<Damagable> alreadylistedddd = new HashSet<Damagable>();

	private static readonly Action<Explosion, List<Damagable>> checkachievementzzz = AccessTools.MethodDelegate<Action<Explosion, List<Damagable>>>(AccessTools.Method(typeof(Explosion), "CheckAchivements", (Type[])null, (Type[])null), (object)null, true);

	private static limbmemoryzzz rememberlimbbb(Rigidbody rigzzz)
	{
		limbmemoryzzz orCreateValue = limbmemoryyy.GetOrCreateValue(rigzzz);
		if ((Object)(object)orCreateValue.rootzzz == (Object)null || Time.time - orCreateValue.stampp > 1f)
		{
			Transform val = (orCreateValue.rootzzz = ((Component)rigzzz).transform.root);
			orCreateValue.dataaa = ((Component)val).GetComponentInChildren<DataHandler>();
			orCreateValue.unitzzz = ((Component)val).GetComponent<Unit>();
			orCreateValue.damagableee = ((Component)rigzzz).GetComponentInParent<Damagable>();
			orCreateValue.damagabledataaa = (((Object)(object)orCreateValue.damagableee != (Object)null) ? ((Component)orCreateValue.damagableee).GetComponent<DataHandler>() : null);
			orCreateValue.stampp = Time.time;
		}
		return orCreateValue;
	}

	private static bool Prefix(Explosion __instance, ref ExplosionEffect[] ___effects, ref ObjectException[] ___exceptions, ref TeamHolder ___teamHolder, ref AddExplosionEffectToChild ___explosionEffectToAdd, ref Team ___team, ref bool ___eventsInvoked, ref Unit ___ownUnit)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected I4, but got Unknown
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected I4, but got Unknown
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Invalid comparison between Unknown and I4
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Invalid comparison between Unknown and I4
		//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Invalid comparison between Unknown and I4
		//IL_02be: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0429: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.boomcachehhh.Value || depthhh > 0)
		{
			return true;
		}
		__instance.Start();
		depthhh++;
		try
		{
			Transform transform = ((Component)__instance).transform;
			Transform root = transform.root;
			Vector3 position = transform.position;
			float num = (__instance.deltaTime ? (Time.deltaTime * 100f) : 1f);
			if ((Object)(object)___teamHolder != (Object)null)
			{
				___team = (Team)(int)___teamHolder.team;
			}
			else
			{
				Unit component = ((Component)root).GetComponent<Unit>();
				if ((Object)(object)component != (Object)null)
				{
					___team = (Team)(int)component.Team;
				}
			}
			float radius = __instance.radius;
			Collider[] array = bufferrr;
			int num2 = Physics.OverlapSphereNonAlloc(position, radius, bufferrr, LayerMask.op_Implicit(__instance.layerMask));
			if (num2 >= bufferrr.Length)
			{
				array = Physics.OverlapSphere(position, radius, LayerMask.op_Implicit(__instance.layerMask));
				num2 = array.Length;
			}
			List<Damagable> list = new List<Damagable>();
			oncepereigzzz.Clear();
			alreadylistedddd.Clear();
			bool flag = false;
			for (int i = 0; i < num2; i++)
			{
				Collider val = array[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Rigidbody attachedRigidbody = val.attachedRigidbody;
				if ((Object)(object)attachedRigidbody == (Object)null)
				{
					continue;
				}
				limbmemoryzzz limbmemoryzzz = rememberlimbbb(attachedRigidbody);
				bool flag2 = (Object)(object)limbmemoryzzz.rootzzz == (Object)(object)root;
				if ((flag2 && __instance.ignoreRoot) || (!flag2 && __instance.onlyRoot) || (__instance.forceOnlyOncePerRig && !oncepereigzzz.Add(attachedRigidbody)))
				{
					continue;
				}
				bool flag3 = true;
				if (___exceptions != null)
				{
					for (int j = 0; j < ___exceptions.Length; j++)
					{
						flag3 = ___exceptions[j].TestException(((Component)attachedRigidbody).gameObject);
					}
				}
				if (!flag3 || __instance.protectedRigs.Contains(attachedRigidbody))
				{
					continue;
				}
				if (__instance.ignoreTeamMates || __instance.onlyTeamMates)
				{
					Unit unitzzz = limbmemoryzzz.unitzzz;
					if ((Object)(object)unitzzz != (Object)null && ((__instance.ignoreTeamMates && (int)unitzzz.Team == (int)___team) || (__instance.onlyTeamMates && (int)unitzzz.Team != (int)___team)))
					{
						continue;
					}
				}
				DataHandler dataaa = limbmemoryzzz.dataaa;
				if ((Object)(object)dataaa != (Object)null && !dataaa.Dead && !___eventsInvoked)
				{
					__instance.hitEvent.Invoke();
					___eventsInvoked = true;
				}
				if (__instance.addEffectFromParent)
				{
					if ((Object)(object)___explosionEffectToAdd != (Object)null)
					{
						___explosionEffectToAdd.DoExplosionEffect(((Component)attachedRigidbody).gameObject);
					}
				}
				else if (___effects != null)
				{
					for (int k = 0; k < ___effects.Length; k++)
					{
						___effects[k].DoEffect(((Component)attachedRigidbody).gameObject);
					}
				}
				float num3 = Mathf.Clamp(attachedRigidbody.drag / 3f, 0.1f, 1f);
				if ((int)__instance.forceDirection == 0)
				{
					WilhelmPhysicsFunctions.AddAxplosionForceWithMinWeight(attachedRigidbody, num * __instance.force * num3, position, radius, (ForceMode)1, __instance.minMassCap);
				}
				else if ((int)__instance.forceDirection == 1)
				{
					WilhelmPhysicsFunctions.AddForceWithMinWeight(attachedRigidbody, num * __instance.force * num3 * transform.forward, (ForceMode)1, __instance.minMassCap);
				}
				attachedRigidbody.velocity *= 0.9f;
				Damagable damagableee = limbmemoryzzz.damagableee;
				if ((Object)(object)damagableee != (Object)null)
				{
					if ((Object)(object)limbmemoryzzz.damagabledataaa != (Object)null && !limbmemoryzzz.damagabledataaa.Dead && alreadylistedddd.Add(damagableee))
					{
						list.Add(damagableee);
					}
					if ((Object)(object)___ownUnit == (Object)null && !flag)
					{
						flag = true;
						if ((Object)(object)___teamHolder != (Object)null && (Object)(object)___teamHolder.spawner != (Object)null)
						{
							___ownUnit = ___teamHolder.spawner.GetComponentInParent<Unit>();
						}
						if ((Object)(object)___ownUnit == (Object)null)
						{
							___ownUnit = ((Component)__instance).GetComponentInParent<Unit>();
						}
					}
					float num4 = num * Mathf.Clamp(1f - Vector3.Distance(position, val.ClosestPoint(position)) / radius, 0f, 1f);
					Vector3 val2 = ((Component)val).transform.position - position;
					damagableee.TakeDamage(__instance.damage * num4, val2, ___ownUnit, (DamageType)0);
					if (__instance.percentDamage > 0f && (Object)(object)dataaa != (Object)null)
					{
						damagableee.TakeDamage(dataaa.maxHealth * __instance.percentDamage * num4, val2, ___ownUnit, (DamageType)0);
					}
				}
				if (!(__instance.stopAttacksFor > 0f))
				{
					continue;
				}
				WeaponHandler componentInChildren = ((Component)limbmemoryzzz.rootzzz).GetComponentInChildren<WeaponHandler>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.StopAttacksFor(__instance.stopAttacksFor);
					continue;
				}
				MultipleWeaponHandler componentInChildren2 = ((Component)limbmemoryzzz.rootzzz).GetComponentInChildren<MultipleWeaponHandler>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.StopAttacksFor(__instance.stopAttacksFor);
				}
			}
			___eventsInvoked = false;
			checkachievementzzz(__instance, list);
		}
		finally
		{
			depthhh--;
			oncepereigzzz.Clear();
			alreadylistedddd.Clear();
		}
		return false;
	}
}
[HarmonyPatch(typeof(ProjectileHit), "Hit")]
public static class hshieldlok
{
	private sealed class shieldlistzzz
	{
		public ProjectileSurfaceEffect[] allzzz;

		public float stampp = -999f;
	}

	private const float rememforz = 0.5f;

	private static readonly ConditionalWeakTable<Transform, shieldlistzzz> shieldmemoryyy = new ConditionalWeakTable<Transform, shieldlistzzz>();

	private static readonly MethodInfo helperrr = AccessTools.Method(typeof(hshieldlok), "surfacefindzzz", (Type[])null, (Type[])null);

	public static ProjectileSurfaceEffect surfacefindzzz(GameObject gozzz)
	{
		if ((Object)(object)gozzz == (Object)null)
		{
			return null;
		}
		if (!modconfiggg.shieldcachezzz.Value || (Object)(object)gozzz.GetComponent<Rigidbody>() == (Object)null)
		{
			return gozzz.GetComponentInChildren<ProjectileSurfaceEffect>();
		}
		Transform transform = gozzz.transform;
		Transform root = transform.root;
		shieldlistzzz orCreateValue = shieldmemoryyy.GetOrCreateValue(root);
		if (orCreateValue.allzzz == null || Time.time - orCreateValue.stampp > 0.5f)
		{
			orCreateValue.allzzz = ((Component)root).GetComponentsInChildren<ProjectileSurfaceEffect>(true);
			orCreateValue.stampp = Time.time;
		}
		ProjectileSurfaceEffect[] allzzz = orCreateValue.allzzz;
		foreach (ProjectileSurfaceEffect val in allzzz)
		{
			if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
			{
				Transform transform2 = ((Component)val).transform;
				if ((Object)(object)transform2 == (Object)(object)transform || transform2.IsChildOf(transform))
				{
					return val;
				}
			}
		}
		return null;
	}

	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		int replacedzzz = 0;
		foreach (CodeInstruction instruction in instructions)
		{
			MethodInfo methodInfo = instruction.operand as MethodInfo;
			if (methodInfo != null && methodInfo.IsGenericMethod && (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt))
			{
				MethodInfo genericMethodDefinition = methodInfo.GetGenericMethodDefinition();
				if (genericMethodDefinition.DeclaringType == typeof(GameObject) && genericMethodDefinition.Name == "GetComponentInChildren" && methodInfo.GetParameters().Length == 0 && methodInfo.GetGenericArguments()[0] == typeof(ProjectileSurfaceEffect))
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = helperrr;
					replacedzzz++;
				}
			}
			yield return instruction;
		}
		if (replacedzzz == 0 && safepatcherzzz.logzzz != null)
		{
			safepatcherzzz.logzzz.LogWarning((object)"no't more fps could no find the callll to replaceee in projectilehit.hit :(. it do nothin");
		}
	}
}
[HarmonyPatch(typeof(SoundPlayer), "PlaySoundEffectNonAlloc")]
public static class sspancapsz
{
	private struct soundkeyyy : IEquatable<soundkeyyy>
	{
		public string cattt;

		public string efffff;

		public bool Equals(soundkeyyy other)
		{
			if (string.Equals(cattt, other.cattt))
			{
				return string.Equals(efffff, other.efffff);
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is soundkeyyy)
			{
				return Equals((soundkeyyy)obj);
			}
			return false;
		}

		public override int GetHashCode()
		{
			int num = ((cattt != null) ? cattt.GetHashCode() : 0);
			int num2 = ((efffff != null) ? efffff.GetHashCode() : 0);
			return num * 31 + num2;
		}
	}

	private static readonly Dictionary<soundkeyyy, int> countsss = new Dictionary<soundkeyyy, int>();

	private static int lastframeee = -1;

	private static bool Prefix(AudioPathData audioPathData, ref AudioPlayer __result)
	{
		if (!modconfiggg.soundcapzzz.Value)
		{
			return true;
		}
		if (audioPathData == null)
		{
			return true;
		}
		if (Time.frameCount != lastframeee)
		{
			lastframeee = Time.frameCount;
			countsss.Clear();
		}
		soundkeyyy key = new soundkeyyy
		{
			cattt = audioPathData.Category,
			efffff = audioPathData.Effect
		};
		countsss.TryGetValue(key, out var value);
		if (value >= modconfiggg.soundcapamountzzz.Value)
		{
			__result = null;
			return false;
		}
		countsss[key] = value + 1;
		return true;
	}
}
[HarmonyPatch(typeof(RangeWeapon), "SetProjectileStats")]
public static class shotsetupcachezzz
{
	private static readonly List<Transform> tflistzzz = new List<Transform>();

	private static readonly List<Compensation> complistzzz = new List<Compensation>();

	private static readonly List<ProjectileHit> hitlistzzz = new List<ProjectileHit>();

	private static readonly List<CollisionWeapon> collistzzz = new List<CollisionWeapon>();

	private static T firstunderrr<T>(List<T> listzzz, Transform trzzz) where T : Component
	{
		for (int i = 0; i < listzzz.Count; i++)
		{
			T val = listzzz[i];
			if (!((Object)(object)val == (Object)null))
			{
				Transform transform = ((Component)val).transform;
				if ((Object)(object)transform == (Object)(object)trzzz || transform.IsChildOf(trzzz))
				{
					return val;
				}
			}
		}
		return default(T);
	}

	private static void clearlistsss()
	{
		tflistzzz.Clear();
		complistzzz.Clear();
		hitlistzzz.Clear();
		collistzzz.Clear();
	}

	private static bool Prefix(RangeWeapon __instance, GameObject spawnedObject, Vector3 spawnDir, Vector3 directionToTarget, Rigidbody targetRig, Vector3 shootPositionForward, Vector3 targetRigPosition, Vector3 targetRigVelocity, byte? randomSeed, ref Level ___myLevel)
	{
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: 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_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0361: Unknown result type (might be due to invalid IL or missing references)
		if (!modconfiggg.shotsetupzzz.Value)
		{
			return true;
		}
		if (randomSeed.HasValue || (Object)(object)spawnedObject == (Object)null)
		{
			return true;
		}
		Transform transform = spawnedObject.transform;
		((Component)transform).GetComponentsInChildren<Transform>(false, tflistzzz);
		if (tflistzzz.Count < 2)
		{
			tflistzzz.Clear();
			return true;
		}
		((Component)transform).GetComponentsInChildren<Compensation>(false, complistzzz);
		((Component)transform).GetComponentsInChildren<ProjectileHit>(false, hitlistzzz);
		((Component)transform).GetComponentsInChildren<CollisionWeapon>(false, collistzzz);
		MoveTransform componentInChildren = spawnedObject.GetComponentInChildren<MoveTransform>();
		AddForce component = spawnedObject.GetComponent<AddForce>();
		DataHandler connectedData = ((Weapon)__instance).connectedData;
		Transform transform2 = ((Component)__instance).transform;
		float levelMultiplier = ((Weapon)__instance).levelMultiplier;
		for (int i = 0; i < tflistzzz.Count; i++)
		{
			Transform val = tflistzzz[i];
			if (__instance.force != 0f)
			{
				Rigidbody component2 = ((Component)val).GetComponent<Rigidbody>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.AddForce(spawnDir * __instance.force, (ForceMode)2);
					if ((Object)(object)___myLevel != (Object)null)
					{
						component2.mass *= Mathf.Pow((float)___myLevel.level, 1.5f);
					}
				}
			}
			Compensation val2 = firstunderrr<Compensation>(complistzzz, val);
			if ((Object)(object)val2 != (Object)null && (Object)(object)targetRig != (Object)null)
			{
				((Component)val2).transform.rotation = Quaternion.LookRotation(val2.GetCompensation(targetRigPosition, targetRigVelocity, __instance.shootHelpAngleCurve.Evaluate(Vector3.Angle(directionToTarget, shootPositionForward))) + 0.01f * __instance.spread * Random.insideUnitSphere);
				if (__instance.extraSpreadInMelee != 0f && (Object)(object)connectedData != (Object)null && connectedData.distanceToTarget < 5f)
				{
					((Weapon)__instance).internalCounter = 0f - __instance.extraCDInMelee;
					((Component)val2).transform.Rotate(__instance.extraSpreadInMelee * Random.insideUnitSphere);
				}
			}
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.projectileSpeedSpread = __instance.projectileSpeedSpread;
				if ((Object)(object)val2 != (Object)null && val2.forwardCompensation > 0f && (Object)(object)targetRig != (Object)null)
				{
					componentInChildren.selfImpulse.z += Mathf.Pow(Mathf.Clamp(Vector3.Distance(targetRigPosition, transform2.position), 0f, val2.clampDistance), val2.rangePow) * val2.forwardCompensation;
				}
			}
			if ((Object)(object)component != (Object)null && (Object)(object)val2 != (Object)null && val2.forwardCompensation > 0f && (Object)(object)targetRig != (Object)null)
			{
				component.force.z += Mathf.Pow(Mathf.Clamp(Vector3.Distance(targetRigPosition, transform2.position), 0f, val2.clampDistance), val2.rangePow) * val2.forwardCompensation;
			}
			ProjectileHit val3 = firstunderrr<ProjectileHit>(hitlistzzz, val);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.damage *= levelMultiplier;
				if ((Object)(object)connectedData != (Object)null && connectedData.input.hasControl)
				{
					val3.alwaysHitTeamMates = true;
				}
				if ((Object)(object)___myLevel != (Object)null)
				{
					val3.ignoreTeamMates = ___myLevel.ignoreTeam;
				}
			}
			CollisionWeapon val4 = firstunderrr<CollisionWeapon>(collistzzz, val);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.damage *= levelMultiplier;
			}
			if (__instance.charge != 0f)
			{
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.selfImpulse *= __instance.charge;
					componentInChildren.worldImpulse.y = 0f;
				}
				if ((Object)(object)val3 != (Object)null)
				{
					val3.damage *= __instance.charge;
					val3.force *= __instance.charge;
				}
			}
		}
		clearlistsss();
		Level val5 = spawnedObject.GetComponent<Level>();
		if ((Object)(object)val5 == (Object)null)
		{
			val5 = spawnedObject.AddComponent<Level>();
		}
		val5.levelMultiplier = levelMultiplier;
		if ((Object)(object)___myLevel == (Object)null)
		{
			return false;
		}
		val5.ignoreTeam = ___myLevel.ignoreTeam;
		val5.level = ___myLevel.level;
		return false;
	}
}
[DefaultExecutionOrder(5000)]
internal sealed class trailrunnn : MonoBehaviour
{
	public static trailrunnn onlyoneee;

	private void Update()
	{
		trailbatchhh.runbatch();
	}

	private void OnDestroy()
	{
		trailbatchhh.cleanupp();
		if ((Object)(object)onlyoneee == (Object)(object)this)
		{
			onlyoneee = null;
		}
	}
}
internal static class trailbatchhh
{
	public sealed class trailstatee
	{
		public RaycastTrail trailzzz;

		public Transform trzzz;

		public ProjectileHit hitzzz;

		public Vector3 lastposs;

		public Vector3 deltaposs;

		public int idxxx = -1;

		public int slottt = -1;
	}

	private const int mincapzzz = 256;

	private static readonly ConditionalWeakTable<RaycastTrail, trailstatee> statezzz = new ConditionalWeakTable<RaycastTrail, trailstatee>();

	private static readonly List<trailstatee> livezzz = new List<trailstatee>();

	private static trailstatee[] snapzzz = new trailstatee[256];

	private static NativeArray<RaycastCommand> cmdzzz;

	private static NativeArray<RaycastHit> hitsss;

	private static int capzzz;

	private static int lastcountzzz;

	private static JobHandle handlezzz;

	private static bool scheduledzzz;

	private static void makerunnerr()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		if (!((Object)(object)trailrunnn.onlyoneee != (Object)null))
		{
			GameObject val = new GameObject("trailrunnn");
			Object.DontDestroyOnLoad((Object)val);
			trailrunnn.onlyoneee = val.AddComponent<trailrunnn>();
		}
	}

	public static void jointrailll(RaycastTrail whoisit)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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)
		trailstatee orCreateValue = statezzz.GetOrCreateValue(whoisit);
		orCreateValue.trailzzz = whoisit;
		orCreateValue.trzzz = ((Component)whoisit).transform;
		orCreateValue.hitzzz = ((Component)whoisit).GetComponent<ProjectileHit>();
		orCreateValue.lastposs = orCreateValue.trzzz.position;
		orCreateValue.deltaposs = Vector3.zero;
		orCreateValue.slottt = -1;
		if (orCreateValue.idxxx < 0)
		{
			orCreateValue.idxxx = livezzz.Count;
			livezzz.Add(orCreateValue);
		}
		makerunnerr();
	}

	public static void leavetrailll(RaycastTrail whoisit)
	{
		if (statezzz.TryGetValue(whoisit, out var value))
		{
			dropstateee(value);
		}
	}

	public static void resettrailll(RaycastTrail whoisit)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (statezzz.TryGetValue(whoisit, out var value) && value.idxxx >= 0)
		{
			value.lastposs = value.trzzz.position;
		}
	}

	private static void dropstateee(trailstatee stzzz)
	{
		if (stzzz.idxxx >= 0)
		{
			int idxxx = stzzz.idxxx;
			trailstatee trailstatee = livezzz[livezzz.Count - 1];
			livezzz[idxxx] = trailstatee;
			trailstatee.idxxx = idxxx;
			livezzz.RemoveAt(livezzz.Count - 1);
			stzzz.idxxx = -1;
			stzzz.slottt = -1;
		}
	}

	private static void reallocc(int newcapzzz, int copyhitsss, int copycmdsss)
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		NativeArray<RaycastCommand> val = default(NativeArray<RaycastCommand>);
		val..ctor(newcapzzz, (Allocator)4, (NativeArrayOptions)1);
		NativeArray<RaycastHit> val2 = default(NativeArray<RaycastHit>);
		val2..ctor(newcapzzz, (Allocator)4, (NativeArrayOptions)1);
		if (capzzz > 0)
		{
			for (int i = 0; i < copyhitsss; i++)
			{
				val2[i] = hitsss[i];
			}
			for (int j = 0; j < copycmdsss; j++)
			{
				val[j] = cmdzzz[j];
			}
			cmdzzz.Dispose();
			hitsss.Dispose();
		}
		cmdzzz = val;
		hitsss = val2;
		capzzz = newcapzzz;
	}

	public static void runbatch()
	{
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0304: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: 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_0318: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: 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_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		if (scheduledzzz)
		{
			((JobHandle)(ref handlezzz)).Complete();
			scheduledzzz = false;
		}
		int count = livezzz.Count;
		if (count == 0)
		{
			return;
		}
		if (snapzzz.Length < count)
		{
			snapzzz = new trailstatee[Mathf.NextPowerOfTwo(count)];
		}
		livezzz.CopyTo(snapzzz);
		if (count > capzzz)
		{
			reallocc(Mathf.NextPowerOfTwo(count), capzzz, 0);
			lastcountzzz = 0;
		}
		int num = 0;
		for (int i = 0; i < count; i++)
		{
			trailstatee trailstatee = snapzzz[i];
			snapzzz[i] = null;
			if (trailstatee.idxxx < 0)
			{
				continue;
			}
			RaycastTrail trailzzz = trailstatee.trailzzz;
			if ((Object)(object)trailzzz == (Object)null)
			{
				dropstateee(trailstatee);
				continue;
			}
			if (!((Behaviour)trailzzz).isActiveAndEnabled)
			{
				trailstatee.slottt = -1;
				continue;
			}
			if (trailzzz.ignoredFrames > 0)
			{
				trailzzz.ignoredFrames--;
				trailstatee.lastposs = trailstatee.trzzz.position;
				trailstatee.slottt = -1;
				continue;
			}
			RaycastHit val = default(RaycastHit);
			bool flag = false;
			if (trailstatee.slottt >= 0)
			{
				val = hitsss[trailstatee.slottt];
				flag = (Object)(object)((RaycastHit)(ref val)).collider != (Object)null;
			}
			trailstatee.slottt = -1;
			ProjectileHit val2 = trailstatee.hitzzz;
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = (trailstatee.hitzzz = ((Component)trailzzz).GetComponent<ProjectileHit>());
			}
			if (trailzzz.useSphereCastOnUnits)
			{
				RaycastHit[] array = Physics.SphereCastAll(trailstatee.lastposs, trailzzz.radius, trailstatee.deltaposs, Vector3.Distance(trailstatee.trzzz.position, trailstatee.lastposs), LayerMask.op_Implicit(trailzzz.mask));
				if ((Object)(object)val2 != (Object)null)
				{
					for (int j = 0; j < array.Length; j++)
					{
						val2.Hit(array[j], 1f);
					}
				}
			}
			if (flag && (Object)(object)val2 != (Object)null)
			{
				val2.Hit(val, 1f);
			}
			if (trailstatee.idxxx >= 0 && !((Object)(object)trailzzz == (Object)null))
			{
				Vector3 position = trailstatee.trzzz.position;
				trailstatee.deltaposs = position - trailstatee.lastposs;
				cmdzzz[num] = new RaycastCommand(trailstatee.lastposs, trailstatee.deltaposs, Vector3.Distance(position, trailstatee.lastposs), LayerMask.op_Implicit(trailzzz.mask), 1);
				trailstatee.slottt = num;
				num++;
				trailstatee.lastposs = position;
			}
		}
		if (num != 0)
		{
			if (capzzz > 256 && num * 4 < capzzz)
			{
				reallocc(Mathf.Max(256, Mathf.NextPowerOfTwo(num)), 0, num);
				lastcountzzz = num;
			}
			RaycastCommand val3 = default(RaycastCommand);
			((RaycastCommand)(ref val3))..ctor(Vector3.zero, Vector3.up, 0f, 0, 1);
			for (int k = num; k < lastcountzzz; k++)
			{
				cmdzzz[k] = val3;
			}
			lastcountzzz = num;
			handlezzz = RaycastCommand.ScheduleBatch(cmdzzz, hitsss, 32, default(JobHandle));
			scheduledzzz = true;
		}
	}

	public static void cleanupp()
	{
		if (scheduledzzz)
		{
			((JobHandle)(ref handlezzz)).Complete();
			scheduledzzz = false;
		}
		if (capzzz > 0)
		{
			cmdzzz.Dispose();
			hitsss.Dispose();
			capzzz = 0;
		}
		lastcountzzz = 0;
		for (int i = 0; i < livezzz.Count; i++)
		{
			livezzz[i].idxxx = -1;
			livezzz[i].slottt = -1;
		}
		livezzz.Clear();
	}
}
[HarmonyPatch(typeof(RaycastTrail), "InitializeOnSpawn")]
internal static class trailinitzzz
{
	private static bool Prefix(RaycastTrail __instance)
	{
		if (!modconfiggg.trailbatchzzz.Value)
		{
			return true;
		}
		trailbatchhh.jointrailll(__instance);
		return false;
	}
}
[HarmonyPatch(typeof(RaycastTrail), "Release")]
internal static class trailleavezzz
{
	private static void Prefix(RaycastTrail __instance)
	{
		trailbatchhh.leavetrailll(__instance);
	}
}
[HarmonyPatch(typeof(RaycastTrail), "Reset")]
internal static class trailresetzzz
{
	private static void Postfix(RaycastTrail __instance)
	{
		trailbatchhh.resettrailll(__instance);
	}
}
[HarmonyPatch(typeof(RuntimeGarbageCollector), "AddGameObject")]
internal static class gcaddobjzzz
{
	private static bool Prefix(GameObject go, ref GameObject[] ___m_trackedObjects, ref int ___m_objectCount)
	{
		if (!modconfiggg.gcgrowzzz.Value)
		{
			return true;
		}
		___m_objectCount++;
		if (___m_objectCount >= ___m_trackedObjects.Length)
		{
			Array.Resize(ref ___m_trackedObjects, ___m_trackedObjects.Length * 2);
		}
		___m_trackedObjects[___m_objectCount - 1] = go;
		return false;
	}
}
[HarmonyPatch(typeof(RuntimeGarbageCollector), "AddPoolable")]
internal static class gcaddpoolzzz
{
	private static bool Prefix(IPoolable poolable, ref IPoolable[] ___m_trackedPooledObjects, ref int ___m_pooledObjectCount)
	{
		if (!modconfiggg.gcgrowzzz.Value)
		{
			return true;
		}
		___m_pooledObjectCount++;
		if (___m_pooledObjectCount >= ___m_trackedPooledObjects.Length)
		{
			Array.Resize(ref ___m_trackedPooledObjects, ___m_trackedPooledObjects.Length * 2);
		}
		___m_trackedPooledObjects[___m_pooledObjectCount - 1] = poolable;
		return false;
	}
}