using Content.Shared.IdentityManagement;
using Content.Shared.Labels.Components;
using Content.Shared.Silicons.StationAi;
+using Content.Shared.Speech;
using Content.Shared.Telephone;
using Content.Shared.UserInterface;
using Content.Shared.Verbs;
entity.Comp.HologramProtoId == null)
return;
- var uid = Spawn(entity.Comp.HologramProtoId, Transform(entity).Coordinates);
+ var hologramUid = Spawn(entity.Comp.HologramProtoId, Transform(entity).Coordinates);
// Safeguard - spawned holograms must have this component
- if (!TryComp<HolopadHologramComponent>(uid, out var component))
+ if (!TryComp<HolopadHologramComponent>(hologramUid, out var holopadHologram))
{
- Del(uid);
+ Del(hologramUid);
return;
}
- entity.Comp.Hologram = new Entity<HolopadHologramComponent>(uid, component);
+ entity.Comp.Hologram = new Entity<HolopadHologramComponent>(hologramUid, holopadHologram);
+
+ // Relay speech preferentially through the hologram
+ if (TryComp<SpeechComponent>(hologramUid, out var hologramSpeech) &&
+ TryComp<TelephoneComponent>(entity, out var entityTelephone))
+ {
+ _telephoneSystem.SetSpeakerForTelephone((entity, entityTelephone), (hologramUid, hologramSpeech));
+ }
}
private void DeleteHologram(Entity<HolopadHologramComponent> hologram, Entity<HolopadComponent> attachedHolopad)
var nameEv = new TransformSpeakerNameEvent(args.MessageSource, Name(args.MessageSource));
RaiseLocalEvent(args.MessageSource, nameEv);
- var name = Loc.GetString("speech-name-relay",
- ("speaker", Name(entity)),
- ("originalName", nameEv.VoiceName));
+ // Determine if speech should be relayed via the telephone itself or a designated speaker
+ var speaker = entity.Comp.Speaker != null ? entity.Comp.Speaker.Value.Owner : entity.Owner;
+
+ var name = Loc.GetString("chat-telephone-name-relay",
+ ("originalName", nameEv.VoiceName),
+ ("speaker", Name(speaker)));
var range = args.TelephoneSource.Comp.LinkedTelephones.Count > 1 ? ChatTransmitRange.HideChat : ChatTransmitRange.GhostRangeLimit;
var volume = entity.Comp.SpeakerVolume == TelephoneVolume.Speak ? InGameICChatType.Speak : InGameICChatType.Whisper;
- _chat.TrySendInGameICMessage(entity, args.Message, volume, range, nameOverride: name, checkRadioPrefix: false);
+ _chat.TrySendInGameICMessage(speaker, args.Message, volume, range, nameOverride: name, checkRadioPrefix: false);
}
#endregion
}
}
+ public void SetSpeakerForTelephone(Entity<TelephoneComponent> entity, Entity<SpeechComponent>? speaker)
+ {
+ entity.Comp.Speaker = speaker;
+ }
+
private (string?, string?) GetNameAndJobOfCallingEntity(EntityUid uid)
{
string? presumedName = null;
using Content.Shared.Chat;
+using Content.Shared.Speech;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
[DataField]
public bool UnlistedNumber = false;
+ /// <summary>
+ /// Speech is relayed through this entity instead of the telephone
+ /// </summary>
+ [ViewVariables(VVAccess.ReadOnly)]
+ public Entity<SpeechComponent>? Speaker = null;
+
/// <summary>
/// Telephone number for this device
/// </summary>
public struct TelephoneCallOptions
{
public bool IgnoreRange; // The source can always reach its target
- public bool ForceConnect; // The source immediately starts a call with the receiver, potentially interrupting a call that is already in progress
+ public bool ForceConnect; // The source immediately starts a call with the receiver, potentially interrupting a call that is already in progress
public bool ForceJoin; // The source smoothly joins a call in progress, or starts a normal call with the receiver if there is none
public bool MuteSource; // Chatter from the source is not transmitted - could be used for eavesdropping when combined with 'ForceJoin'
public bool MuteReceiver; // Chatter from the receiver is not transmitted - useful for broadcasting messages to multiple receivers
[Serializable, NetSerializable]
public enum TelephoneRange : byte
{
- Grid, // Can only reach telephones that are on the same grid
+ Grid, // Can only reach telephones that are on the same grid
Map, // Can reach any telephone that is on the same map
Unlimited, // Can reach any telephone, across any distance
}
chat-telephone-caller-id-without-job = [color={$color}][font={$fontType} size={$fontSize}][bold]{CAPITALIZE($callerName)}[/bold][/font][/color]
chat-telephone-unknown-device = [color={$color}][font={$fontType} size={$fontSize}][bolditalic]Unknown source[/bolditalic][/font][/color]
chat-telephone-device-id = [color={$color}][font={$fontType} size={$fontSize}][bold]{CAPITALIZE($deviceName)}[/bold][/font][/color]
+
+# Chat text
+chat-telephone-name-relay = {$originalName} ({$speaker})
\ No newline at end of file
# These are spawned by holopads
- type: entity
id: HolopadHologram
+ name: hologram
categories: [ HideSpawnMenu ]
suffix: DO NOT MAP
components:
- type: Appearance
- type: TypingIndicator
proto: robot
+ - type: Speech
+ speechVerb: Robotic
+ speechSounds: Borg
+ speechBubbleOffset: 0.45
- type: HolopadHologram
rsiPath: Structures/Machines/holopad.rsi
rsiState: icon_in_call