Decompiled source of IAmBecomeMissiles v1.3.1

MissileRework.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HG.Reflection;
using IL.RoR2;
using ModularEclipse;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MoreStats;
using On.RoR2;
using On.RoR2.Projectile;
using ProcSolver;
using R2API;
using R2API.Utils;
using RainrotSharedUtils.MoreProjectiles;
using RoR2;
using RoR2.ContentManagement;
using RoR2.ExpansionManagement;
using RoR2.Items;
using RoR2.Projectile;
using RoR2BepInExPack.GameAssetPaths.Version_1_39_0;
using RoR2BepInExPack.GameAssetPathsBetter;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MissileRework")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MissileRework")]
[assembly: AssemblyTitle("MissileRework")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: UnverifiableCode]
[module: UnverifiableCode]
[module: UnverifiableCode]
[module: UnverifiableCode]
[module: UnverifiableCode]
namespace MissileRework;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.RiskOfBrainrot.IAmBecomeMissiles", "IAmBecomeMissiles", "1.2.1")]
[R2APISubmoduleDependency(new string[] { "LanguageAPI", "ContentAddition", "DamageAPI" })]
public class MissileReworkPlugin : BaseUnityPlugin
{
	public static GameObject missilePrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/MissileProjectile");

	public float procCoefficient = 0.75f;

	public float procChance = 10f;

	public static float missileTotalDamageBase = 3f;

	public static float missileTotalDamageStack = 3f;

	private static int maxMissiles = 40;

	public static float overspillBaseDamageThreshold = 3f;

	public static ArtifactDef MissileArtifact = null;

	public const float missileSpread = 45f;

	public const float projectileSpread = 20f;

	public const string guid = "com.RiskOfBrainrot.IAmBecomeMissiles";

	public const string teamName = "RiskOfBrainrot";

	public const string modName = "IAmBecomeMissiles";

	public const string version = "1.2.1";

	public static bool ModularEclipseLoaded = isLoaded("com.HouseOfFruits.ModularEclipse");

	private ItemDef icbmItemDef;

	private static AssetBundle _assetBundle;

	private float shrimpShieldBase = 40f;

	private float shrimpDamageCoeffBase = 0.3f;

	private float shrimpDamageCoeffStack = 0.3f;

	public static PluginInfo PInfo { get; private set; }

	internal static ConfigFile CustomConfigFile { get; set; }

	public static ConfigEntry<bool> ShouldReworkIcbm { get; set; }

	public static ConfigEntry<bool> ShouldAddArtifact { get; set; }

	public static ConfigEntry<bool> ShouldReworkAtg { get; set; }

	public static ConfigEntry<bool> ShouldReworkShrimp { get; set; }

	public static ConfigEntry<bool> ShouldReworkDml { get; set; }

	public static ConfigEntry<bool> ShouldReworkEnemyMissileTargeting { get; set; }

	public static AssetBundle assetBundle
	{
		get
		{
			if ((Object)(object)_assetBundle == (Object)null)
			{
				_assetBundle = AssetBundle.LoadFromFile(GetAssetBundlePath("missilereworkassets"));
			}
			return _assetBundle;
		}
		set
		{
			_assetBundle = value;
		}
	}

	internal void ReworkAtg()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		MissileReworkPlugin.LoadAsync<GameObject>(RoR2_Base_Common.MissileProjectile_prefab, (Action<GameObject>)delegate(GameObject projectile)
		{
			ProjectileController val = default(ProjectileController);
			if (projectile.TryGetComponent<ProjectileController>(ref val))
			{
				val.procCoefficient = procCoefficient;
			}
		});
		GlobalEventManager.ProcessHitEnemy += new Manipulator(RemoveVanillaAtgLogic);
		OnHit.GetHitBehavior += new HitHookEventHandler(AtgReworkLogic);
		LanguageAPI.Add("ITEM_MISSILE_NAME", "AtG Missile Mk.3");
		LanguageAPI.Add("ITEM_MISSILE_PICKUP", "Watch for the backblast.");
		LanguageAPI.Add("ITEM_MISSILE_DESC", $"<style=cIsDamage>{procChance}%</style> chance to fire a volley of missiles on hit " + "for <style=cIsDamage>" + missileTotalDamageBase.AsPercent() + " TOTAL damage</style> <style=cStack>(+" + missileTotalDamageStack.AsPercent() + " per stack)</style>. Every <style=cIsDamage>" + overspillBaseDamageThreshold.AsPercent() + "</style> attack damage dealt causes an additional missile to fire, splitting the total damage.");
	}

	private void AtgReworkLogic(CharacterBody attackerBody, DamageInfo damageInfo, CharacterBody victimBody)
	{
		if (((ProcChainMask)(ref damageInfo.procChainMask)).HasProc((ProcType)1))
		{
			return;
		}
		CharacterMaster master = attackerBody.master;
		Inventory inventory = attackerBody.inventory;
		if (!((Object)(object)master == (Object)null) && !((Object)(object)inventory == (Object)null))
		{
			int itemCountEffective = inventory.GetItemCountEffective(Items.Missile);
			if (itemCountEffective > 0 && Util.CheckRoll(procChance * GetProcRate(damageInfo), master))
			{
				DoMissileProc(damageInfo, ((Component)victimBody).gameObject, attackerBody, master, itemCountEffective);
			}
		}
	}

	private void RemoveVanillaAtgLogic(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_005b: 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)
		ILCursor val = new ILCursor(il);
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.RoR2Content/Items", "Missile"),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCountEffective")
		});
		val.Emit(OpCodes.Pop);
		val.Emit(OpCodes.Ldc_I4, 0);
	}

	public static int CalculateOverspill(DamageInfo damageInfo, float attackerBodyDamage, float overspillThreshold, bool rollForMore = false)
	{
		int num = 0;
		float num2 = damageInfo.damage / attackerBodyDamage;
		num = Mathf.FloorToInt(num2 / overspillThreshold);
		if (!rollForMore)
		{
			return num;
		}
		float num3 = num2 % overspillThreshold;
		if (num3 <= Mathf.Epsilon)
		{
			return num;
		}
		if (Util.CheckRoll0To1(num3 / overspillThreshold, 0f, (CharacterMaster)null))
		{
			num++;
		}
		return num;
	}

	private void DoMissileProc(DamageInfo damageInfo, GameObject victim, CharacterBody attackerBody, CharacterMaster attackerMaster, int missileItemCount)
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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)
		if (missileItemCount > 0)
		{
			Mk3MissileBehavior component = ((Component)attackerBody).gameObject.GetComponent<Mk3MissileBehavior>();
			if (!((Object)(object)component == (Object)null))
			{
				float damage = damageInfo.damage;
				float num = damage / attackerBody.damage;
				int num2 = Mathf.CeilToInt(num / overspillBaseDamageThreshold);
				float num3 = damage * (missileTotalDamageBase + missileTotalDamageStack * (float)(missileItemCount - 1));
				FireProjectileInfo val = default(FireProjectileInfo);
				val.projectilePrefab = CommonAssets.missilePrefab;
				val.procChainMask = damageInfo.procChainMask;
				val.damage = num3 / (float)num2;
				val.crit = damageInfo.crit;
				val.target = victim;
				FireProjectileInfo newMissile = val;
				component.AddMissiles(newMissile, Mathf.Min(num2, maxMissiles - component.currentMissiles.Count));
			}
		}
	}

	private bool IsVanillaIcbmHeld(CharacterBody sender)
	{
		return Object.op_Implicit((Object)(object)sender.inventory) && sender.inventory.GetItemCountEffective(Items.MoreMissile) > 0;
	}

	internal void ReworkIcbm()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		MoreProjectilesModule.MoreProjectilesProvider += new MoreProjectilesEventHandler(IsVanillaIcbmHeld);
		MissileUtils.GetMoreMissileDamageMultiplier += new hook_GetMoreMissileDamageMultiplier(ChangeIcbmMissileDamageMultiplier);
		LanguageAPI.Add("ITEM_MOREMISSILE_PICKUP", "Triple most projectile attacks.");
		LanguageAPI.Add("ITEM_MOREMISSILE_DESC", "Most projectile attacks fire an additional <style=cIsDamage>2 projectiles</style>. Increase missile damage by <style=cIsDamage>0%</style> <style=cStack>+50% per stack)</style>.");
	}

	private float ChangeIcbmMissileDamageMultiplier(orig_GetMoreMissileDamageMultiplier orig, int moreMissileCount)
	{
		return orig.Invoke(moreMissileCount);
	}

	private void DisableICBM()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		AssetReferenceT<ItemDef> val = new AssetReferenceT<ItemDef>(RoR2_DLC1_MoreMissile.MoreMissile_asset);
		AsyncOperationHandle<ItemDef> val2 = AssetAsyncReferenceManager<ItemDef>.LoadAsset(val, (AsyncReferenceHandleUnloadType)2);
		val2.Completed += delegate(AsyncOperationHandle<ItemDef> ctx)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			ItemDef result = ctx.Result;
			result.tier = (ItemTier)5;
			result.deprecatedTier = (ItemTier)5;
		};
	}

	private bool IsMoreMissilesActive(CharacterBody sender)
	{
		return RunArtifactManager.instance.IsArtifactEnabled(MissileArtifact);
	}

	private void CreateArtifact()
	{
		//IL_0080: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Expected O, but got Unknown
		MissileArtifact = ScriptableObject.CreateInstance<ArtifactDef>();
		MissileArtifact.cachedName = "BorboWarfare";
		MissileArtifact.nameToken = "ARTIFACT_MISSILE_NAME";
		MissileArtifact.descriptionToken = "ARTIFACT_MISSILE_DESC";
		MissileArtifact.smallIconSelectedSprite = assetBundle.LoadAsset<Sprite>("Assets/warfare.png");
		MissileArtifact.smallIconDeselectedSprite = assetBundle.LoadAsset<Sprite>("Assets/warfaredeactivated.png");
		MissileArtifact.unlockableDef = null;
		MissileArtifact.requiredExpansion = Addressables.LoadAssetAsync<ExpansionDef>((object)"RoR2/DLC1/Common/DLC1.asset").WaitForCompletion();
		LanguageAPI.Add(MissileArtifact.nameToken, "Artifact of Warfare");
		LanguageAPI.Add(MissileArtifact.descriptionToken, "Triple most projectile attacks.");
		ContentAddition.AddArtifactDef(MissileArtifact);
		if (ModularEclipseLoaded)
		{
			ModularEclipseCompat(MissileArtifact);
		}
		MoreProjectilesModule.MoreProjectilesProvider += new MoreProjectilesEventHandler(IsMoreMissilesActive);
	}

	internal static bool isLoaded(string modguid)
	{
		foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
		{
			string key = pluginInfo.Key;
			PluginInfo value = pluginInfo.Value;
			if (key == modguid)
			{
				return true;
			}
		}
		return false;
	}

	public static string GetAssetBundlePath(string bundleName)
	{
		return Path.Combine(Path.GetDirectoryName(PInfo.Location), bundleName);
	}

	public void Awake()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Expected O, but got Unknown
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Expected O, but got Unknown
		PInfo = ((BaseUnityPlugin)this).Info;
		CustomConfigFile = new ConfigFile(Paths.ConfigPath + "\\IAmBecomeMissiles.cfg", true);
		ShouldAddArtifact = CustomConfigFile.Bind<bool>("IAmBecomeMissiles: Content", "Artifact of Warfare", true, "Set to TRUE to turn Pocket ICBM into an artifact.");
		ShouldReworkIcbm = CustomConfigFile.Bind<bool>("IAmBecomeMissiles: Reworks", "Pocket ICBM", true, "Set to TRUE to disable Pocket ICBM. Recommended with Artifact of Warfare enabled!");
		ShouldReworkAtg = CustomConfigFile.Bind<bool>("IAmBecomeMissiles: Reworks", "AtG Missile Mk.3", true, "Set to TRUE to rework AtG Missile Mk.1.");
		ShouldReworkShrimp = CustomConfigFile.Bind<bool>("IAmBecomeMissiles: Reworks", "Plasma Shrimp", true, "Set to TRUE to rework Plasma Shrimp.");
		ShouldReworkDml = CustomConfigFile.Bind<bool>("IAmBecomeMissiles: Reworks", "Disposable Missile Launcher", true, "Set to TRUE to rework Disposable Missile Launcher.");
		ShouldReworkEnemyMissileTargeting = CustomConfigFile.Bind<bool>("IAmBecomeMissiles: Reworks", "Missile Tracking", true, "Set to TRUE to rework missile tracking on enemies.");
		if (ShouldAddArtifact.Value)
		{
			CreateArtifact();
		}
		if (ShouldReworkIcbm.Value)
		{
			ReworkIcbm();
		}
		if (ShouldReworkAtg.Value)
		{
			ReworkAtg();
		}
		if (ShouldReworkShrimp.Value)
		{
			ReworkPrimp();
		}
		if (ShouldReworkEnemyMissileTargeting.Value)
		{
			MissileController.FixedUpdate += new hook_FixedUpdate(MissileController_FixedUpdate);
			MissileController.FindTarget += new hook_FindTarget(MissileController_FindTarget);
		}
	}

	private void MissileController_FixedUpdate(orig_FixedUpdate orig, MissileController self)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Invalid comparison between Unknown and I4
		if ((Object)(object)self.teamFilter != (Object)null && (int)self.teamFilter.teamIndex != 1 && (Object)(object)self.targetComponent.target != (Object)null)
		{
			HurtBox component = ((Component)self.targetComponent.target).GetComponent<HurtBox>();
			object obj;
			if (component == null)
			{
				obj = null;
			}
			else
			{
				HealthComponent healthComponent = component.healthComponent;
				obj = ((healthComponent != null) ? healthComponent.body.characterMotor : null);
			}
			CharacterMotor val = (CharacterMotor)obj;
			if ((Object)(object)val != (Object)null && val.isGrounded)
			{
				self.targetComponent.target = self.FindTarget();
			}
		}
		orig.Invoke(self);
	}

	private Transform MissileController_FindTarget(orig_FindTarget orig, MissileController self)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Invalid comparison between Unknown and I4
		//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_0043: 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)
		//IL_005e: 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)
		if ((int)self.teamFilter.teamIndex == 1)
		{
			return orig.Invoke(self);
		}
		self.search.searchOrigin = self.transform.position;
		self.search.searchDirection = self.transform.forward;
		((TeamMask)(ref self.search.teamMaskFilter)).RemoveTeam(self.teamFilter.teamIndex);
		self.search.sortMode = (SortMode)1;
		self.search.RefreshCandidates();
		self.search.candidatesEnumerable = (from v in self.search.candidatesEnumerable.AsEnumerable()
			where !((Object)(object)v.hurtBox.healthComponent.body.characterMotor != (Object)null) || !v.hurtBox.healthComponent.body.characterMotor.isGrounded
			select v).ToList();
		HurtBox val = self.search.GetResults().FirstOrDefault();
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		return ((Component)val).transform;
	}

	public static float GetProcRate(DamageInfo damageInfo)
	{
		if (!Chainloader.PluginInfos.ContainsKey("com.RiskOfBrainrot.ProcSolver"))
		{
			return damageInfo.procCoefficient;
		}
		return _GetProcRate(damageInfo);
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	private static float _GetProcRate(DamageInfo damageInfo)
	{
		return ProcSolverPlugin.GetProcRateMod(damageInfo);
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	public static void ModularEclipseCompat(ArtifactDef artifactDef)
	{
		ModularEclipsePlugin.SetArtifactDefaultWhitelist(artifactDef, true);
	}

	public static AssetReferenceT<T> LoadAsync<T>(string guid, Action<T> callback) where T : Object
	{
		//IL_0018: 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_0040: Unknown result type (might be due to invalid IL or missing references)
		AssetReferenceT<T> val = new AssetReferenceT<T>(guid);
		AsyncOperationHandle<T> handle2 = AssetAsyncReferenceManager<T>.LoadAsset(val, (AsyncReferenceHandleUnloadType)2);
		if (callback == null)
		{
			return val;
		}
		if (handle2.IsDone)
		{
			onCompleted(handle2);
			return val;
		}
		handle2.Completed += onCompleted;
		return val;
		void onCompleted(AsyncOperationHandle<T> handle)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			if (handle.Result == null || (int)handle.Status != 1)
			{
				Debug.LogError((object)$"Failed to load asset [{handle.DebugName}] : {handle.OperationException}");
			}
			else
			{
				callback(handle.Result);
			}
		}
	}

	internal void ReworkPrimp()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		GlobalEventManager.ProcessHitEnemy += new Manipulator(ShrimpRework);
		RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(ShrimpShieldFix);
		LanguageAPI.Add("ITEM_MISSILEVOID_PICKUP", "While you have shield, fire a missile on every hit. <style=cIsVoid>Corrupts all AtG Missile Mk. 3s</style>.");
		LanguageAPI.Add("ITEM_MISSILEVOID_DESC", $"Gain <style=cIsHealing>{shrimpShieldBase} shield</style>. " + "While you have a <style=cIsHealing>shield</style>, hitting an enemy fires a missile that deals " + $"<style=cIsDamage>{shrimpDamageCoeffBase * 100f}%</style> " + $"<style=cStack>(+{shrimpDamageCoeffStack * 100f}% per stack)</style> TOTAL damage. " + "<style=cIsVoid>Corrupts all AtG Missile Mk. 3s</style>.");
	}

	private void ShrimpShieldFix(CharacterBody sender, StatHookEventArgs args)
	{
		Inventory inventory = sender.inventory;
		if (Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCountEffective(Items.MissileVoid) > 0)
		{
			args.shieldMultAdd -= 0.1f;
			args.baseShieldAdd += shrimpShieldBase;
		}
	}

	private void ShrimpRework(ILContext il)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		int shrimpLoc = 32;
		if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.DLC1Content/Items", "MissileVoid"),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCountEffective"),
			(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref shrimpLoc)
		}))
		{
			Debug.LogError((object)"IAmBecomeMissiles: Shrimp rework hook failed (breakpoint 1)");
			return;
		}
		if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "RoR2.Util", "OnHitProcDamage")
		}))
		{
			Debug.LogError((object)"IAmBecomeMissiles: Shrimp rework hook failed (breakpoint 2)");
			return;
		}
		val.Emit(OpCodes.Ldloc, shrimpLoc);
		val.EmitDelegate<Func<float, int, float>>((Func<float, int, float>)((float damageCoefficient, int itemCount) => shrimpDamageCoeffBase + shrimpDamageCoeffStack * (float)(itemCount - 1)));
		if (!ShouldReworkIcbm.Value)
		{
			return;
		}
		if (!val.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.DLC1Content/Items", "MoreMissile"),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCountEffective")
		}))
		{
			Debug.LogError((object)"IAmBecomeMissiles: Shrimp rework hook failed (breakpoint 3)");
			return;
		}
		val.EmitDelegate<Func<int, int>>((Func<int, int>)((int icbmCount) => RunArtifactManager.instance.IsArtifactEnabled(MissileArtifact) ? 1 : 0));
	}
}
public class Mk3MissileBehavior : BaseItemBodyBehavior
{
	public List<FireProjectileInfo> currentMissiles = new List<FireProjectileInfo>(0);

	private float missileMaxTimer = 0.2f;

	private float currentMissileTimer = 0f;

	private float missileSpread = 0f;

	private float missileSpreadFraction = 0.33f;

	private float missileSpreadMax = 0.6f;

	[ItemDefAssociation(useOnServer = true, useOnClient = false)]
	private static ItemDef GetItemDef()
	{
		return Items.Missile;
	}

	public void AddMissiles(FireProjectileInfo newMissile, int count)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		while (count > 0)
		{
			count--;
			currentMissiles.Add(newMissile);
		}
	}

	private void FixedUpdate()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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)
		//IL_004d: 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_0084: 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_0090: 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)
		//IL_009c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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)
		if (currentMissiles.Count > 0 && base.stack > 0)
		{
			while (currentMissileTimer <= 0f)
			{
				FireProjectileInfo val = currentMissiles[0];
				val.position = ((Component)((BaseItemBodyBehavior)this).body).gameObject.transform.position;
				missileSpread += (missileSpreadMax - missileSpread) * missileSpreadFraction;
				MissileUtils.FireMissile(((BaseItemBodyBehavior)this).body.corePosition, ((BaseItemBodyBehavior)this).body, val.procChainMask, val.target, val.damage, val.crit, val.projectilePrefab, (DamageColorIndex)3, Vector3.up + Random.insideUnitSphere * missileSpread, 200f, true);
				currentMissiles.RemoveAt(0);
				currentMissileTimer += GetScaledDelay();
			}
			if (currentMissileTimer > 0f)
			{
				currentMissileTimer -= Time.fixedDeltaTime;
			}
		}
		else
		{
			currentMissileTimer = GetScaledDelay();
			missileSpread = 0f;
		}
	}

	private float GetScaledDelay()
	{
		return missileMaxTimer / ((BaseItemBodyBehavior)this).body.attackSpeed;
	}
}
public static class Extensions
{
	public static string AsPercent(this float d)
	{
		return d * 100f + "%";
	}

	public static GameObject FixItemModel(this GameObject prefab)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_0076: 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: Expected O, but got Unknown
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: 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_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)prefab == (Object)null)
		{
			prefab = Resources.Load<GameObject>("prefabs/NullModel");
		}
		ModelPanelParameters val = prefab.AddComponent<ModelPanelParameters>();
		val.minDistance = 1f;
		val.maxDistance = 15f;
		Transform val2 = prefab.transform.Find("FocusPos");
		if ((Object)(object)val2 == (Object)null)
		{
			GameObject val3 = new GameObject("FocusPos");
			val2 = val3.transform;
			val2.parent = prefab.transform;
			val2.localPosition = Vector3.zero;
		}
		val.focusPointTransform = val2;
		Transform val4 = prefab.transform.Find("CameraPos");
		if ((Object)(object)val4 == (Object)null)
		{
			GameObject val5 = new GameObject("CameraPos");
			val4 = val5.transform;
			val4.parent = prefab.transform;
			val4.SetPositionAndRotation(val2.position + Vector3.forward * -7f + Vector3.right * -1f, val4.rotation);
		}
		val.cameraPositionTransform = val4;
		return prefab;
	}

	public static void AddPersistentListener(this HoldoutZoneControllerChargedUnityEvent unityEvent, UnityAction<HoldoutZoneController> action)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//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)
		PersistentCallGroup persistentCalls = ((UnityEventBase)unityEvent).m_PersistentCalls;
		PersistentCall val = new PersistentCall();
		ref Object target = ref val.m_Target;
		object? target2 = ((Delegate)(object)action).Target;
		target = (Object)((target2 is Object) ? target2 : null);
		val.m_TargetAssemblyTypeName = UnityEventTools.TidyAssemblyTypeName(((Delegate)(object)action).Method.DeclaringType.AssemblyQualifiedName);
		val.m_MethodName = ((Delegate)(object)action).Method.Name;
		val.m_CallState = (UnityEventCallState)2;
		val.m_Mode = (PersistentListenerMode)0;
		persistentCalls.AddListener(val);
	}

	public static void AddPersistentListener(this UnityEvent<Interactor> unityEvent, UnityAction<Interactor> action)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//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)
		PersistentCallGroup persistentCalls = ((UnityEventBase)unityEvent).m_PersistentCalls;
		PersistentCall val = new PersistentCall();
		ref Object target = ref val.m_Target;
		object? target2 = ((Delegate)(object)action).Target;
		target = (Object)((target2 is Object) ? target2 : null);
		val.m_TargetAssemblyTypeName = UnityEventTools.TidyAssemblyTypeName(((Delegate)(object)action).Method.DeclaringType.AssemblyQualifiedName);
		val.m_MethodName = ((Delegate)(object)action).Method.Name;
		val.m_CallState = (UnityEventCallState)2;
		val.m_Mode = (PersistentListenerMode)0;
		persistentCalls.AddListener(val);
	}

	public static void AddPersistentListener(this UnityEvent<CharacterMaster> unityEvent, UnityAction<CharacterMaster> action)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//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)
		PersistentCallGroup persistentCalls = ((UnityEventBase)unityEvent).m_PersistentCalls;
		PersistentCall val = new PersistentCall();
		ref Object target = ref val.m_Target;
		object? target2 = ((Delegate)(object)action).Target;
		target = (Object)((target2 is Object) ? target2 : null);
		val.m_TargetAssemblyTypeName = UnityEventTools.TidyAssemblyTypeName(((Delegate)(object)action).Method.DeclaringType.AssemblyQualifiedName);
		val.m_MethodName = ((Delegate)(object)action).Method.Name;
		val.m_CallState = (UnityEventCallState)2;
		val.m_Mode = (PersistentListenerMode)0;
		persistentCalls.AddListener(val);
	}

	public static void AddPersistentListener(this UnityEvent<GameObject> unityEvent, UnityAction<GameObject> action)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//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)
		PersistentCallGroup persistentCalls = ((UnityEventBase)unityEvent).m_PersistentCalls;
		PersistentCall val = new PersistentCall();
		ref Object target = ref val.m_Target;
		object? target2 = ((Delegate)(object)action).Target;
		target = (Object)((target2 is Object) ? target2 : null);
		val.m_TargetAssemblyTypeName = UnityEventTools.TidyAssemblyTypeName(((Delegate)(object)action).Method.DeclaringType.AssemblyQualifiedName);
		val.m_MethodName = ((Delegate)(object)action).Method.Name;
		val.m_CallState = (UnityEventCallState)2;
		val.m_Mode = (PersistentListenerMode)0;
		persistentCalls.AddListener(val);
	}
}
public static class Tools
{
}