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.1.0
TF2Minigun.dll
Decompiled a month 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 HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("CzajnikXD")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("TF2Minigun")] [assembly: AssemblyTitle("TF2Minigun")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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.1.0")] public class TF2MinigunPlugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.czajnikxd.repo.tf2minigunmod"); private void Awake() { harmony.PatchAll(Assembly.GetExecutingAssembly()); foreach (MethodBase patchedMethod in harmony.GetPatchedMethods()) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Patched: " + patchedMethod.DeclaringType.Name + "." + patchedMethod.Name)); } } } } namespace CzajnikXD.TF2MinigunMod.Patches { [HarmonyPatch(typeof(ItemGun), "ShootLogic")] internal static class ItemGun_ShootLogic_Patch { private static bool Prefix(ItemGun __instance) { return (Object)(object)((Component)__instance).GetComponent<MinigunContinuousFireLogic>() == (Object)null; } } [HarmonyPatch(typeof(ItemGun), "Misfire")] internal static class ItemGun_Misfire_Patch { private static bool Prefix(ItemGun __instance) { return (Object)(object)((Component)__instance).GetComponent<MinigunContinuousFireLogic>() == (Object)null; } } } namespace CzajnikXD.TF2MinigunMod.Behaviours { [RequireComponent(typeof(PhotonView))] public class MinigunContinuousFireLogic : MonoBehaviour { public enum MinigunState { Idle, WindingUp, Spinning, Shooting, ShootingEmpty, WindingDown } private ItemGun itemGun; private ItemBattery itemBattery; private PhysGrabObject physGrabObject; private PhotonView photonView; public MinigunState currentState; public float windUpDuration = 0.87f; public float windDownDuration = 0.87f; public KeyCode fireKey = (KeyCode)101; [Header("Sounds (game Sound class)")] public Sound soundWindUp; public Sound soundWindDown; public Sound soundSpinLoop; public Sound soundShootLoop; public Sound soundEmptyClick; [Tooltip("Volume units per second. Loop volume is capped by the Sound's Volume.")] public float loopFadeIn = 6f; public float loopFadeOut = 6f; [Header("Debug")] public bool debugLogging = true; private bool loggedShootResult; private AudioSource windUpHandle; private AudioSource windDownHandle; private bool spinLoopOn; private bool shootLoopOn; private bool localTriggerHeld; private bool triggerHeld; private float stateTimer; private float shotTimer; private bool loopSourcesDone; private void Awake() { itemGun = ((Component)this).GetComponent<ItemGun>(); itemBattery = ((Component)this).GetComponent<ItemBattery>(); physGrabObject = ((Component)this).GetComponent<PhysGrabObject>(); photonView = ((Component)this).GetComponent<PhotonView>(); if (!Object.op_Implicit((Object)(object)itemGun) || !Object.op_Implicit((Object)(object)itemBattery) || !Object.op_Implicit((Object)(object)physGrabObject)) { Debug.LogError((object)"[MinigunLogic] Missing ItemGun / ItemBattery / PhysGrabObject on prefab root. Disabling."); ((Behaviour)this).enabled = false; } else { TryCreateLoopSources(); } } private void TryCreateLoopSources() { if (!loopSourcesDone && !((Object)(object)AudioManager.instance == (Object)null)) { loopSourcesDone = true; EnsureLoopSource(soundSpinLoop, "MinigunLoop_Spin"); EnsureLoopSource(soundShootLoop, "MinigunLoop_Shoot"); WarnIfLoopBroken(soundSpinLoop, "spinLoop"); WarnIfLoopBroken(soundShootLoop, "shootLoop"); } } private void EnsureLoopSource(Sound s, string objectName) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 if (!HasClips(s) || Object.op_Implicit((Object)(object)s.Source)) { return; } GameObject val = new GameObject(objectName); val.transform.SetParent(((Component)this).transform, false); AudioSource val2 = val.AddComponent<AudioSource>(); val2.playOnAwake = false; val2.loop = true; AudioSource val3 = TemplateFor(s.Type); if (Object.op_Implicit((Object)(object)val3)) { val2.outputAudioMixerGroup = val3.outputAudioMixerGroup; val2.rolloffMode = val3.rolloffMode; val2.minDistance = val3.minDistance; val2.maxDistance = val3.maxDistance; if ((int)val3.rolloffMode == 2) { val2.SetCustomCurve((AudioSourceCurveType)0, val3.GetCustomCurve((AudioSourceCurveType)0)); } } else { val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 3f; val2.maxDistance = 25f; } s.Source = val2; } private static AudioSource TemplateFor(AudioType type) { //IL_000d: 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) //IL_003d: Expected I4, but got Unknown AudioManager instance = AudioManager.instance; GameObject val = instance.AudioDefault; switch (type - 1) { case 0: val = instance.AudioHighFalloff; break; case 1: val = instance.AudioFootstep; break; case 2: val = instance.AudioMaterialImpact; break; case 3: val = instance.AudioCutscene; break; case 4: val = instance.AudioAmbienceBreaker; break; case 5: val = instance.AudioLowFalloff; break; case 6: val = instance.AudioGlobal; break; case 7: val = instance.AudioHigherFalloff; break; case 8: val = instance.AudioAttack; break; case 9: val = instance.AudioPersistent; break; } if (!Object.op_Implicit((Object)(object)val)) { return null; } return val.GetComponent<AudioSource>(); } private static bool HasClips(Sound s) { if (s != null && s.Sounds != null) { return s.Sounds.Length != 0; } return false; } private static bool LoopReady(Sound s) { if (HasClips(s)) { return Object.op_Implicit((Object)(object)s.Source); } return false; } private static void WarnIfLoopBroken(Sound s, string label) { if (HasClips(s) && !Object.op_Implicit((Object)(object)s.Source)) { Debug.LogWarning((object)("[MinigunLogic] Sound '" + label + "' has clips but no Source (AudioSource) assigned; the loop is skipped.")); } else if (!HasClips(s)) { Debug.LogWarning((object)("[MinigunLogic] Sound '" + label + "' has no clips; the loop is skipped.")); } } private void Update() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) bool flag = false; if (physGrabObject.grabbed && physGrabObject.grabbedLocal && PlayerController.instance.InputDisableTimer <= 0f) { flag = Input.GetKey(fireKey); } if (flag != localTriggerHeld) { localTriggerHeld = flag; BroadcastTrigger(flag); } bool flag2 = triggerHeld && physGrabObject.grabbed; float deltaTime = Time.deltaTime; stateTimer += deltaTime; shotTimer -= deltaTime; MinigunState minigunState = currentState; switch (currentState) { case MinigunState.Idle: if (flag2) { minigunState = MinigunState.WindingUp; } break; case MinigunState.WindingUp: if (!flag2) { minigunState = MinigunState.WindingDown; } else if (stateTimer >= windUpDuration) { minigunState = MinigunState.Spinning; } break; case MinigunState.Spinning: minigunState = (flag2 ? (IsEmpty() ? MinigunState.ShootingEmpty : MinigunState.Shooting) : MinigunState.WindingDown); break; case MinigunState.Shooting: if (!flag2) { minigunState = MinigunState.WindingDown; } else if (IsEmpty()) { minigunState = MinigunState.ShootingEmpty; } else if (shotTimer <= 0f && SemiFunc.IsMasterClientOrSingleplayer()) { if (itemGun.Shoot()) { shotTimer = Mathf.Max(itemGun.shootCooldown, 0.02f); } if (!loggedShootResult) { loggedShootResult = true; } } break; case MinigunState.ShootingEmpty: if (!flag2) { minigunState = MinigunState.WindingDown; } else if (!IsEmpty()) { minigunState = MinigunState.Shooting; } else if (shotTimer <= 0f) { PlayOneShot(soundEmptyClick); shotTimer = Mathf.Max(itemGun.shootCooldown, 0.2f); } break; case MinigunState.WindingDown: if (flag2) { minigunState = MinigunState.WindingUp; } else if (stateTimer >= windDownDuration) { minigunState = MinigunState.Idle; } break; } if (minigunState != currentState) { currentState = minigunState; stateTimer = 0f; loggedShootResult = false; OnStateEnter(minigunState); } TryCreateLoopSources(); if (LoopReady(soundSpinLoop)) { soundSpinLoop.PlayLoop(spinLoopOn, loopFadeIn, loopFadeOut, 1f, 1f); } if (LoopReady(soundShootLoop)) { soundShootLoop.PlayLoop(shootLoopOn, loopFadeIn, loopFadeOut, 1f, 1f); } } private bool IsEmpty() { return itemBattery.batteryLifeInt <= 0; } private void BroadcastTrigger(bool held) { if (SemiFunc.IsMultiplayer()) { if (photonView.ViewID != 0) { photonView.RPC("SetTriggerHeldRPC", (RpcTarget)0, new object[1] { held }); } } else { SetTriggerHeldRPC(held); } } [PunRPC] private void SetTriggerHeldRPC(bool held) { triggerHeld = held; } [Conditional("DEBUG")] private void Dbg(string msg) { if (debugLogging) { Debug.Log((object)("[MinigunLogic] " + msg)); } } private void OnStateEnter(MinigunState state) { switch (state) { case MinigunState.WindingUp: StopHandle(ref windDownHandle); StopHandle(ref windUpHandle); windUpHandle = PlayOneShot(soundWindUp); spinLoopOn = true; shootLoopOn = false; break; case MinigunState.Spinning: spinLoopOn = true; shootLoopOn = false; break; case MinigunState.Shooting: spinLoopOn = true; shootLoopOn = true; break; case MinigunState.ShootingEmpty: spinLoopOn = true; shootLoopOn = false; shotTimer = 0f; break; case MinigunState.WindingDown: StopHandle(ref windUpHandle); StopHandle(ref windDownHandle); windDownHandle = PlayOneShot(soundWindDown); spinLoopOn = false; shootLoopOn = false; break; case MinigunState.Idle: spinLoopOn = false; shootLoopOn = false; break; } } private AudioSource PlayOneShot(Sound s) { if (!HasClips(s)) { return null; } return s.Play(((Component)this).transform, 1f, 1f, 1f, 1f); } private static void StopHandle(ref AudioSource handle) { if (Object.op_Implicit((Object)(object)handle)) { handle.Stop(); } handle = null; } private static void StopLoopNow(Sound s) { if (s != null && Object.op_Implicit((Object)(object)s.Source) && s.Source.isPlaying) { s.Source.Stop(); } } private void OnDisable() { StopHandle(ref windUpHandle); StopHandle(ref windDownHandle); StopLoopNow(soundSpinLoop); StopLoopNow(soundShootLoop); spinLoopOn = false; shootLoopOn = false; currentState = MinigunState.Idle; localTriggerHeld = false; triggerHeld = false; } } }