Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component for clothes to suppress scream noise #32588

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Centronias
Copy link
Contributor

@Centronias Centronias commented Oct 2, 2024

About the PR

Made it so that Muzzles suppress all vocal emotes as well as the scream action, instead giving you a "You can't emote right now", eg. "You can't scream right now!".
This is implemented by adding the EmoteBlocker component which marks an equipable as blocking emotes as specified by the component's configuration, which can block any combination of specific emotes or emote categories. Right now, the component only has this effect when applied to equipment in the hands, head and/or mouth slot.

Why / Balance

Fixes #13776
The people want to be able to muzzle each other and have it be effective.

Technical details

Added components:

  • EmoteBlocker, which contains a set of EmoteCategorys and EmotePrototype ID strings which should be blocked.
    Added Systems:
  • GetEmoteBlockersEvent, which is raised by the ChatSystem's emote processing to determine if the attempted emote should be blocked.
    • In the case that the emote is blocked, the corresponding EmoteEvent is not raised and popup saying "You can't emote right now!" appears (localized and emote is replaced by the localized name of the emote).
  • EmoteBlockerSystem, which handles the calculation of emote blockers, as well as the special case handling of the scream action to make it work like the scream emote
  • New localization string for the "You can't emote" message with en-US localization.

Media

No media changes

Requirements

Screenshots:
(Lemme know if you want a gifs -- but I'll need a recommendation on not-garbage screen recording software for Windows)

Note that for testing, I set the power gloves to block snapping and only snapping.

Can't cry while muzzled
image

Can't action scream while muzzled
image

Can't snap while power gloved (again, only while testing)
image

Verification that the emotes still work without the clothes on Can cry without the muzzle on image

Can action scream without the muzzle on
image

Can snap without the gloves on
image

Can clap with the gloves on
image

Can @custom emote with the gloves on
image

Breaking changes

New public classes:

  • EmoteBlockerComponent
  • EmoteBlockerSystem
  • GetEmoteBlockersEvent

Modified en-US Localization of

  • chat-emote-name-crying
  • chat-emote-name-cathisses
  • chat-emote-name-monkeyscreeches
    to be in the imperative mood, which is consistent with the rest of the emote names.

Changelog
🆑

  • tweak: Muzzles now prevent wearers from screaming and suppress sounds on audio emotes.

GaggedComponent + AddGaggedClothingComponent and relevant systems to make them work.

Currently only stifles the scream _action_, not all emotes

because if a mime can silently emote, so can gagged you!
/// Applies <see cref="GaggedComponent"/> to user while they wear entity as clothing.
/// </summary>
[RegisterComponent]
public sealed partial class AddGaggedClothingComponent : Component
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should try using an inventory relay event instead (InventoryRelayedEvent and InventorySystem.Relay.cs are good places to find examples)! It'll allow you remove all this stuff and will make the entire thing a lot nicer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is good advice 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this approach, I'm able to hook into the emote lifecycle in more places.
Does it makes sense to prevent the entire emote, or leave it as the mime-like chat-without-sound I've got now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emotes can also be non-verbal (for example "points at" or "stares"), which would not be affected by the gag. So I think emotes should still be possible in general

Copy link
Contributor Author

@Centronias Centronias Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that makes sense to me.
I think I've got two separate questions:

  1. Should this component prevent both the sound and the chat message for emotes that are in specific categories? eg. using the UI radial wheel could be blocked, while @literally explodes. would not be.
  2. With the relay approach, it's a lot easier to make this more flexible such that the component indicates that it blocks Vocal emotes or Hand emotes specifically, or even particular emote prototypes by referencing their IDs. This'd enable something like "if you're wearing gloves you can't snap". Is adding this capability now desireable? To be clear, I would not modify any existing items besides the muzzle to block vocal emotes.

One note on this is that handling the special Scream Action would be just kind of under the vocal emote category -- basically if you couldn't @scream, it'll block the Scream Action.

@slarticodefast slarticodefast added the Status: Awaiting Changes This PR needs its reviews addressed or changes to be made in order to be merged. label Oct 2, 2024
and make it more general such that specific emotes or emotes of a given category can be blocked
Copy link
Contributor Author

@Centronias Centronias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My remarks are in this comment-review, plus upon posting this, the PR's main content should be updated with the new changes.

Comment on lines +94 to +104
// Check if this emote should be blocked. Forced emotes ignore this check.
if (!forceEmote)
{
var ev = new GetEmoteBlockersEvent();
RaiseLocalEvent(source, ref ev);
if (ev.ShouldBlock(emote))
{
_popupSystem.PopupEntity(Loc.GetString("emote-blocked", ("emote", Loc.GetString(emote.Name).ToLower())), source, source);
return;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check is moved here such that the emote sound and text and blocked by way of the EmoteEvent never being raised.


[ViewVariables(VVAccess.ReadWrite)]
[DataField("blocksEmotes")]
public HashSet<string> BlocksEmotes = new HashSet<string>();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried EmotePrototype for the type in the set, but it looks like the yaml deserialization doesn't like that, so it's just the string ID.

Comment on lines +49 to +54
// Handle ScreamActionEvent like it's a Scream emote.
if (ev.ShouldBlock(_screamPrototype))
{
_popupSystem.PopupEntity(Loc.GetString("emote-blocked", ("emote", Loc.GetString(_screamPrototype.Name).ToLower())), args.Performer, args.Performer);
args.Handled = true;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little sketchy, but I think it guards against problems in the future to use the scream emote as a stand-in for the decision here.

(Probably get rid of the Scream action at some point since it's just a weird double implementation on top of the emote now?)

Comment on lines +64 to +71
foreach (var category in component.BlocksCategories)
{
args.BlockedCategories.Add(category);
}
foreach (var emote in component.BlocksEmotes)
{
args.BlockedEmotes.Add(emote);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have next to no C# experience, so somebody please tell me if there's a better way to do this.

_screamPrototype = null;
foreach (var emote in _prototypeManager.EnumeratePrototypes<EmotePrototype>())
{
if (emote.ID == "Scream")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am loathe to hardcode the Scream emote ID in here, but I don't think there's a way around it.

Comment on lines +27 to +28
chat-emote-name-cathisses = Cat Hiss
chat-emote-name-monkeyscreeches = Monkey Screech
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as Crying above -- these seemed to have been in the third person declarative.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to EmoteEvents.cs

@@ -0,0 +1 @@
emote-blocked = You can't {$emote} right now!
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Localization for the message you get when you try to emote, but it's blocked.
Based on `You can't speak right now!" from Muted's implementation.

@@ -185,6 +185,9 @@
- type: Fiber
fiberMaterial: fibers-nanomachines
- type: FingerprintMask
- type: EmoteBlocker
blocksEmotes:
- Snap
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops forgot to get rid of this, but check it out, it works!

Comment on lines +324 to +326
- type: EmoteBlocker
blocksCategories:
- Vocal
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muzzles block all vocal emotes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting Changes This PR needs its reviews addressed or changes to be made in order to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Spessmen can scream while muffled
3 participants