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

[DRAFT] Departmental Telephones #458

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
93 changes: 93 additions & 0 deletions Content.Client/_CD/Telephone/TelephoneBui.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using Content.Client.UserInterface.ControlExtensions;
using Content.Shared._CD.Telephone;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using static Robust.Client.UserInterface.Controls.BoxContainer;

namespace Content.Client._CD.Telephone;

public sealed class TelephoneBui(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
{
private TelephoneWindow? _window;

protected override void Open()
{
_window = this.CreateWindow<TelephoneWindow>();

if (EntMan.TryGetComponent(Owner, out MetaDataComponent? metaData))
_window.Title = metaData.EntityName;

Refresh();
}

protected override void UpdateState(BoundUserInterfaceState state)
{
Refresh();
}

private void Refresh()
{
if (_window is not { IsOpen: true })
return;

if (State is not TelephoneBuiState state)
return;

_window.Tabs.DisposeAllChildren();
var categories = new Dictionary<string, BoxContainer>();
foreach (var phone in state.Phones)
{
if (!categories.TryGetValue(phone.Category, out var category))
{
var tab = new BoxContainer { Orientation = LayoutOrientation.Vertical };

var scroll = new ScrollContainer
{
HScrollEnabled = false,
VScrollEnabled = true,
VerticalExpand = true,
};

category = new BoxContainer { Orientation = LayoutOrientation.Vertical };
scroll.AddChild(category);
categories[phone.Category] = category;

var searchBar = new LineEdit();
tab.AddChild(searchBar);
tab.AddChild(scroll);

searchBar.OnTextChanged += args =>
{
foreach (var scroll in _window.Tabs.GetControlOfType<ScrollContainer>())
{
foreach (var container in scroll.GetControlOfType<BoxContainer>())
{
foreach (var child in container.Children)
{
if (child is LineEdit otherBar)
{
otherBar.SetText(args.Text, false);
}
else if (child is Button button)
{
button.Visible = button.Text?.Contains(args.Text, StringComparison.OrdinalIgnoreCase) ?? false;
}
}
}
}
};

_window.Tabs.AddChild(tab);
TabContainer.SetTabTitle(tab, phone.Category);
}

var phoneButton = new Button
{
Text = phone.Name,
StyleClasses = { "OpenBoth" },
};
phoneButton.OnPressed += _ => SendPredictedMessage(new TelephoneCallBuiMsg(phone.Id));
category.AddChild(phoneButton);
}
}
}
45 changes: 45 additions & 0 deletions Content.Client/_CD/Telephone/TelephoneOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Content.Shared._CD.Telephone;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Map;

namespace Content.Client._CD.Telephone;

public sealed class TelephoneOverlay : Overlay
{
[Dependency] private readonly IEntityManager _entity = default!;

public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowEntities;

public TelephoneOverlay()
{
IoCManager.InjectDependencies(this);
}

protected override void Draw(in OverlayDrawArgs args)
{
var containerSystem = _entity.System<ContainerSystem>();
var transformSystem = _entity.System<TransformSystem>();
var handle = args.WorldHandle;

var rotarys = _entity.EntityQueryEnumerator<RotaryPhoneComponent>();
while (rotarys.MoveNext(out var rotaryId, out var rotary))
{
if (rotary.Phone is not { Valid: true } phone ||
!containerSystem.TryGetContainer(rotaryId, rotary.ContainerId, out var container) ||
container.ContainedEntities.Count > 0 ||
!_entity.TryGetComponent(rotaryId, out TransformComponent? rotaryTransform) ||
rotaryTransform.MapID == MapId.Nullspace ||
!_entity.TryGetComponent(phone, out TransformComponent? phoneTransform) ||
phoneTransform.MapID == MapId.Nullspace)
{
continue;
}

var rotaryPosition = transformSystem.GetMapCoordinates(rotaryId);
var phonePosition = transformSystem.GetMapCoordinates(phone);
handle.DrawLine(rotaryPosition.Position, phonePosition.Position, Color.Black);
}
}
}
22 changes: 22 additions & 0 deletions Content.Client/_CD/Telephone/TelephoneSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Content.Shared._CD.Telephone;
using Robust.Client.Graphics;

namespace Content.Client._CD.Telephone;

public sealed class TelephoneSystem : SharedTelephoneSystem
{
[Dependency] private readonly IOverlayManager _overlay = default!;

public override void Initialize()
{
base.Initialize();
if (!_overlay.HasOverlay<TelephoneOverlay>())
_overlay.AddOverlay(new TelephoneOverlay());
}

public override void Shutdown()
{
base.Shutdown();
_overlay.RemoveOverlay<TelephoneOverlay>();
}
}
10 changes: 10 additions & 0 deletions Content.Client/_CD/Telephone/TelephoneWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<controls:TelephoneWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client._CD.Telephone"
Title="Telephone" MinSize="500 400">
<BoxContainer Orientation="Vertical">
<TabContainer Name="Tabs" Access="Public" HorizontalExpand="True" VerticalExpand="True" />
<Button Name="DialButton" Access="Public" Text="Dial" StyleClasses="OpenBoth" />
<!-- <Button Name="DoNotDisturbButton" Access="Public" Text="Do Not Disturb" StyleClasses="OpenBoth" /> -->
</BoxContainer>
</controls:TelephoneWindow>
14 changes: 14 additions & 0 deletions Content.Client/_CD/Telephone/TelephoneWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client._CD.Telephone;

[GenerateTypedNameReferences]
public sealed partial class TelephoneWindow : DefaultWindow
{
public TelephoneWindow()
{
RobustXamlLoader.Load(this);
}
}
4 changes: 2 additions & 2 deletions Content.Server/Chat/Managers/ChatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,13 @@

#region Utility

public void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0, NetUserId? author = null)
public void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0, NetUserId? author = null, bool hidePopup = false)
{
var user = author == null ? null : EnsurePlayer(author);
var netSource = _entityManager.GetNetEntity(source);
user?.AddEntity(netSource);

var msg = new ChatMessage(channel, message, wrappedMessage, netSource, user?.Key, hideChat, colorOverride, audioPath, audioVolume);
var msg = new ChatMessage(channel, message, wrappedMessage, netSource, user?.Key, hideChat, colorOverride, audioPath, audioVolume, hidePopup);

Check failure on line 305 in Content.Server/Chat/Managers/ChatManager.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

'ChatMessage' does not contain a constructor that takes 10 arguments

Check failure on line 305 in Content.Server/Chat/Managers/ChatManager.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

'ChatMessage' does not contain a constructor that takes 10 arguments

Check failure on line 305 in Content.Server/Chat/Managers/ChatManager.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

'ChatMessage' does not contain a constructor that takes 10 arguments

Check failure on line 305 in Content.Server/Chat/Managers/ChatManager.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

'ChatMessage' does not contain a constructor that takes 10 arguments

Check failure on line 305 in Content.Server/Chat/Managers/ChatManager.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

'ChatMessage' does not contain a constructor that takes 10 arguments
_netManager.ServerSendMessage(new MsgChatMessage() { Message = msg }, client);

if (!recordReplay)
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Chat/Managers/IChatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public interface IChatManager : ISharedChatManager
void SendAdminAnnouncementMessage(ICommonSession player, string message, bool suppressLog = true);

void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat,
INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0, NetUserId? author = null);
INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0, NetUserId? author = null, bool hidePopup = false);

void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay,
IEnumerable<INetChannel> clients, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0, NetUserId? author = null);
Expand Down
57 changes: 57 additions & 0 deletions Content.Server/_CD/Telephone/TelephoneSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Content.Server.Chat.Managers;
using Content.Server.Hands.Systems;
using Content.Server.Radio;
using Content.Server.Speech;
using Content.Server.Speech.Components;
using Content.Shared._CD.Telephone;
using Content.Shared.Chat;
using Content.Shared.Coordinates;
using Robust.Server.Audio;
using Robust.Shared.Player;
using Robust.Shared.Utility;

namespace Content.Server._CD.Telephone;

public sealed class TelephoneSystem : SharedTelephoneSystem
{
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly HandsSystem _hands = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<RadioSendAttemptEvent>(OnRadioSendAttempt);

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'OnRadioSendAttempt' does not exist in the current context

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'OnRadioSendAttempt' does not exist in the current context

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioSendAttempt' does not exist in the current context

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioSendAttempt' does not exist in the current context

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'OnRadioSendAttempt' does not exist in the current context

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'OnRadioSendAttempt' does not exist in the current context

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioSendAttempt' does not exist in the current context

Check failure on line 25 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioSendAttempt' does not exist in the current context
SubscribeLocalEvent<RadioReceiveAttemptEvent>(OnRadioReceiveAttempt);

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'OnRadioReceiveAttempt' does not exist in the current context

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'OnRadioReceiveAttempt' does not exist in the current context

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioReceiveAttempt' does not exist in the current context

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioReceiveAttempt' does not exist in the current context

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'OnRadioReceiveAttempt' does not exist in the current context

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'OnRadioReceiveAttempt' does not exist in the current context

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioReceiveAttempt' does not exist in the current context

Check failure on line 26 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'OnRadioReceiveAttempt' does not exist in the current context

SubscribeLocalEvent<TelephoneComponent, ListenEvent>(OnListen);
}

private void OnListen(Entity<TelephoneComponent> ent, ref ListenEvent args)
{
if (HasComp<TelephoneComponent>(args.Source))
return;

if (!_hands.IsHolding(args.Source, ent))
return;

if (ent.Comp.RotaryPhone is not { } rotary ||
!TryGetOtherPhone(rotary, out var otherPhone) ||
!TryComp(holder, out ActorComponent? actor))

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'holder' does not exist in the current context

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'holder' does not exist in the current context

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'holder' does not exist in the current context

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'holder' does not exist in the current context

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'holder' does not exist in the current context

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'holder' does not exist in the current context

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'holder' does not exist in the current context

Check failure on line 41 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'holder' does not exist in the current context
{
return;
}

var name = GetPhoneName(rotary);

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'GetPhoneName' does not exist in the current context

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

The name 'GetPhoneName' does not exist in the current context

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'GetPhoneName' does not exist in the current context

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'GetPhoneName' does not exist in the current context

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'GetPhoneName' does not exist in the current context

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

The name 'GetPhoneName' does not exist in the current context

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'GetPhoneName' does not exist in the current context

Check failure on line 46 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

The name 'GetPhoneName' does not exist in the current context
var message = $"{name} says, \"{FormattedMessage.EscapeText(args.Message)}\"";
var sound = _audio.GetSound(ent.Comp.SpeakSound);
_chatManager.ChatMessageToOne(ChatChannel.Local, message, message, otherPhone, false, actor.PlayerSession.Channel, Color.FromHex("#9956D3"), true, sound, -12, hidePopup: true);

Check failure on line 49 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

Dereference of a possibly null reference.

Check failure on line 49 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Dereference of a possibly null reference.

Check failure on line 49 in Content.Server/_CD/Telephone/TelephoneSystem.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Dereference of a possibly null reference.
}

protected override void PickupPhone(Entity<RotaryPhoneComponent> rotary, EntityUid telephone, EntityUid user)
{
base.PickupPhone(rotary, telephone, user);
EnsureComp<ActiveListenerComponent>(telephone);
}
}
11 changes: 11 additions & 0 deletions Content.Shared/_CD/Telephone/PickedUpPhoneComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Robust.Shared.GameStates;

namespace Content.Shared._CD.Telephone;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedTelephoneSystem))]
public sealed partial class PickedUpPhoneComponent : Component
{
[DataField, AutoNetworkedField]
public int Range = 7;
}
65 changes: 65 additions & 0 deletions Content.Shared/_CD/Telephone/RotaryPhoneComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Shared._CD.Telephone;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause]
[Access(typeof(SharedTelephoneSystem))]
public sealed partial class RotaryPhoneComponent : Component
{
[DataField, AutoNetworkedField]
public string Category = "Almayer";

[DataField, AutoNetworkedField]
public bool CanDnd;

[DataField, AutoNetworkedField]
public SoundSpecifier? DialingSound = new SoundPathSpecifier("/Audio/_CD/Phone/dial.ogg", AudioParams.Default.WithVolume(-3));

[DataField, AutoNetworkedField]
public SoundSpecifier? DialingIdleSound = new SoundPathSpecifier("/Audio/_CD/Phone/ring_outgoing.ogg", AudioParams.Default.WithVolume(-3));

[DataField, AutoNetworkedField]
public SoundSpecifier? ReceivingSound = new SoundPathSpecifier("/Audio/_CD/Phone/telephone_ring.ogg", AudioParams.Default.WithVolume(-3));

[DataField, AutoNetworkedField]
public EntProtoId<TelephoneComponent> PhoneId = "CDTelephone";

[DataField, AutoNetworkedField]
public string ContainerId = "cd_rotary_phone_telephone";

[DataField, AutoNetworkedField]
public EntityUid? Phone;

[DataField, AutoNetworkedField]
public EntityUid? Sound;

[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField]
public TimeSpan LastCall;

[DataField, AutoNetworkedField]
public TimeSpan CallCooldown = TimeSpan.FromSeconds(1);

[DataField, AutoNetworkedField]
public TimeSpan DialingIdleDelay = TimeSpan.FromSeconds(3);

[DataField, AutoNetworkedField]
public bool Idle;
}

[Serializable, NetSerializable]
public enum RotaryPhoneLayers
{
Layer,
}

[Serializable, NetSerializable]
public enum RotaryPhoneVisuals
{
Base,
Ring,
Ear,
}
11 changes: 11 additions & 0 deletions Content.Shared/_CD/Telephone/RotaryPhoneDialingComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Robust.Shared.GameStates;

namespace Content.Shared._CD.Telephone;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedTelephoneSystem))]
public sealed partial class RotaryPhoneDialingComponent : Component
{
[DataField, AutoNetworkedField]
public EntityUid? Other;
}
11 changes: 11 additions & 0 deletions Content.Shared/_CD/Telephone/RotaryPhoneReceivingComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Robust.Shared.GameStates;

namespace Content.Shared._CD.Telephone;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedTelephoneSystem))]
public sealed partial class RotaryPhoneReceivingComponent : Component
{
[DataField, AutoNetworkedField]
public EntityUid? Other;
}
Loading
Loading