using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using OtherLoader;
using UnityEngine;
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace BitWizrd.HuntChokeBomb
{
[BepInPlugin("BitWizrd.HuntChokeBomb", "HuntChokeBomb", "1.0.1")]
[BepInProcess("h3vr.exe")]
[Description("Built with MeatKit")]
[BepInDependency("h3vr.otherloader", "1.3.0")]
public class HuntChokeBombPlugin : BaseUnityPlugin
{
private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
internal static ManualLogSource Logger;
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
LoadAssets();
}
private void LoadAssets()
{
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "BitWizrd.HuntChokeBomb");
OtherLoader.RegisterDirectLoad(BasePath, "BitWizrd.HuntChokeBomb", "", "chokebomb", "", "");
}
}
}
namespace BitWizrd.GrenadeMod
{
public class GrenadeMod : FVRPhysicalObject
{
[Header("Grenade Settings")]
public GameObject grenadeGameObject;
public PinnedGrenadeRing pinnedGrenadeRing;
public Rigidbody grenadeRigidbody;
public bool activateLeverOnPinPull = false;
[Header("Sticky Grenade Settings")]
public bool isStickyGrenade = true;
public Collider stickyCollider;
public float stickingDistance = 0.1f;
public LayerMask stickyLayers;
public float embeddingDistance = 0.02f;
public bool playStickSoundForRigidbodiesOnly = true;
public AudioSource stickSoundSource;
public AudioClip[] stickSounds;
public float minimumStickVelocity = 2f;
public float regrabActivationDelay = 0.5f;
public float massWhileStuck = 10f;
[Header("Grenade Cooking Settings")]
public GameObject pinPullEffectPrefab;
public AudioSource cookingAudioSource;
public AudioClip[] cookingClips;
public float cookingSoundDelay = 1f;
[Header("Grenade Fast Throw Settings")]
public AudioSource fastThrowAudioSource;
public AudioClip[] fastThrowClips;
public float fastThrowVelocityThreshold = 10f;
public float releaseWindow = 0.5f;
private PinnedGrenade grenade;
private Collider grenadeCollider;
private bool hasPlayedFastThrowSound = false;
private bool isPinPulled = false;
private bool isHeld = false;
private bool wasHeld = false;
private bool pinPulledChecked = false;
private bool shouldCheckVelocity = false;
private bool hasReleasedLever = false;
private bool isSticking = false;
private bool canStick = false;
private float timeSinceRelease = 0f;
private GameObject parentObject;
private Vector3 savedPosition;
private Quaternion savedRotation;
private Vector3 savedScale;
private FVRInteractiveObject interactiveObject;
private void Start()
{
interactiveObject = ((Component)this).GetComponent<FVRInteractiveObject>();
}
public override void FVRUpdate()
{
((FVRPhysicalObject)this).FVRUpdate();
if ((Object)(object)grenadeGameObject == (Object)null)
{
return;
}
grenade = grenadeGameObject.GetComponent<PinnedGrenade>();
if ((Object)(object)grenade == (Object)null)
{
return;
}
FVRPhysicalObject component = grenadeGameObject.GetComponent<FVRPhysicalObject>();
if ((Object)(object)component == (Object)null)
{
return;
}
grenadeCollider = grenadeGameObject.GetComponent<Collider>();
if ((Object)(object)grenadeCollider == (Object)null)
{
return;
}
isHeld = ((FVRInteractiveObject)component).IsHeld;
if ((Object)(object)pinnedGrenadeRing != (Object)null)
{
isPinPulled = pinnedGrenadeRing.HasPinDetached();
if (!pinPulledChecked && isPinPulled)
{
pinPulledChecked = true;
shouldCheckVelocity = true;
if (isStickyGrenade)
{
EnableStickyCollider();
}
if ((Object)(object)pinPullEffectPrefab != (Object)null)
{
pinPullEffectPrefab.SetActive(true);
}
}
if (!wasHeld && isHeld)
{
hasPlayedFastThrowSound = false;
timeSinceRelease = 0f;
if (isPinPulled)
{
EnableStickyCollider();
}
shouldCheckVelocity = isPinPulled;
wasHeld = true;
canStick = true;
isSticking = false;
FixedJoint component2 = ((Component)this).GetComponent<FixedJoint>();
if ((Object)(object)component2 != (Object)null)
{
Object.Destroy((Object)(object)component2);
grenadeRigidbody.isKinematic = false;
grenadeRigidbody.detectCollisions = true;
grenadeRigidbody.useGravity = true;
grenadeRigidbody.constraints = (RigidbodyConstraints)0;
Debug.Log((object)"FixedJoint grenade unstuck upon being picked up.");
}
if (isStickyGrenade)
{
DisableStickyColliderTemporarily();
}
}
if (wasHeld && !isHeld)
{
isSticking = false;
wasHeld = false;
}
}
if (isPinPulled || !isHeld)
{
DisableMeleeDamage(component);
}
else
{
EnableMeleeDamage(component);
}
if (isPinPulled && !cookingAudioSource.isPlaying && cookingClips.Length > 0)
{
if (cookingSoundDelay == 0f)
{
PlayCookingSoundImmediately();
}
else
{
((MonoBehaviour)this).StartCoroutine(HandleCookingSoundDelay());
}
}
if (isPinPulled && (Object)(object)pinPullEffectPrefab != (Object)null)
{
pinPullEffectPrefab.SetActive(true);
}
if (isPinPulled && activateLeverOnPinPull && !hasReleasedLever)
{
grenade.ReleaseLever();
hasReleasedLever = true;
}
}
public override void FVRFixedUpdate()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
((FVRPhysicalObject)this).FVRFixedUpdate();
if (shouldCheckVelocity && isHeld)
{
Vector3 velocity = grenadeRigidbody.velocity;
if (((Vector3)(ref velocity)).magnitude >= minimumStickVelocity)
{
canStick = true;
}
else
{
canStick = false;
}
}
if (!shouldCheckVelocity || isHeld)
{
return;
}
timeSinceRelease += Time.fixedDeltaTime;
if (timeSinceRelease <= releaseWindow)
{
Vector3 velocity2 = grenadeRigidbody.velocity;
if (((Vector3)(ref velocity2)).magnitude > fastThrowVelocityThreshold && !hasPlayedFastThrowSound)
{
PlayFastThrowSound();
}
}
else
{
shouldCheckVelocity = false;
}
}
private void DisableMeleeDamage(FVRPhysicalObject physicalObject)
{
if (physicalObject.MP != null && physicalObject.MP.IsMeleeWeapon)
{
physicalObject.MP.IsMeleeWeapon = false;
}
}
private void EnableMeleeDamage(FVRPhysicalObject physicalObject)
{
if (physicalObject.MP != null && !physicalObject.MP.IsMeleeWeapon)
{
physicalObject.MP.IsMeleeWeapon = true;
}
}
private void PlayFastThrowSound()
{
if (fastThrowClips.Length > 0 && (Object)(object)fastThrowAudioSource != (Object)null)
{
AudioClip val = fastThrowClips[Random.Range(0, fastThrowClips.Length)];
fastThrowAudioSource.PlayOneShot(val);
}
hasPlayedFastThrowSound = true;
}
private void OnCollisionEnter(Collision collision)
{
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: 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_011e: Unknown result type (might be due to invalid IL or missing references)
if (!isPinPulled || isSticking || !isStickyGrenade || !((Object)(object)stickyCollider != (Object)null) || !canStick || (Object)(object)collision.gameObject.GetComponent<BreakableGlass>() != (Object)null || (Object)(object)collision.gameObject.GetComponent<PinnedGrenade>() != (Object)null || (Object)(object)collision.gameObject.GetComponent<PinnedGrenadePin>() != (Object)null || (Object)(object)collision.gameObject.GetComponent<SosigWeapon>() != (Object)null)
{
return;
}
ContactPoint[] contacts = collision.contacts;
for (int i = 0; i < contacts.Length; i++)
{
ContactPoint contact = contacts[i];
if (!((Object)(object)((ContactPoint)(ref contact)).thisCollider == (Object)(object)stickyCollider))
{
continue;
}
if ((LayerMask.op_Implicit(stickyLayers) & (1 << collision.gameObject.layer)) == 0 || !IsContactPointWithinStickingDistance(((ContactPoint)(ref contact)).point))
{
break;
}
isSticking = true;
StickToSurface(collision, contact);
PlayStickingSound(collision);
parentObject = collision.gameObject;
if ((Object)(object)parentObject != (Object)null)
{
DestroyNotifier destroyNotifier = parentObject.GetComponent<DestroyNotifier>();
if ((Object)(object)destroyNotifier == (Object)null)
{
destroyNotifier = parentObject.AddComponent<DestroyNotifier>();
}
destroyNotifier.OnDestroyed += OnDestroyUnstickGrenade;
}
break;
}
}
private bool IsContactPointWithinStickingDistance(Vector3 contactPoint)
{
//IL_0007: 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_000d: 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_000f: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = stickyCollider.ClosestPoint(contactPoint);
float num = Vector3.Distance(contactPoint, val);
return num < stickingDistance;
}
private void StickToSurface(Collision collision, ContactPoint contact)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: 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_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Expected O, but got Unknown
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_021e: 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_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: 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)
if ((Object)(object)stickyCollider == (Object)null)
{
return;
}
if ((Object)(object)interactiveObject != (Object)null && interactiveObject.IsHeld)
{
interactiveObject.ForceBreakInteraction();
}
savedPosition = ((Component)this).transform.position;
savedRotation = ((Component)this).transform.rotation;
Vector3 lossyScale = ((Component)this).transform.lossyScale;
Rigidbody rigidbody = collision.rigidbody;
Vector3 val = ((ContactPoint)(ref contact)).normal * embeddingDistance;
if ((Object)(object)rigidbody != (Object)null)
{
((Component)this).transform.position = ((ContactPoint)(ref contact)).point + val;
FixedJoint component = ((Component)this).GetComponent<FixedJoint>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
FixedJoint val2 = ((Component)this).gameObject.AddComponent<FixedJoint>();
((Joint)val2).connectedBody = rigidbody;
((Joint)val2).breakForce = float.MaxValue;
((Joint)val2).breakTorque = float.MaxValue;
grenadeRigidbody.useGravity = false;
grenadeRigidbody.isKinematic = false;
grenadeRigidbody.constraints = (RigidbodyConstraints)0;
grenadeRigidbody.mass = massWhileStuck;
SetCollidersToLayer(stickyCollider, "NoCol");
}
else
{
GameObject val3 = new GameObject("DummyParent");
val3.transform.position = ((ContactPoint)(ref contact)).point;
val3.transform.rotation = collision.transform.rotation;
grenadeRigidbody.isKinematic = true;
val3.transform.SetParent(collision.transform, true);
((Component)this).transform.SetParent(val3.transform, false);
((Component)this).transform.localScale = new Vector3(lossyScale.x / ((Component)this).transform.lossyScale.x, lossyScale.y / ((Component)this).transform.lossyScale.y, lossyScale.z / ((Component)this).transform.lossyScale.z);
((Component)this).transform.position = ((ContactPoint)(ref contact)).point + val;
((Component)this).transform.rotation = savedRotation;
}
}
private void UnstickFromSurface()
{
if ((Object)(object)((Component)this).GetComponent<FixedJoint>() != (Object)null)
{
Object.Destroy((Object)(object)((Component)this).GetComponent<FixedJoint>());
}
SetCollidersToLayer(stickyCollider, "Default");
grenadeRigidbody.isKinematic = false;
grenadeRigidbody.detectCollisions = true;
grenadeRigidbody.useGravity = true;
grenadeRigidbody.constraints = (RigidbodyConstraints)0;
grenadeRigidbody.mass = 1f;
isSticking = false;
}
private void EnableStickyCollider()
{
if ((Object)(object)stickyCollider != (Object)null)
{
stickyCollider.enabled = true;
}
}
private void DisableStickyColliderTemporarily()
{
if ((Object)(object)stickyCollider != (Object)null)
{
stickyCollider.enabled = false;
}
((MonoBehaviour)this).StartCoroutine(ReenableStickyColliderAfterDelay());
}
private IEnumerator ReenableStickyColliderAfterDelay()
{
yield return (object)new WaitForSeconds(regrabActivationDelay);
EnableStickyCollider();
}
private void PlayStickingSound(Collision collision)
{
if ((Object)(object)stickSoundSource != (Object)null && stickSounds.Length > 0 && ((playStickSoundForRigidbodiesOnly && (Object)(object)collision.rigidbody != (Object)null) || !playStickSoundForRigidbodiesOnly))
{
int num = Random.Range(0, stickSounds.Length);
stickSoundSource.clip = stickSounds[num];
stickSoundSource.Play();
}
}
private void OnDestroyUnstickGrenade()
{
if ((Object)(object)parentObject != (Object)null)
{
Object.Destroy((Object)(object)parentObject.GetComponent<DestroyNotifier>());
}
FixedJoint component = ((Component)this).GetComponent<FixedJoint>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
else
{
((Component)this).transform.SetParent((Transform)null);
}
grenadeRigidbody.isKinematic = false;
grenadeRigidbody.detectCollisions = true;
grenadeRigidbody.useGravity = true;
grenadeRigidbody.constraints = (RigidbodyConstraints)0;
isSticking = false;
stickyCollider.enabled = false;
canStick = false;
}
private void SetCollidersToLayer(Collider collider, string layer)
{
((Component)collider).gameObject.layer = LayerMask.NameToLayer(layer);
}
private IEnumerator HandleCookingSoundDelay()
{
if (cookingSoundDelay > 0f)
{
yield return (object)new WaitForSeconds(cookingSoundDelay);
}
if ((Object)(object)cookingAudioSource != (Object)null && cookingClips.Length > 0)
{
int num = Random.Range(0, cookingClips.Length);
cookingAudioSource.clip = cookingClips[num];
cookingAudioSource.Play();
}
}
private void PlayCookingSoundImmediately()
{
if ((Object)(object)cookingAudioSource != (Object)null && cookingClips.Length > 0)
{
int num = Random.Range(0, cookingClips.Length);
cookingAudioSource.clip = cookingClips[num];
cookingAudioSource.Play();
}
}
}
public class DestroyNotifier : MonoBehaviour
{
public delegate void DestroyedAction();
public event DestroyedAction OnDestroyed;
private void OnDestroy()
{
if (this.OnDestroyed != null)
{
this.OnDestroyed();
}
}
}
}