using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using ThrowEverything.Models;
using ThrowEverything.Patches;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Spantle")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Adds a new ability to throw (almost) any item in Lethal Company. Throw items to deal damage, distract enemies, trigger landmines, and more!")]
[assembly: AssemblyFileVersion("0.4.1.0")]
[assembly: AssemblyInformationalVersion("0.4.1")]
[assembly: AssemblyProduct("ThrowEverything")]
[assembly: AssemblyTitle("Spantle.ThrowEverything")]
[assembly: AssemblyVersion("0.4.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ThrowEverything
{
internal class ControlTips
{
internal static void Set(GrabbableObject item)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: 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)
try
{
ChargingThrow chargingThrow = State.GetChargingThrow();
Item itemProperties = item.itemProperties;
int num = 1;
if (itemProperties.toolTips != null)
{
num = itemProperties.toolTips.Length + 1;
if (num > 3)
{
return;
}
}
string[] array = new string[num];
string itemName = itemProperties.itemName;
if (chargingThrow.isCharging)
{
int chargedPercentage = chargingThrow.GetChargedPercentage();
array[0] = $"Throw {itemName} : [{chargedPercentage}%]";
}
else
{
InputBinding val = InputSettings.Instance.ThrowItem.bindings[0];
string text = ((InputBinding)(ref val)).path.Split('/').Last().ToUpper();
array[0] = "Throw " + itemName + " : [" + text + "]";
}
for (int i = 1; i < array.Length; i++)
{
array[i] = itemProperties.toolTips[i - 1];
}
HUDManager.Instance.ChangeControlTipMultiple(array, true, itemProperties);
}
catch (Exception ex)
{
Plugin.Logger.LogWarning((object)"failed to inject control tips");
Plugin.Logger.LogWarning((object)ex);
}
}
}
internal class InputSettings : LcInputActions
{
public static readonly InputSettings Instance = new InputSettings();
[InputAction("<Keyboard>/r", Name = "ThrowEverything: Throw Item")]
public InputAction ThrowItem { get; set; }
}
[BepInPlugin("Spantle.ThrowEverything", "ThrowEverything", "0.4.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("Spantle.ThrowEverything");
internal static ManualLogSource Logger;
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
harmony.PatchAll(typeof(GrabbableObject_Patch));
harmony.PatchAll(typeof(HUDManager_Patch));
harmony.PatchAll(typeof(PlayerControllerB_Patch));
if (((LcInputActions)InputSettings.Instance).Enabled)
{
Logger.LogInfo((object)"InputUtils is working");
}
Logger.LogInfo((object)"Spantle.ThrowEverything is loaded!");
}
}
internal class State
{
private static Throwable heldThrowable = null;
private static readonly ChargingThrow chargingThrow = new ChargingThrow();
private static readonly ThrownItems thrownItems = new ThrownItems();
internal static void SetHeldThrowable(GrabbableObject item)
{
heldThrowable = new Throwable(item, item.playerHeldBy);
heldThrowable.HookEvents();
}
internal static void ClearHeldThrowable()
{
chargingThrow.Stop();
if (heldThrowable != null)
{
heldThrowable.UnhookEvents();
heldThrowable = null;
}
}
internal static Throwable GetHeldThrowable()
{
return heldThrowable;
}
internal static ChargingThrow GetChargingThrow()
{
return chargingThrow;
}
internal static ThrownItems GetThrownItems()
{
return thrownItems;
}
}
internal class Utils
{
internal static string Name(GrabbableObject __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return "NULL";
}
if ((Object)(object)__instance.itemProperties == (Object)null)
{
return ((Object)__instance).name + " (props was NULL)";
}
return ((Object)__instance.itemProperties).name;
}
internal static float ItemWeight(GrabbableObject __instance)
{
float weight = __instance.itemProperties.weight;
float num = ((!__instance.itemProperties.twoHanded) ? 1 : 2);
return Math.Clamp((weight - 1f) * num, 0f, 1f);
}
internal static float ItemPower(GrabbableObject __instance, float powerDecimal, bool inverse = false)
{
float num = ItemWeight(__instance);
float value = ((!inverse) ? (num * num) : ((1f - num) * (1f - num)));
value = Math.Clamp(value, 0f, 1f);
return value * powerDecimal;
}
internal static float ItemScale(GrabbableObject __instance)
{
//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)
Vector3 localScale = ((Component)__instance).transform.localScale;
return Math.Clamp(((Vector3)(ref localScale)).magnitude, 0.2f, 3f);
}
internal static void DamagePlayer(PlayerControllerB player, int damage, Vector3 hitDirection, PlayerControllerB damager)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if (player.AllowPlayerDeath() && !Object.op_Implicit((Object)(object)player.inAnimationWithEnemy))
{
player.DamagePlayerFromOtherClientServerRpc(damage, hitDirection, (int)damager.playerClientId);
}
}
internal static Vector3 FindLandingRay(Vector3 location, bool logging = false)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: 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)
//IL_006d: 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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
Ray val = default(Ray);
((Ray)(ref val))..ctor(location, Vector3.down);
RaycastHit val2 = default(RaycastHit);
if (Physics.Raycast(val, ref val2, 100f, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
{
if (logging)
{
Plugin.Logger.LogInfo((object)"we hit the floor");
}
return ((RaycastHit)(ref val2)).point + Vector3.up * 0.05f;
}
if (logging)
{
Plugin.Logger.LogInfo((object)"we did not hit the floor");
}
return ((Ray)(ref val)).GetPoint(100f);
}
internal static Vector3 GetItemThrowDestination(GrabbableObject item, PlayerControllerB thrower, float chargeDecimal)
{
//IL_000d: 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_0036: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
Ray val = default(Ray);
((Ray)(ref val))..ctor(((Component)thrower.gameplayCamera).transform.position, ((Component)thrower.gameplayCamera).transform.forward);
float num = ItemPower(item, chargeDecimal, inverse: true) * 20f;
RaycastHit val2 = default(RaycastHit);
float num2;
if (Physics.Raycast(val, ref val2, num, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
{
Plugin.Logger.LogInfo((object)"we hit a surface");
num2 = ((RaycastHit)(ref val2)).distance;
}
else
{
Plugin.Logger.LogInfo((object)"we did not hit a surface");
num2 = num;
}
num2 = Math.Max(0f, num2 - ItemScale(item) / 2f);
Plugin.Logger.LogInfo((object)$"throwing {Name(item)} ({item.itemProperties.weight}): {num2} units ({num}, {ItemScale(item)})");
return FindLandingRay(((Ray)(ref val)).GetPoint(num2));
}
internal static Vector3 GetItemThrowDestination(ThrownItem thrownItem)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
return GetItemThrowDestination(thrownItem.GetItem(), thrownItem.GetThrower(), thrownItem.GetChargeDecimal());
}
internal static bool CanUseItem(PlayerControllerB player)
{
if ((!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || (((NetworkBehaviour)player).IsServer && !player.isHostPlayerObject)) && !player.isTestingPlayer)
{
return false;
}
if (!player.isHoldingObject || (Object)(object)player.currentlyHeldObjectServer == (Object)null)
{
return false;
}
if (player.quickMenuManager.isMenuOpen)
{
return false;
}
if (player.isPlayerDead)
{
return false;
}
if (!player.currentlyHeldObjectServer.itemProperties.usableInSpecialAnimations && (player.isGrabbingObjectAnimation || player.inTerminalMenu || player.isTypingChat || (player.inSpecialInteractAnimation && !player.inShockingMinigame)))
{
return false;
}
return true;
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "Spantle.ThrowEverything";
public const string PLUGIN_NAME = "ThrowEverything";
public const string PLUGIN_VERSION = "0.4.1";
}
}
namespace ThrowEverything.Patches
{
[HarmonyPatch(typeof(GrabbableObject))]
public class GrabbableObject_Patch
{
[HarmonyPostfix]
[HarmonyPatch(typeof(GrabbableObject), "EquipItem")]
private static void EquipItem(GrabbableObject __instance)
{
if (((NetworkBehaviour)__instance).IsOwner)
{
Plugin.Logger.LogInfo((object)("equipped " + Utils.Name(__instance)));
State.ClearHeldThrowable();
State.SetHeldThrowable(__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GrabbableObject), "PocketItem")]
private static void PocketItem(GrabbableObject __instance)
{
if (((NetworkBehaviour)__instance).IsOwner)
{
Plugin.Logger.LogInfo((object)("pocketed " + Utils.Name(__instance)));
State.ClearHeldThrowable();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GrabbableObject), "DiscardItem")]
private static void DiscardItem(GrabbableObject __instance)
{
if (((NetworkBehaviour)__instance).IsOwner)
{
Plugin.Logger.LogInfo((object)("discarded " + Utils.Name(__instance)));
State.ClearHeldThrowable();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GrabbableObject), "SetControlTipsForItem")]
private static void SetControlTipsForItem(GrabbableObject __instance)
{
ControlTips.Set(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GrabbableObject), "Update")]
private static void Update(GrabbableObject __instance)
{
ThrownItems thrownItems = State.GetThrownItems();
if (thrownItems.thrownItemsDict.TryGetValue(((Object)__instance).GetInstanceID(), out var value))
{
thrownItems.Update(value);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GrabbableObject), "FallWithCurve")]
private static bool FallWithCurve(GrabbableObject __instance)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: 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_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: 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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_0099: 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)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: 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_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: 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_00ea: 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_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = __instance.startFallingPosition - __instance.targetFloorPosition;
float magnitude = ((Vector3)(ref val)).magnitude;
((Component)__instance).transform.rotation = Quaternion.Lerp(((Component)__instance).transform.rotation, Quaternion.Euler(__instance.itemProperties.restingRotation.x, ((Component)__instance).transform.eulerAngles.y, __instance.itemProperties.restingRotation.z), 14f * Time.deltaTime / magnitude);
((Component)__instance).transform.localPosition = Vector3.Lerp(__instance.startFallingPosition, __instance.targetFloorPosition, FallCurve.fallCurve.Evaluate(__instance.fallTime));
if (magnitude > 5f)
{
((Component)__instance).transform.localPosition = Vector3.Lerp(new Vector3(((Component)__instance).transform.localPosition.x, __instance.startFallingPosition.y, ((Component)__instance).transform.localPosition.z), new Vector3(((Component)__instance).transform.localPosition.x, __instance.targetFloorPosition.y, ((Component)__instance).transform.localPosition.z), FallCurve.verticalFallCurveNoBounce.Evaluate(__instance.fallTime));
}
else
{
((Component)__instance).transform.localPosition = Vector3.Lerp(new Vector3(((Component)__instance).transform.localPosition.x, __instance.startFallingPosition.y, ((Component)__instance).transform.localPosition.z), new Vector3(((Component)__instance).transform.localPosition.x, __instance.targetFloorPosition.y, ((Component)__instance).transform.localPosition.z), FallCurve.verticalFallCurve.Evaluate(__instance.fallTime));
}
__instance.fallTime += Mathf.Abs(Time.deltaTime * 12f / magnitude);
return false;
}
}
[HarmonyPatch(typeof(HUDManager))]
public class HUDManager_Patch
{
[HarmonyPostfix]
[HarmonyPatch(typeof(HUDManager), "Update")]
private static void Update(HUDManager __instance)
{
Throwable heldThrowable = State.GetHeldThrowable();
if (heldThrowable != null)
{
ControlTips.Set(heldThrowable.GetItem());
}
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
public class PlayerControllerB_Patch
{
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
private static void Update(PlayerControllerB __instance)
{
if ((Object)(object)StartOfRound.Instance.localPlayerController != (Object)(object)__instance)
{
return;
}
ChargingThrow chargingThrow = State.GetChargingThrow();
if (chargingThrow.isCharging)
{
chargingThrow.DrawLandingCircle();
if (!chargingThrow.hasFullyCharged)
{
__instance.sprintMeter = Mathf.Clamp(__instance.sprintMeter - 0.0025f, 0f, 1f);
}
else
{
__instance.sprintMeter = Mathf.Clamp(__instance.sprintMeter - 0.00125f, 0f, 1f);
}
}
if (__instance.sprintMeter < 0.3f || __instance.isExhausted)
{
__instance.isExhausted = true;
chargingThrow.Exhausted();
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
private static void ScrollMouse_performed(PlayerControllerB __instance)
{
if (State.GetChargingThrow().isCharging)
{
__instance.isGrabbingObjectAnimation = false;
}
if (Utils.CanUseItem(__instance))
{
Throwable heldThrowable = State.GetHeldThrowable();
if (heldThrowable != null)
{
GrabbableObject item = heldThrowable.GetItem();
State.ClearHeldThrowable();
State.SetHeldThrowable(item);
}
}
}
}
}
namespace ThrowEverything.Models
{
internal class ChargingThrow
{
private const int MIN_CHARGING_TIME = 500;
private const int MAX_CHARGING_TIME = 2000;
internal bool isCharging;
internal DateTime startChargingTime;
internal bool hasRunOutOfStamina;
internal DateTime runOutOfStaminaTime;
internal bool hasFullyCharged;
private GameObject preview;
internal void StartCharging()
{
isCharging = true;
startChargingTime = DateTime.Now;
hasRunOutOfStamina = false;
hasFullyCharged = false;
}
internal void Stop()
{
isCharging = false;
hasRunOutOfStamina = false;
hasFullyCharged = false;
Object.Destroy((Object)(object)preview);
}
internal void Exhausted()
{
if (!hasRunOutOfStamina)
{
hasRunOutOfStamina = true;
runOutOfStaminaTime = DateTime.Now;
}
}
private float GetTime()
{
if (hasRunOutOfStamina)
{
return (float)(runOutOfStaminaTime - startChargingTime).TotalMilliseconds;
}
return (float)(DateTime.Now - startChargingTime).TotalMilliseconds;
}
internal float GetChargeDecimal()
{
float num = Utils.ItemWeight(State.GetHeldThrowable().GetItem());
float num2 = Math.Clamp(GetTime() / (float)Math.Clamp((int)Math.Round(num * 2000f), 500, 2000), 0f, 1f);
if (isCharging && num2 == 1f)
{
hasFullyCharged = true;
}
return num2;
}
internal int GetChargedPercentage()
{
return (int)Math.Floor(GetChargeDecimal() * 100f);
}
internal void DrawLandingCircle()
{
//IL_0068: 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)
if ((Object)(object)preview == (Object)null)
{
preview = GameObject.CreatePrimitive((PrimitiveType)0);
preview.layer = 6;
preview.GetComponent<Renderer>().material = ShipBuildModeManager.Instance.ghostObjectGreen;
}
Throwable heldThrowable = State.GetHeldThrowable();
ChargingThrow chargingThrow = State.GetChargingThrow();
GrabbableObject item = heldThrowable.GetItem();
float num = Utils.ItemScale(item);
preview.transform.localScale = new Vector3(num, num, num);
preview.transform.position = Utils.GetItemThrowDestination(item, heldThrowable.GetThrower(), chargingThrow.GetChargeDecimal());
}
}
internal class FallCurve
{
internal static readonly Keyframe[] fallCurveKeyframes = (Keyframe[])(object)new Keyframe[2]
{
new Keyframe(0f, 0f, 2f, 2f),
new Keyframe(1f, 1f, 0f, 0f)
};
internal static readonly Keyframe[] verticalFallCurveKeyframes = (Keyframe[])(object)new Keyframe[5]
{
new Keyframe(0f, 0f, 0.116908506f, 0.116908506f, 0f, 0.27230743f),
new Keyframe(0.49081117f, 1f, 4.1146584f, -1.81379f, 0.07234045f, 0.28319725f),
new Keyframe(0.7587703f, 1f, 1.4123471f, -1.3678839f, 0.31997186f, 0.56917864f),
new Keyframe(0.9393898f, 1f, 0.82654804f, -0.029021755f, 0.53747445f, 1f),
new Keyframe(1f, 1f)
};
internal static readonly Keyframe[] verticalFallCurveNoBounceKeyFrames = (Keyframe[])(object)new Keyframe[4]
{
new Keyframe(0f, 0f, 0.116908506f, 0.116908506f, 0f, 0.27230743f),
new Keyframe(0.69081116f, 1f, 0.1146584f, 0.06098772f, 0.07234045f, 0.20768756f),
new Keyframe(0.9393898f, 1f, 0.06394797f, -0.029021755f, 0.1980713f, 1f),
new Keyframe(1f, 1f)
};
internal static readonly AnimationCurve fallCurve = new AnimationCurve(fallCurveKeyframes);
internal static readonly AnimationCurve verticalFallCurve = new AnimationCurve(verticalFallCurveKeyframes);
internal static readonly AnimationCurve verticalFallCurveNoBounce = new AnimationCurve(verticalFallCurveNoBounceKeyFrames);
}
internal class Throwable
{
private readonly GrabbableObject item;
private readonly PlayerControllerB thrower;
internal Throwable(GrabbableObject item, PlayerControllerB thrower)
{
this.item = item;
this.thrower = thrower;
}
internal GrabbableObject GetItem()
{
return item;
}
internal PlayerControllerB GetThrower()
{
return thrower;
}
internal void StartThrowing(CallbackContext ctx)
{
if (!Utils.CanUseItem(thrower))
{
Plugin.Logger.LogInfo((object)"cannot use item");
return;
}
thrower.isGrabbingObjectAnimation = true;
State.GetChargingThrow().StartCharging();
}
internal void Throw(CallbackContext ctx)
{
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
thrower.isGrabbingObjectAnimation = false;
if ((Object)(object)item == (Object)null || (Object)(object)item.playerHeldBy != (Object)(object)thrower)
{
Plugin.Logger.LogWarning((object)$"tried to throw an invalid item {(Object)(object)item == (Object)null}");
State.ClearHeldThrowable();
return;
}
ChargingThrow chargingThrow = State.GetChargingThrow();
if (!chargingThrow.isCharging)
{
Plugin.Logger.LogInfo((object)"tried to throw without charging");
return;
}
float chargeDecimal = chargingThrow.GetChargeDecimal();
float markiplier = Utils.ItemPower(item, chargeDecimal);
ThrownItem thrownItem = new ThrownItem(item, item.playerHeldBy, chargeDecimal, markiplier);
State.GetThrownItems().thrownItemsDict.Add(((Object)item).GetInstanceID(), thrownItem);
item.playerHeldBy.DiscardHeldObject(true, (NetworkObject)null, Utils.GetItemThrowDestination(thrownItem), true);
}
internal void HookEvents()
{
InputSettings.Instance.ThrowItem.started += StartThrowing;
InputSettings.Instance.ThrowItem.canceled += Throw;
}
internal void UnhookEvents()
{
InputSettings.Instance.ThrowItem.started -= StartThrowing;
InputSettings.Instance.ThrowItem.canceled -= Throw;
thrower.isGrabbingObjectAnimation = false;
}
}
internal class ThrownItem
{
private readonly GrabbableObject item;
private readonly PlayerControllerB thrower;
private readonly float chargeDecimal;
private readonly float markiplier;
private readonly DateTime thrownAt;
private readonly List<IHittable> hits = new List<IHittable>();
internal ThrownItem(GrabbableObject item, PlayerControllerB thrower, float chargeDecimal, float markiplier)
{
this.item = item;
this.thrower = thrower;
this.chargeDecimal = chargeDecimal;
this.markiplier = markiplier;
thrownAt = DateTime.Now;
}
internal GrabbableObject GetItem()
{
return item;
}
internal PlayerControllerB GetThrower()
{
return thrower;
}
internal float GetMarkiplier()
{
return markiplier;
}
internal float GetChargeDecimal()
{
return chargeDecimal;
}
internal bool CheckIfHitOrAdd(IHittable hittable)
{
if (hits.Contains(hittable))
{
return true;
}
hits.Add(hittable);
return false;
}
internal bool IsPanicking()
{
return (DateTime.Now - thrownAt).TotalMilliseconds >= 5000.0;
}
internal void LandAndRemove()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
float num = 1f - (1f - markiplier) * (1f - markiplier);
Plugin.Logger.LogInfo((object)$"playing sound for {((Object)item).name} at markiplier {num}");
RoundManager.Instance.PlayAudibleNoise(((Component)item).transform.position, Math.Clamp(num * 50f, 8f, 50f), Math.Clamp(num, 0.5f, 1f), 0, item.isInElevator && StartOfRound.Instance.hangarDoorsClosed, 941);
State.GetThrownItems().thrownItemsDict.Remove(((Object)item).GetInstanceID());
}
}
internal class ThrownItems
{
internal Dictionary<int, ThrownItem> thrownItemsDict = new Dictionary<int, ThrownItem>();
internal void Update(ThrownItem thrownItem)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: 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_0277: 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)
//IL_030d: Unknown result type (might be due to invalid IL or missing references)
//IL_0312: Unknown result type (might be due to invalid IL or missing references)
GrabbableObject item = thrownItem.GetItem();
if (item.reachedFloorTarget || thrownItem.IsPanicking())
{
thrownItem.LandAndRemove();
return;
}
float num = Utils.ItemScale(item);
RaycastHit[] array = Physics.SphereCastAll(((Component)item).transform.position, num, ((Component)item).transform.forward, 0f, 11012424, (QueryTriggerInteraction)2);
PlayerControllerB val2 = default(PlayerControllerB);
IHittable val3 = default(IHittable);
EnemyAI val4 = default(EnemyAI);
for (int i = 0; i < array.Length; i++)
{
RaycastHit val = array[i];
string name = ((Object)((RaycastHit)(ref val)).collider).name;
if ((Object)(object)item == (Object)(object)((RaycastHit)(ref val)).collider)
{
Plugin.Logger.LogDebug((object)("skipping " + name + " (is itself)"));
continue;
}
if (((Component)((RaycastHit)(ref val)).transform).gameObject.layer != 3 && ((Component)((RaycastHit)(ref val)).transform).gameObject.layer != 19)
{
Plugin.Logger.LogDebug((object)("skipping " + name + " (failed layer check)"));
continue;
}
((Component)((RaycastHit)(ref val)).transform).TryGetComponent<PlayerControllerB>(ref val2);
if ((Object)(object)thrownItem.GetThrower() == (Object)(object)val2)
{
Plugin.Logger.LogDebug((object)("skipping " + name + " (is the thrower)"));
continue;
}
if (!((Component)((RaycastHit)(ref val)).transform).TryGetComponent<IHittable>(ref val3))
{
Plugin.Logger.LogInfo((object)("skipping " + name + " (not hittable)"));
continue;
}
if (thrownItem.CheckIfHitOrAdd(val3))
{
Plugin.Logger.LogDebug((object)("skipping " + name + " (already been hit)"));
continue;
}
float markiplier = thrownItem.GetMarkiplier();
if ((Object)(object)val2 != (Object)null)
{
int num2 = (int)Math.Round(markiplier * 100f);
Plugin.Logger.LogInfo((object)$"damaging a player {num2} ({val2.health}");
Utils.DamagePlayer(val2, num2, ((Component)item).transform.forward, thrownItem.GetThrower());
Plugin.Logger.LogInfo((object)$"they now have {val2.health} ({val2.isPlayerDead})");
if (val2.isPlayerDead || val2.health == 0 || val2.health - num2 <= 0)
{
Plugin.Logger.LogInfo((object)"it killed them (lol)");
continue;
}
}
else
{
int num3 = (int)Math.Round(markiplier * 10f);
Plugin.Logger.LogInfo((object)$"hitting something else {num3}");
val3.Hit(num3, ((Component)item).transform.forward, thrownItem.GetThrower(), true);
}
if (((Component)((RaycastHit)(ref val)).collider).TryGetComponent<EnemyAI>(ref val4))
{
float num4 = markiplier * 5f;
Plugin.Logger.LogInfo((object)$"stunning an enemy {num4}");
val4.SetEnemyStunned(true, markiplier * 5f, thrownItem.GetThrower());
if (val4.isEnemyDead || val4.enemyHP == 0)
{
Plugin.Logger.LogInfo((object)"it killed it");
continue;
}
}
Plugin.Logger.LogInfo((object)"dropping to floor");
item.startFallingPosition = ((Component)item).transform.localPosition;
item.FallToGround(false);
thrownItem.LandAndRemove();
break;
}
}
}
}