diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 216c782ce1..89214cdc5e 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -750,7 +750,7 @@ public sealed partial class ChatSystem : SharedChatSystem /// /// Sends a chat message to the given players in range of the source entity. /// - private void SendInVoiceRange(ChatChannel channel, string message, string wrappedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null) + public void SendInVoiceRange(ChatChannel channel, string message, string wrappedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null) { foreach (var (session, data) in GetRecipients(source, VoiceRange)) { diff --git a/Content.Server/White/Halt/HaltComponent.cs b/Content.Server/White/Halt/HaltComponent.cs new file mode 100644 index 0000000000..11f71259fd --- /dev/null +++ b/Content.Server/White/Halt/HaltComponent.cs @@ -0,0 +1,37 @@ +using Robust.Shared.Audio; + +namespace Content.Server.White.Halt; + +[RegisterComponent] +public sealed partial class HaltComponent : Component +{ + [DataField("color"), ViewVariables(VVAccess.ReadWrite)] + public string ChatColor { get; private set; } = Color.Red.ToHex(); + + [DataField("locale"), ViewVariables(VVAccess.ReadWrite)] + public string ChatLoc { get; private set; } = "chat-manager-entity-say-hailer-wrap-message"; + + [DataField("actionEntity")] public EntityUid? ActionEntity; + + public readonly Dictionary PhraseToSoundMap = new() + { + ["halt-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/halt.ogg"), + ["bobby-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/bobby.ogg"), + ["compliance-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/compliance.ogg"), + ["justice-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/justice.ogg"), + ["running-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/running.ogg"), + ["dontmove-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/dontmove.ogg"), + ["floor-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/floor.ogg"), + ["robocop-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/robocop.ogg"), + ["god-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/god.ogg"), + ["freeze-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/freeze.ogg"), + ["imperial-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/imperial.ogg"), + ["bash-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/bash.ogg"), + ["harry-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/harry.ogg"), + ["asshole-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/asshole.ogg"), + ["stfu-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/stfu.ogg"), + ["shutup-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/shutup.ogg"), + ["super-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/super.ogg"), + ["dredd-phrase"] = new SoundPathSpecifier("/Audio/Voice/Complionator/dredd.ogg") + }; +} diff --git a/Content.Server/White/Halt/HaltSystem.cs b/Content.Server/White/Halt/HaltSystem.cs new file mode 100644 index 0000000000..1aae23c1ef --- /dev/null +++ b/Content.Server/White/Halt/HaltSystem.cs @@ -0,0 +1,62 @@ +using System.Linq; +using Content.Shared.Actions; +using Content.Server.Chat.Systems; +using Robust.Shared.Utility; +using Content.Shared.Chat; +using Content.Shared.White.Other; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server.White.Halt +{ + public sealed class HaltSystem : EntitySystem + { + [Dependency] private readonly ChatSystem _chat = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnGetEquipped); + SubscribeLocalEvent(Act); + } + + private void OnGetEquipped(EntityUid uid, HaltComponent component, GetItemActionsEvent args) + { + if (args.InHands) + return; + + args.AddAction(ref component.ActionEntity, "Halt"); + } + + private void Act(EntityUid uid, HaltComponent component, HaltAction args) + { + if (args.Handled) + return; + + if (!component.PhraseToSoundMap.Any()) + return; + + var randomIndex = _random.Next(component.PhraseToSoundMap.Count); + var selectedPhrase = component.PhraseToSoundMap.Keys.ElementAt(randomIndex); + var selectedSound = component.PhraseToSoundMap[selectedPhrase]; + + _audio.PlayPvs(selectedSound, uid); + + var hMessage = Loc.GetString(selectedPhrase); + var wrappedMessage = Loc.GetString( + component.ChatLoc, + ("entityName", args.Performer), + ("hMessage", FormattedMessage.EscapeText(hMessage)), + ("color", component.ChatColor) + ); + + _chat.SendInVoiceRange(ChatChannel.Local, hMessage, wrappedMessage, args.Performer, ChatTransmitRange.Normal); + + args.Handled = true; + } + } +} diff --git a/Content.Server/White/Other/CritSystem/CritSystem.cs b/Content.Server/White/Other/CritSystem/CritSystem.cs index e14d7e5d95..26ef0cbf27 100644 --- a/Content.Server/White/Other/CritSystem/CritSystem.cs +++ b/Content.Server/White/Other/CritSystem/CritSystem.cs @@ -24,8 +24,9 @@ public sealed class CritSystem : EntitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(HandleHit); + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(HandleHit); } private void OnExamine(EntityUid uid, CritComponent component, ExaminedEvent args) @@ -33,7 +34,7 @@ public sealed class CritSystem : EntitySystem if (component.IsBloodDagger) { args.PushMarkup( - "[color=red]Критическая жажда: Кинжал Жажды обладает смертоносной точностью. Его владелец имеет 20% шанс нанести критический урон, поражая врага в его самые уязвимые места.\n" + + "[color=red]Критическая жажда: Кинжал Жажды обладает смертоносной точностью. Его владелец имеет 25% шанс нанести критический урон, поражая врага в его самые уязвимые места.\n" + "Кровавый абсорб: При каждом успешном критическом ударе, кинжал извлекает кровь из цели, восстанавливая здоровье владельцу пропорционально количеству высосанной крови.[/color]" ); } diff --git a/Content.Shared/Mobs/Components/HaltAction.cs b/Content.Shared/Mobs/Components/HaltAction.cs new file mode 100644 index 0000000000..6c0c19e9be --- /dev/null +++ b/Content.Shared/Mobs/Components/HaltAction.cs @@ -0,0 +1,7 @@ +using Content.Shared.Actions; + +namespace Content.Shared.White.Other; + +public sealed partial class HaltAction : InstantActionEvent +{ +} diff --git a/Resources/Audio/Voice/Complionator/asshole.ogg b/Resources/Audio/Voice/Complionator/asshole.ogg new file mode 100644 index 0000000000..a6a326abe4 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/asshole.ogg differ diff --git a/Resources/Audio/Voice/Complionator/bash.ogg b/Resources/Audio/Voice/Complionator/bash.ogg new file mode 100644 index 0000000000..c14feb5b5f Binary files /dev/null and b/Resources/Audio/Voice/Complionator/bash.ogg differ diff --git a/Resources/Audio/Voice/Complionator/bobby.ogg b/Resources/Audio/Voice/Complionator/bobby.ogg new file mode 100644 index 0000000000..b4a6a890f2 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/bobby.ogg differ diff --git a/Resources/Audio/Voice/Complionator/compliance.ogg b/Resources/Audio/Voice/Complionator/compliance.ogg new file mode 100644 index 0000000000..231f70aa36 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/compliance.ogg differ diff --git a/Resources/Audio/Voice/Complionator/dontmove.ogg b/Resources/Audio/Voice/Complionator/dontmove.ogg new file mode 100644 index 0000000000..cb3ee03f7b Binary files /dev/null and b/Resources/Audio/Voice/Complionator/dontmove.ogg differ diff --git a/Resources/Audio/Voice/Complionator/dredd.ogg b/Resources/Audio/Voice/Complionator/dredd.ogg new file mode 100644 index 0000000000..8a3010489e Binary files /dev/null and b/Resources/Audio/Voice/Complionator/dredd.ogg differ diff --git a/Resources/Audio/Voice/Complionator/floor.ogg b/Resources/Audio/Voice/Complionator/floor.ogg new file mode 100644 index 0000000000..0e29c78143 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/floor.ogg differ diff --git a/Resources/Audio/Voice/Complionator/freeze.ogg b/Resources/Audio/Voice/Complionator/freeze.ogg new file mode 100644 index 0000000000..1be9ba7361 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/freeze.ogg differ diff --git a/Resources/Audio/Voice/Complionator/god.ogg b/Resources/Audio/Voice/Complionator/god.ogg new file mode 100644 index 0000000000..a109e2a351 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/god.ogg differ diff --git a/Resources/Audio/Voice/Complionator/halt.ogg b/Resources/Audio/Voice/Complionator/halt.ogg new file mode 100644 index 0000000000..457091f4ce Binary files /dev/null and b/Resources/Audio/Voice/Complionator/halt.ogg differ diff --git a/Resources/Audio/Voice/Complionator/harry.ogg b/Resources/Audio/Voice/Complionator/harry.ogg new file mode 100644 index 0000000000..2ff2acc856 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/harry.ogg differ diff --git a/Resources/Audio/Voice/Complionator/imperial.ogg b/Resources/Audio/Voice/Complionator/imperial.ogg new file mode 100644 index 0000000000..df40102de1 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/imperial.ogg differ diff --git a/Resources/Audio/Voice/Complionator/justice.ogg b/Resources/Audio/Voice/Complionator/justice.ogg new file mode 100644 index 0000000000..14409495ca Binary files /dev/null and b/Resources/Audio/Voice/Complionator/justice.ogg differ diff --git a/Resources/Audio/Voice/Complionator/robocop.ogg b/Resources/Audio/Voice/Complionator/robocop.ogg new file mode 100644 index 0000000000..f7a19c7850 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/robocop.ogg differ diff --git a/Resources/Audio/Voice/Complionator/running.ogg b/Resources/Audio/Voice/Complionator/running.ogg new file mode 100644 index 0000000000..82d68cdf2f Binary files /dev/null and b/Resources/Audio/Voice/Complionator/running.ogg differ diff --git a/Resources/Audio/Voice/Complionator/shutup.ogg b/Resources/Audio/Voice/Complionator/shutup.ogg new file mode 100644 index 0000000000..8ca70a0989 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/shutup.ogg differ diff --git a/Resources/Audio/Voice/Complionator/stfu.ogg b/Resources/Audio/Voice/Complionator/stfu.ogg new file mode 100644 index 0000000000..44c878ac11 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/stfu.ogg differ diff --git a/Resources/Audio/Voice/Complionator/super.ogg b/Resources/Audio/Voice/Complionator/super.ogg new file mode 100644 index 0000000000..2ec5183ae6 Binary files /dev/null and b/Resources/Audio/Voice/Complionator/super.ogg differ diff --git a/Resources/Locale/ru-RU/white/hailer.ftl b/Resources/Locale/ru-RU/white/hailer.ftl new file mode 100644 index 0000000000..ce2e0067ab --- /dev/null +++ b/Resources/Locale/ru-RU/white/hailer.ftl @@ -0,0 +1,20 @@ +chat-manager-entity-say-hailer-wrap-message = { $entityName } командует, "[font size=13][color={ $color }]{ $hMessage }[/color][/size]" + +halt-phrase = СТОЯТЬ! СТОЯТЬ! СТОЯТЬ! +bobby-phrase = Стоять! Во имя Закона! +compliance-phrase = Сдаться в ваших интересах. +justice-phrase = Приготовьтесь к справедливости! +running-phrase = Бег только увеличит ваш срок. +dontmove-phrase = Не двигаться, уёбок! +floor-phrase = На пол, сука! +robocop-phrase = Мёртвый или живой ты пойдешь со мной. +god-phrase = Бог создал сегодня для жуликов, которых мы не могли поймать вчера. +freeze-phrase = Замри, подонок! +imperial-phrase = Стоять, преступная мразь! +bash-phrase = Остановись или я тебя ударю. +harry-phrase = Сделай мой день. +asshole-phrase = Хватит нарушать закон, гадина. +stfu-phrase = Вы имеете право завалить ебало. +shutup-phrase = Заткнись нахуй! +super-phrase = Сейчас ты познаешь гнев золотой сферы. +dredd-phrase = Я ЗАКОН! diff --git a/Resources/Prototypes/Actions/types.yml b/Resources/Prototypes/Actions/types.yml index f301589879..427acd1863 100644 --- a/Resources/Prototypes/Actions/types.yml +++ b/Resources/Prototypes/Actions/types.yml @@ -315,3 +315,16 @@ event: !type:ToggleEyesActionEvent useDelay: 1 # so u cant give yourself and observers eyestrain by rapidly spamming the action + +- type: entity + id: Halt + name: Halt! + description: Halt! + noSpawn: true + components: + - type: InstantAction + useDelay: 5 + icon: + sprite: Objects/Weapons/Melee/stunbaton.rsi + state: stunbaton_off + event: !type:HaltAction diff --git a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml index 59dfb526c5..bf3e9fcd20 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml @@ -36,6 +36,7 @@ Slash: 0.95 Piercing: 0.95 Heat: 0.95 + - type: Halt - type: entity parent: ClothingMaskGas