Decompiled source of EngiArsenal v1.2.3

EngiArsenal.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.EngiTurret.EngiTurretWeapon;
using KinematicCharacterController;
using On.EntityStates.EngiTurret.EngiTurretWeapon;
using On.RoR2;
using RoR2;
using RoR2.ContentManagement;
using RoR2.Projectile;
using RoR2.Skills;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace EngiArsenal;

internal static class Assets
{
	public static T Load<T>(string key) where T : Object
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			T val = Addressables.LoadAssetAsync<T>((object)key).WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Log.LogWarning((object)("Asset not found: " + key));
			}
			return val;
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Asset failed to load: " + key + " (" + ex.GetType().Name + ")"));
			return default(T);
		}
	}
}
internal static class CrosshairHud
{
	private static Texture2D dot;

	private static float fuelAlpha;

	private static float heatAlpha;

	private static float shieldAlpha;

	private static float shownFuel = 1f;

	private static float shownHeat;

	private static float shownShield;

	public static void Draw()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Invalid comparison between Unknown and I4
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: 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_03e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: 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_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0302: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.ShowHud.Value || (int)Event.current.type != 7 || !Object.op_Implicit((Object)(object)Run.instance))
		{
			return;
		}
		LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
		CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.healthComponent) && val.healthComponent.alive)
		{
			if (!Object.op_Implicit((Object)(object)dot))
			{
				dot = MakeDot();
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			float num = (float)Screen.height / 1080f * Mathf.Clamp(Plugin.HudSize.Value, 0.5f, 2f);
			Vector2 center = default(Vector2);
			((Vector2)(ref center))..ctor((float)Screen.width / 2f, (float)Screen.height / 2f);
			float num2 = 44f * num;
			float size = 5f * num;
			if (Jetpack.HasJetpack(val))
			{
				JetpackFuel component = ((Component)val).GetComponent<JetpackFuel>();
				float num3 = (Object.op_Implicit((Object)(object)component) ? Mathf.Clamp01(component.fuel) : 1f);
				bool flag = Object.op_Implicit((Object)(object)component) && (component.flying || component.braking);
				shownFuel = Mathf.MoveTowards(shownFuel, num3, unscaledDeltaTime * 3f);
				fuelAlpha = Fade(fuelAlpha, flag || num3 < 0.995f, unscaledDeltaTime);
				Color color = ((num3 <= 0.2f) ? new Color(1f, 0.3f, 0.25f) : new Color(1f, 0.75f, 0.25f));
				DrawArc(center, num2, size, -55f, 55f, shownFuel, color, fuelAlpha);
			}
			if (Object.op_Implicit((Object)(object)val.skillLocator) && Object.op_Implicit((Object)(object)val.skillLocator.primary) && (Object)(object)val.skillLocator.primary.skillDef == (Object)(object)Plugin.TwinGunsSkill)
			{
				GunHeat component2 = ((Component)val).GetComponent<GunHeat>();
				float num4 = (Object.op_Implicit((Object)(object)component2) ? Mathf.Clamp01(component2.heat) : 0f);
				bool flag2 = Object.op_Implicit((Object)(object)component2) && component2.overheated;
				shownHeat = ((num4 >= shownHeat) ? num4 : Mathf.MoveTowards(shownHeat, num4, unscaledDeltaTime * 6f));
				heatAlpha = Fade(heatAlpha, num4 > 0.001f, unscaledDeltaTime);
				DrawArc(color: (Color)((!flag2) ? Color.Lerp(new Color(1f, 0.9f, 0.4f), new Color(1f, 0.35f, 0.15f), num4) : ((Mathf.Repeat(Time.unscaledTime * 4f, 1f) < 0.5f) ? new Color(1f, 0.15f, 0.1f) : new Color(1f, 0.55f, 0.4f))), center: center, radius: num2, size: size, startDeg: 235f, endDeg: 125f, fill: shownHeat, alpha: heatAlpha, roundUp: flag2);
			}
			if (Object.op_Implicit((Object)(object)PersonalShield.ShieldBuff))
			{
				int buffCount = val.GetBuffCount(PersonalShield.ShieldBuff);
				bool flag3 = buffCount >= 200;
				float num5 = (flag3 ? 0f : Mathf.Clamp01((float)buffCount / 100f));
				shownShield = Mathf.MoveTowards(shownShield, num5, unscaledDeltaTime * 3f);
				shieldAlpha = Fade(shieldAlpha, buffCount > 0, unscaledDeltaTime);
				Color color2 = (Color)((flag3 && Mathf.Repeat(Time.unscaledTime * 8f, 1f) < 0.5f) ? Color.white : new Color(0.5f, 0.85f, 1f));
				DrawArc(center, num2 + 8f * num, size, 240f, 300f, flag3 ? 1f : shownShield, color2, shieldAlpha);
			}
		}
	}

	private static float Fade(float alpha, bool show, float dt)
	{
		return Mathf.MoveTowards(alpha, show ? 1f : 0f, dt * (show ? 6f : 1.5f));
	}

	private static void DrawArc(Vector2 center, float radius, float size, float startDeg, float endDeg, float fill, Color color, float alpha, bool roundUp = true)
	{
		//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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		if (!(alpha <= 0.01f))
		{
			float num = Mathf.Clamp01(fill) * 16f;
			int num2 = (roundUp ? Mathf.CeilToInt(num - 0.001f) : Mathf.FloorToInt(num + 0.001f));
			Color color2 = GUI.color;
			for (int i = 0; i < 16; i++)
			{
				float num3 = (float)i / 15f;
				float num4 = Mathf.Lerp(startDeg, endDeg, num3) * ((float)Math.PI / 180f);
				float num5 = center.x + Mathf.Cos(num4) * radius;
				float num6 = center.y - Mathf.Sin(num4) * radius;
				GUI.color = ((i < num2) ? new Color(color.r, color.g, color.b, 0.9f * alpha) : new Color(0f, 0f, 0f, 0.35f * alpha));
				GUI.DrawTexture(new Rect(num5 - size / 2f, num6 - size / 2f, size, size), (Texture)(object)dot);
			}
			GUI.color = color2;
		}
	}

	private static Texture2D MakeDot()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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)
		Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false)
		{
			filterMode = (FilterMode)1
		};
		for (int i = 0; i < 16; i++)
		{
			for (int j = 0; j < 16; j++)
			{
				float num = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(8f, 8f)) / 8f;
				val.SetPixel(j, i, new Color(1f, 1f, 1f, Mathf.Clamp01((1f - num) * 3f)));
			}
		}
		val.Apply();
		return val;
	}
}
internal static class Jetpack
{
	public static GameObject BurnEffect;

	public static GameObject ExhaustEffect;

	public static void Init()
	{
		BurnEffect = Assets.Load<GameObject>("RoR2/Base/IgniteOnKill/IgniteExplosionVFX.prefab");
		ExhaustEffect = Assets.Load<GameObject>("RoR2/Base/FireballsOnHit/MuzzleflashFireMeatBall.prefab");
		CharacterBody.onBodyStartGlobal += delegate(CharacterBody body)
		{
			//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_003e: Unknown result type (might be due to invalid IL or missing references)
			if (HasJetpack(body))
			{
				if (!Object.op_Implicit((Object)(object)((Component)body).GetComponent<JetpackFuel>()))
				{
					((Component)body).gameObject.AddComponent<JetpackFuel>();
				}
				if (NetworkServer.active && Plugin.NoFallDamage.Value)
				{
					body.bodyFlags = (BodyFlags)(body.bodyFlags | 1);
				}
			}
		};
	}

	public static bool HasJetpack(CharacterBody body)
	{
		if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.skillLocator) && Object.op_Implicit((Object)(object)body.skillLocator.secondary))
		{
			return (Object)(object)body.skillLocator.secondary.skillDef == (Object)(object)Plugin.JetpackSkill;
		}
		return false;
	}
}
public class JetpackFuel : MonoBehaviour
{
	public float fuel = 1f;

	public bool flying;

	public bool braking;

	private float idleTime;

	private float exhaustTimer;

	private CharacterBody body;

	public float Capacity()
	{
		GenericSkill val = ((Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.skillLocator)) ? body.skillLocator.secondary : null);
		float num = (Object.op_Implicit((Object)(object)val) ? Mathf.Max(1f, (float)val.maxStock / 10f) : 1f);
		return Mathf.Max(0.1f, Plugin.FlightTime.Value * num);
	}

	private void FixedUpdate()
	{
		if (!Object.op_Implicit((Object)(object)body))
		{
			body = ((Component)this).GetComponent<CharacterBody>();
		}
		if (!Object.op_Implicit((Object)(object)body) || !body.hasEffectiveAuthority)
		{
			return;
		}
		braking = !flying && TryAutoBrake();
		bool flag = Object.op_Implicit((Object)(object)body.characterMotor) && body.characterMotor.isGrounded;
		if (flying || braking || !flag)
		{
			idleTime = 0f;
		}
		else
		{
			idleTime += Time.fixedDeltaTime;
			if (idleTime >= Plugin.RefuelDelay.Value)
			{
				fuel = Mathf.Min(1f, fuel + Time.fixedDeltaTime / Mathf.Max(0.1f, Plugin.RefuelTime.Value));
			}
		}
		GenericSkill val = (Object.op_Implicit((Object)(object)body.skillLocator) ? body.skillLocator.secondary : null);
		if (Object.op_Implicit((Object)(object)val) && (Object)(object)val.skillDef == (Object)(object)Plugin.JetpackSkill)
		{
			int num = ((!(fuel <= 0.0001f)) ? Mathf.CeilToInt(fuel * (float)val.maxStock - 0.0001f) : 0);
			val.stock = Mathf.Clamp(num, 0, val.maxStock);
		}
	}

	private bool TryAutoBrake()
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: 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_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: 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_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Expected O, but got Unknown
		if (!Plugin.AutoBrake.Value || fuel <= 0f)
		{
			return false;
		}
		CharacterMotor characterMotor = body.characterMotor;
		if (!Object.op_Implicit((Object)(object)characterMotor) || characterMotor.isGrounded)
		{
			return false;
		}
		float num = 0f - characterMotor.velocity.y;
		if (num < Plugin.BrakeFallSpeed.Value)
		{
			return false;
		}
		float num2 = num * 0.6f + 1f;
		Vector3 val = body.footPosition + Vector3.up * 0.2f;
		Vector3 down = Vector3.down;
		LayerIndex world = LayerIndex.world;
		if (!Physics.Raycast(val, down, num2, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1))
		{
			return false;
		}
		Vector3 velocity = characterMotor.velocity;
		velocity.y = Mathf.MoveTowards(velocity.y, 0f - Mathf.Abs(Plugin.SafeLandingSpeed.Value), 120f * Time.fixedDeltaTime);
		characterMotor.velocity = velocity;
		fuel = Mathf.Max(0f, fuel - Time.fixedDeltaTime / Capacity());
		exhaustTimer -= Time.fixedDeltaTime;
		if (exhaustTimer <= 0f && Object.op_Implicit((Object)(object)Jetpack.ExhaustEffect))
		{
			exhaustTimer = 0.15f;
			EffectManager.SpawnEffect(Jetpack.ExhaustEffect, new EffectData
			{
				origin = body.footPosition,
				rotation = Quaternion.LookRotation(Vector3.down)
			}, true);
		}
		return true;
	}
}
public class JetpackFlight : GenericCharacterMain
{
	private JetpackFuel fuel;

	private float burnTimer;

	public override void OnEnter()
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		((GenericCharacterMain)this).OnEnter();
		fuel = ((EntityState)this).gameObject.GetComponent<JetpackFuel>() ?? ((EntityState)this).gameObject.AddComponent<JetpackFuel>();
		fuel.flying = true;
		if (NetworkServer.active && Plugin.NoFallDamage.Value && Object.op_Implicit((Object)(object)((EntityState)this).characterBody))
		{
			CharacterBody characterBody = ((EntityState)this).characterBody;
			characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags | 1);
		}
		if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
		{
			((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
		}
	}

	public override void FixedUpdate()
	{
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: 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_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: 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)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: 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)
		((GenericCharacterMain)this).FixedUpdate();
		if (!((EntityState)this).isAuthority || !Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
		{
			return;
		}
		bool num = Object.op_Implicit((Object)(object)((EntityState)this).inputBank) && ((EntityState)this).inputBank.skill2.down;
		fuel.fuel -= Time.fixedDeltaTime / fuel.Capacity();
		if (!num || fuel.fuel <= 0f)
		{
			fuel.fuel = Mathf.Max(0f, fuel.fuel);
			((EntityState)this).outer.SetNextStateToMain();
			return;
		}
		if (((EntityState)this).characterMotor.isGrounded)
		{
			((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
		}
		Vector3 velocity = ((EntityState)this).characterMotor.velocity;
		velocity.y = Mathf.MoveTowards(velocity.y, Plugin.LiftSpeed.Value, 50f * Time.fixedDeltaTime);
		Vector3 val = (Object.op_Implicit((Object)(object)((EntityState)this).inputBank) ? ((EntityState)this).inputBank.moveVector : Vector3.zero) * ((BaseState)this).moveSpeedStat * Plugin.AirSpeed.Value;
		velocity.x = Mathf.MoveTowards(velocity.x, val.x, 45f * Time.fixedDeltaTime);
		velocity.z = Mathf.MoveTowards(velocity.z, val.z, 45f * Time.fixedDeltaTime);
		((EntityState)this).characterMotor.velocity = velocity;
		burnTimer -= Time.fixedDeltaTime;
		if (burnTimer <= 0f)
		{
			burnTimer = Mathf.Max(0.05f, Plugin.BurnInterval.Value);
			Burn();
		}
	}

	private void Burn()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Expected O, but got Unknown
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: 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_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Expected O, but got Unknown
		Vector3 footPosition = ((EntityState)this).characterBody.footPosition;
		if (Object.op_Implicit((Object)(object)Jetpack.ExhaustEffect))
		{
			EffectManager.SpawnEffect(Jetpack.ExhaustEffect, new EffectData
			{
				origin = footPosition,
				rotation = Quaternion.LookRotation(Vector3.down)
			}, true);
		}
		float num = Mathf.Max(1f, Plugin.BurnMaxHeight.Value);
		Vector3 val = footPosition + Vector3.up * 0.25f;
		Vector3 down = Vector3.down;
		float num2 = num + 0.25f;
		LayerIndex world = LayerIndex.world;
		RaycastHit val2 = default(RaycastHit);
		if (Physics.Raycast(val, down, ref val2, num2, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1))
		{
			float num3 = Mathf.Clamp01(((RaycastHit)(ref val2)).distance / num);
			float num4 = Mathf.Lerp(Plugin.BurnRadiusMin.Value, Plugin.BurnRadiusMax.Value, num3);
			new BlastAttack
			{
				attacker = ((EntityState)this).gameObject,
				inflictor = ((EntityState)this).gameObject,
				teamIndex = TeamComponent.GetObjectTeam(((EntityState)this).gameObject),
				position = ((RaycastHit)(ref val2)).point + Vector3.up * 0.5f,
				radius = num4,
				baseDamage = ((BaseState)this).damageStat * Plugin.BurnDamage.Value,
				baseForce = 0f,
				procCoefficient = 0.5f,
				crit = ((BaseState)this).RollCrit(),
				falloffModel = (FalloffModel)0,
				attackerFiltering = (AttackerFiltering)2,
				damageType = DamageTypeCombo.op_Implicit((DamageType)128)
			}.Fire();
			if (Object.op_Implicit((Object)(object)Jetpack.BurnEffect))
			{
				EffectManager.SpawnEffect(Jetpack.BurnEffect, new EffectData
				{
					origin = ((RaycastHit)(ref val2)).point,
					scale = num4
				}, true);
			}
		}
	}

	public override void OnExit()
	{
		if (Object.op_Implicit((Object)(object)fuel))
		{
			fuel.flying = false;
		}
		((GenericCharacterMain)this).OnExit();
	}

	public override InterruptPriority GetMinimumInterruptPriority()
	{
		return (InterruptPriority)1;
	}
}
internal static class MissileTurret
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static Action <>9__5_0;

		public static Action<Run> <>9__5_1;

		public static hook_OnEnter <>9__5_2;

		public static hook_Fire <>9__5_3;

		public static hook_RecalculateStats <>9__5_4;

		internal void <Init>b__5_0()
		{
			//IL_0005: 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)
			turretBodyIndex = BodyCatalog.FindBodyIndex("EngiTurretBody");
		}

		internal void <Init>b__5_1(Run _)
		{
			knownCannonTurrets.Clear();
		}

		internal void <Init>b__5_2(orig_OnEnter orig, FireGauss self)
		{
			CharacterBody val = (Object.op_Implicit((Object)(object)((EntityState)self).outer) ? ((Component)((EntityState)self).outer).GetComponent<CharacterBody>() : null);
			bool flag = IsCannonTurret(val);
			firingTurret = (flag ? val : null);
			try
			{
				orig.Invoke(self);
			}
			finally
			{
				firingTurret = null;
			}
			if (flag)
			{
				Util.PlaySound("Play_MULT_m1_grenade_launcher_shoot", ((Component)val).gameObject);
			}
		}

		internal void <Init>b__5_3(orig_Fire orig, BulletAttack self)
		{
			if (Object.op_Implicit((Object)(object)firingTurret) && Object.op_Implicit((Object)(object)shellPrefab) && (Object)(object)self.owner == (Object)(object)((Component)firingTurret).gameObject)
			{
				FireShell(self);
			}
			else
			{
				orig.Invoke(self);
			}
		}

		internal void <Init>b__5_4(orig_RecalculateStats orig, CharacterBody self)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			if (!(setAttackSpeed == null) && Object.op_Implicit((Object)(object)self) && self.bodyIndex == turretBodyIndex && IsCannonTurret(self))
			{
				float num = Mathf.Clamp(Plugin.CannonFireRate.Value, 0.05f, 1f);
				setAttackSpeed.Invoke(self, new object[1] { self.attackSpeed * num });
			}
		}
	}

	private static GameObject shellPrefab;

	private static CharacterBody firingTurret;

	private static BodyIndex turretBodyIndex = (BodyIndex)(-1);

	private static readonly HashSet<NetworkInstanceId> knownCannonTurrets = new HashSet<NetworkInstanceId>();

	private static readonly MethodInfo setAttackSpeed = typeof(CharacterBody).GetProperty("attackSpeed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetSetMethod(nonPublic: true);

	public static void Init()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Expected O, but got Unknown
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Expected O, but got Unknown
		shellPrefab = Assets.Load<GameObject>("RoR2/Base/Toolbot/ToolbotGrenadeLauncherProjectile.prefab");
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
		{
			//IL_0005: 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)
			turretBodyIndex = BodyCatalog.FindBodyIndex("EngiTurretBody");
		});
		Run.onRunStartGlobal += delegate
		{
			knownCannonTurrets.Clear();
		};
		object obj = <>c.<>9__5_2;
		if (obj == null)
		{
			hook_OnEnter val = delegate(orig_OnEnter orig, FireGauss self)
			{
				CharacterBody val4 = (Object.op_Implicit((Object)(object)((EntityState)self).outer) ? ((Component)((EntityState)self).outer).GetComponent<CharacterBody>() : null);
				bool flag = IsCannonTurret(val4);
				firingTurret = (flag ? val4 : null);
				try
				{
					orig.Invoke(self);
				}
				finally
				{
					firingTurret = null;
				}
				if (flag)
				{
					Util.PlaySound("Play_MULT_m1_grenade_launcher_shoot", ((Component)val4).gameObject);
				}
			};
			<>c.<>9__5_2 = val;
			obj = (object)val;
		}
		FireGauss.OnEnter += (hook_OnEnter)obj;
		object obj2 = <>c.<>9__5_3;
		if (obj2 == null)
		{
			hook_Fire val2 = delegate(orig_Fire orig, BulletAttack self)
			{
				if (Object.op_Implicit((Object)(object)firingTurret) && Object.op_Implicit((Object)(object)shellPrefab) && (Object)(object)self.owner == (Object)(object)((Component)firingTurret).gameObject)
				{
					FireShell(self);
				}
				else
				{
					orig.Invoke(self);
				}
			};
			<>c.<>9__5_3 = val2;
			obj2 = (object)val2;
		}
		BulletAttack.Fire += (hook_Fire)obj2;
		object obj3 = <>c.<>9__5_4;
		if (obj3 == null)
		{
			hook_RecalculateStats val3 = delegate(orig_RecalculateStats orig, CharacterBody self)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				orig.Invoke(self);
				if (!(setAttackSpeed == null) && Object.op_Implicit((Object)(object)self) && self.bodyIndex == turretBodyIndex && IsCannonTurret(self))
				{
					float num = Mathf.Clamp(Plugin.CannonFireRate.Value, 0.05f, 1f);
					setAttackSpeed.Invoke(self, new object[1] { self.attackSpeed * num });
				}
			};
			<>c.<>9__5_4 = val3;
			obj3 = (object)val3;
		}
		CharacterBody.RecalculateStats += (hook_RecalculateStats)obj3;
	}

	public static bool IsCannonTurret(CharacterBody turret)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)turret) || !Object.op_Implicit((Object)(object)Plugin.MissileTurretSkill))
		{
			return false;
		}
		CharacterMaster master = turret.master;
		if (!Object.op_Implicit((Object)(object)master))
		{
			return false;
		}
		if (knownCannonTurrets.Contains(((NetworkBehaviour)master).netId))
		{
			return true;
		}
		CharacterMaster val = (Object.op_Implicit((Object)(object)master.minionOwnership) ? master.minionOwnership.ownerMaster : null);
		CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetBody() : null);
		if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.skillLocator) && Object.op_Implicit((Object)(object)val2.skillLocator.special) && (Object)(object)val2.skillLocator.special.skillDef == (Object)(object)Plugin.MissileTurretSkill)
		{
			knownCannonTurrets.Add(((NetworkBehaviour)master).netId);
			return true;
		}
		return false;
	}

	private static void FireShell(BulletAttack bullet)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: 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)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		Vector3 aimVector = bullet.aimVector;
		Vector3 val;
		if (!(((Vector3)(ref aimVector)).sqrMagnitude > 0.001f))
		{
			val = Vector3.forward;
		}
		else
		{
			aimVector = bullet.aimVector;
			val = ((Vector3)(ref aimVector)).normalized;
		}
		Vector3 val2 = val;
		ProjectileManager.instance.FireProjectile(new FireProjectileInfo
		{
			projectilePrefab = shellPrefab,
			position = bullet.origin,
			rotation = Util.QuaternionSafeLookRotation(val2),
			owner = bullet.owner,
			damage = bullet.damage * Plugin.CannonDamage.Value,
			force = 600f,
			crit = bullet.isCrit,
			damageColorIndex = (DamageColorIndex)0
		});
	}
}
internal static class PersonalShield
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static Action<CharacterBody> <>9__9_0;

		public static hook_TakeDamage <>9__9_1;

		internal void <Init>b__9_0(CharacterBody body)
		{
			if (HasShieldSkill(body) && !Object.op_Implicit((Object)(object)((Component)body).GetComponent<PersonalShieldController>()))
			{
				((Component)body).gameObject.AddComponent<PersonalShieldController>();
			}
		}

		internal void <Init>b__9_1(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			if (damageInfo != null && Object.op_Implicit((Object)(object)self) && NetworkServer.active)
			{
				PersonalShieldController component = ((Component)self).GetComponent<PersonalShieldController>();
				if (Object.op_Implicit((Object)(object)component) && component.CanAbsorb && (Object)(object)damageInfo.attacker != (Object)(object)((Component)self).gameObject && !IsFallDamage(damageInfo))
				{
					component.Absorb(damageInfo);
				}
			}
			orig.Invoke(self, damageInfo);
		}
	}

	public const int PulseStacks = 200;

	public static BuffDef ShieldBuff;

	public static NetworkSoundEventDef PulseSound;

	public static NetworkSoundEventDef ExplodeSound;

	private static GameObject bubblePrefab;

	private static GameObject bubbleGhostPrefab;

	public static GameObject PulseEffect;

	public static GameObject ExplosionEffect;

	public static void CreateContent()
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		ShieldBuff = ScriptableObject.CreateInstance<BuffDef>();
		((Object)ShieldBuff).name = "EngiArsenalPersonalShield";
		ShieldBuff.canStack = true;
		ShieldBuff.isDebuff = false;
		ShieldBuff.isHidden = true;
		ShieldBuff.buffColor = new Color(0.55f, 0.85f, 1f);
		PulseSound = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
		((Object)PulseSound).name = "EngiArsenalShieldPulse";
		PulseSound.eventName = "Play_engi_shift_end";
		ExplodeSound = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
		((Object)ExplodeSound).name = "EngiArsenalShieldExplode";
		ExplodeSound.eventName = "Play_item_proc_vagrantNova_explode";
	}

	public static void Init()
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		bubblePrefab = Assets.Load<GameObject>("RoR2/Base/Engi/EngiBubbleShield.prefab");
		bubbleGhostPrefab = Assets.Load<GameObject>("RoR2/Base/Engi/EngiBubbleShieldGhost.prefab");
		PulseEffect = Assets.Load<GameObject>("RoR2/Base/Engi/BubbleShieldEndEffect.prefab");
		ExplosionEffect = Assets.Load<GameObject>("RoR2/Base/Common/VFX/OmniExplosionVFX.prefab");
		CharacterBody.onBodyStartGlobal += delegate(CharacterBody body)
		{
			if (HasShieldSkill(body) && !Object.op_Implicit((Object)(object)((Component)body).GetComponent<PersonalShieldController>()))
			{
				((Component)body).gameObject.AddComponent<PersonalShieldController>();
			}
		};
		object obj = <>c.<>9__9_1;
		if (obj == null)
		{
			hook_TakeDamage val = delegate(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
			{
				if (damageInfo != null && Object.op_Implicit((Object)(object)self) && NetworkServer.active)
				{
					PersonalShieldController component = ((Component)self).GetComponent<PersonalShieldController>();
					if (Object.op_Implicit((Object)(object)component) && component.CanAbsorb && (Object)(object)damageInfo.attacker != (Object)(object)((Component)self).gameObject && !IsFallDamage(damageInfo))
					{
						component.Absorb(damageInfo);
					}
				}
				orig.Invoke(self, damageInfo);
			};
			<>c.<>9__9_1 = val;
			obj = (object)val;
		}
		HealthComponent.TakeDamage += (hook_TakeDamage)obj;
	}

	public static bool HasShieldSkill(CharacterBody body)
	{
		if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.skillLocator) && Object.op_Implicit((Object)(object)body.skillLocator.utility))
		{
			return (Object)(object)body.skillLocator.utility.skillDef == (Object)(object)Plugin.PersonalShieldSkill;
		}
		return false;
	}

	private static bool IsFallDamage(DamageInfo info)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Invalid comparison between Unknown and I4
		return (info.damageType.damageType & 0x200000) > 0;
	}

	public static GameObject MakeVisual(Transform follow, float radius)
	{
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Expected O, but got Unknown
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: 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_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: 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_01a5: 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_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			MeshFilter val = null;
			float num = 0f;
			List<MeshFilter> list = new List<MeshFilter>();
			if (Object.op_Implicit((Object)(object)bubblePrefab))
			{
				list.AddRange(bubblePrefab.GetComponentsInChildren<MeshFilter>(true));
			}
			if (Object.op_Implicit((Object)(object)bubbleGhostPrefab))
			{
				list.AddRange(bubbleGhostPrefab.GetComponentsInChildren<MeshFilter>(true));
			}
			Bounds bounds;
			foreach (MeshFilter item in list)
			{
				if (Object.op_Implicit((Object)(object)item.sharedMesh))
				{
					bounds = item.sharedMesh.bounds;
					Vector3 val2 = Vector3.Scale(((Bounds)(ref bounds)).size, ((Component)item).transform.lossyScale);
					float magnitude = ((Vector3)(ref val2)).magnitude;
					if (magnitude > num && Object.op_Implicit((Object)(object)((Component)item).GetComponent<MeshRenderer>()))
					{
						val = item;
						num = magnitude;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			GameObject val3 = new GameObject("PersonalShieldHolder");
			val3.SetActive(false);
			GameObject val4 = Object.Instantiate<GameObject>(((Component)val).gameObject, val3.transform);
			for (int i = 0; i < 2; i++)
			{
				Component[] componentsInChildren = val4.GetComponentsInChildren<Component>(true);
				foreach (Component val5 in componentsInChildren)
				{
					if (Object.op_Implicit((Object)(object)val5) && !(val5 is Transform) && !(val5 is MeshFilter) && !(val5 is Renderer) && !(val5 is ParticleSystem))
					{
						Object.DestroyImmediate((Object)(object)val5);
					}
				}
			}
			val4.transform.SetParent(follow, false);
			val4.transform.localRotation = Quaternion.identity;
			bounds = val.sharedMesh.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			float num2 = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
			float num3 = ((num2 > 0.001f) ? (radius * 2f / num2) : 1f);
			val4.transform.localScale = Vector3.one * num3;
			Transform transform = val4.transform;
			bounds = val.sharedMesh.bounds;
			transform.localPosition = -((Bounds)(ref bounds)).center * num3;
			Object.Destroy((Object)(object)val3);
			val4.SetActive(true);
			return val4;
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Personal shield visual failed: " + ex.Message));
			return null;
		}
	}
}
public class PersonalShieldController : MonoBehaviour
{
	private float hp;

	private float maxHp;

	private float remaining;

	private bool pulsing;

	private float pulseTimer;

	private int lastSentStacks = -1;

	private const string HumStart = "Play_engi_shift_start";

	private const string HumStop = "Stop_engi_shift_loop";

	private bool shown;

	private GameObject visual;

	private Vector3 visualBaseScale;

	private CharacterBody body;

	public bool CanAbsorb
	{
		get
		{
			if (remaining > 0f && !pulsing)
			{
				return hp > 0f;
			}
			return false;
		}
	}

	private CharacterBody Body
	{
		get
		{
			if (!Object.op_Implicit((Object)(object)body))
			{
				return body = ((Component)this).GetComponent<CharacterBody>();
			}
			return body;
		}
	}

	public void ActivateServer(float duration)
	{
		if (NetworkServer.active && Object.op_Implicit((Object)(object)Body) && Object.op_Implicit((Object)(object)Body.healthComponent))
		{
			maxHp = Mathf.Max(1f, Body.healthComponent.fullCombinedHealth * Mathf.Max(0.01f, Plugin.ShieldHealth.Value));
			hp = maxHp;
			remaining = duration;
			pulsing = false;
			SyncStacks();
		}
	}

	public void Absorb(DamageInfo damageInfo)
	{
		float num = Mathf.Min(damageInfo.damage, hp);
		hp -= num;
		damageInfo.damage -= num;
		if (damageInfo.damage <= 0f)
		{
			damageInfo.damage = 0f;
			damageInfo.rejected = true;
		}
		if (hp <= 0f)
		{
			StartPulse();
		}
		else
		{
			SyncStacks();
		}
	}

	private void FixedUpdate()
	{
		if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Body))
		{
			return;
		}
		if (pulsing)
		{
			pulseTimer -= Time.fixedDeltaTime;
			if (pulseTimer <= 0f)
			{
				Explode();
			}
		}
		else if (!(remaining <= 0f))
		{
			remaining -= Time.fixedDeltaTime;
			if (remaining <= 0f)
			{
				remaining = 0f;
				SyncStacks();
			}
			else
			{
				EatProjectiles();
			}
		}
	}

	private void EatProjectiles()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)Body.teamComponent))
		{
			return;
		}
		TeamIndex teamIndex = Body.teamComponent.teamIndex;
		Vector3 corePosition = Body.corePosition;
		float value = Plugin.ShieldRadius.Value;
		LayerIndex projectile = LayerIndex.projectile;
		Collider[] array = Physics.OverlapSphere(corePosition, value, LayerMask.op_Implicit(((LayerIndex)(ref projectile)).mask), (QueryTriggerInteraction)2);
		foreach (Collider val in array)
		{
			ProjectileController val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponentInParent<ProjectileController>() : null);
			if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.teamFilter) && val2.teamFilter.teamIndex != teamIndex)
			{
				ProjectileDamage component = ((Component)val2).GetComponent<ProjectileDamage>();
				hp -= (Object.op_Implicit((Object)(object)component) ? component.damage : 0f);
				Object.Destroy((Object)(object)((Component)val2).gameObject);
				if (hp <= 0f)
				{
					StartPulse();
					return;
				}
			}
		}
		SyncStacks();
	}

	private void StartPulse()
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		hp = 0f;
		pulsing = true;
		pulseTimer = 0.5f;
		SyncStacks();
		if (Object.op_Implicit((Object)(object)PersonalShield.PulseEffect))
		{
			EffectManager.SpawnEffect(PersonalShield.PulseEffect, new EffectData
			{
				origin = Body.corePosition,
				scale = Plugin.ShieldRadius.Value
			}, true);
		}
		if (Object.op_Implicit((Object)(object)PersonalShield.PulseSound))
		{
			EffectManager.SimpleSoundEffect(PersonalShield.PulseSound.index, Body.corePosition, true);
		}
	}

	private void Explode()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: 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_00fe: Expected O, but got Unknown
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		pulsing = false;
		remaining = 0f;
		SyncStacks();
		float num = Mathf.Max(1f, Plugin.ExplosionRadius.Value);
		new BlastAttack
		{
			attacker = ((Component)this).gameObject,
			inflictor = ((Component)this).gameObject,
			teamIndex = TeamComponent.GetObjectTeam(((Component)this).gameObject),
			position = Body.corePosition,
			radius = num,
			baseDamage = Body.damage * Plugin.ExplosionDamage.Value,
			baseForce = 1500f,
			procCoefficient = 1f,
			crit = Body.RollCrit(),
			falloffModel = (FalloffModel)2,
			attackerFiltering = (AttackerFiltering)2
		}.Fire();
		if (Object.op_Implicit((Object)(object)PersonalShield.ExplosionEffect))
		{
			EffectManager.SpawnEffect(PersonalShield.ExplosionEffect, new EffectData
			{
				origin = Body.corePosition,
				scale = num
			}, true);
		}
		if (Object.op_Implicit((Object)(object)PersonalShield.ExplodeSound))
		{
			EffectManager.SimpleSoundEffect(PersonalShield.ExplodeSound.index, Body.corePosition, true);
		}
	}

	private void SyncStacks()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		int num = (pulsing ? 200 : ((remaining > 0f && hp > 0f) ? Mathf.Clamp(Mathf.CeilToInt(hp / maxHp * 100f), 1, 100) : 0));
		if (num != lastSentStacks)
		{
			lastSentStacks = num;
			Body.SetBuffCount(PersonalShield.ShieldBuff.buffIndex, num);
		}
	}

	private void Update()
	{
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)Body) || !Object.op_Implicit((Object)(object)PersonalShield.ShieldBuff))
		{
			return;
		}
		int buffCount = Body.GetBuffCount(PersonalShield.ShieldBuff);
		if (buffCount > 0 && !shown)
		{
			shown = true;
			Util.PlaySound("Play_engi_shift_start", ((Component)this).gameObject);
			Transform follow = (Object.op_Implicit((Object)(object)Body.coreTransform) ? Body.coreTransform : ((Component)this).transform);
			visual = PersonalShield.MakeVisual(follow, Plugin.ShieldRadius.Value);
			if (Object.op_Implicit((Object)(object)visual))
			{
				visualBaseScale = visual.transform.localScale;
			}
		}
		else if (buffCount == 0 && shown)
		{
			Hide();
		}
		if (Object.op_Implicit((Object)(object)visual))
		{
			float num = ((buffCount >= 200) ? (1f + 0.25f * Mathf.Abs(Mathf.Sin(Time.time * 25f))) : 1f);
			visual.transform.localScale = visualBaseScale * num;
		}
	}

	private void Hide()
	{
		shown = false;
		Util.PlaySound("Stop_engi_shift_loop", ((Component)this).gameObject);
		if (Object.op_Implicit((Object)(object)visual))
		{
			Object.Destroy((Object)(object)visual);
		}
		visual = null;
	}

	private void OnDisable()
	{
		if (shown)
		{
			Hide();
		}
	}

	private void OnDestroy()
	{
		if (shown)
		{
			Hide();
		}
	}
}
public class PersonalShieldSkillDef : SkillDef
{
	public override bool IsReady(GenericSkill skillSlot)
	{
		CharacterBody val = (Object.op_Implicit((Object)(object)skillSlot) ? ((Component)skillSlot).GetComponent<CharacterBody>() : null);
		bool flag = Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)PersonalShield.ShieldBuff) && val.GetBuffCount(PersonalShield.ShieldBuff) > 0;
		if (((SkillDef)this).IsReady(skillSlot))
		{
			return !flag;
		}
		return false;
	}
}
public class ActivatePersonalShield : BaseSkillState
{
	public override void OnEnter()
	{
		((BaseState)this).OnEnter();
		PersonalShieldController personalShieldController = ((EntityState)this).gameObject.GetComponent<PersonalShieldController>() ?? ((EntityState)this).gameObject.AddComponent<PersonalShieldController>();
		if (NetworkServer.active)
		{
			personalShieldController.ActivateServer(Plugin.ShieldDuration.Value);
		}
	}

	public override void FixedUpdate()
	{
		((EntityState)this).FixedUpdate();
		if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= 0.2f)
		{
			((EntityState)this).outer.SetNextStateToMain();
		}
	}

	public override InterruptPriority GetMinimumInterruptPriority()
	{
		return (InterruptPriority)1;
	}
}
[BepInPlugin("com.engiarsenal", "EngiArsenal", "1.2.3")]
public class Plugin : BaseUnityPlugin
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static CollectContentPackProvidersDelegate <>9__43_0;

		internal void <Awake>b__43_0(AddContentPackProviderDelegate add)
		{
			add.Invoke((IContentPackProvider)(object)new EngiContent());
		}
	}

	internal static ManualLogSource Log;

	public static ConfigEntry<float> GunDamage;

	public static ConfigEntry<float> GunInterval;

	public static ConfigEntry<float> GunSpread;

	public static ConfigEntry<float> GunRecoil;

	public static ConfigEntry<string> GunSound;

	public static ConfigEntry<float> HeatPerShot;

	public static ConfigEntry<float> CoolDelay;

	public static ConfigEntry<float> CoolSeconds;

	public static ConfigEntry<float> OverheatCoolSeconds;

	public static ConfigEntry<string> OverheatSound;

	public static ConfigEntry<string> DryFireSound;

	public static ConfigEntry<bool> OverheatSmoke;

	public static ConfigEntry<float> FlightTime;

	public static ConfigEntry<float> RefuelTime;

	public static ConfigEntry<float> RefuelDelay;

	public static ConfigEntry<float> LiftSpeed;

	public static ConfigEntry<float> AirSpeed;

	public static ConfigEntry<float> BurnDamage;

	public static ConfigEntry<float> BurnInterval;

	public static ConfigEntry<float> BurnMaxHeight;

	public static ConfigEntry<float> BurnRadiusMin;

	public static ConfigEntry<float> BurnRadiusMax;

	public static ConfigEntry<bool> NoFallDamage;

	public static ConfigEntry<bool> AutoBrake;

	public static ConfigEntry<float> BrakeFallSpeed;

	public static ConfigEntry<float> SafeLandingSpeed;

	public static ConfigEntry<bool> ShowHud;

	public static ConfigEntry<float> HudSize;

	public static ConfigEntry<float> ShieldDuration;

	public static ConfigEntry<float> ShieldCooldown;

	public static ConfigEntry<float> ShieldRadius;

	public static ConfigEntry<float> ShieldHealth;

	public static ConfigEntry<float> ExplosionDamage;

	public static ConfigEntry<float> ExplosionRadius;

	public static ConfigEntry<float> CannonDamage;

	public static ConfigEntry<float> CannonFireRate;

	private static ConfigEntry<int> ConfigVersion;

	public static SkillDef TwinGunsSkill;

	public static SkillDef JetpackSkill;

	public static SkillDef PersonalShieldSkill;

	public static SkillDef MissileTurretSkill;

	internal static readonly List<SkillDef> AllSkills = new List<SkillDef>();

	public void Awake()
	{
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0338: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0343: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		BindConfig();
		GameObject val = Assets.Load<GameObject>("RoR2/Base/Engi/EngiBody.prefab");
		SkillLocator val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<SkillLocator>() : null);
		if (!Object.op_Implicit((Object)(object)val2))
		{
			Log.LogError((object)"Could not find the Engineer, no skills were added.");
			return;
		}
		TwinGunsSkill = MakeSkill("EngiArsenalTwinGuns", "Twin Guns", $"Rapidly fire both arm cannons for <style=cIsDamage>{GunDamage.Value * 100f:0}% damage</style> per shot. " + "Shooting builds <style=cIsUtility>heat</style>; let it max out and the guns <style=cIsHealth>overheat</style> until fully cooled.", "TwinGuns", typeof(FireTwinGuns), "Weapon", 0f, 1, typeof(TwinGunsSkillDef));
		TwinGunsSkill.rechargeStock = 1;
		TwinGunsSkill.mustKeyPress = false;
		TwinGunsSkill.cancelSprintingOnActivation = true;
		TwinGunsSkill.interruptPriority = (InterruptPriority)0;
		JetpackSkill = MakeSkill("EngiArsenalJetpack", "Jetpack", "Hold to fly. Uses <style=cIsUtility>fuel</style> that refills once you're back on the ground. Your exhaust <style=cIsDamage>ignites</style> enemies on the ground below you, and it fires on its own to soften hard landings.", "Jetpack", typeof(JetpackFlight), "Body", 0f, 10);
		JetpackSkill.rechargeStock = 0;
		JetpackSkill.stockToConsume = 0;
		JetpackSkill.requiredStock = 1;
		JetpackSkill.mustKeyPress = true;
		JetpackSkill.isCombatSkill = false;
		JetpackSkill.cancelSprintingOnActivation = false;
		JetpackSkill.fullRestockOnAssign = true;
		JetpackSkill.interruptPriority = (InterruptPriority)1;
		PersonalShieldSkill = MakeSkill("EngiArsenalPersonalShield", "Personal Shield", $"Wrap yourself in a small bubble for <style=cIsUtility>{ShieldDuration.Value:0} seconds</style> that soaks up " + $"<style=cIsUtility>{ShieldHealth.Value * 100f:0}% of your max health</style> in damage and eats enemy projectiles. " + $"If it breaks, it pulses and <style=cIsDamage>explodes for {ExplosionDamage.Value * 100f:0}% damage</style>.", "PersonalShield", typeof(ActivatePersonalShield), "Weapon", ShieldCooldown.Value, 1, typeof(PersonalShieldSkillDef));
		PersonalShieldSkill.mustKeyPress = true;
		PersonalShieldSkill.isCombatSkill = false;
		PersonalShieldSkill.cancelSprintingOnActivation = false;
		PersonalShieldSkill.interruptPriority = (InterruptPriority)1;
		SkillDef val3 = Assets.Load<SkillDef>("RoR2/Base/Engi/EngiBodyPlaceTurret.asset");
		if (Object.op_Implicit((Object)(object)val3))
		{
			MissileTurretSkill = Object.Instantiate<SkillDef>(val3);
			((Object)MissileTurretSkill).name = "EngiArsenalMissileTurret";
			MissileTurretSkill.skillName = "EngiArsenalMissileTurret";
			MissileTurretSkill.skillNameToken = "TR58 Cannon Turret";
			MissileTurretSkill.skillDescriptionToken = "Place a turret that <style=cIsUtility>inherits all your items.</style> It fires slow, heavy " + $"<style=cIsDamage>explosive shells for {CannonDamage.Value * 100f:0}%</style> of a turret shot. They fly straight, so they can miss. Can place up to 2.";
			MissileTurretSkill.icon = Icons.Load("MissileTurret") ?? val3.icon;
			AllSkills.Add(MissileTurretSkill);
		}
		AddVariant(val2.primary, TwinGunsSkill);
		AddVariant(val2.secondary, JetpackSkill);
		AddVariant(val2.utility, PersonalShieldSkill);
		if (Object.op_Implicit((Object)(object)MissileTurretSkill))
		{
			AddVariant(val2.special, MissileTurretSkill);
		}
		PersonalShield.CreateContent();
		object obj = <>c.<>9__43_0;
		if (obj == null)
		{
			CollectContentPackProvidersDelegate val4 = delegate(AddContentPackProviderDelegate add)
			{
				add.Invoke((IContentPackProvider)(object)new EngiContent());
			};
			<>c.<>9__43_0 = val4;
			obj = (object)val4;
		}
		ContentManager.collectContentPackProviders += (CollectContentPackProvidersDelegate)obj;
		TwinGuns.Init();
		Jetpack.Init();
		PersonalShield.Init();
		MissileTurret.Init();
		Log.LogInfo((object)$"EngiArsenal loaded: {AllSkills.Count} new Engineer skills added to the loadout.");
	}

	private void OnGUI()
	{
		CrosshairHud.Draw();
	}

	private void BindConfig()
	{
		GunDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "DamagePerShot", 0.7f, "Damage per shot (0.7 = 70%).");
		GunInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "SecondsBetweenShots", 0.16f, "Time between shots before attack speed.");
		GunSpread = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "SpreadDegrees", 0.4f, "How far shots can stray from the crosshair, in degrees. 0 is perfectly accurate.");
		GunRecoil = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "RecoilKick", 0f, "How much the camera kicks per shot. 0 is none, 1 is a lot.");
		GunSound = ((BaseUnityPlugin)this).Config.Bind<string>("Twin Guns", "ShotSound", "Play_commando_M1", "Sound each shot makes. Other gun sounds that work: Play_wPistol (plain pistol), Play_bandit2_m1_rifle (rifle), Play_MULT_m1_smg_shoot (SMG), Play_bandit_M1_shot (old Bandit). Leave it empty for the turret's cannon sound.");
		HeatPerShot = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "HeatPerShot", 0.05f, "Heat each shot adds (1 is full). 0.05 means about 20 shots to overheat.");
		CoolDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "CoolDelay", 0.35f, "Seconds after you stop shooting before the guns start cooling.");
		CoolSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "CoolSeconds", 1.5f, "Seconds to cool from full heat to zero normally.");
		OverheatCoolSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Twin Guns", "OverheatCoolSeconds", 3f, "Seconds to cool from full to zero after overheating. You can't shoot until it's empty.");
		OverheatSound = ((BaseUnityPlugin)this).Config.Bind<string>("Twin Guns", "OverheatSound", "Play_UI_podSteamBurst,Play_engi_M2_arm", "Sounds played when the guns jam from overheating, comma separated. Also try Play_item_proc_delicateWatch_break or Play_UI_insufficient_funds.");
		DryFireSound = ((BaseUnityPlugin)this).Config.Bind<string>("Twin Guns", "DryFireSound", "Play_engi_M1_chargeStock", "Click you hear when pulling the trigger while overheated. Leave empty for none. Also try Play_UI_menuClick.");
		OverheatSmoke = ((BaseUnityPlugin)this).Config.Bind<bool>("Twin Guns", "OverheatSmoke", true, "Puff smoke out of both cannons while overheated.");
		FlightTime = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "FlightSeconds", 3f, "How many seconds a full tank of fuel lasts. Backup Magazines add 10% each.");
		RefuelTime = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "RefuelSeconds", 4f, "How many seconds it takes to refill an empty tank.");
		RefuelDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "RefuelDelay", 0.5f, "Seconds after you stop flying before fuel starts refilling.");
		LiftSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "LiftSpeed", 7f, "How fast you rise while flying.");
		AirSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "AirSpeedMultiplier", 1.25f, "Sideways flying speed compared to your run speed.");
		BurnDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "BurnDamagePerTick", 0.6f, "Damage of each exhaust burst (0.6 = 60%), and it ignites enemies.");
		BurnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "BurnInterval", 0.25f, "Seconds between exhaust bursts.");
		BurnMaxHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "BurnMaxHeight", 5f, "The exhaust only reaches the ground if you are this close to it, in meters.");
		BurnRadiusMin = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "BurnRadiusLow", 2.5f, "Size of the burn on the ground when you fly low.");
		BurnRadiusMax = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "BurnRadiusHigh", 4f, "Size of the burn on the ground at the top of its reach (the cone spreads out).");
		NoFallDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Jetpack", "AlwaysNoFallDamage", false, "Never take fall damage with the jetpack equipped. Off by default, the auto brake handles landings instead.");
		AutoBrake = ((BaseUnityPlugin)this).Config.Bind<bool>("Jetpack", "AutoBrake", true, "When you're about to land hard and have fuel left, the jetpack fires on its own to slow you down. Out of fuel means you take the fall.");
		BrakeFallSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "BrakeWhenFallingFasterThan", 20f, "The auto brake only kicks in when you fall faster than this.");
		SafeLandingSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Jetpack", "BrakeToSpeed", 8f, "How slow the auto brake gets you before you touch down.");
		ShowHud = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowCrosshairHud", true, "Show fuel, heat and shield health as small arcs around the crosshair.");
		HudSize = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Size", 1f, "Size of the crosshair arcs (1 is normal).");
		ShieldDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Personal Shield", "DurationSeconds", 8f, "How long the shield lasts.");
		ShieldCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Personal Shield", "CooldownSeconds", 20f, "Cooldown of the shield.");
		ShieldRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Personal Shield", "BubbleRadius", 2.5f, "Size of the bubble around you.");
		ShieldHealth = ((BaseUnityPlugin)this).Config.Bind<float>("Personal Shield", "ShieldHealth", 0.5f, "How much damage the shield soaks, as a portion of your max health (0.5 = 50%).");
		ExplosionDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Personal Shield", "ExplosionDamage", 2.5f, "Damage when the shield breaks and explodes (2.5 = 250%).");
		ExplosionRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Personal Shield", "ExplosionRadius", 9f, "Size of the explosion when the shield breaks.");
		CannonDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Cannon Turret", "ShellDamage", 2.5f, "Damage of each cannon shell compared to a normal turret bullet (2.5 = 250%).");
		CannonFireRate = ((BaseUnityPlugin)this).Config.Bind<float>("Cannon Turret", "FireRate", 0.35f, "Fire rate compared to a normal turret (0.35 = about a third as fast).");
		MigrateConfig();
	}

	private void MigrateConfig()
	{
		ConfigVersion = ((BaseUnityPlugin)this).Config.Bind<int>("Internal", "ConfigVersion", 0, "Used to update old settings. Don't change this.");
		if (ConfigVersion.Value < 2)
		{
			BurnMaxHeight.Value = (float)((ConfigEntryBase)BurnMaxHeight).DefaultValue;
			BurnRadiusMax.Value = (float)((ConfigEntryBase)BurnRadiusMax).DefaultValue;
			ConfigVersion.Value = 2;
		}
		try
		{
			(typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(((BaseUnityPlugin)this).Config) as IDictionary)?.Clear();
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Could not tidy old settings: " + ex.Message));
		}
		((BaseUnityPlugin)this).Config.Save();
	}

	private static SkillDef MakeSkill(string id, string name, string desc, string icon, Type state, string machine, float cooldown, int stock, Type defType = null)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		SkillDef val = (SkillDef)ScriptableObject.CreateInstance(defType ?? typeof(SkillDef));
		((Object)val).name = id;
		val.skillName = id;
		val.skillNameToken = name;
		val.skillDescriptionToken = desc;
		val.icon = Icons.Load(icon);
		val.activationState = new SerializableEntityStateType(state);
		val.activationStateMachineName = machine;
		val.baseRechargeInterval = cooldown;
		val.baseMaxStock = stock;
		val.rechargeStock = 1;
		val.requiredStock = 1;
		val.stockToConsume = 1;
		val.beginSkillCooldownOnSkillEnd = false;
		val.canceledFromSprinting = false;
		val.cancelSprintingOnActivation = true;
		val.fullRestockOnAssign = true;
		val.isCombatSkill = true;
		val.mustKeyPress = false;
		val.resetCooldownTimerOnUse = false;
		val.dontAllowPastMaxStocks = false;
		val.keywordTokens = Array.Empty<string>();
		AllSkills.Add(val);
		return val;
	}

	private static void AddVariant(GenericSkill slot, SkillDef skill)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)slot) && Object.op_Implicit((Object)(object)slot.skillFamily) && Object.op_Implicit((Object)(object)skill))
		{
			SkillFamily skillFamily = slot.skillFamily;
			Variant[] array = skillFamily.variants;
			Array.Resize(ref array, array.Length + 1);
			Variant[] array2 = array;
			int num = array.Length - 1;
			Variant val = new Variant
			{
				skillDef = skill
			};
			((Variant)(ref val)).viewableNode = new Node(skill.skillNameToken, false, (Node)null);
			array2[num] = val;
			skillFamily.variants = array;
		}
	}
}
public class EngiContent : IContentPackProvider
{
	private readonly ContentPack pack = new ContentPack();

	public string identifier => "com.engiarsenal";

	public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
	{
		pack.skillDefs.Add(Plugin.AllSkills.ToArray());
		pack.entityStateTypes.Add(new Type[3]
		{
			typeof(FireTwinGuns),
			typeof(JetpackFlight),
			typeof(ActivatePersonalShield)
		});
		pack.buffDefs.Add((BuffDef[])(object)new BuffDef[1] { PersonalShield.ShieldBuff });
		pack.networkSoundEventDefs.Add((NetworkSoundEventDef[])(object)new NetworkSoundEventDef[2]
		{
			PersonalShield.PulseSound,
			PersonalShield.ExplodeSound
		});
		args.ReportProgress(1f);
		yield break;
	}

	public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
	{
		ContentPack.Copy(pack, args.output);
		args.ReportProgress(1f);
		yield break;
	}

	public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
	{
		args.ReportProgress(1f);
		yield break;
	}
}
internal static class Icons
{
	public static Sprite Load(string name)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("EngiArsenal.icons." + name + ".png");
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, array);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("Icon " + name + " failed to load: " + ex.Message));
			return null;
		}
	}
}
internal static class TwinGuns
{
	public static GameObject Tracer;

	public static GameObject Impact;

	public static GameObject Muzzleflash;

	public static GameObject Smoke;

	public static string Sound;

	public static void Init()
	{
		Tracer = Assets.Load<GameObject>("RoR2/Base/Commando/TracerCommandoDefault.prefab");
		Impact = Assets.Load<GameObject>("RoR2/Base/Commando/HitsparkCommando.prefab");
		Muzzleflash = Assets.Load<GameObject>("RoR2/Base/Common/VFX/Muzzleflash1.prefab");
		Smoke = Assets.Load<GameObject>("RoR2/Base/Common/VFX/MuzzleflashSmokeRing.prefab");
	}

	public static string GetSound()
	{
		string value = Plugin.GunSound.Value;
		if (!string.IsNullOrWhiteSpace(value))
		{
			return value.Trim();
		}
		if (Sound != null)
		{
			return Sound;
		}
		Sound = (typeof(FireGauss).GetField("attackSoundString", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) as string) ?? "";
		return Sound;
	}
}
public class GunSide : MonoBehaviour
{
	public bool left;
}
public class GunHeat : MonoBehaviour
{
	public float heat;

	public bool overheated;

	private float sinceShot = 99f;

	private float smokeTimer;

	private float clickTimer;

	private bool smokeLeft;

	private CharacterBody body;

	private static void PlaySounds(string list, GameObject source)
	{
		if (string.IsNullOrWhiteSpace(list))
		{
			return;
		}
		string[] array = list.Split(',');
		foreach (string text in array)
		{
			if (!string.IsNullOrWhiteSpace(text))
			{
				Util.PlaySound(text.Trim(), source);
			}
		}
	}

	public void AddShot(float attackSpeed)
	{
		heat += Mathf.Max(0.001f, Plugin.HeatPerShot.Value) / Mathf.Max(0.1f, attackSpeed);
		sinceShot = 0f;
		if (heat >= 1f)
		{
			heat = 1f;
			if (!overheated)
			{
				PlaySounds(Plugin.OverheatSound.Value, ((Component)this).gameObject);
			}
			overheated = true;
			smokeTimer = 0f;
		}
	}

	private void FixedUpdate()
	{
		sinceShot += Time.fixedDeltaTime;
		if (overheated)
		{
			OverheatedEffects();
			heat -= Time.fixedDeltaTime / Mathf.Max(0.1f, Plugin.OverheatCoolSeconds.Value);
			if (heat <= 0f)
			{
				heat = 0f;
				overheated = false;
			}
		}
		else if (sinceShot >= Plugin.CoolDelay.Value)
		{
			heat = Mathf.Max(0f, heat - Time.fixedDeltaTime / Mathf.Max(0.1f, Plugin.CoolSeconds.Value));
		}
	}

	private void OverheatedEffects()
	{
		smokeTimer -= Time.fixedDeltaTime;
		if (smokeTimer <= 0f && Plugin.OverheatSmoke.Value && Object.op_Implicit((Object)(object)TwinGuns.Smoke))
		{
			smokeTimer = 0.18f;
			smokeLeft = !smokeLeft;
			EffectManager.SimpleMuzzleFlash(TwinGuns.Smoke, ((Component)this).gameObject, smokeLeft ? "MuzzleLeft" : "MuzzleRight", false);
		}
		if (!Object.op_Implicit((Object)(object)body))
		{
			body = ((Component)this).GetComponent<CharacterBody>();
		}
		if (Object.op_Implicit((Object)(object)body) && body.hasEffectiveAuthority && Object.op_Implicit((Object)(object)body.inputBank))
		{
			clickTimer -= Time.fixedDeltaTime;
			GenericSkill val = (Object.op_Implicit((Object)(object)body.skillLocator) ? body.skillLocator.primary : null);
			if (body.inputBank.skill1.down && clickTimer <= 0f && Object.op_Implicit((Object)(object)val) && (Object)(object)val.skillDef == (Object)(object)Plugin.TwinGunsSkill)
			{
				clickTimer = 0.35f;
				PlaySounds(Plugin.DryFireSound.Value, ((Component)this).gameObject);
			}
		}
	}
}
public class TwinGunsSkillDef : SkillDef
{
	public override bool IsReady(GenericSkill skillSlot)
	{
		GunHeat gunHeat = (Object.op_Implicit((Object)(object)skillSlot) ? ((Component)skillSlot).GetComponent<GunHeat>() : null);
		if (((SkillDef)this).IsReady(skillSlot))
		{
			if (Object.op_Implicit((Object)(object)gunHeat))
			{
				return !gunHeat.overheated;
			}
			return true;
		}
		return false;
	}
}
public class FireTwinGuns : BaseSkillState
{
	private float duration;

	public override void OnEnter()
	{
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: 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_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: 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)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		((BaseState)this).OnEnter();
		duration = Plugin.GunInterval.Value / ((BaseState)this).attackSpeedStat;
		GunHeat gunHeat = ((EntityState)this).gameObject.GetComponent<GunHeat>() ?? ((EntityState)this).gameObject.AddComponent<GunHeat>();
		if (gunHeat.overheated)
		{
			if (((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
			return;
		}
		gunHeat.AddShot(((BaseState)this).attackSpeedStat);
		GunSide gunSide = ((EntityState)this).gameObject.GetComponent<GunSide>() ?? ((EntityState)this).gameObject.AddComponent<GunSide>();
		gunSide.left = !gunSide.left;
		string text = (gunSide.left ? "MuzzleLeft" : "MuzzleRight");
		PlayGunAnimation(gunSide.left);
		string sound = TwinGuns.GetSound();
		if (!string.IsNullOrEmpty(sound))
		{
			Util.PlaySound(sound, ((EntityState)this).gameObject);
		}
		if (Object.op_Implicit((Object)(object)TwinGuns.Muzzleflash))
		{
			EffectManager.SimpleMuzzleFlash(TwinGuns.Muzzleflash, ((EntityState)this).gameObject, text, false);
		}
		Ray aimRay = ((BaseState)this).GetAimRay();
		((BaseState)this).StartAimMode(aimRay, 2f, false);
		if (((EntityState)this).isAuthority)
		{
			new BulletAttack
			{
				owner = ((EntityState)this).gameObject,
				weapon = ((EntityState)this).gameObject,
				origin = ((Ray)(ref aimRay)).origin,
				aimVector = ((Ray)(ref aimRay)).direction,
				minSpread = 0f,
				maxSpread = Mathf.Max(0f, Plugin.GunSpread.Value),
				bulletCount = 1u,
				damage = ((BaseState)this).damageStat * Plugin.GunDamage.Value,
				force = 150f,
				tracerEffectPrefab = TwinGuns.Tracer,
				hitEffectPrefab = TwinGuns.Impact,
				muzzleName = text,
				isCrit = ((BaseState)this).RollCrit(),
				radius = 0.15f,
				smartCollision = true,
				procCoefficient = 1f,
				falloffModel = (FalloffModel)1
			}.Fire();
		}
		((EntityState)this).characterBody.AddSpreadBloom(0.05f);
		float num = Mathf.Max(0f, Plugin.GunRecoil.Value);
		if (num > 0f)
		{
			((BaseState)this).AddRecoil(-0.4f * num, -0.6f * num, -0.2f * num, 0.2f * num);
		}
	}

	private void PlayGunAnimation(bool left)
	{
		Animator modelAnimator = ((EntityState)this).GetModelAnimator();
		if (!Object.op_Implicit((Object)(object)modelAnimator))
		{
			return;
		}
		string[] array = ((!left) ? new string[2] { "Gesture Right Cannon, Additive", "Gesture, Right Cannon" } : new string[2] { "Gesture Left Cannon, Additive", "Gesture, Left Cannon" });
		foreach (string text in array)
		{
			if (modelAnimator.GetLayerIndex(text) >= 0)
			{
				((EntityState)this).PlayAnimation(text, left ? "FireGrenadeLeft" : "FireGrenadeRight");
				break;
			}
		}
	}

	public override void FixedUpdate()
	{
		((EntityState)this).FixedUpdate();
		if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= duration)
		{
			((EntityState)this).outer.SetNextStateToMain();
		}
	}

	public override InterruptPriority GetMinimumInterruptPriority()
	{
		return (InterruptPriority)1;
	}
}