using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using CzajnikXD.TF2MinigunMod.Behaviours;
using CzajnikXD.TF2MinigunMod.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
[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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("CzajnikXD")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TF2Minigun")]
[assembly: AssemblyTitle("TF2Minigun")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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.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;
}
}
[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 CzajnikXD.TF2MinigunMod
{
[BepInPlugin("com.czajnikxd.repo.tf2minigunmod", "TF2 Minigun Mod", "1.0.3")]
public class TF2MinigunPlugin : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("com.czajnikxd.repo.tf2minigunmod");
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"TF2 Minigun Mod is loading and patching!");
harmony.PatchAll(typeof(ItemGunPatches));
((BaseUnityPlugin)this).Logger.LogInfo((object)"TF2 Minigun Mod patches applied.");
}
}
}
namespace CzajnikXD.TF2MinigunMod.Behaviours
{
[RequireComponent(typeof(PhotonView))]
public class MinigunContinuousFireLogic : MonoBehaviour
{
public enum MinigunState
{
Idle,
WindingUp,
Spinning,
Shooting,
ShootingEmpty,
WindingDown
}
private ItemGun itemGun;
private ItemToggle itemToggle;
private ItemBattery itemBattery;
private PhysGrabObject physGrabObject;
private float localShootCooldownTimer;
public MinigunState currentState = MinigunState.Idle;
public MinigunState previousStateForLog = MinigunState.Idle;
public float windUpDuration = 0.87f;
public float windDownDuration = 0.87f;
private float stateTimer = 0f;
public KeyCode fireKey = (KeyCode)101;
public AudioClip windUpAudioClip;
public AudioClip windDownAudioClip;
public AudioClip spinLoopAudioClip;
public AudioClip shootLoopAudioClip;
public AudioClip emptyShootAudioClip;
[Range(0f, 1f)]
public float windUpVolume = 0.1f;
[Range(0f, 1f)]
public float windDownVolume = 0.1f;
[Range(0f, 1f)]
public float spinLoopVolume = 0.05f;
[Range(0f, 1f)]
public float shootLoopVolume = 0.1f;
[Range(0f, 1f)]
public float emptyShootVolume = 0.1f;
private AudioSource windUpAudioSource;
private AudioSource windDownAudioSource;
private AudioSource spinAudioSourceComponent;
private AudioSource shootLoopAudioSource;
private AudioSource emptyShootAudioSource;
private bool canShootAfterWindUp = false;
private void Awake()
{
itemGun = ((Component)this).GetComponent<ItemGun>();
itemToggle = ((Component)this).GetComponent<ItemToggle>();
itemBattery = ((Component)this).GetComponent<ItemBattery>();
physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
if ((Object)(object)itemGun == (Object)null)
{
Debug.LogError((object)"[MinigunLogic] ItemGun component not found!");
((Behaviour)this).enabled = false;
return;
}
if ((Object)(object)itemBattery == (Object)null)
{
Debug.LogError((object)"[MinigunLogic] ItemBattery component not found!");
((Behaviour)this).enabled = false;
return;
}
if ((Object)(object)physGrabObject == (Object)null)
{
Debug.LogError((object)"[MinigunLogic] PhysGrabObject component not found!");
((Behaviour)this).enabled = false;
return;
}
windUpAudioSource = SetupAudioSource(windUpAudioClip, loop: false, windUpVolume, "WindUp");
windDownAudioSource = SetupAudioSource(windDownAudioClip, loop: false, windDownVolume, "WindDown");
spinAudioSourceComponent = SetupAudioSource(spinLoopAudioClip, loop: true, spinLoopVolume, "SpinLoop");
shootLoopAudioSource = SetupAudioSource(shootLoopAudioClip, loop: true, shootLoopVolume, "ShootLoop");
emptyShootAudioSource = SetupAudioSource(emptyShootAudioClip, loop: false, emptyShootVolume, "EmptyShoot");
previousStateForLog = currentState;
Debug.Log((object)"[MinigunLogic] Awake: Initialized all custom AudioSources.");
}
private AudioSource SetupAudioSource(AudioClip clip, bool loop, float volume = 1f, string sourceNameForDebug = "Unnamed")
{
if ((Object)(object)clip == (Object)null)
{
Debug.LogWarning((object)("[MinigunLogic] AudioClip for '" + sourceNameForDebug + "' is not assigned in Inspector. This sound will not play."));
return null;
}
AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>();
val.clip = clip;
val.loop = loop;
val.playOnAwake = false;
val.volume = volume;
return val;
}
private void Update()
{
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)itemGun == (Object)null || (Object)(object)physGrabObject == (Object)null || !physGrabObject.grabbed || !physGrabObject.grabbedLocal)
{
if (currentState != 0 && currentState != MinigunState.WindingDown)
{
TransitionToState(MinigunState.WindingDown);
}
UpdateStateMachine(isFireKeyPressed: false);
return;
}
if (localShootCooldownTimer > 0f)
{
localShootCooldownTimer -= Time.deltaTime;
}
bool key = Input.GetKey(fireKey);
UpdateStateMachine(key);
}
private void UpdateStateMachine(bool isFireKeyPressed)
{
stateTimer += Time.deltaTime;
MinigunState minigunState = currentState;
switch (currentState)
{
case MinigunState.Idle:
if (isFireKeyPressed)
{
minigunState = MinigunState.WindingUp;
}
break;
case MinigunState.WindingUp:
canShootAfterWindUp = false;
if (!isFireKeyPressed)
{
minigunState = MinigunState.WindingDown;
}
else if (stateTimer >= windUpDuration)
{
minigunState = MinigunState.Spinning;
canShootAfterWindUp = true;
}
break;
case MinigunState.Spinning:
minigunState = (isFireKeyPressed ? ((!(itemBattery.batteryLife > 0f)) ? MinigunState.ShootingEmpty : MinigunState.Shooting) : MinigunState.WindingDown);
break;
case MinigunState.Shooting:
if (!isFireKeyPressed)
{
minigunState = MinigunState.WindingDown;
}
else if (itemBattery.batteryLife <= 0f)
{
minigunState = MinigunState.ShootingEmpty;
}
else if (canShootAfterWindUp && localShootCooldownTimer <= 0f)
{
itemGun.Shoot();
localShootCooldownTimer = itemGun.shootCooldown;
}
break;
case MinigunState.ShootingEmpty:
if (!isFireKeyPressed)
{
minigunState = MinigunState.WindingDown;
}
else if (itemBattery.batteryLife > 0f)
{
minigunState = MinigunState.Shooting;
}
else if (localShootCooldownTimer <= 0f)
{
AudioSource obj = emptyShootAudioSource;
if (obj != null)
{
obj.PlayOneShot(emptyShootAudioSource.clip, emptyShootAudioSource.volume);
}
itemGun.StartTriggerAnimation();
localShootCooldownTimer = itemGun.shootCooldown;
}
break;
case MinigunState.WindingDown:
canShootAfterWindUp = false;
if (stateTimer >= windDownDuration)
{
minigunState = MinigunState.Idle;
}
else if (isFireKeyPressed)
{
minigunState = MinigunState.WindingUp;
}
break;
}
if (minigunState != currentState)
{
TransitionToState(minigunState);
}
}
private void TransitionToState(MinigunState newState)
{
if (currentState != newState || newState == MinigunState.Idle || newState == MinigunState.WindingUp)
{
if (previousStateForLog != currentState || currentState != newState)
{
Debug.Log((object)$"[MinigunLogic] Transitioning from {currentState} to {newState}");
}
previousStateForLog = currentState;
OnStateExit(currentState, newState);
currentState = newState;
stateTimer = 0f;
OnStateEnter(newState);
}
}
private void OnStateEnter(MinigunState state)
{
switch (state)
{
case MinigunState.WindingUp:
{
AudioSource obj3 = windUpAudioSource;
if (obj3 != null)
{
obj3.Play();
}
StartSpinSound();
StopShootLoopSound();
break;
}
case MinigunState.Spinning:
StartSpinSound();
StopShootLoopSound();
break;
case MinigunState.Shooting:
StartSpinSound();
StartShootLoopSound();
break;
case MinigunState.ShootingEmpty:
StartSpinSound();
StopShootLoopSound();
break;
case MinigunState.WindingDown:
{
AudioSource obj = windDownAudioSource;
if (obj != null)
{
obj.Play();
}
AudioSource obj2 = windUpAudioSource;
if (obj2 != null)
{
obj2.Stop();
}
StopSpinSound();
break;
}
case MinigunState.Idle:
StopAllMinigunSounds();
canShootAfterWindUp = false;
break;
}
}
private void OnStateExit(MinigunState oldState, MinigunState newState)
{
if (oldState == MinigunState.WindingUp && newState != MinigunState.Spinning && newState != MinigunState.WindingDown)
{
AudioSource obj = windUpAudioSource;
if (obj != null)
{
obj.Stop();
}
}
if (oldState == MinigunState.WindingDown && newState != 0 && newState != MinigunState.WindingUp)
{
AudioSource obj2 = windDownAudioSource;
if (obj2 != null)
{
obj2.Stop();
}
}
if (oldState == MinigunState.Shooting && newState != MinigunState.Shooting)
{
StopShootLoopSound();
}
bool flag = oldState == MinigunState.WindingUp || oldState == MinigunState.Spinning || oldState == MinigunState.Shooting || oldState == MinigunState.ShootingEmpty || oldState == MinigunState.WindingDown;
bool flag2 = newState == MinigunState.Idle;
if (flag && flag2)
{
StopSpinSound();
StopShootLoopSound();
}
}
private void StartSpinSound()
{
if ((Object)(object)spinAudioSourceComponent != (Object)null && !spinAudioSourceComponent.isPlaying)
{
spinAudioSourceComponent.Play();
}
}
private void StopSpinSound()
{
if ((Object)(object)spinAudioSourceComponent != (Object)null && spinAudioSourceComponent.isPlaying)
{
spinAudioSourceComponent.Stop();
}
}
private void StartShootLoopSound()
{
if ((Object)(object)shootLoopAudioSource != (Object)null && !shootLoopAudioSource.isPlaying)
{
shootLoopAudioSource.Play();
}
}
private void StopShootLoopSound()
{
if ((Object)(object)shootLoopAudioSource != (Object)null && shootLoopAudioSource.isPlaying)
{
shootLoopAudioSource.Stop();
}
}
private void StopAllMinigunSounds(bool includeSpinAndShootLoops = true)
{
AudioSource obj = windUpAudioSource;
if (obj != null)
{
obj.Stop();
}
AudioSource obj2 = windDownAudioSource;
if (obj2 != null)
{
obj2.Stop();
}
AudioSource obj3 = emptyShootAudioSource;
if (obj3 != null)
{
obj3.Stop();
}
if (includeSpinAndShootLoops)
{
StopSpinSound();
StopShootLoopSound();
}
}
private void OnDestroy()
{
StopAllMinigunSounds();
if ((Object)(object)spinAudioSourceComponent != (Object)null)
{
Object.Destroy((Object)(object)spinAudioSourceComponent);
}
if ((Object)(object)windUpAudioSource != (Object)null)
{
Object.Destroy((Object)(object)windUpAudioSource);
}
if ((Object)(object)windDownAudioSource != (Object)null)
{
Object.Destroy((Object)(object)windDownAudioSource);
}
if ((Object)(object)shootLoopAudioSource != (Object)null)
{
Object.Destroy((Object)(object)shootLoopAudioSource);
}
if ((Object)(object)emptyShootAudioSource != (Object)null)
{
Object.Destroy((Object)(object)emptyShootAudioSource);
}
}
}
}
namespace CzajnikXD.TF2MinigunMod.Patches
{
public static class ItemGunPatches
{
[HarmonyPatch(typeof(ItemGun), "UpdateMaster")]
public static class ItemGun_UpdateMaster_Patch
{
private static bool Prefix(ItemGun __instance, ref bool ___prevToggleState, ItemToggle ___itemToggle)
{
MinigunContinuousFireLogic component = ((Component)__instance).GetComponent<MinigunContinuousFireLogic>();
if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled)
{
if ((Object)(object)___itemToggle != (Object)null)
{
___prevToggleState = ___itemToggle.toggleState;
}
return true;
}
return true;
}
}
[HarmonyPatch(typeof(ItemGun), "Misfire")]
public static class ItemGun_Misfire_Patch
{
private static bool Prefix(ItemGun __instance)
{
MinigunContinuousFireLogic component = ((Component)__instance).GetComponent<MinigunContinuousFireLogic>();
if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ItemGun), "ShootRPC")]
public static class ItemGun_ShootRPC_Patch
{
private static bool Prefix(ItemGun __instance, Sound ___soundShoot, Sound ___soundShootGlobal)
{
MinigunContinuousFireLogic component = ((Component)__instance).GetComponent<MinigunContinuousFireLogic>();
if (!((Object)(object)component != (Object)null) || ((Behaviour)component).enabled)
{
}
return true;
}
}
}
}