Decompiled source of Throwwaway v1.2.4

BepInEx/plugins/Throwwaway/ThrowTeammate.dll

Decompiled a month ago
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ThrowTeammate;

[BepInProcess("PEAK.exe")]
[BepInPlugin("com.throwthrow.throwteammate", "Throwwaway", "1.2.4")]
public class Plugin : BaseUnityPlugin
{
	private Harmony harmony;

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Throwwaway v1.2.4 loading...");
		harmony = new Harmony("com.throwthrow.throwteammate");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Throwwaway loaded successfully!");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"  Hold the game's Drop key (default Q) with empty hands to throw a carried teammate.");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"  The top-row 4 / backpack action still drops the teammate normally.");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"  Only the thrower needs this mod; teammates receive native PEAK network messages.");
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		ThrowTeammateBehaviour[] array = Object.FindObjectsByType<ThrowTeammateBehaviour>((FindObjectsSortMode)0);
		foreach (ThrowTeammateBehaviour throwTeammateBehaviour in array)
		{
			Object.Destroy((Object)(object)throwTeammateBehaviour);
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Throwwaway unloaded");
	}
}
public static class PluginInfo
{
	public const string GUID = "com.throwthrow.throwteammate";

	public const string Name = "Throwwaway";

	public const string Version = "1.2.4";
}
public sealed class ThrowTeammateBehaviour : MonoBehaviour
{
	[HarmonyPatch(typeof(Character), "Awake")]
	private static class AttachPatch
	{
		[HarmonyPostfix]
		internal static void Postfix(Character __instance)
		{
			ThrowTeammateBehaviour throwTeammateBehaviour = ((Component)__instance).GetComponent<ThrowTeammateBehaviour>();
			if ((Object)(object)throwTeammateBehaviour == (Object)null)
			{
				throwTeammateBehaviour = ((Component)__instance).gameObject.AddComponent<ThrowTeammateBehaviour>();
			}
			throwTeammateBehaviour.character = __instance;
		}
	}

	[HarmonyPatch(typeof(CharacterItems), "DoDropping")]
	private static class DropInputPatch
	{
		[HarmonyPrefix]
		internal static bool Prefix(CharacterItems __instance, Character ___character, ref bool ___pressedDrop, ref float ___lastPressedDrop)
		{
			if (!___character.IsLocal)
			{
				return true;
			}
			ThrowTeammateBehaviour component = ((Component)___character).GetComponent<ThrowTeammateBehaviour>();
			if (!((Object)(object)component == (Object)null))
			{
				return component.BeforeDropping(__instance, ref ___pressedDrop, ref ___lastPressedDrop);
			}
			return true;
		}
	}

	private static readonly FieldInfo PressedDrop = AccessTools.Field(typeof(CharacterItems), "pressedDrop");

	private static readonly Func<Vector3, Vector3, Vector3> LookToDirection = (Func<Vector3, Vector3, Vector3>)Delegate.CreateDelegate(typeof(Func<Vector3, Vector3, Vector3>), AccessTools.Method(typeof(HelperFunctions), "LookToDirection", (Type[])null, (Type[])null));

	private Character character;

	private Character chargeTarget;

	private bool charging;

	internal bool BeforeDropping(CharacterItems items, ref bool pressedDrop, ref float lastPressedDrop)
	{
		if (charging && (!CanCharge() || !pressedDrop))
		{
			CancelCharge();
		}
		if (character.input.dropWasPressed && CanStartCharge())
		{
			chargeTarget = character.data.carriedPlayer;
			charging = true;
			items.throwChargeLevel = 0f;
			lastPressedDrop = Time.time;
			pressedDrop = true;
		}
		if (charging && character.input.dropWasReleased)
		{
			Character target = chargeTarget;
			float throwChargeLevel = items.throwChargeLevel;
			CancelCharge();
			Throw(target, throwChargeLevel);
			return false;
		}
		return true;
	}

	private bool CanStartCharge()
	{
		if (character.IsLocal && Application.isFocused && CanThrowPair(character, character.data.carriedPlayer) && !character.refs.afflictions.isStruggling)
		{
			if (!((Object)(object)GUIManager.instance == (Object)null))
			{
				if (!GUIManager.instance.windowBlockingInput)
				{
					return !GUIManager.instance.wheelActive;
				}
				return false;
			}
			return true;
		}
		return false;
	}

	private bool CanCharge()
	{
		if (CanStartCharge() && (Object)(object)chargeTarget != (Object)null)
		{
			return (Object)(object)character.data.carriedPlayer == (Object)(object)chargeTarget;
		}
		return false;
	}

	private static bool CanThrowPair(Character carrier, Character target)
	{
		if ((Object)(object)carrier != (Object)null && (Object)(object)target != (Object)null && (Object)(object)carrier != (Object)(object)target && !carrier.data.isCarried && !carrier.data.dead && !carrier.data.passedOut && !carrier.data.fullyPassedOut && (Object)(object)carrier.data.currentItem == (Object)null && (Object)(object)carrier.data.carriedPlayer == (Object)(object)target && target.data.isCarried && (Object)(object)target.data.carrier == (Object)(object)carrier && target.data.fullyPassedOut)
		{
			return !target.data.dead;
		}
		return false;
	}

	private void LateUpdate()
	{
		if (charging && (!CanCharge() || !character.input.dropIsPressed))
		{
			CancelCharge();
		}
	}

	private void OnApplicationFocus(bool focused)
	{
		if (!focused)
		{
			CancelCharge();
		}
	}

	private void OnDisable()
	{
		CancelCharge();
	}

	private void CancelCharge()
	{
		if (charging)
		{
			charging = false;
			chargeTarget = null;
			if (!((Object)(object)character == (Object)null) && !((Object)(object)character.refs.items == (Object)null))
			{
				CharacterItems items = character.refs.items;
				PressedDrop.SetValue(items, false);
				items.throwChargeLevel = 0f;
				items.isChargingThrow = false;
			}
		}
	}

	internal void Throw(Character target, float charge)
	{
		//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)
		//IL_00a9: 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_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)
		//IL_00bc: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null || !character.IsLocal || !((MonoBehaviourPun)character).photonView.IsMine || !CanThrowPair(character, target) || !(charge > 0f) || !(charge <= 1f))
		{
			return;
		}
		CharacterItems items = character.refs.items;
		float num = (items.minThrowForce + (items.maxThrowForce - items.minThrowForce) * charge) * 0.5f;
		if (!(num > 0f) || !(Time.fixedDeltaTime > 0f))
		{
			return;
		}
		Vector3 val = LookToDirection(Vector2.op_Implicit(character.data.lookValues), Vector3.forward);
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		Vector3 val2 = normalized * (num / Time.fixedDeltaTime);
		if (!(((Vector3)(ref val2)).sqrMagnitude > 0f) || float.IsInfinity(((Vector3)(ref val2)).sqrMagnitude) || !target.refs.ragdoll.partDict.TryGetValue((BodypartType)2, out var value) || (Object)(object)value == (Object)null || (Object)(object)value.Rig == (Object)null)
		{
			return;
		}
		character.BreakCharacterCarrying(true);
		if (!target.data.isCarried && !((Object)(object)target.data.carrier != (Object)null))
		{
			target.AddForceToBodyPart(value.Rig, Vector3.zero, val2);
			if (charge > 0.1f && (Object)(object)character.refs.animations != (Object)null)
			{
				character.refs.animations.throwTime = 0.125f;
			}
		}
	}
}