Decompiled source of FruityJumps v1.0.5

JumpRework.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using EntityStates;
using EntityStates.ClayBoss;
using EntityStates.Headstompers;
using IL.EntityStates;
using IL.EntityStates.Headstompers;
using IL.RoR2;
using MissileRework;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.EntityStates;
using On.RoR2.Items;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.Items;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

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

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.RiskOfBrainrot.FruityJumps", "FruityJumps", "1.0.5")]
[R2APISubmoduleDependency(new string[] { "LanguageAPI", "ContentAddition" })]
public class JumpReworkPlugin : BaseUnityPlugin
{
	public static int featherJumpCount = 1;

	public float hopooDamageBuffDuration = 0.5f;

	public static float hopooDamageIncreasePerBuff = 0.1f;

	private float featherBaseDuration = 0.75f;

	private float featherStackDuration = 0.5f;

	public static int fallBootsJumpCount = 3;

	public bool fallBootsSuperJumpLast = true;

	public float superJumpStrengthFirst = 1.2f;

	public float superJumpStrengthLast = 2f;

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

	public const string teamName = "RiskOfBrainrot";

	public const string modName = "FruityJumps";

	public const string version = "1.0.5";

	public static float doubleJumpVerticalBonus = 1f;

	public static float doubleJumpHorizontalBonus = 1.1f;

	public static float dynamicJumpAscentHoldGravity = 0.8f;

	public static float dynamicJumpAscentReleaseGravity = 1.3f;

	public static float dynamicJumpDescentGravity = 1f;

	public static int urnJumpCount = 2;

	public int urnBallCountBase = 3;

	public int urnBallCountStack = 0;

	public float urnBallYawSpread = 25f;

	public float urnBallDamageCoefficient = 2.5f;

	public float urnBallChance = 0.3f;

	public static GameObject miredUrnTarball;

	public static PluginInfo PInfo { get; private set; }

	private void FeatherRework()
	{
		JumpStatHook.OnJumpEvent += FeatherOnJump;
		LanguageAPI.Add("ITEM_FEATHER_PICKUP", "Double jump. Jumping gives you a boost of movement speed.");
		LanguageAPI.Add("ITEM_FEATHER_DESC", $"Gain <style=cIsUtility>{featherJumpCount}</style> jumps. " + "<style=cIsUtility>On jump</style>, increases <style=cIsUtility>movement speed</style> by <style=cIsUtility>125%</style>, " + $"fading over <style=cIsUtility>{featherBaseDuration}</style> <style=cStack>(+{featherStackDuration} per stack)</style> seconds.");
	}

	private void FeatherOnJump(CharacterMotor motor, ref float verticalBonus)
	{
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: 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_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
		CharacterBody body = motor.body;
		if (!Object.op_Implicit((Object)(object)body))
		{
			return;
		}
		Inventory inventory = body.inventory;
		if (!Object.op_Implicit((Object)(object)inventory))
		{
			return;
		}
		int itemCount = inventory.GetItemCount(Items.Feather);
		if (itemCount <= 0 || !IsDoubleJump(motor, body))
		{
			return;
		}
		int num = 5;
		float num2 = featherBaseDuration + (float)(itemCount - 1) * featherStackDuration;
		body.ClearTimedBuffs(Buffs.KillMoveSpeed);
		for (int i = 0; i < num; i++)
		{
			body.AddTimedBuff(Buffs.KillMoveSpeed, num2 * (float)(i + 1) / (float)num);
		}
		EffectData val = new EffectData();
		val.origin = body.corePosition;
		CharacterMotor characterMotor = body.characterMotor;
		bool flag = false;
		if (Object.op_Implicit((Object)(object)characterMotor))
		{
			Vector3 moveDirection = characterMotor.moveDirection;
			if (moveDirection != Vector3.zero)
			{
				val.rotation = Util.QuaternionSafeLookRotation(moveDirection);
				flag = true;
			}
		}
		if (!flag)
		{
			val.rotation = body.transform.rotation;
		}
		EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/MoveSpeedOnKillActivate"), val, true);
	}

	private void StompersRework()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		HeadstompersIdle.FixedUpdateAuthority += new Manipulator(HeadstompersJumpBoost);
		LanguageAPI.Add("ITEM_FALLBOOTS_PICKUP", "Quadruple jump. Hold 'Interact' to slam down to the ground.");
		LanguageAPI.Add("ITEM_FALLBOOTS_DESC", $"Gain <style=cIsUtility>{fallBootsJumpCount}</style> jumps. " + "Creates a <style=cIsDamage>5m-100m</style> radius <style=cIsDamage>kinetic explosion</style> on hitting the ground, dealing <style=cIsDamage>1000%-10000%</style> base damage that scales up with <style=cIsDamage>fall distance</style>. Recharges in <style=cIsDamage>10</style> <style=cStack>(-50% per stack)</style> seconds.");
	}

	private void HeadstompersJumpBoost(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0039: 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)
		ILCursor val = new ILCursor(il);
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[1]
		{
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<BaseHeadstompersState>(x, "get_isGrounded")
		});
		val.Emit(OpCodes.Ldarg_0);
		val.EmitDelegate<Func<bool, HeadstompersIdle, bool>>((Func<bool, HeadstompersIdle, bool>)delegate(bool isGrounded, HeadstompersIdle self)
		{
			bool result = isGrounded;
			if (fallBootsSuperJumpLast)
			{
				CharacterMotor bodyMotor = ((BaseHeadstompersState)self).bodyMotor;
				if (Object.op_Implicit((Object)(object)bodyMotor))
				{
					result = IsLastJump(bodyMotor, ((BaseHeadstompersState)self).body);
				}
			}
			return result;
		});
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdflda<Vector3>(x, "y"),
			(Instruction x) => ILPatternMatchingExt.MatchDup(x)
		});
		float num = default(float);
		val.GotoNext((MoveType)0, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num),
			(Instruction x) => ILPatternMatchingExt.MatchMul(x)
		});
		val.Remove();
		val.Emit(OpCodes.Ldc_R4, fallBootsSuperJumpLast ? superJumpStrengthLast : superJumpStrengthFirst);
	}

	public static bool IsMissileArtifactEnabled()
	{
		if (Tools.isLoaded("com.RiskOfBrainrot.IAmBecomeMissiles"))
		{
			return GetMissileArtifactEnabled();
		}
		return false;
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	private static bool GetMissileArtifactEnabled()
	{
		return RunArtifactManager.instance.IsArtifactEnabled(MissileReworkPlugin.MissileArtifact);
	}

	public void Awake()
	{
		CreateMiredUrnTarball();
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(JumpReworks));
	}

	public static bool IsDoubleJump(CharacterMotor motor, CharacterBody body)
	{
		int maxJumpCount = body.maxJumpCount;
		int baseJumpCount = body.baseJumpCount;
		int num = motor.jumpCount + 1;
		if (num > baseJumpCount)
		{
			return true;
		}
		return false;
	}

	public static bool IsBaseJump(CharacterMotor motor, CharacterBody body)
	{
		int maxJumpCount = body.maxJumpCount;
		int baseJumpCount = body.baseJumpCount;
		int num = motor.jumpCount + 1;
		if (num <= baseJumpCount)
		{
			return true;
		}
		return false;
	}

	public static bool IsLastJump(CharacterMotor motor, CharacterBody body)
	{
		int maxJumpCount = body.maxJumpCount;
		int baseJumpCount = body.baseJumpCount;
		int num = motor.jumpCount + 1;
		if (num == maxJumpCount)
		{
			return true;
		}
		return false;
	}

	private void JumpReworks()
	{
		//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
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		CharacterBody.RecalculateStats += new Manipulator(JumpReworkJumpCount);
		GenericCharacterMain.ApplyJumpVelocity += new hook_ApplyJumpVelocity(DoJumpEvent);
		CharacterMotor.PreMove += new Manipulator(DynamicJump);
		GenericCharacterMain.ProcessJump += new Manipulator(FeatherNerf);
		FeatherRework();
		StompersRework();
		MiredUrnRework();
	}

	private void FeatherNerf(ILContext il)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Expected O, but got Unknown
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: 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>[3]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<EntityState>(x, "get_characterBody"),
			(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterBody>(x, "baseJumpCount")
		});
		int horizontalBoostLoc = 3;
		float num2 = default(float);
		val.GotoNext((MoveType)0, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num2),
			(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref horizontalBoostLoc)
		});
		val.Remove();
		val.Emit(OpCodes.Ldc_R4, doubleJumpHorizontalBonus);
		int index = val.Index;
		val.Index = index + 1;
		int verticalBoostLoc = 4;
		float num = default(float);
		val.GotoNext((MoveType)0, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, ref num),
			(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref verticalBoostLoc)
		});
		val.Remove();
		val.Emit(OpCodes.Ldc_R4, doubleJumpVerticalBonus);
	}

	private void DynamicJump(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)
		ILCursor val = new ILCursor(il);
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Physics>(x, "get_gravity"),
			(Instruction x) => ILPatternMatchingExt.MatchLdfld<Vector3>(x, "y")
		});
		val.Emit(OpCodes.Ldarg_0);
		val.EmitDelegate<Func<float, CharacterMotor, float>>((Func<float, CharacterMotor, float>)delegate(float gravityIn, CharacterMotor motor)
		{
			float num = gravityIn;
			if (!motor.disableAirControlUntilCollision)
			{
				num = ((!(motor.velocity.y >= 0f)) ? (num * dynamicJumpDescentGravity) : ((!motor.body.inputBank.jump.down) ? (num * dynamicJumpAscentReleaseGravity) : (num * dynamicJumpAscentHoldGravity)));
			}
			return num;
		});
	}

	private void JumpReworkJumpCount(ILContext il)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Expected O, but got Unknown
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		int featherCountLoc = 0;
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[3]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.RoR2Content/Items", "Feather"),
			(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCount"),
			(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref featherCountLoc)
		});
		val.GotoNext((MoveType)2, new Func<Instruction, bool>[2]
		{
			(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterBody>(x, "baseJumpCount"),
			(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, featherCountLoc)
		});
		val.Emit(OpCodes.Ldarg_0);
		val.EmitDelegate<Func<int, CharacterBody, int>>((Func<int, CharacterBody, int>)delegate(int featherCount, CharacterBody self)
		{
			int num = 0;
			Inventory inventory = self.inventory;
			if ((Object)(object)inventory != (Object)null)
			{
				if (featherCount > 0)
				{
					num += featherJumpCount;
				}
				if (inventory.GetItemCount(Items.SiphonOnLowHealth) > 0)
				{
					num += urnJumpCount;
				}
				if (inventory.GetItemCount(Items.FallBoots) > 0)
				{
					num += fallBootsJumpCount;
				}
				num += JumpStatHook.InvokeStatHook(self);
			}
			return num;
		});
	}

	private void DoJumpEvent(orig_ApplyJumpVelocity orig, CharacterMotor characterMotor, CharacterBody characterBody, float horizontalBonus, float verticalBonus, bool vault)
	{
		JumpStatHook.InvokeJumpHook(characterMotor, ref verticalBonus);
		orig.Invoke(characterMotor, characterBody, horizontalBonus, verticalBonus, vault);
	}

	private void MiredUrnRework()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		JumpStatHook.OnJumpEvent += UrnOnJump;
		SiphonOnLowHealthItemBodyBehavior.OnEnable += new hook_OnEnable(VoidVanillaUrnBehavior);
		LanguageAPI.Add("ITEM_SIPHONONLOWHEALTH_PICKUP", "Triple jump. Jumping fires tar balls in front of you.");
		LanguageAPI.Add("ITEM_SIPHONONLOWHEALTH_DESC", $"Gain <style=cIsUtility>{urnJumpCount}</style> jumps. " + "While in danger, jumping has a <style=cIsUtility>" + Tools.ConvertDecimal(urnBallChance) + " chance</style> to fire <style=cIsDamage>sentient tar pots</style> in front of you, dealing <style=cIsDamage>" + Tools.ConvertDecimal(urnBallDamageCoefficient) + "</style> damage <style=cStack>(+" + Tools.ConvertDecimal(urnBallDamageCoefficient) + " per stack)</style> and <style=cIsUtility>slowing</style> enemies hit.");
	}

	private void CreateMiredUrnTarball()
	{
		//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)
		miredUrnTarball = PrefabAPI.InstantiateClone(Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/ClayBoss/TarSeeker.prefab").WaitForCompletion(), "MiredUrnTarball", true);
		ProjectileImpactExplosion component = miredUrnTarball.GetComponent<ProjectileImpactExplosion>();
		if (Object.op_Implicit((Object)(object)component))
		{
			component.lifetime = 2f;
		}
		ContentAddition.AddProjectile(miredUrnTarball);
	}

	private void VoidVanillaUrnBehavior(orig_OnEnable orig, SiphonOnLowHealthItemBodyBehavior self)
	{
		self.DestroyAttachment();
		Object.Destroy((Object)(object)self);
	}

	private void UrnOnJump(CharacterMotor motor, ref float verticalBonus)
	{
		//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_0188: 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_0135: 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_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		CharacterBody body = motor.body;
		if (body.outOfDanger)
		{
			return;
		}
		int num = 0;
		Inventory inventory = body.inventory;
		if (Object.op_Implicit((Object)(object)inventory))
		{
			num = body.inventory.GetItemCount(Items.SiphonOnLowHealth);
		}
		if (!Util.CheckRoll((1f - Mathf.Pow(1f - urnBallChance, (float)num)) * 100f, body.master))
		{
			return;
		}
		Util.PlaySound(FireTarball.attackSoundString, ((Component)body).gameObject);
		Ray aimRay = body.inputBank.GetAimRay();
		if (Object.op_Implicit((Object)(object)FireTarball.effectPrefab))
		{
			EffectManager.SimpleMuzzleFlash(FireTarball.effectPrefab, ((Component)body).gameObject, "", false);
		}
		if (((NetworkBehaviour)body).hasAuthority)
		{
			if (IsMissileArtifactEnabled())
			{
				int num2 = 3;
				float num3 = urnBallYawSpread * 2f / (float)(num2 + 1);
				float num4 = (float)(num2 - 1) * urnBallYawSpread;
				float num5 = num4 / 2f;
				for (int i = 0; i < num2; i++)
				{
					float num6 = (float)(i / (num2 - 1)) * num4 - num5;
					float num7 = urnBallYawSpread * (float)i - num3 * 2f;
					Vector3 forward = Util.ApplySpread(((Ray)(ref aimRay)).direction, 0f, 0f, 1f, 0f, num7, 0f);
					FireTarballProjectile(body, ((Ray)(ref aimRay)).origin, forward);
				}
			}
			else
			{
				FireTarballProjectile(body, ((Ray)(ref aimRay)).origin, ((Ray)(ref aimRay)).direction);
			}
		}
		body.AddSpreadBloom(FireTarball.spreadBloomValue);
	}

	private void FireTarballProjectile(CharacterBody body, Vector3 origin, Vector3 forward)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		ProjectileManager.instance.FireProjectile(miredUrnTarball, origin, Util.QuaternionSafeLookRotation(forward), ((Component)body).gameObject, body.damage * urnBallDamageCoefficient, 0f, Util.CheckRoll(body.crit, body.master), (DamageColorIndex)0, (GameObject)null, -1f);
	}
}
public class JumpStatHook
{
	public delegate void JumpStatHandler(CharacterBody sender, ref int jumpCount);

	public delegate void OnJumpHandler(CharacterMotor sender, ref float verticalBonus);

	public static event JumpStatHandler JumpStatCoefficient;

	public static event OnJumpHandler OnJumpEvent;

	public static int InvokeStatHook(CharacterBody self)
	{
		int jumpCount = 0;
		JumpStatHook.JumpStatCoefficient?.Invoke(self, ref jumpCount);
		return jumpCount;
	}

	public static float InvokeJumpHook(CharacterMotor self, ref float verticalBonus)
	{
		JumpStatHook.OnJumpEvent?.Invoke(self, ref verticalBonus);
		return verticalBonus;
	}
}
public static class Tools
{
	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;
	}

	internal static string ConvertDecimal(float d)
	{
		return d * 100f + "%";
	}

	public static void ClearDotStacksForType(this DotController dotController, DotIndex dotIndex)
	{
		//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)
		for (int num = dotController.dotStackList.Count - 1; num >= 0; num--)
		{
			if (dotController.dotStackList[num].dotIndex == dotIndex)
			{
				dotController.RemoveDotStackAtServer(num);
			}
		}
	}
}