Decompiled source of PalThrow v1.7.1

PalThrow.dll

Decompiled 4 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("PalThrow")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PalThrow")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("15a56718-251a-4536-8cc0-c9f38bd1b995")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PalThrow;

[BepInPlugin("com.lamia.palthrow", "PalThrow", "1.6.5")]
public class Plugin : BaseUnityPlugin
{
	public static ConfigEntry<float> MaxChargeTime;

	public static ConfigEntry<float> StaminaCost;

	public static ConfigEntry<float> MinThrowStrength;

	public static ConfigEntry<float> MaxThrowStrength;

	public static ConfigEntry<float> SpeedPerStrength;

	public static ConfigEntry<float> ThrowLoft;

	public static ConfigEntry<float> AirDrag;

	public static ConfigEntry<float> AirTransition;

	public static ConfigEntry<KeyCode> ThrowKey;

	internal static ManualLogSource Log;

	private Harmony harmony;

	private void Awake()
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Expected O, but got Unknown
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Expected O, but got Unknown
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Expected O, but got Unknown
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Expected O, but got Unknown
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Expected O, but got Unknown
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Expected O, but got Unknown
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ThrowKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ThrowKey", (KeyCode)120, "Hold to charge a throw, release to throw.");
		MaxChargeTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxChargeTime", 3f, new ConfigDescription("Full charge time in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
		StaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("General", "StaminaCost", 1f, new ConfigDescription("Stamina drain multiplier while charging.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
		MinThrowStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Throwing", "MinThrowStrength", 1.5f, new ConfigDescription("Strength at minimum charge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), Array.Empty<object>()));
		MaxThrowStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Throwing", "MaxThrowStrength", 4f, new ConfigDescription("Strength at full charge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), Array.Empty<object>()));
		SpeedPerStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Throwing", "SpeedPerStrength", 6f, new ConfigDescription("Launch metres per second for each strength unit. Default charge range gives 3 to 15 m/s.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
		ThrowLoft = ((BaseUnityPlugin)this).Config.Bind<float>("Throwing", "ThrowLoft", 1.25f, new ConfigDescription("Small upward lift for horizontal throws. Fades out when aiming straight up or down.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()));
		AirDrag = ((BaseUnityPlugin)this).Config.Bind<float>("Throwing", "AirDrag", 0.8f, new ConfigDescription("Initial linear air resistance per second. Only removes speed; gravity and angular damping remain active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>()));
		AirTransition = ((BaseUnityPlugin)this).Config.Bind<float>("Throwing", "AirTransition", 1.8f, new ConfigDescription("Seconds to blend back to normal PEAK air drag, beginning immediately at launch.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 3f), Array.Empty<object>()));
		harmony = new Harmony("com.lamia.palthrow");
		harmony.PatchAll(typeof(Plugin).Assembly);
		Character[] array = Object.FindObjectsByType<Character>((FindObjectsSortMode)0);
		foreach (Character character in array)
		{
			Attach(character);
		}
		Log.LogInfo((object)"PalThrow loaded. Charge-based launch with gradual air drag. Multiplayer participants need the same build.");
	}

	internal static void Attach(Character character)
	{
		if (!Object.op_Implicit((Object)(object)((Component)character).GetComponent<PalThrowManager>()))
		{
			((Component)character).gameObject.AddComponent<PalThrowManager>();
		}
		PhotonView component = ((Component)character).GetComponent<PhotonView>();
		if (Object.op_Implicit((Object)(object)component))
		{
			component.RefreshRpcMonoBehaviourCache();
		}
	}

	private void OnDestroy()
	{
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
		PalThrowManager[] array = Object.FindObjectsByType<PalThrowManager>((FindObjectsSortMode)0);
		foreach (PalThrowManager palThrowManager in array)
		{
			palThrowManager.CancelFlight();
		}
	}
}
[HarmonyPatch(typeof(Character), "Awake")]
internal static class AttachThrowManager
{
	private static void Postfix(Character __instance)
	{
		Plugin.Attach(__instance);
	}
}
public class PalThrowManager : MonoBehaviourPun
{
	private Character character;

	private Character chargedTarget;

	private float chargeTime;

	private float lastThrowTime = float.NegativeInfinity;

	private bool isCharging;

	private int throwSequence;

	private int lastReceivedSequence;

	private float lastAcceptedThrow = float.NegativeInfinity;

	private bool inThrowFlight;

	private float flightStarted;

	private float flightStrength;

	private void Awake()
	{
		character = ((Component)this).GetComponent<Character>();
	}

	private void CancelCharge()
	{
		isCharging = false;
		chargeTime = 0f;
		chargedTarget = null;
	}

	internal void CancelFlight()
	{
		inThrowFlight = false;
	}

	private void OnDisable()
	{
		CancelCharge();
		CancelFlight();
	}

	private void OnDestroy()
	{
		CancelFlight();
	}

	private void Update()
	{
		//IL_0096: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)character) || !character.IsLocal)
		{
			return;
		}
		if (Time.time < lastThrowTime + 3f)
		{
			CancelCharge();
			return;
		}
		Character characterStandingOnMe = GetCharacterStandingOnMe();
		if (!Object.op_Implicit((Object)(object)characterStandingOnMe))
		{
			CancelCharge();
			return;
		}
		if (isCharging && (Object)(object)chargedTarget != (Object)(object)characterStandingOnMe)
		{
			CancelCharge();
		}
		if (Input.GetKey(Plugin.ThrowKey.Value))
		{
			if (!isCharging)
			{
				isCharging = true;
				chargedTarget = characterStandingOnMe;
				chargeTime = 0f;
			}
			chargeTime = Mathf.Min(chargeTime + Time.deltaTime, Plugin.MaxChargeTime.Value);
			float num = Plugin.StaminaCost.Value * 0.2f * Time.deltaTime;
			if (character.GetTotalStamina() < num)
			{
				CancelCharge();
				character.PassOutInstantly();
			}
			else
			{
				character.AddStamina(0f - num);
				character.data.sinceUseStamina = 0f;
			}
		}
		else if (isCharging)
		{
			float num2 = Mathf.Clamp01(chargeTime / Mathf.Max(0.1f, Plugin.MaxChargeTime.Value));
			float num3 = Mathf.Lerp(Plugin.MinThrowStrength.Value, Plugin.MaxThrowStrength.Value, num2);
			float num4 = Mathf.Clamp(num3 * Plugin.SpeedPerStrength.Value, 0f, 30f);
			Vector3 normalized = ((Vector3)(ref character.data.lookDirection)).normalized;
			Vector3 val = Vector3.ClampMagnitude(BodyVelocity(character), 8f);
			float num5 = Plugin.ThrowLoft.Value * (1f - Mathf.Abs(normalized.y));
			Vector3 val2 = Vector3.ClampMagnitude(normalized * num4 + Vector3.up * num5 + val, 35f);
			if (Finite(val2) && ((Vector3)(ref normalized)).sqrMagnitude > 0.5f && Object.op_Implicit((Object)(object)characterStandingOnMe.refs.view) && characterStandingOnMe.refs.view.Owner != null)
			{
				((MonoBehaviourPun)this).photonView.RPC("ThrowCharacterRpc", characterStandingOnMe.refs.view.Owner, new object[4]
				{
					characterStandingOnMe.refs.view.ViewID,
					val2,
					num4,
					++throwSequence
				});
				lastThrowTime = Time.time;
			}
			CancelCharge();
		}
	}

	private Character GetCharacterStandingOnMe()
	{
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if (Object.op_Implicit((Object)(object)allCharacter) && (Object)(object)allCharacter != (Object)(object)character && !allCharacter.data.isRopeClimbing && (Object)(object)allCharacter.data.lastStoodOnPlayer == (Object)(object)character && allCharacter.data.sinceStandOnPlayer <= 0.3f)
			{
				return allCharacter;
			}
		}
		return null;
	}

	private static bool Finite(Vector3 value)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_0042: Unknown result type (might be due to invalid IL or missing references)
		return !float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z) && !float.IsInfinity(value.z);
	}

	private static Vector3 BodyVelocity(Character who)
	{
		//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_00ac: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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_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_0073: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Vector3.zero;
		float num = 0f;
		foreach (Bodypart part in who.refs.ragdoll.partList)
		{
			if (Object.op_Implicit((Object)(object)part.Rig) && !part.Rig.isKinematic)
			{
				val += part.Rig.linearVelocity * part.Rig.mass;
				num += part.Rig.mass;
			}
		}
		return (num > 0f) ? (val / num) : Vector3.zero;
	}

	[PunRPC]
	public void ThrowCharacterRpc(int viewID, Vector3 launch, float speed, int sequence, PhotonMessageInfo info)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)character) || !Object.op_Implicit((Object)(object)((MonoBehaviourPun)this).photonView) || info.Sender == null || info.Sender != ((MonoBehaviourPun)this).photonView.Owner || sequence <= lastReceivedSequence || !Finite(launch) || ((Vector3)(ref launch)).magnitude > 35.01f || float.IsNaN(speed) || float.IsInfinity(speed) || speed < 0f || speed > 30f)
		{
			return;
		}
		double num = PhotonNetwork.Time - ((PhotonMessageInfo)(ref info)).SentServerTime;
		if (num < -0.1 || num > 1.0)
		{
			return;
		}
		Character val = null;
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if (Object.op_Implicit((Object)(object)allCharacter) && Object.op_Implicit((Object)(object)allCharacter.refs.view) && allCharacter.refs.view.ViewID == viewID)
			{
				val = allCharacter;
				break;
			}
		}
		PalThrowManager palThrowManager = default(PalThrowManager);
		if (!Object.op_Implicit((Object)(object)val) || !val.IsLocal || (Object)(object)val == (Object)(object)character || val.data.isRopeClimbing || (Object)(object)val.data.lastStoodOnPlayer != (Object)(object)character || val.data.sinceStandOnPlayer > 0.65f || !((Component)val).TryGetComponent<PalThrowManager>(ref palThrowManager) || Time.time < palThrowManager.lastAcceptedThrow + 0.5f)
		{
			return;
		}
		lastReceivedSequence = sequence;
		palThrowManager.lastAcceptedThrow = Time.time;
		Vector3 val2 = BodyVelocity(val);
		if (!Finite(val2))
		{
			return;
		}
		Vector3 val3 = launch - val2;
		foreach (Bodypart part in val.refs.ragdoll.partList)
		{
			if (Object.op_Implicit((Object)(object)part.Rig) && !part.Rig.isKinematic)
			{
				Rigidbody rig = part.Rig;
				rig.linearVelocity += val3;
			}
		}
		val.data.lastStoodOnPlayer = null;
		val.data.sinceStandOnPlayer = 1f;
		palThrowManager.inThrowFlight = speed > 0.5f;
		palThrowManager.flightStarted = Time.time;
		palThrowManager.flightStrength = Mathf.InverseLerp(0.5f, 12f, speed);
	}

	internal bool TryFlightRetention(float nativeRetention, out float retention)
	{
		retention = nativeRetention;
		if (!inThrowFlight || !Object.op_Implicit((Object)(object)character) || !character.IsLocal)
		{
			return false;
		}
		float num = Mathf.Max(0f, Time.time - flightStarted);
		float num2 = Mathf.Max(0.2f, Plugin.AirTransition.Value);
		if (num >= num2 || character.data.isRopeClimbing || character.data.isClimbing || (num > 0.2f && character.data.isGrounded) || character.data.currentRagdollControll < 0.3f)
		{
			CancelFlight();
			return false;
		}
		float num3 = flightStrength * (1f - Mathf.Clamp01(num / num2));
		float num4 = Mathf.Exp((0f - Plugin.AirDrag.Value) * Time.fixedDeltaTime);
		retention = Mathf.Lerp(nativeRetention, num4, num3);
		return true;
	}
}
[HarmonyPatch(typeof(Bodypart), "Drag")]
internal static class ThrownPlayerAirDrag
{
	private static void Prefix(Bodypart __instance, Character ___character, float drag, bool ignoreRagdoll, out Vector3 __state)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		__state = Vector3.zero;
		PalThrowManager palThrowManager = default(PalThrowManager);
		if (!ignoreRagdoll && !(drag <= 0f) && !(drag >= 1f) && Object.op_Implicit((Object)(object)___character) && ___character.IsLocal && ((Component)___character).TryGetComponent<PalThrowManager>(ref palThrowManager) && Object.op_Implicit((Object)(object)__instance.Rig) && !__instance.Rig.isKinematic)
		{
			float num = Mathf.Lerp(1f, drag, ___character.data.currentRagdollControll);
			if (palThrowManager.TryFlightRetention(num, out var retention))
			{
				__state = __instance.Rig.linearVelocity * Mathf.Max(0f, retention - num);
			}
		}
	}

	private static void Postfix(Bodypart __instance, Vector3 __state)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)__instance.Rig) && !__instance.Rig.isKinematic && ((Vector3)(ref __state)).sqrMagnitude > 0f)
		{
			__instance.Rig.AddForce(__state, (ForceMode)2);
		}
	}
}