Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TF2Minigun Mod v1.0.3
TF2Minigun.dll
Decompiled 10 months agousing 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; } } } }