Stealthier whispers (#17898)
* Stealth whisper take 2 * weh * fix whisper maxrange * make variables more distinct
This commit is contained in:
@@ -13,6 +13,8 @@ using Content.Shared.CCVar;
|
|||||||
using Content.Shared.Chat;
|
using Content.Shared.Chat;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
using Content.Shared.Radio;
|
using Content.Shared.Radio;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -49,9 +51,11 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
|
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||||
|
|
||||||
public const int VoiceRange = 10; // how far voice goes in world units
|
public const int VoiceRange = 10; // how far voice goes in world units
|
||||||
public const int WhisperRange = 2; // how far whisper goes in world units
|
public const int WhisperClearRange = 2; // how far whisper goes while still being understandable, in world units
|
||||||
|
public const int WhisperMuffledRange = 5; // how far whisper goes at all, in world units
|
||||||
public const string DefaultAnnouncementSound = "/Audio/Announcements/announce.ogg";
|
public const string DefaultAnnouncementSound = "/Audio/Announcements/announce.ogg";
|
||||||
|
|
||||||
private bool _loocEnabled = true;
|
private bool _loocEnabled = true;
|
||||||
@@ -373,7 +377,9 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
|
|
||||||
var obfuscatedMessage = ObfuscateMessageReadability(message, 0.2f);
|
var obfuscatedMessage = ObfuscateMessageReadability(message, 0.2f);
|
||||||
|
|
||||||
// get the entity's apparent name (if no override provided).
|
// get the entity's name by visual identity (if no override provided).
|
||||||
|
string nameIdentity = FormattedMessage.EscapeText(nameOverride ?? Identity.Name(source, EntityManager));
|
||||||
|
// get the entity's name by voice (if no override provided).
|
||||||
string name;
|
string name;
|
||||||
if (nameOverride != null)
|
if (nameOverride != null)
|
||||||
{
|
{
|
||||||
@@ -391,23 +397,33 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
|
var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
|
||||||
("entityName", name), ("message", FormattedMessage.EscapeText(message)));
|
("entityName", name), ("message", FormattedMessage.EscapeText(message)));
|
||||||
|
|
||||||
|
|
||||||
var wrappedobfuscatedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
|
var wrappedobfuscatedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
|
||||||
("entityName", name), ("message", FormattedMessage.EscapeText(obfuscatedMessage)));
|
("entityName", nameIdentity), ("message", FormattedMessage.EscapeText(obfuscatedMessage)));
|
||||||
|
|
||||||
|
var wrappedUnknownMessage = Loc.GetString("chat-manager-entity-whisper-unknown-wrap-message",
|
||||||
|
("message", FormattedMessage.EscapeText(obfuscatedMessage)));
|
||||||
|
|
||||||
|
|
||||||
foreach (var (session, data) in GetRecipients(source, VoiceRange))
|
foreach (var (session, data) in GetRecipients(source, WhisperMuffledRange))
|
||||||
{
|
{
|
||||||
|
EntityUid listener;
|
||||||
|
|
||||||
if (session.AttachedEntity is not { Valid: true } playerEntity)
|
if (session.AttachedEntity is not { Valid: true } playerEntity)
|
||||||
continue;
|
continue;
|
||||||
|
listener = session.AttachedEntity.Value;
|
||||||
|
|
||||||
if (MessageRangeCheck(session, data, range) != MessageRangeCheckResult.Full)
|
if (MessageRangeCheck(session, data, range) != MessageRangeCheckResult.Full)
|
||||||
continue; // Won't get logged to chat, and ghosts are too far away to see the pop-up, so we just won't send it to them.
|
continue; // Won't get logged to chat, and ghosts are too far away to see the pop-up, so we just won't send it to them.
|
||||||
|
|
||||||
if (data.Range <= WhisperRange)
|
if (data.Range <= WhisperClearRange)
|
||||||
_chatManager.ChatMessageToOne(ChatChannel.Whisper, message, wrappedMessage, source, false, session.ConnectedClient);
|
_chatManager.ChatMessageToOne(ChatChannel.Whisper, message, wrappedMessage, source, false, session.ConnectedClient);
|
||||||
else
|
//If listener is too far, they only hear fragments of the message
|
||||||
|
//Collisiongroup.Opaque is not ideal for this use. Preferably, there should be a check specifically with "Can Ent1 see Ent2" in mind
|
||||||
|
else if (_interactionSystem.InRangeUnobstructed(source, listener, WhisperMuffledRange, Shared.Physics.CollisionGroup.Opaque)) //Shared.Physics.CollisionGroup.Opaque
|
||||||
_chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedobfuscatedMessage, source, false, session.ConnectedClient);
|
_chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedobfuscatedMessage, source, false, session.ConnectedClient);
|
||||||
|
//If listener is too far and has no line of sight, they can't identify the whisperer's identity
|
||||||
|
else
|
||||||
|
_chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedUnknownMessage, source, false, session.ConnectedClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
_replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, source, MessageRangeHideChatForReplay(range)));
|
_replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, source, MessageRangeHideChatForReplay(range)));
|
||||||
@@ -647,7 +663,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns list of players and ranges for all players withing some range. Also returns observers with a range of -1.
|
/// Returns list of players and ranges for all players withing some range. Also returns observers with a range of -1.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<ICommonSession, ICChatRecipientData> GetRecipients(EntityUid source, float voiceRange)
|
private Dictionary<ICommonSession, ICChatRecipientData> GetRecipients(EntityUid source, float voiceGetRange)
|
||||||
{
|
{
|
||||||
// TODO proper speech occlusion
|
// TODO proper speech occlusion
|
||||||
|
|
||||||
@@ -672,7 +688,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
var observer = ghosts.HasComponent(playerEntity);
|
var observer = ghosts.HasComponent(playerEntity);
|
||||||
|
|
||||||
// even if they are an observer, in some situations we still need the range
|
// even if they are an observer, in some situations we still need the range
|
||||||
if (sourceCoords.TryDistance(EntityManager, transformEntity.Coordinates, out var distance) && distance < voiceRange)
|
if (sourceCoords.TryDistance(EntityManager, transformEntity.Coordinates, out var distance) && distance < voiceGetRange)
|
||||||
{
|
{
|
||||||
recipients.Add(player, new ICChatRecipientData(distance, observer));
|
recipients.Add(player, new ICChatRecipientData(distance, observer));
|
||||||
continue;
|
continue;
|
||||||
@@ -682,7 +698,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
recipients.Add(player, new ICChatRecipientData(-1, true));
|
recipients.Add(player, new ICChatRecipientData(-1, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
RaiseLocalEvent(new ExpandICChatRecipientstEvent(source, voiceRange, recipients));
|
RaiseLocalEvent(new ExpandICChatRecipientstEvent(source, voiceGetRange, recipients));
|
||||||
return recipients;
|
return recipients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public sealed class ListeningSystem : EntitySystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obfuscatedEv != null && distance > ChatSystem.WhisperRange)
|
if (obfuscatedEv != null && distance > ChatSystem.WhisperClearRange)
|
||||||
RaiseLocalEvent(listenerUid, obfuscatedEv);
|
RaiseLocalEvent(listenerUid, obfuscatedEv);
|
||||||
else
|
else
|
||||||
RaiseLocalEvent(listenerUid, ev);
|
RaiseLocalEvent(listenerUid, ev);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ chat-manager-sender-announcement-wrap-message = {$sender} Announcement:
|
|||||||
{$message}
|
{$message}
|
||||||
chat-manager-entity-say-wrap-message = {$entityName} says, "{$message}"
|
chat-manager-entity-say-wrap-message = {$entityName} says, "{$message}"
|
||||||
chat-manager-entity-whisper-wrap-message = {$entityName} whispers, "{$message}"
|
chat-manager-entity-whisper-wrap-message = {$entityName} whispers, "{$message}"
|
||||||
|
chat-manager-entity-whisper-unknown-wrap-message = Someone whispers, "{$message}"
|
||||||
chat-manager-entity-me-wrap-message = {$entityName} {$message}
|
chat-manager-entity-me-wrap-message = {$entityName} {$message}
|
||||||
chat-manager-entity-looc-wrap-message = LOOC: {$entityName}: {$message}
|
chat-manager-entity-looc-wrap-message = LOOC: {$entityName}: {$message}
|
||||||
chat-manager-send-ooc-wrap-message = OOC: {$playerName}: {$message}
|
chat-manager-send-ooc-wrap-message = OOC: {$playerName}: {$message}
|
||||||
|
|||||||
Reference in New Issue
Block a user