using System;
using System.Collections;
using System.Collections.Generic;
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 BitWizrd.GrenadeMod;
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.HuntChaosBomb
{
[BepInPlugin("BitWizrd.HuntChaosBomb", "HuntChaosBomb", "1.0.1")]
[BepInProcess("h3vr.exe")]
[Description("Built with MeatKit")]
[BepInDependency("h3vr.otherloader", "1.3.0")]
public class HuntChaosBombPlugin : 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.HuntChaosBomb");
OtherLoader.RegisterDirectLoad(BasePath, "BitWizrd.HuntChaosBomb", "", "huntchaosbomb", "", "");
}
}
}
namespace BitWizrd.ChaosBombExplosion
{
public class ChaosBombExplosion : MonoBehaviour
{
[Header("Chaos Bomb Explosion Settings")]
public bool isChaosBombExplosion = false;
public float minChaosDuration = 30f;
public float maxChaosDuration = 60f;
private float totalChaosDuration;
public float destroyDelay = 10f;
[Header("Grenade Settings")]
public GameObject grenadeGameObject;
private PinnedGrenade grenade;
public float grenadeFuseTime = 5f;
private bool grenadeHasExploded = false;
private bool isActivated = false;
private bool chaosSequenceEnded = false;
public WeaponSettings Shotgun1;
public WeaponSettings Shotgun2;
public WeaponSettings Shotgun3;
public WeaponSettings Rifle1;
public WeaponSettings Rifle2;
public WeaponSettings Rifle3;
public WeaponSettings Rifle4;
public WeaponSettings Rifle5;
public WeaponSettings Handgun1;
public WeaponSettings Handgun2;
public WeaponSettings Handgun3;
public WeaponSettings Handgun4;
private int firstWeaponType = -1;
private BitWizrd.GrenadeMod.GrenadeMod grenadeMod;
[Header("Extinguish Sound Settings")]
public AudioSource extinguishAudioSource;
public AudioClip[] extinguishSounds;
private List<Coroutine> activeFiringCoroutines = new List<Coroutine>();
private Dictionary<WeaponType, CoroutineState> coroutineStates = new Dictionary<WeaponType, CoroutineState>();
private void Start()
{
if (isChaosBombExplosion)
{
totalChaosDuration = Random.Range(minChaosDuration, maxChaosDuration);
AttachPinnedGrenade();
firstWeaponType = Random.Range(0, 3);
if ((Object)(object)grenadeGameObject != (Object)null)
{
grenadeMod = grenadeGameObject.GetComponent<BitWizrd.GrenadeMod.GrenadeMod>();
}
((MonoBehaviour)this).StartCoroutine(SimulateChaosBombExplosion());
}
}
private void AttachPinnedGrenade()
{
if ((Object)(object)grenadeGameObject != (Object)null)
{
grenade = grenadeGameObject.GetComponent<PinnedGrenade>();
if (!((Object)(object)grenade == (Object)null))
{
}
}
}
private IEnumerator SimulateChaosBombExplosion()
{
if ((Object)(object)grenade != (Object)null)
{
yield return ((MonoBehaviour)this).StartCoroutine(MonitorGrenadeExplosion());
}
if (isActivated)
{
switch (firstWeaponType)
{
case 0:
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Shotgun, fireImmediately: true)));
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Rifle, fireImmediately: false)));
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Handgun, fireImmediately: false)));
break;
case 1:
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Rifle, fireImmediately: true)));
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Shotgun, fireImmediately: false)));
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Handgun, fireImmediately: false)));
break;
case 2:
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Handgun, fireImmediately: true)));
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Shotgun, fireImmediately: false)));
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(WeaponType.Rifle, fireImmediately: false)));
break;
}
yield return (object)new WaitForSeconds(totalChaosDuration);
if (!chaosSequenceEnded)
{
EndChaosBombSequence();
}
}
}
private IEnumerator MonitorGrenadeExplosion()
{
while (!grenade.m_isPinPulled)
{
yield return null;
}
yield return (object)new WaitForSeconds(grenadeFuseTime);
ActivateChaosBomb();
}
private void ActivateChaosBomb()
{
if ((Object)(object)grenade != (Object)null && !grenadeHasExploded)
{
isActivated = true;
grenadeHasExploded = true;
}
}
private IEnumerator WeaponFireCycle(WeaponType type, bool fireImmediately)
{
WeaponSettings weapon = SelectRandomWeapon(type);
CoroutineState state = new CoroutineState
{
fireImmediately = fireImmediately,
remainingCoverTime = ((!fireImmediately) ? Random.Range(weapon.minCoverTime, weapon.maxCoverTime) : 0f),
remainingShots = Random.Range(weapon.minShotAmount, weapon.maxShotAmount + 1),
remainingFireDelay = Random.Range(weapon.minFireDelay, weapon.maxFireDelay)
};
SaveCoroutineState(type, state);
yield return WeaponFireCycle(type, state);
}
private IEnumerator WeaponFireCycle(WeaponType type, CoroutineState state)
{
WeaponSettings weapon = SelectRandomWeapon(type);
if (!state.fireImmediately)
{
yield return (object)new WaitForSeconds(state.remainingCoverTime);
}
while (!chaosSequenceEnded)
{
int numShots = state.remainingShots;
for (int i = 0; i < numShots; i++)
{
if (chaosSequenceEnded)
{
yield break;
}
float fireDelay = state.remainingFireDelay;
((MonoBehaviour)this).StartCoroutine(PlayChaosBombExplosion(weapon.fireObjects));
yield return (object)new WaitForSeconds(fireDelay);
state.remainingFireDelay = Random.Range(weapon.minFireDelay, weapon.maxFireDelay);
}
state.remainingShots = Random.Range(weapon.minShotAmount, weapon.maxShotAmount + 1);
state.remainingCoverTime = Random.Range(weapon.minCoverTime, weapon.maxCoverTime);
yield return (object)new WaitForSeconds(state.remainingCoverTime);
}
}
private WeaponSettings SelectRandomWeapon(WeaponType type)
{
return type switch
{
WeaponType.Shotgun => SelectRandomShotgun(),
WeaponType.Rifle => SelectRandomRifle(),
WeaponType.Handgun => SelectRandomHandgun(),
_ => null,
};
}
private WeaponSettings SelectRandomShotgun()
{
return Random.Range(0, 3) switch
{
0 => Shotgun1,
1 => Shotgun2,
_ => Shotgun3,
};
}
private WeaponSettings SelectRandomRifle()
{
return Random.Range(0, 5) switch
{
0 => Rifle1,
1 => Rifle2,
2 => Rifle3,
3 => Rifle4,
_ => Rifle5,
};
}
private WeaponSettings SelectRandomHandgun()
{
return Random.Range(0, 4) switch
{
0 => Handgun1,
1 => Handgun2,
2 => Handgun3,
_ => Handgun4,
};
}
private void EndChaosBombSequence()
{
if (chaosSequenceEnded)
{
return;
}
chaosSequenceEnded = true;
SetCookingAudioVolumeToZero();
PlayRandomExtinguishSound();
StopParticleEmission();
foreach (Coroutine activeFiringCoroutine in activeFiringCoroutines)
{
if (activeFiringCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(activeFiringCoroutine);
}
}
activeFiringCoroutines.Clear();
((MonoBehaviour)this).StartCoroutine(DelayedDestroy());
}
private IEnumerator DelayedDestroy()
{
yield return (object)new WaitForSeconds(destroyDelay);
KillMe();
}
private void PlayRandomExtinguishSound()
{
if (extinguishSounds.Length > 0 && (Object)(object)extinguishAudioSource != (Object)null)
{
int num = Random.Range(0, extinguishSounds.Length);
AudioClip val = extinguishSounds[num];
if ((Object)(object)val != (Object)null)
{
extinguishAudioSource.PlayOneShot(val);
}
}
}
private void StopParticleEmission()
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)grenadeMod != (Object)null && (Object)(object)grenadeMod.pinPullEffectPrefab != (Object)null)
{
ParticleSystem component = grenadeMod.pinPullEffectPrefab.GetComponent<ParticleSystem>();
if ((Object)(object)component != (Object)null)
{
EmissionModule emission = component.emission;
((EmissionModule)(ref emission)).enabled = false;
}
}
}
private void SetCookingAudioVolumeToZero()
{
if ((Object)(object)grenadeMod != (Object)null && (Object)(object)grenadeMod.cookingAudioSource != (Object)null)
{
grenadeMod.cookingAudioSource.volume = 0f;
}
}
private void KillMe()
{
PinnedGrenade componentInParent = ((Component)this).GetComponentInParent<PinnedGrenade>();
if ((Object)(object)componentInParent != (Object)null)
{
Object.Destroy((Object)(object)((Component)componentInParent).gameObject);
}
else
{
Debug.LogWarning((object)"PinnedGrenade component not found.");
}
}
private IEnumerator PlayChaosBombExplosion(GameObject[] weaponObjects)
{
if (weaponObjects.Length != 0)
{
GameObject selectedPrefab = weaponObjects[Random.Range(0, weaponObjects.Length)];
if (!((Object)(object)selectedPrefab == (Object)null))
{
GameObject explosionInstance = Object.Instantiate<GameObject>(selectedPrefab, ((Component)this).transform.position, ((Component)this).transform.rotation);
yield return (object)new WaitForSeconds(2f);
Object.Destroy((Object)(object)explosionInstance);
}
}
}
private void OnEnable()
{
if (isActivated && grenadeHasExploded)
{
RestartFiringCoroutines();
}
}
private void RestartFiringCoroutines()
{
if (!isActivated || chaosSequenceEnded)
{
return;
}
foreach (KeyValuePair<WeaponType, CoroutineState> coroutineState in coroutineStates)
{
activeFiringCoroutines.Add(((MonoBehaviour)this).StartCoroutine(WeaponFireCycle(coroutineState.Key, coroutineState.Value)));
}
}
private void SaveCoroutineState(WeaponType type, CoroutineState state)
{
if (!coroutineStates.ContainsKey(type))
{
coroutineStates[type] = new CoroutineState();
}
coroutineStates[type].fireImmediately = state.fireImmediately;
coroutineStates[type].remainingCoverTime = state.remainingCoverTime;
coroutineStates[type].remainingShots = state.remainingShots;
coroutineStates[type].remainingFireDelay = state.remainingFireDelay;
}
}
public enum WeaponType
{
Shotgun,
Rifle,
Handgun
}
[Serializable]
public class WeaponSettings
{
public GameObject[] fireObjects;
public int minShotAmount = 1;
public int maxShotAmount = 2;
public float minFireDelay = 1.25f;
public float maxFireDelay = 1.35f;
public float minCoverTime = 3f;
public float maxCoverTime = 6f;
}
public class CoroutineState
{
public bool fireImmediately;
public float remainingCoverTime;
public int remainingShots;
public float remainingFireDelay;
public CoroutineState()
{
fireImmediately = false;
remainingCoverTime = 0f;
remainingShots = 0;
remainingFireDelay = 0f;
}
}
}
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();
}
}
}
}