Decompiled source of TF2Minigun Mod v1.0.3

TF2Minigun.dll

Decompiled a week ago
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;
			}
		}
	}
}