using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("McNutMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("McNutMod")]
[assembly: AssemblyTitle("McNutMod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace McNutMod
{
public class McNutInputs : LcInputActions
{
[InputAction("<Keyboard>/k", Name = "Mode Manuel")]
public InputAction SuicideKey { get; set; }
[InputAction("<Keyboard>/h", Name = "Ronnie McNuttcracked")]
public InputAction RonnieKey { get; set; }
}
[BepInPlugin("McNut.RonnieMcNuttcracked", "Ronnie McNuttcracked", "1.0.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("McNut.RonnieMcNuttcracked");
internal static McNutInputs Inputs = new McNutInputs();
public static AudioClip SoundPreShot;
public static AudioClip SoundAfterShot;
public static bool IsLockingInventory = false;
public static Plugin Instance;
private void Awake()
{
Instance = this;
harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"--- Ronnie McNuttcracked : FINAL GOLD ---");
((MonoBehaviour)this).StartCoroutine(LoadAllSounds());
}
private IEnumerator LoadAllSounds()
{
yield return LoadAudio("mcnutpreshot.ogg", delegate(AudioClip clip)
{
SoundPreShot = clip;
});
yield return LoadAudio("ringtoneaftershot.ogg", delegate(AudioClip clip)
{
SoundAfterShot = clip;
});
}
private IEnumerator LoadAudio(string filename, Action<AudioClip> onLoaded)
{
string folderPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
string fullPath = Path.Combine(folderPath, filename);
string uri = "file://" + fullPath;
UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(uri, (AudioType)14);
try
{
yield return www.SendWebRequest();
if ((int)www.result == 1)
{
AudioClip clip = DownloadHandlerAudioClip.GetContent(www);
((Object)clip).name = filename;
onLoaded(clip);
}
else
{
((BaseUnityPlugin)this).Logger.LogError((object)("[Ronnie] Erreur chargement audio : " + filename));
}
}
finally
{
((IDisposable)www)?.Dispose();
}
}
}
[HarmonyPatch]
public class NetworkHandler
{
public static void RequestRonnieSync(NetworkObjectReference shotgunNetId)
{
//IL_0060: 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_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
if (NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
{
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1);
((FastBufferWriter)(ref val)).WriteValueSafe<NetworkObjectReference>(ref shotgunNetId, default(ForNetworkSerializable));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("Ronnie_Server", 0uL, val, (NetworkDelivery)3);
}
else
{
BroadcastAndExecute(shotgunNetId);
}
}
private static void OnServerReceived(ulong clientId, FastBufferReader reader)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
if (NetworkManager.Singleton.IsServer)
{
NetworkObjectReference shotgunNetId = default(NetworkObjectReference);
((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref shotgunNetId, default(ForNetworkSerializable));
BroadcastAndExecute(shotgunNetId);
}
}
private static void BroadcastAndExecute(NetworkObjectReference shotgunNetId)
{
//IL_0015: 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_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1);
((FastBufferWriter)(ref val)).WriteValueSafe<NetworkObjectReference>(ref shotgunNetId, default(ForNetworkSerializable));
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("Ronnie_Client", val, (NetworkDelivery)3);
RunSequenceLocally(shotgunNetId);
}
private static void OnClientReceived(ulong clientId, FastBufferReader reader)
{
//IL_0007: 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_0024: Unknown result type (might be due to invalid IL or missing references)
NetworkObjectReference netId = default(NetworkObjectReference);
((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref netId, default(ForNetworkSerializable));
if (!NetworkManager.Singleton.IsServer)
{
RunSequenceLocally(netId);
}
}
private static void RunSequenceLocally(NetworkObjectReference netId)
{
NetworkObject val = default(NetworkObject);
if (!((NetworkObjectReference)(ref netId)).TryGet(ref val, (NetworkManager)null))
{
return;
}
ShotgunItem component = ((Component)val).GetComponent<ShotgunItem>();
if ((Object)(object)component != (Object)null)
{
SuicideModeController component2 = ((Component)component).GetComponent<SuicideModeController>();
if ((Object)(object)component2 != (Object)null)
{
component2.StartSyncedSequence();
}
}
}
[HarmonyPatch(typeof(GameNetworkManager), "Start")]
[HarmonyPostfix]
private static void RegisterMessages()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Ronnie_Server", new HandleNamedMessageDelegate(OnServerReceived));
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("Ronnie_Client", new HandleNamedMessageDelegate(OnClientReceived));
}
}
public class SuicideModeController : MonoBehaviour
{
private ShotgunItem shotgun;
public bool isSuicideMode = false;
private Vector3 originalScale;
private AudioSource gunAudioSource;
private AudioSource ronnieAudioSource;
private float originalVolume = 1f;
public bool isRonnieSequenceActive = false;
private bool isWaitingForConfirmation = false;
private float confirmationTimer = 0f;
private const float MAX_CONFIRM_TIME = 5f;
private void Awake()
{
//IL_0030: 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)
shotgun = ((Component)this).GetComponent<ShotgunItem>();
gunAudioSource = ((Component)this).GetComponent<AudioSource>();
if ((Object)(object)((Component)this).transform != (Object)null)
{
originalScale = ((Component)this).transform.localScale;
}
if ((Object)(object)gunAudioSource != (Object)null)
{
originalVolume = gunAudioSource.volume;
}
}
private void Start()
{
CreateRonnieAudioSource();
UpdateHUD();
}
private void CreateRonnieAudioSource()
{
ronnieAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
ronnieAudioSource.playOnAwake = false;
ronnieAudioSource.spatialBlend = 1f;
ronnieAudioSource.priority = 0;
ronnieAudioSource.volume = 1f;
ronnieAudioSource.minDistance = 3f;
ronnieAudioSource.maxDistance = 40f;
}
private void Update()
{
if ((Object)(object)shotgun == (Object)null || !((GrabbableObject)shotgun).isHeld)
{
if (isSuicideMode || isRonnieSequenceActive)
{
ResetGun();
}
}
else
{
if ((Object)(object)((GrabbableObject)shotgun).playerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController)
{
return;
}
if (isRonnieSequenceActive)
{
if ((Object)(object)HUDManager.Instance != (Object)null)
{
HUDManager.Instance.ChangeControlTip(0, "Goodbye...", false);
}
return;
}
if (isWaitingForConfirmation)
{
confirmationTimer -= Time.deltaTime;
if (confirmationTimer <= 0f)
{
isWaitingForConfirmation = false;
UpdateHUD();
}
}
if (!isWaitingForConfirmation && Plugin.Inputs.SuicideKey.triggered)
{
ToggleMode();
}
if (Plugin.Inputs.RonnieKey.triggered)
{
TryTriggerRonnie();
}
UpdateHUD();
}
}
private void TryTriggerRonnie()
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if (shotgun.shellsLoaded <= 0 || shotgun.safetyOn || isSuicideMode)
{
return;
}
if (!isWaitingForConfirmation)
{
isWaitingForConfirmation = true;
confirmationTimer = 5f;
return;
}
isWaitingForConfirmation = false;
if ((Object)(object)((NetworkBehaviour)shotgun).NetworkObject != (Object)null)
{
NetworkHandler.RequestRonnieSync(NetworkObjectReference.op_Implicit(((NetworkBehaviour)shotgun).NetworkObject));
}
}
public void StartSyncedSequence()
{
if ((Object)(object)((GrabbableObject)shotgun).playerHeldBy != (Object)null)
{
((MonoBehaviour)this).StartCoroutine(RunRonnieCinematic(((GrabbableObject)shotgun).playerHeldBy));
}
}
private IEnumerator RunRonnieCinematic(PlayerControllerB player)
{
bool isMe = (Object)(object)player == (Object)(object)GameNetworkManager.Instance.localPlayerController;
isRonnieSequenceActive = true;
if (isMe)
{
Plugin.IsLockingInventory = true;
}
float waitDuration = 2f;
if ((Object)(object)Plugin.SoundPreShot != (Object)null && (Object)(object)ronnieAudioSource != (Object)null)
{
ronnieAudioSource.PlayOneShot(Plugin.SoundPreShot);
waitDuration = Plugin.SoundPreShot.length;
}
float delayAfterFlip = 1f;
float waitTimeBeforeFlip = Mathf.Max(0f, waitDuration - delayAfterFlip);
yield return (object)new WaitForSeconds(waitTimeBeforeFlip);
((Component)this).transform.localScale = new Vector3(originalScale.x, originalScale.y, 0f - originalScale.z);
if ((Object)(object)gunAudioSource != (Object)null && (Object)(object)shotgun.noAmmoSFX != (Object)null)
{
gunAudioSource.PlayOneShot(shotgun.noAmmoSFX);
}
yield return (object)new WaitForSeconds(delayAfterFlip);
isRonnieSequenceActive = false;
if (isMe)
{
isSuicideMode = true;
Plugin.IsLockingInventory = false;
Debug.Log((object)"[Ronnie] BOUM.");
shotgun.ShootGun(((Component)shotgun).transform.position, ((Component)shotgun).transform.forward);
}
if ((Object)(object)ronnieAudioSource != (Object)null)
{
ronnieAudioSource.Stop();
}
yield return (object)new WaitForSeconds(0.5f);
DeadBodyInfo targetBody = null;
DeadBodyInfo[] allBodies = Object.FindObjectsOfType<DeadBodyInfo>();
DeadBodyInfo[] array = allBodies;
foreach (DeadBodyInfo body in array)
{
if ((Object)(object)body.playerScript == (Object)(object)player)
{
targetBody = body;
break;
}
}
if ((Object)(object)Plugin.SoundAfterShot != (Object)null)
{
if ((Object)(object)targetBody != (Object)null)
{
PlaySoundAttached(Plugin.SoundAfterShot, ((Component)targetBody).gameObject, 3f);
}
else
{
PlaySoundLoud(Plugin.SoundAfterShot, ((Component)player).transform.position, 3f);
}
}
}
private void PlaySoundAttached(AudioClip clip, GameObject target, float volumeMult)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("McNutRingtone");
val.transform.SetParent(target.transform, false);
val.transform.localPosition = Vector3.zero;
AudioSource val2 = val.AddComponent<AudioSource>();
val2.clip = clip;
val2.volume = 1f * volumeMult;
val2.spatialBlend = 1f;
val2.minDistance = 10f;
val2.maxDistance = 60f;
val2.priority = 0;
val2.rolloffMode = (AudioRolloffMode)1;
val2.Play();
Object.Destroy((Object)(object)val, clip.length + 0.5f);
}
private void PlaySoundLoud(AudioClip clip, Vector3 pos, float volumeMult)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("McNutRingtoneStatic");
val.transform.position = pos;
AudioSource val2 = val.AddComponent<AudioSource>();
val2.clip = clip;
val2.volume = 1f * volumeMult;
val2.spatialBlend = 1f;
val2.minDistance = 10f;
val2.maxDistance = 60f;
val2.priority = 0;
val2.Play();
Object.Destroy((Object)(object)val, clip.length + 0.5f);
}
private void ToggleMode()
{
isSuicideMode = !isSuicideMode;
if ((Object)(object)gunAudioSource != (Object)null && (Object)(object)shotgun.noAmmoSFX != (Object)null)
{
gunAudioSource.PlayOneShot(shotgun.noAmmoSFX);
}
ApplyRotation();
}
public void ApplyRotation()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
if (isSuicideMode)
{
((Component)this).transform.localScale = new Vector3(originalScale.x, originalScale.y, 0f - originalScale.z);
}
else
{
((Component)this).transform.localScale = originalScale;
}
}
public void ResetGun()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
isSuicideMode = false;
isRonnieSequenceActive = false;
isWaitingForConfirmation = false;
Plugin.IsLockingInventory = false;
((Component)this).transform.localScale = originalScale;
if ((Object)(object)ronnieAudioSource != (Object)null)
{
ronnieAudioSource.Stop();
}
if ((Object)(object)gunAudioSource != (Object)null)
{
gunAudioSource.volume = originalVolume;
}
if ((Object)(object)HUDManager.Instance != (Object)null)
{
HUDManager.Instance.ChangeControlTip(0, "Tirer", false);
}
}
public void UpdateHUD()
{
if ((Object)(object)HUDManager.Instance == (Object)null)
{
return;
}
string bindingDisplayString = InputActionRebindingExtensions.GetBindingDisplayString(Plugin.Inputs.SuicideKey, (DisplayStringOptions)0, (string)null);
string bindingDisplayString2 = InputActionRebindingExtensions.GetBindingDisplayString(Plugin.Inputs.RonnieKey, (DisplayStringOptions)0, (string)null);
string text = "Tirer:[LMB]";
if (!isRonnieSequenceActive)
{
if (isWaitingForConfirmation)
{
int num = Mathf.CeilToInt(confirmationTimer);
HUDManager.Instance.ChangeControlTip(0, $"CONFIRMER RONNIE ? {bindingDisplayString2}:OUI ({num}s)", true);
}
else if (isSuicideMode)
{
HUDManager.Instance.ChangeControlTip(0, text + " | " + bindingDisplayString + ":Normal", false);
}
else
{
string text2 = ((shotgun.shellsLoaded > 0 && !shotgun.safetyOn) ? (bindingDisplayString + ":Inverser | " + bindingDisplayString2 + ":Ronnie") : (bindingDisplayString + ":Inverser"));
HUDManager.Instance.ChangeControlTip(0, text + " | " + text2, false);
}
}
}
public IEnumerator TriggerSuicideAndTP(PlayerControllerB player)
{
Vector3 deathPosition = ((Component)player).transform.position;
Transform bodyTransform = ((Component)player).transform;
isSuicideMode = false;
((Component)this).transform.localScale = originalScale;
yield return (object)new WaitForEndOfFrame();
Vector3 knockback = -bodyTransform.forward * 25f + Vector3.up * 5f;
player.DamagePlayer(100, true, true, (CauseOfDeath)7, 0, false, knockback);
yield return (object)new WaitForSeconds(0.25f);
DeadBodyInfo[] allBodies = Object.FindObjectsOfType<DeadBodyInfo>();
DeadBodyInfo[] array = allBodies;
foreach (DeadBodyInfo body in array)
{
if ((Object)(object)body.playerScript == (Object)(object)player)
{
if (Vector3.Distance(deathPosition, ((Component)body).transform.position) > 15f)
{
((Component)body).transform.position = deathPosition + Vector3.up * 0.6f;
}
break;
}
}
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class PlayerControllerPatch
{
[HarmonyPatch("SwitchToItemSlot")]
[HarmonyPrefix]
private static bool PreventSlotSwitch(PlayerControllerB __instance)
{
if (Plugin.IsLockingInventory && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
{
return false;
}
return true;
}
[HarmonyPatch("Discard_performed")]
[HarmonyPrefix]
private static bool PreventDiscard(PlayerControllerB __instance)
{
if (Plugin.IsLockingInventory && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ShotgunItem))]
internal class ShotgunPatch
{
[HarmonyPatch("EquipItem")]
[HarmonyPostfix]
private static void OnEquip(ShotgunItem __instance)
{
SuicideModeController suicideModeController = ((Component)__instance).gameObject.GetComponent<SuicideModeController>();
if ((Object)(object)suicideModeController == (Object)null)
{
suicideModeController = ((Component)__instance).gameObject.AddComponent<SuicideModeController>();
}
if ((Object)(object)suicideModeController != (Object)null)
{
suicideModeController.ResetGun();
}
}
[HarmonyPatch("DiscardItem")]
[HarmonyPrefix]
private static bool OnDrop(ShotgunItem __instance)
{
SuicideModeController component = ((Component)__instance).gameObject.GetComponent<SuicideModeController>();
if ((Object)(object)component != (Object)null && component.isRonnieSequenceActive)
{
return false;
}
if ((Object)(object)component != (Object)null)
{
component.ResetGun();
}
return true;
}
[HarmonyPatch("ShootGun")]
[HarmonyPrefix]
private static bool OnShoot(ShotgunItem __instance, ref Vector3 shotgunPosition, ref Vector3 shotgunForward)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
SuicideModeController component = ((Component)__instance).gameObject.GetComponent<SuicideModeController>();
if ((Object)(object)component != (Object)null && component.isRonnieSequenceActive)
{
return false;
}
if ((Object)(object)component != (Object)null && component.isSuicideMode)
{
shotgunForward = -shotgunForward;
if ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null)
{
((MonoBehaviour)component).StartCoroutine(component.TriggerSuicideAndTP(((GrabbableObject)__instance).playerHeldBy));
}
return true;
}
return true;
}
[HarmonyPatch("ItemInteractLeftRight")]
[HarmonyPrefix]
private static bool BlockInteraction(ShotgunItem __instance)
{
SuicideModeController component = ((Component)__instance).gameObject.GetComponent<SuicideModeController>();
if ((Object)(object)component != (Object)null && component.isRonnieSequenceActive)
{
return false;
}
return true;
}
}
}