From 0a51307ddfcbb6bf527fb05833cd4658f88182d4 Mon Sep 17 00:00:00 2001 From: aga Date: Wed, 21 Jan 2026 19:13:48 +0200 Subject: [PATCH] added knife_kill, taser_kill, round_start, and round_freeze_end sounds with event handlers [build] --- resources/translations/en.jsonc | 6 +++- src/Configuration/QuakeSoundsConfig.cs | 4 +++ src/EventHandlers/PlayerDeathHandler.cs | 23 ++++++++++--- src/EventHandlers/RoundStartHandler.cs | 45 +++++++++++++++++++++++++ src/QuakeSounds.cs | 2 +- 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/resources/translations/en.jsonc b/resources/translations/en.jsonc index cb17a9c..68d4519 100644 --- a/resources/translations/en.jsonc +++ b/resources/translations/en.jsonc @@ -24,15 +24,19 @@ "quake.headshot": "[blue]Headshot", "quake.humiliation": "[green]Humiliation", "quake.knifekill": "[green]Knife Kill", + "quake.knife_kill": "[green]Knife Kill", + "quake.taser_kill": "[green]Taser Kill", "quake.teamkill": "[red]Team Kill", "quake.selfkill": "[red]Self Kill", "quake.grenadekill": "[green]Grenade Kill", "quake.roundstart": "[default]Round Start", + "quake.round_start": "[default]Round Start", "quake.roundend": "[default]Round End", + "quake.round_freeze_end": "[default]Freeze Time End", "commands.common.only_player": "This command can only be used by a player.", "commands.volume.current": "Current QuakeSounds volume: {volume}/10", "commands.volume.usage": "Usage: !volume <0-10>", "commands.volume.set": "QuakeSounds volume set to {volume}/10.", "commands.quake.enabled": "QuakeSounds enabled.", - "commands.quake.disabled": "QuakeSounds disabled.", + "commands.quake.disabled": "QuakeSounds disabled." } diff --git a/src/Configuration/QuakeSoundsConfig.cs b/src/Configuration/QuakeSoundsConfig.cs index f78773b..2820ebb 100644 --- a/src/Configuration/QuakeSoundsConfig.cs +++ b/src/Configuration/QuakeSoundsConfig.cs @@ -35,6 +35,7 @@ public sealed class QuakeSoundsConfig ["holyshit"] = "holyshit.mp3", ["humiliation"] = "humiliation.mp3", ["impressive"] = "impressive.mp3", + ["knife_kill"] = "knife_kill.mp3", ["killingspree"] = "killingspree.mp3", ["ludicrouskill"] = "ludicrouskill.mp3", ["monsterkill"] = "monsterkill.mp3", @@ -42,6 +43,9 @@ public sealed class QuakeSoundsConfig ["ownage"] = "ownage.mp3", ["perfect"] = "perfect.mp3", ["rampage"] = "rampage.mp3", + ["round_freeze_end"] = "round_freeze_end.mp3", + ["round_start"] = "round_start.mp3", + ["taser_kill"] = "taser_kill.mp3", ["triplekill"] = "triplekill.mp3", ["ultrakill"] = "ultrakill.mp3", ["unstoppable"] = "unstoppable.mp3", diff --git a/src/EventHandlers/PlayerDeathHandler.cs b/src/EventHandlers/PlayerDeathHandler.cs index a53a43e..9626a3f 100644 --- a/src/EventHandlers/PlayerDeathHandler.cs +++ b/src/EventHandlers/PlayerDeathHandler.cs @@ -75,6 +75,24 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event) } } + if (@event.Weapon.Contains("taser", StringComparison.OrdinalIgnoreCase) && TryPlay(attacker, "taser_kill")) + { + return HookResult.Continue; + } + + if (@event.Weapon.Contains("knife", StringComparison.OrdinalIgnoreCase)) + { + if (TryPlay(attacker, "knife_kill")) + { + return HookResult.Continue; + } + + if (TryPlay(attacker, "humiliation")) + { + return HookResult.Continue; + } + } + if (isMultiKill) { if (TryPlayKillStreak(attacker, multiKillCount)) @@ -98,11 +116,6 @@ public HookResult OnPlayerDeath(EventPlayerDeath @event) if (playedHeadshot) return HookResult.Continue; } - if (@event.Weapon.Contains("knife", StringComparison.OrdinalIgnoreCase) && TryPlay(attacker, "humiliation")) - { - return HookResult.Continue; - } - if (@event.Weapon.Contains("hegrenade", StringComparison.OrdinalIgnoreCase) && TryPlay(attacker, "perfect")) { return HookResult.Continue; diff --git a/src/EventHandlers/RoundStartHandler.cs b/src/EventHandlers/RoundStartHandler.cs index ef6aa57..eb4017c 100644 --- a/src/EventHandlers/RoundStartHandler.cs +++ b/src/EventHandlers/RoundStartHandler.cs @@ -1,11 +1,48 @@ using SwiftlyS2.Shared.GameEvents; using SwiftlyS2.Shared.GameEventDefinitions; using SwiftlyS2.Shared.Misc; +using System.Linq; namespace QuakeSounds; public partial class QuakeSounds { + private void TryPlayRoundSoundToAll(string soundKey) + { + var anyPlayer = Core.PlayerManager.GetAllPlayers() + .FirstOrDefault(p => p is { IsValid: true } && !p.IsFakeClient); + + if (anyPlayer == null) + { + return; + } + + var originalPlayToAll = _config.PlayToAll; + var originalCenter = _config.Messages.EnableCenterMessage; + var originalChat = _config.Messages.EnableChatMessage; + + try + { + _config.PlayToAll = true; + _config.Messages.EnableCenterMessage = false; + _config.Messages.EnableChatMessage = false; + + _audioService?.TryPlay( + anyPlayer, + soundKey, + _config, + id => _gameStateService.IsPlayerEnabled(id), + id => _gameStateService.GetPlayerVolume(id) + ); + } + finally + { + _config.PlayToAll = originalPlayToAll; + _config.Messages.EnableCenterMessage = originalCenter; + _config.Messages.EnableChatMessage = originalChat; + } + } + [GameEventHandler(HookMode.Post)] public HookResult OnRoundStart(EventRoundStart @event) { @@ -15,6 +52,14 @@ public HookResult OnRoundStart(EventRoundStart @event) } _gameStateService.ClearRoundState(); + TryPlayRoundSoundToAll("round_start"); + return HookResult.Continue; + } + + [GameEventHandler(HookMode.Post)] + public HookResult OnRoundFreezeEnd(EventRoundFreezeEnd @event) + { + TryPlayRoundSoundToAll("round_freeze_end"); return HookResult.Continue; } } diff --git a/src/QuakeSounds.cs b/src/QuakeSounds.cs index f18609d..d462ae5 100644 --- a/src/QuakeSounds.cs +++ b/src/QuakeSounds.cs @@ -11,7 +11,7 @@ namespace QuakeSounds; -[PluginMetadata(Id = "QuakeSounds", Version = "1.0.1", Name = "QuakeSounds", Author = "aga", Description = "No description.")] +[PluginMetadata(Id = "QuakeSounds", Version = "1.0.2", Name = "QuakeSounds", Author = "aga", Description = "No description.")] public partial class QuakeSounds : BasePlugin { private AudioService? _audioService; private readonly GameStateService _gameStateService;