Skip to content
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
216f9fd
Created / modified needed files
May 12, 2025
fccaa56
Added custom action event
May 12, 2025
ed1c788
Added events on System, added properties to Component, added special …
May 13, 2025
0fb29d8
Switched to a sharedsystem and a server one for ic chat use
May 14, 2025
4f37c8a
Tests on server side
May 15, 2025
dc0ddec
Exclamation code
May 15, 2025
27ae216
added localization file
May 15, 2025
46f7896
Added ALL files for now with copyright, will need to remove some for …
May 15, 2025
88d3262
trying audio stuff...
May 15, 2025
793977a
Basic sound + IC chat working
May 16, 2025
b068fb7
Updated SharedToolSystem to have ScrewQuality and updates references …
May 16, 2025
258953f
Began interaction with tools
May 16, 2025
f1e3b75
Screwed this up (literally)
Lanedon May 16, 2025
c270034
Made the mask skip the transformation of the chat message (and broke …
Lanedon May 16, 2025
34445e5
Wirecutting WIP
Lanedon May 16, 2025
2a4f3cc
Added ALL of the sounds, which is NOT what should be in the final PR.…
Lanedon May 16, 2025
00a1e01
Avoid the wearer being exclamated at
Lanedon May 17, 2025
65c1024
Added demo video for the forums
Lanedon May 17, 2025
2745699
Changed some audio
Lanedon May 17, 2025
4d0fccf
Finished cutting
Lanedon May 17, 2025
1e915dd
Added popup when screwing it
Lanedon May 18, 2025
a93b017
Emag interaction and OnExamine stuff
Lanedon May 18, 2025
63047ec
Remove actions if the mask is pulled down
Lanedon May 18, 2025
4e9e8eb
Trying to merge, fix conflicts and removed demo video
Lanedon May 19, 2025
dc51354
Remove useless ftl file
Lanedon May 19, 2025
4a5aff0
Added ERT / HOS hailer. ERT have special lines. HOS has an exemption …
Lanedon May 19, 2025
67917e9
fix of ftl
Lanedon May 19, 2025
c4b56ba
fixed some uses of the new public stirng ScrewingQuality
Lanedon May 20, 2025
4af5434
credits stuff
Lanedon May 20, 2025
dfb95ef
Changed where action is stored and added a WIP icon for the hail
Lanedon May 20, 2025
4aeeef5
bugfix
Lanedon May 20, 2025
dd23f59
quickfix YAML
Lanedon May 20, 2025
8184921
Removed the "trans" out of nanotrasen (word typo, don't freak)
Lanedon May 21, 2025
a639999
Add some comments to hails.ftl for clarity
Lanedon May 21, 2025
4b5f4cf
rearranged some audio and ftl files to be more in line with aggressio…
Lanedon May 21, 2025
fe0bef2
Remove some meh voicelines (will include in audio post to compare)
Lanedon May 21, 2025
4b7433c
Used localization support for enums as reviewed
Lanedon May 21, 2025
e13f721
Changed some speaker name for ERT and lowercased the normal one
Lanedon May 21, 2025
9791d01
Add some DoAfter for the cutting
Lanedon May 21, 2025
02929e2
Putting warnings when others do something to your mask [Not working]
Lanedon May 21, 2025
0ac10ae
Merge branch 'sec-hail-merge' of https://github.com/Lanedon/space-sta…
Lanedon May 21, 2025
fa0d021
fix
Lanedon May 22, 2025
e88aa52
finished doAfter, abandonned interacting with someone else mask becau…
Lanedon May 22, 2025
b4f9133
Added verb interaction
Lanedon May 22, 2025
5217665
Goofin around with access
Lanedon May 22, 2025
bd051db
Added access check to the verb action
Lanedon May 22, 2025
b655d75
Forgor the SWAT mask :(
Lanedon May 22, 2025
4810ab7
Added real cooldown
Lanedon May 22, 2025
8a888a2
Added some verb cooldown and some sound variations for the beeps
Lanedon May 22, 2025
d0b8c1b
FUCK
Lanedon May 22, 2025
31259f2
Did a oopsie in yaml + error sound is LOUD
Lanedon May 22, 2025
c620b7b
More oopsies
Lanedon May 22, 2025
9085e11
Added a really bad looksing wire cutted swat mask visual
Lanedon May 22, 2025
d6fb110
Moving playing the voiceline to Shared for prediction ?
Lanedon May 23, 2025
444325a
Cleanup
Lanedon May 23, 2025
90228e6
typo
Lanedon May 23, 2025
b61c35a
Bugfix + Cleaning
Lanedon May 23, 2025
89d171d
CLEAN CLEAN CLEAN
Lanedon May 23, 2025
b6e4023
added copyright
Lanedon May 23, 2025
80818c0
Attributions fix + forgor a sound
Lanedon May 23, 2025
21ff0f4
I HATE VISUAL STUDIO I HATE VISUAL STUDIO I HATE VISUAL STUDIO
Lanedon May 23, 2025
75e3fc4
deleting ALL audio NYAHAHAHA
Lanedon May 23, 2025
032b010
Adding all back without first letter capitalization
Lanedon May 23, 2025
179132c
Pleasing the YAML gods
Lanedon May 23, 2025
63baa10
deleting because formatting
Lanedon May 23, 2025
5337275
adding again...
Lanedon May 23, 2025
9afdb37
fix: file-scoped namespaces
Lanedon May 25, 2025
0972939
Making User nullable
Lanedon May 25, 2025
50d6582
Localized chat name
Lanedon May 25, 2025
822c297
Added attributes + moved enums out of component
Lanedon May 25, 2025
7b32837
fixing previous commit's errors
Lanedon May 25, 2025
f8de898
Redoing replacement sounds, WIP
Lanedon May 25, 2025
2766b99
solution for sound replacement for HOS
Lanedon May 26, 2025
2f9f746
Datafields + documentation
Lanedon May 26, 2025
56dec09
primary constructor
Lanedon May 26, 2025
ac208b5
Undoing the primary constructor
Lanedon May 26, 2025
84d481a
changed enum to ToolQualityPrototype
Lanedon May 29, 2025
599c0eb
fix use delay
Lanedon May 29, 2025
5bb64e3
Merge branch 'space-wizards:master' into sec-hail-merge
Lanedon May 31, 2025
a46acc8
Trying stuff for linter, dont mind me
Lanedon Jun 3, 2025
5947cfb
Hmmm
Lanedon Jun 3, 2025
b33c0ef
Merge branch 'master' into sec-hail-merge
Lanedon Jun 11, 2025
996b27d
Fix YAML Linter
Lanedon Jun 12, 2025
e39fb3c
Merge branch 'space-wizards:master' into sec-hail-merge
Lanedon Jun 26, 2025
9effc4d
Added platform for handle in attributions
Lanedon Jun 26, 2025
af3ced2
Merge branch 'space-wizards:master' into sec-hail-merge
Lanedon Aug 26, 2025
1013b28
Refactor part 1
Lanedon Aug 29, 2025
e803ba7
YAML / Component changes
Lanedon Sep 17, 2025
5337606
BUI
Lanedon Sep 18, 2025
12c4ec1
BUI is love, BUI is life
Lanedon Sep 23, 2025
e535878
Feeding BUI + ItemGrantAction
Lanedon Sep 24, 2025
b4cdf5e
cancel the UI is mask is pulled down
Lanedon Sep 24, 2025
93a6274
BUI stuff
Lanedon Sep 25, 2025
c8323f8
Interactions with tools
Lanedon Sep 25, 2025
ee86a3f
Spirte stuff
Lanedon Sep 26, 2025
6a0bccb
Emag interaction (not complete)
Lanedon Oct 13, 2025
20b66df
New sounds
Lanedon Oct 13, 2025
889d5d9
Remove metadata
Lanedon Oct 13, 2025
bd94799
Reorganisation
Lanedon Oct 15, 2025
be553d7
Updated attributions
Lanedon Oct 15, 2025
81f457b
Emag Interaction
Lanedon Oct 15, 2025
b4a5a2b
Emag, icons, descriptions
Lanedon Oct 16, 2025
30953f0
ERT + Clean up code/comments
Lanedon Oct 16, 2025
fc96f87
Remove error.ogg sound, was too long and too disruptive
Lanedon Oct 16, 2025
9a13363
Add dirty to cooldown timer
Lanedon Oct 16, 2025
989a05a
Applied to SWAT mask
Lanedon Oct 16, 2025
c5259a0
Merge branch 'master' into sec-hail-merge
Lanedon Oct 16, 2025
de1a3da
Codebase change broke my BUI :(
Lanedon Oct 16, 2025
aa2fcfe
Merge branch 'space-wizards:master' into sec-hail-merge
Lanedon Oct 16, 2025
0aa65cb
Changed audio
Lanedon Oct 17, 2025
eec3506
Trying predicted in shared
Lanedon Oct 17, 2025
2175153
Prediction + networking AreWiresCut
Lanedon Oct 19, 2025
7d89949
Merge branch 'master' into sec-hail-merge
Lanedon Oct 20, 2025
82c0ddd
chat system in shared + prediction for popup
Lanedon Oct 20, 2025
195dd35
Made the text go bold again
Lanedon Oct 20, 2025
5edf18a
First step towards a working radial menu
Lanedon Oct 20, 2025
34fa37b
Minor changes to locale and file replacement
Lanedon Oct 21, 2025
fad059d
Finished radio menu
Lanedon Oct 21, 2025
eaa96a3
Added voiceline sound handling to server since Robust Random is used
Lanedon Oct 21, 2025
814cc77
Added SpeechComponent to hailer and made the hailer says the IC chat …
Lanedon Oct 21, 2025
66477e8
some event handling
Lanedon Oct 21, 2025
f0d51c1
Testing removing chat code
Lanedon Oct 22, 2025
be7fb69
Fixed loc string
Lanedon Oct 22, 2025
e538c9b
Fixed chat system interaction, no more modifying chat system
Lanedon Oct 22, 2025
4c4b028
SpeechComp for ALL !
Lanedon Oct 22, 2025
86a21d0
Audio changes for ERT, file renaming
Lanedon Oct 22, 2025
a4293f0
Typo
Lanedon Oct 22, 2025
595323e
Halt audio change
Lanedon Oct 22, 2025
e292901
Tidying up code
Lanedon Oct 23, 2025
2a58cc2
Attributions cleanup
Lanedon Oct 23, 2025
179212e
whitespace
Lanedon Oct 23, 2025
2bc98cc
revert fuckup
Lanedon Oct 23, 2025
0d32c7a
Make deathsquad gasmask not inherit ERT gas mask
Lanedon Oct 23, 2025
12b374c
YAML tidying
Lanedon Oct 23, 2025
91e39f7
Merge branch 'sec-hail-merge' of https://github.com/Lanedon/space-sta…
Lanedon Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions Content.Server/Chat/Systems/ChatSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ private void OnGameChange(GameRunLevelChangedEvent ev)
/// <param name="shell"></param>
/// <param name="player">The player doing the speaking</param>
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
/// <param name="ignoreActionBlocker">If set to true, action blocker will not be considered for whether an entity can send this message.</param>
/// <param name="skipTransform">Skips the transformation of the message sent, by accents for example.</param>
public void TrySendInGameICMessage(
EntityUid source,
string message,
Expand All @@ -145,9 +147,11 @@ public void TrySendInGameICMessage(
IConsoleShell? shell = null,
ICommonSession? player = null, string? nameOverride = null,
bool checkRadioPrefix = true,
bool ignoreActionBlocker = false)
bool ignoreActionBlocker = false,
bool skipTransform = false)
{
TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride, checkRadioPrefix, ignoreActionBlocker);
TrySendInGameICMessage(source, message, desiredType, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, hideLog, shell, player, nameOverride,
checkRadioPrefix, ignoreActionBlocker, skipTransform);
}

/// <summary>
Expand All @@ -161,6 +165,7 @@ public void TrySendInGameICMessage(
/// <param name="player">The player doing the speaking</param>
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
/// <param name="ignoreActionBlocker">If set to true, action blocker will not be considered for whether an entity can send this message.</param>
/// <param name="skipTransform">Skips the transformation of the message sent, by accents for example.</param>
public void TrySendInGameICMessage(
EntityUid source,
string message,
Expand All @@ -171,7 +176,8 @@ public void TrySendInGameICMessage(
ICommonSession? player = null,
string? nameOverride = null,
bool checkRadioPrefix = true,
bool ignoreActionBlocker = false
bool ignoreActionBlocker = false,
bool skipTransform = false
)
{
if (HasComp<GhostComponent>(source))
Expand Down Expand Up @@ -247,7 +253,7 @@ public void TrySendInGameICMessage(
switch (desiredType)
{
case InGameICChatType.Speak:
SendEntitySpeak(source, message, range, nameOverride, hideLog, ignoreActionBlocker);
SendEntitySpeak(source, message, range, nameOverride, hideLog, ignoreActionBlocker, skipTransform);
break;
case InGameICChatType.Whisper:
SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker);
Expand Down Expand Up @@ -414,13 +420,14 @@ private void SendEntitySpeak(
ChatTransmitRange range,
string? nameOverride,
bool hideLog = false,
bool ignoreActionBlocker = false
bool ignoreActionBlocker = false,
bool skipTransform = false
)
{
if (!_actionBlocker.CanSpeak(source) && !ignoreActionBlocker)
return;

var message = TransformSpeech(source, originalMessage);
var message = skipTransform ? originalMessage : TransformSpeech(source, originalMessage);

if (message.Length == 0)
return;
Expand Down
108 changes: 108 additions & 0 deletions Content.Server/Clothing/Systems/SecurityHailerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using Content.Shared.Clothing.ActionEvent;
using Content.Shared.Clothing.Components;
using Content.Shared.Clothing.EntitySystems;
using Content.Server.Chat.Systems;
using Robust.Server.Audio;
using Robust.Shared.Audio;
using Content.Shared.Emag.Components;

namespace Content.Server.Clothing.Systems
{
public sealed class SecurityHailerSystem : SharedSecurityHailerSystem
{
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly AudioSystem _audio = default!;
private readonly (string, string) _replaceLineHos = ("hail-high-8", "hail-high-HOS"); //the line to replace if a HOS gas mask hails

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SecurityHailerComponent, ActionSecHailerActionEvent>(OnHailOrder);
}

private void OnHailOrder(Entity<SecurityHailerComponent> ent, ref ActionSecHailerActionEvent ev)
{
//If the event is already handled
if (ev.Handled)
return;

//Put the exclamations mark around people at the distance specified in the comp side
//Just like a whistle
bool exclamationHandled = base.ExclamateHumanoidsAround(ent);

//Play the damn sound
int index = PlaySoundEffect(ent); // index gotten from AudioSystem.ResolveSound() of the sound chosen in the soundcollection (Basically, which random line is playing ?)
bool chatHandled = SayChatMessage(ent, ev, index);

//If both exclamation and chat were done, we handled it yay !
ev.Handled = exclamationHandled && chatHandled;
}

private bool SayChatMessage(Entity<SecurityHailerComponent> ent, ActionSecHailerActionEvent ev, int index)
{
string ftlLine = GetTheCorrectLine(ent, index);
if (IsVoiceReplaced(ent, index)) //This is some bandaid code, replace it omg
ftlLine = _replaceLineHos.Item2;

//Make a chat line with the sec hailer as speaker, in bold and UPPERCASE for added impact
_chat.TrySendInGameICMessage(ev.Performer, Loc.GetString(ftlLine).ToUpper(), InGameICChatType.Speak, hideChat: false, hideLog: true, nameOverride: ent.Comp.ChatName,
checkRadioPrefix: false, ignoreActionBlocker: true, skipTransform: true);
return true;
}

private int PlaySoundEffect(Entity<SecurityHailerComponent> ent)
{
var (uid, comp) = ent;

SoundSpecifier currentSpecifier;
if (comp.SpecialCircumtance == SecurityHailerComponent.SpecialUseCase.ERT)
currentSpecifier = comp.ERTAggressionSounds;
else if (HasComp<EmaggedComponent>(ent))
currentSpecifier = ent.Comp.EmagAggressionSounds;
else
{
currentSpecifier = comp.AggresionLevel switch
{
SecurityHailerComponent.AggresionState.Medium => comp.MediumAggressionSounds,
SecurityHailerComponent.AggresionState.High => comp.HighAggressionSounds,
_ => comp.LowAggressionSounds,
};
}
var resolver = _audio.ResolveSound(currentSpecifier);
if (resolver is not ResolvedCollectionSpecifier collectionResolver)
return -1;

if (IsVoiceReplaced(ent, collectionResolver.Index))
{
collectionResolver = (ResolvedCollectionSpecifier)_audio.ResolveSound(comp.HOSReplaceSounds); //add a check ? What to do if multiple in future ?
}

_audio.PlayPvs(resolver, ent.Owner, audioParams: new AudioParams().WithVolume(-3f));

return collectionResolver.Index;
}

private bool IsVoiceReplaced(Entity<SecurityHailerComponent> ent, int index)
{
if (ent.Comp.SpecialCircumtance == SecurityHailerComponent.SpecialUseCase.HOS && GetTheCorrectLine(ent, index) == _replaceLineHos.Item1)
{
return true;
}

return false;
}

private string GetTheCorrectLine(Entity<SecurityHailerComponent> ent, int index)
{
string finalLine = String.Empty;
if (HasComp<EmaggedComponent>(ent))
finalLine = $"hail-emag-{index}";
else if (ent.Comp.SpecialCircumtance == SecurityHailerComponent.SpecialUseCase.ERT)
finalLine = $"hail-ERT-{index}";
else
finalLine = $"hail-{ent.Comp.AggresionLevel.ToString().ToLower()}-{index}";

return finalLine;
}
}
}
2 changes: 1 addition & 1 deletion Content.Server/Fax/FaxSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ private void OnInteractUsing(EntityUid uid, FaxMachineComponent component, Inter
{
if (args.Handled ||
!TryComp<ActorComponent>(args.User, out var actor) ||
!_toolSystem.HasQuality(args.Used, "Screwing")) // Screwing because Pulsing already used by device linking
!_toolSystem.HasQuality(args.Used, ToolSystem.ScrewQuality)) // Screwing because Pulsing already used by device linking
return;

_quickDialog.OpenDialog(actor.PlayerSession,
Expand Down
113 changes: 113 additions & 0 deletions Content.Shared/Clothing/Components/SecurityHailerComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;


namespace Content.Shared.Clothing.Components
{
/// <summary>
/// Handle the hails (audible orders to stop) coming from a security gas mask / swat mask
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class SecurityHailerComponent : Component
{
/// <summary>
///
/// </summary>
[DataField]
public SecMaskState CurrentState = SecMaskState.Functional;

/// <summary>
/// Range value
/// </summary>
[DataField]
public float Distance = 0;

/// <summary>
/// The name displayed as the speaker when hailing orders
/// </summary>
[DataField]
public string? ChatName = "Security Hailer";

/// <summary>
/// Delay when the hailer is screwed to change aggression level
/// </summary>
[DataField]
public float ScrewingDoAfterDelay = 1f;

public enum SpecialUseCase : byte
{
None = 0,
HOS = 1,
ERT = 2
}

/// <summary>
/// Special use cases where some voicelines shouldn't play or we want to play some other voicelines, ex: HOS or ERT
/// </summary>
[DataField]
public SpecialUseCase SpecialCircumtance = SpecialUseCase.None;

/// <summary>
/// What ftl line to replace in special circumstances
/// </summary>
public Dictionary<SpecialUseCase, (string[], string[])> ReplaceVoicelinesSpecial = new() //List of Tuples
{
{ SpecialUseCase.HOS, (["hail-high-8"], ["hail-high-HOS"]) }//"Take it to the HOS voice" line, make no sense if HOS
};

/// <summary>
/// How aggresive are the orders coming from the hailer ? Higher means more aggressive / shitsec
/// </summary>
public enum AggresionState : byte
{
Low = 0,
Medium = 1,
High = 2
}

[DataField, AutoNetworkedField]
public AggresionState AggresionLevel = AggresionState.Low;

public SoundSpecifier LowAggressionSounds = new SoundCollectionSpecifier("SecHailLow");
public SoundSpecifier MediumAggressionSounds = new SoundCollectionSpecifier("SecHailMedium");
public SoundSpecifier HighAggressionSounds = new SoundCollectionSpecifier("SecHailHigh");
public SoundSpecifier EmagAggressionSounds = new SoundCollectionSpecifier("SecHailEmag");
public SoundSpecifier ERTAggressionSounds = new SoundCollectionSpecifier("SecHailERT");
public SoundSpecifier HOSReplaceSounds = new SoundCollectionSpecifier("SecHailHOS");
public SoundSpecifier ScrewedSounds = new SoundCollectionSpecifier("Screwdriver"); //From the soundcollection of tools
public SoundSpecifier CutSounds = new SoundCollectionSpecifier("Wirecutter"); //From the soundcollection of tools

/// <summary>
/// The action that gets displayed when the gas mask is equipped.
/// </summary>
[DataField]
public EntProtoId Action = "ActionSecHailer";

/// <summary>
/// Reference to the action.
/// </summary>
[DataField]
public EntityUid? ActionEntity;

/// <summary>
/// Entity prototype to spawn when used, using the whistle one
/// </summary>
[DataField]
public EntProtoId ExclamationEffect = "WhistleExclamation";
}

[Serializable, NetSerializable]
public enum SecMaskVisuals : byte
{
State
}

[Serializable, NetSerializable]
public enum SecMaskState : byte
{
Functional,
WiresCut
}
}
Loading
Loading