diff --git a/EXILED/Exiled.API/Enums/GunSoundType.cs b/EXILED/Exiled.API/Enums/GunSoundType.cs new file mode 100644 index 0000000000..4e06de866f --- /dev/null +++ b/EXILED/Exiled.API/Enums/GunSoundType.cs @@ -0,0 +1,180 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- +namespace Exiled.API.Enums +{ + /// + /// Represents the type of sound a firearm can produce. + /// + /// + public enum GunSoundType + { + /// + /// Unknown or unmapped sound. + /// + Unknown, + + /// + /// Sound of a gunshot. + /// + Fire, + + /// + /// Sound of a suppressed gunshot. + /// + SuppressedFire, + + /// + /// Sound of a dry fire (trigger pulled with an empty chamber). + /// + DryFire, + + /// + /// Sound of a firearm being equipped or drawn. + /// + Equip, + + /// + /// Sound of a rare or special equip animation. + /// + EquipRare, + + /// + /// Sound of a firearm being cocked or charged. + /// + Cock, + + /// + /// Sound of an initial or special cocking animation. + /// + CockInitial, + + /// + /// Sound of a magazine being inserted. + /// + MagInsert, + + /// + /// Sound of a magazine being ejected. + /// + MagRemove, + + /// + /// Sound of a general reload action (often used for revolvers or shotguns). + /// + Reload, + + /// + /// Sound of a bolt or slide being pulled back. + /// + BoltPull, + + /// + /// Sound of a bolt or slide releasing forward. + /// + BoltReturn, + + /// + /// Sound of a round being ejected from the chamber. + /// + ChamberEject, + + /// + /// Sound of a revolver's cylinder rotating. + /// + CylinderRotate, + + /// + /// Sound of a revolver's cylinder being spun playfully. + /// + CylinderSpin, + + /// + /// Sound of a gunshot using special buckshot ammunition. + /// + FireBuckshot, + + /// + /// Sound of loading buckshot ammunition into an empty firearm. + /// + ReloadBuckshotEmpty, + + /// + /// Sound of ejecting or emptying buckshot ammunition. + /// + EjectBuckshot, + + /// + /// Sound of the weapon being inspected. + /// + Inspect, + + /// + /// Sound of a single shot in Disintegrator mode. + /// + FireDisintegrator, + + /// + /// Sound of the last shot in Disintegrator mode. + /// + FireDisintegratorLast, + + /// + /// Sound of a shot in 3x Burst mode. + /// + FireBurst3x, + + /// + /// Sound of the last shot in a 3x Burst sequence. + /// + FireBurst3xLast, + + /// + /// Sound of general weapon handling, rustling, or adjusting grip. + /// + WeaponHandling, + + /// + /// Sound of a weapon's stock being extended or adjusted. + /// + StockExtend, + + /// + /// Sound of the second sequential shot, often used in double-shot shotgun modes. + /// + FireDouble, + + /// + /// Sound of a single shotgun shell being ejected during unload. + /// + ShellEject, + + /// + /// Sound indicating the completion of a shotgun unload sequence. + /// + UnloadComplete, + + /// + /// Sound of a magazine being firmly tapped or locked into the firearm. + /// + ReloadLock, + + /// + /// Sound of a drum or extended magazine being ejected. + /// + ReloadEjectDrum, + + /// + /// Sound of a drum or extended magazine being inserted. + /// + ReloadInsertDrum, + + /// + /// Sound of a drum or extended magazine being firmly tapped or locked into place. + /// + ReloadLockDrum, + } +} \ No newline at end of file diff --git a/EXILED/Exiled.API/Extensions/ItemExtensions.cs b/EXILED/Exiled.API/Extensions/ItemExtensions.cs index 3a4bb791cc..e988000fa5 100644 --- a/EXILED/Exiled.API/Extensions/ItemExtensions.cs +++ b/EXILED/Exiled.API/Extensions/ItemExtensions.cs @@ -346,6 +346,416 @@ public static uint GetBaseCode(this FirearmType type) /// of the specified . public static ItemCategory GetCategory(this ItemType type) => GetItemBase(type).Category; + /// + /// Gets the associated with a specific and sound index. + /// + /// The of the firearm. + /// The mapped index of the sound. + /// The mapped , or if not found. + public static GunSoundType GetGunSoundType(this ItemType type, int index) => type switch + { + ItemType.GunCOM15 => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.SuppressedFire, + 4 => GunSoundType.Equip, + 5 => GunSoundType.MagInsert, + 6 => GunSoundType.MagRemove, + 7 => GunSoundType.Cock, + 8 => GunSoundType.BoltPull, + 9 => GunSoundType.BoltReturn, + 11 => GunSoundType.ChamberEject, + _ => GunSoundType.Unknown, + }, + + ItemType.GunCOM18 => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.SuppressedFire, + 3 => GunSoundType.Equip, + 4 => GunSoundType.MagInsert, + 5 => GunSoundType.MagRemove, + 6 => GunSoundType.BoltPull, + 7 => GunSoundType.BoltReturn, + 8 => GunSoundType.ChamberEject, + 9 => GunSoundType.EquipRare, + _ => GunSoundType.Unknown, + }, + + ItemType.GunRevolver => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.CylinderRotate, + 4 => GunSoundType.Fire, + 5 => GunSoundType.FireBuckshot, + 7 => GunSoundType.Equip, + 8 => GunSoundType.CylinderSpin, + 9 => GunSoundType.CockInitial, + 11 => GunSoundType.ReloadBuckshotEmpty, + 14 => GunSoundType.Reload, + 15 => GunSoundType.EquipRare, + 16 => GunSoundType.EjectBuckshot, + _ => GunSoundType.Unknown, + }, + + ItemType.GunCom45 => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.Equip, + 3 => GunSoundType.CockInitial, + 4 => GunSoundType.MagInsert, + 5 => GunSoundType.MagRemove, + 6 => GunSoundType.BoltPull, + 7 => GunSoundType.BoltReturn, + _ => GunSoundType.Unknown, + }, + + ItemType.ParticleDisruptor => index switch + { + 0 => GunSoundType.Reload, + 2 => GunSoundType.CockInitial, + 3 => GunSoundType.Inspect, + 4 => GunSoundType.Inspect, + 5 => GunSoundType.Inspect, + 6 => GunSoundType.Equip, + 7 => GunSoundType.FireDisintegrator, + 9 => GunSoundType.FireDisintegrator, + 8 => GunSoundType.FireDisintegratorLast, + 10 => GunSoundType.FireDisintegratorLast, + 11 => GunSoundType.FireBurst3x, + 13 => GunSoundType.FireBurst3x, + 12 => GunSoundType.FireBurst3xLast, + 14 => GunSoundType.FireBurst3xLast, + _ => GunSoundType.Unknown, + }, + + ItemType.GunFSP9 => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.SuppressedFire, + 3 => GunSoundType.WeaponHandling, + 4 => GunSoundType.Equip, + 5 => GunSoundType.WeaponHandling, + 7 => GunSoundType.MagRemove, + 8 => GunSoundType.BoltPull, + 9 => GunSoundType.StockExtend, + 11 => GunSoundType.BoltReturn, + 12 => GunSoundType.MagInsert, + 13 => GunSoundType.ChamberEject, + _ => GunSoundType.Unknown, + }, + + ItemType.GunShotgun => index switch + { + 0 => GunSoundType.FireDouble, + 1 => GunSoundType.Fire, + 2 => GunSoundType.DryFire, + 3 => GunSoundType.WeaponHandling, + 4 => GunSoundType.MagInsert, + 5 => GunSoundType.MagInsert, + 6 => GunSoundType.BoltPull, + 7 => GunSoundType.BoltReturn, + 8 => GunSoundType.UnloadComplete, + 9 => GunSoundType.ShellEject, + 10 => GunSoundType.Equip, + _ => GunSoundType.Unknown, + }, + + ItemType.GunFRMG0 => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.SuppressedFire, + 5 => GunSoundType.Equip, + 7 => GunSoundType.MagRemove, + 8 => GunSoundType.ReloadEjectDrum, + 9 => GunSoundType.Cock, + 10 => GunSoundType.MagInsert, + 11 => GunSoundType.ReloadInsertDrum, + 13 => GunSoundType.ReloadLock, + 14 => GunSoundType.ReloadLockDrum, + 16 => GunSoundType.ChamberEject, + _ => GunSoundType.Unknown, + }, + + ItemType.GunAK => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.SuppressedFire, + 6 => GunSoundType.Equip, + 7 => GunSoundType.MagRemove, + 8 => GunSoundType.ReloadEjectDrum, + 10 => GunSoundType.Cock, + 11 => GunSoundType.CockInitial, + 12 => GunSoundType.ReloadInsertDrum, + 14 => GunSoundType.MagInsert, + 19 => GunSoundType.ChamberEject, + _ => GunSoundType.Unknown, + }, + + ItemType.GunA7 => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.CockInitial, + 3 => GunSoundType.Equip, + 5 => GunSoundType.MagRemove, + 6 => GunSoundType.WeaponHandling, + 7 => GunSoundType.MagInsert, + 8 => GunSoundType.ChamberEject, + _ => GunSoundType.Unknown, + }, + + ItemType.GunSCP127 => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.CockInitial, + 4 => GunSoundType.Equip, + 5 => GunSoundType.Cock, + 6 => GunSoundType.WeaponHandling, + _ => GunSoundType.Unknown, + }, + + ItemType.GunLogicer => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.Equip, + 3 => GunSoundType.Cock, + 4 => GunSoundType.BoltPull, + 5 => GunSoundType.MagRemove, + 6 => GunSoundType.MagInsert, + 7 => GunSoundType.BoltReturn, + 8 => GunSoundType.WeaponHandling, + _ => GunSoundType.Unknown, + }, + + ItemType.GunCrossvec => index switch + { + 0 => GunSoundType.DryFire, + 1 => GunSoundType.Fire, + 2 => GunSoundType.SuppressedFire, + 4 => GunSoundType.Equip, + 5 => GunSoundType.StockExtend, + 6 => GunSoundType.BoltPull, + 7 => GunSoundType.BoltReturn, + 8 => GunSoundType.MagRemove, + 9 => GunSoundType.MagInsert, + 10 => GunSoundType.WeaponHandling, + 15 => GunSoundType.ChamberEject, + _ => GunSoundType.Unknown, + }, + + _ => GunSoundType.Unknown, + }; + + /// + /// Gets the mapped index associated with a specific and . + /// + /// The of the firearm. + /// The to find the index for. + /// The mapped index, or -1 if not found. + public static int GetGunSoundIndex(this ItemType type, GunSoundType soundType) => type switch + { + ItemType.GunCOM15 => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.SuppressedFire => 2, + GunSoundType.Equip => 4, + GunSoundType.MagInsert => 5, + GunSoundType.MagRemove => 6, + GunSoundType.Cock => 7, + GunSoundType.BoltPull => 8, + GunSoundType.BoltReturn => 9, + GunSoundType.ChamberEject => 11, + _ => -1, + }, + + ItemType.GunCOM18 => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.SuppressedFire => 2, + GunSoundType.Equip => 3, + GunSoundType.MagInsert => 4, + GunSoundType.MagRemove => 5, + GunSoundType.BoltPull => 6, + GunSoundType.BoltReturn => 7, + GunSoundType.ChamberEject => 8, + GunSoundType.EquipRare => 9, + _ => -1, + }, + + ItemType.GunRevolver => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.CylinderRotate => 1, + GunSoundType.Fire => 4, + GunSoundType.FireBuckshot => 5, + GunSoundType.Equip => 7, + GunSoundType.CylinderSpin => 8, + GunSoundType.CockInitial => 9, + GunSoundType.ReloadBuckshotEmpty => 11, + GunSoundType.Reload => 14, + GunSoundType.EquipRare => 15, + GunSoundType.EjectBuckshot => 16, + _ => -1, + }, + + ItemType.GunCom45 => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.Equip => 2, + GunSoundType.CockInitial => 3, + GunSoundType.MagInsert => 4, + GunSoundType.MagRemove => 5, + GunSoundType.BoltPull => 6, + GunSoundType.BoltReturn => 7, + _ => -1, + }, + + ItemType.ParticleDisruptor => soundType switch + { + GunSoundType.Reload => 0, + GunSoundType.CockInitial => 2, + GunSoundType.Inspect => 3, + GunSoundType.Equip => 6, + GunSoundType.FireDisintegrator => 7, + GunSoundType.FireDisintegratorLast => 8, + GunSoundType.FireBurst3x => 11, + GunSoundType.FireBurst3xLast => 12, + _ => -1, + }, + + ItemType.GunFSP9 => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.SuppressedFire => 2, + GunSoundType.WeaponHandling => 3, + GunSoundType.Equip => 4, + GunSoundType.MagRemove => 7, + GunSoundType.BoltPull => 8, + GunSoundType.StockExtend => 9, + GunSoundType.BoltReturn => 11, + GunSoundType.MagInsert => 12, + GunSoundType.ChamberEject => 13, + _ => -1, + }, + + ItemType.GunShotgun => soundType switch + { + GunSoundType.FireDouble => 0, + GunSoundType.Fire => 1, + GunSoundType.DryFire => 2, + GunSoundType.WeaponHandling => 3, + GunSoundType.MagInsert => 4, + GunSoundType.BoltPull => 6, + GunSoundType.BoltReturn => 7, + GunSoundType.UnloadComplete => 8, + GunSoundType.ShellEject => 9, + GunSoundType.Equip => 10, + _ => -1, + }, + + ItemType.GunFRMG0 => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.SuppressedFire => 2, + GunSoundType.Equip => 5, + GunSoundType.MagRemove => 7, + GunSoundType.ReloadEjectDrum => 8, + GunSoundType.Cock => 9, + GunSoundType.MagInsert => 10, + GunSoundType.ReloadInsertDrum => 11, + GunSoundType.ReloadLock => 13, + GunSoundType.ReloadLockDrum => 14, + GunSoundType.ChamberEject => 16, + _ => -1, + }, + + ItemType.GunAK => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.SuppressedFire => 2, + GunSoundType.Equip => 6, + GunSoundType.MagRemove => 7, + GunSoundType.ReloadEjectDrum => 8, + GunSoundType.Cock => 10, + GunSoundType.CockInitial => 11, + GunSoundType.ReloadInsertDrum => 12, + GunSoundType.MagInsert => 14, + GunSoundType.ChamberEject => 19, + _ => -1, + }, + + ItemType.GunA7 => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.CockInitial => 2, + GunSoundType.Equip => 3, + GunSoundType.MagRemove => 5, + GunSoundType.WeaponHandling => 6, + GunSoundType.MagInsert => 7, + GunSoundType.ChamberEject => 8, + _ => -1, + }, + + ItemType.GunSCP127 => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.CockInitial => 2, + GunSoundType.Equip => 4, + GunSoundType.Cock => 5, + GunSoundType.WeaponHandling => 6, + _ => -1, + }, + + ItemType.GunLogicer => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.Equip => 2, + GunSoundType.Cock => 3, + GunSoundType.BoltPull => 4, + GunSoundType.MagRemove => 5, + GunSoundType.MagInsert => 6, + GunSoundType.BoltReturn => 7, + GunSoundType.WeaponHandling => 8, + _ => -1, + }, + + ItemType.GunCrossvec => soundType switch + { + GunSoundType.DryFire => 0, + GunSoundType.Fire => 1, + GunSoundType.SuppressedFire => 2, + GunSoundType.Equip => 4, + GunSoundType.StockExtend => 5, + GunSoundType.BoltPull => 6, + GunSoundType.BoltReturn => 7, + GunSoundType.MagRemove => 8, + GunSoundType.MagInsert => 9, + GunSoundType.WeaponHandling => 10, + GunSoundType.ChamberEject => 15, + _ => -1, + }, + + _ => -1, + }; + /// /// Checks if the specified has the specified . /// diff --git a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs index bbd3258782..352f4786d1 100644 --- a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs +++ b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs @@ -218,6 +218,26 @@ public static ReadOnlyDictionary RpcFullNames public static void PlayGunSound(this Player player, Vector3 position, ItemType itemType, byte volume, byte audioClipId = 0) => PlayGunSound(player, position, itemType.GetFirearmType(), volume, audioClipId); + /// + /// Plays a gun sound for a specific player at a given position using the specified firearm type. + /// + /// The player who will hear the sound. + /// World position where the sound will be played. + /// Type of firearm whose sound set will be used. + /// Playback pitch for the sound. Default is 1. + /// Which sound from the firearm's sound set to play (for example Fire, Cock, etc.). + public static void PlayGunSound(this Player player, Vector3 position, FirearmType firearmType, float pitch = 1, GunSoundType soundType = GunSoundType.Fire) + { + int index = firearmType.GetItemType().GetGunSoundIndex(soundType); + if (index == -1) + { + Log.Warn($"Failed to find gun sound for {firearmType} with sound type {soundType}."); + return; + } + + player.PlayGunSound(position, firearmType, pitch, index); + } + /// /// Plays a gun sound that only the can hear. /// @@ -228,7 +248,7 @@ public static void PlayGunSound(this Player player, Vector3 position, ItemType i /// Index of clip. public static void PlayGunSound(this Player player, Vector3 position, FirearmType firearmType, float pitch = 1, int clipIndex = 0) { - if (firearmType is FirearmType.ParticleDisruptor or FirearmType.None) + if (firearmType is FirearmType.None) return; Features.Items.Firearm firearm = Features.Items.Firearm.ItemTypeToFirearmInstance[firearmType]; diff --git a/EXILED/Exiled.Events/EventArgs/Player/ReceivingGunSoundEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ReceivingGunSoundEventArgs.cs index 8620534e04..f8fe2606e4 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ReceivingGunSoundEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ReceivingGunSoundEventArgs.cs @@ -9,6 +9,8 @@ namespace Exiled.Events.EventArgs.Player { using AudioPooling; + using Exiled.API.Enums; + using Exiled.API.Extensions; using Exiled.API.Features; using Exiled.API.Features.Items; using Exiled.Events.EventArgs.Interfaces; @@ -67,6 +69,25 @@ public ReceivingGunSoundEventArgs(ReferenceHub hub, InventorySystem.Items.Firear /// public int AudioIndex { get; set; } + /// + /// Gets or sets or set the type of the gun sound. + /// + public GunSoundType SoundType + { + get => Firearm.Type.GetGunSoundType(AudioIndex); + set + { + int index = Firearm.Type.GetGunSoundIndex(value); + if (index == -1) + { + Log.Warn($"The firearm {Firearm} doesn't have a sound of type {value}."); + return; + } + + AudioIndex = index; + } + } + /// /// Gets or sets the mixer channel through which the sound will be played. /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/SendingGunSoundEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/SendingGunSoundEventArgs.cs index 636d3fec80..cb726b35ab 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/SendingGunSoundEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/SendingGunSoundEventArgs.cs @@ -8,6 +8,8 @@ namespace Exiled.Events.EventArgs.Player { using AudioPooling; + using Exiled.API.Enums; + using Exiled.API.Extensions; using Exiled.API.Features; using Exiled.API.Features.Items; using Exiled.Events.EventArgs.Interfaces; @@ -57,6 +59,25 @@ public SendingGunSoundEventArgs(InventorySystem.Items.Firearms.Firearm firearm, /// public int AudioIndex { get; set; } + /// + /// Gets or sets or set the type of the gun sound. + /// + public GunSoundType SoundType + { + get => Firearm.Type.GetGunSoundType(AudioIndex); + set + { + int index = Firearm.Type.GetGunSoundIndex(value); + if (index == -1) + { + Log.Warn($"The firearm {Firearm} doesn't have a sound of type {value}."); + return; + } + + AudioIndex = index; + } + } + /// /// Gets or sets the mixer channel through which the sound will be played. /// diff --git a/EXILED/Exiled.Example/Commands/Test.cs b/EXILED/Exiled.Example/Commands/Test.cs index b15a3f0f74..79b1b58def 100644 --- a/EXILED/Exiled.Example/Commands/Test.cs +++ b/EXILED/Exiled.Example/Commands/Test.cs @@ -11,8 +11,8 @@ namespace Exiled.Example.Commands using CommandSystem; + using Exiled.API.Enums; using Exiled.API.Features; - using Exiled.API.Features.Pickups; /// /// This is an example of how commands should be made. @@ -34,18 +34,26 @@ public bool Execute(ArraySegment arguments, ICommandSender sender, out s { Player player = Player.Get(sender); - Log.Warn($"{player.Items.Count} -- {player.Inventory.UserInventory.Items.Count}"); + if (!Enum.TryParse(arguments.At(0), out FirearmType itemType)) + { + response = "notitem type."; + return false; + } - foreach (Player item in Player.List) - Log.Warn(item); + if (!float.TryParse(arguments.At(1), out float pitch)) + { + response = "not index."; + return false; + } - foreach (Pickup pickup in Pickup.List) - Log.Warn($"{pickup.Type} ({pickup.Serial}) -- {pickup.Position}"); + if (!byte.TryParse(arguments.At(2), out byte clipIndex)) + { + response = "not index."; + return false; + } - foreach (PocketDimensionTeleport teleport in Map.PocketDimensionTeleports) - Log.Warn($"{teleport._type}"); + player.PlayGunSound(itemType, pitch, clipIndex); - player.ClearInventory(); response = $"{player.Nickname} sent the command!"; // Return true if the command was executed successfully; otherwise, false.