Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

Commit

Permalink
radio rework
Browse files Browse the repository at this point in the history
  • Loading branch information
KonChenY1 committed Apr 26, 2024
1 parent 5917e7c commit 2b99b5e
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 4 deletions.
59 changes: 59 additions & 0 deletions Content.Client/Radio/Ui/HandheldRadioBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Content.Shared.Radio;
using JetBrains.Annotations;
using Robust.Client.GameObjects;

namespace Content.Client.Radio.Ui;


[UsedImplicitly]
public sealed class HandheldRadioBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private HandheldRadioMenu? _menu;

public HandheldRadioBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{

}

protected override void Open()
{
base.Open();

_menu = new();

_menu.OnMicPressed += enabled =>
{
SendMessage(new ToggleHandheldRadioMicMessage(enabled));
};
_menu.OnSpeakerPressed += enabled =>
{
SendMessage(new ToggleHandheldRadioSpeakerMessage(enabled));
};
_menu.OnFrequencyChanged += frequency =>
{
SendMessage(new SelectHandheldRadioFrequencyMessage(frequency));
};

_menu.OnClose += Close;
_menu.OpenCentered();
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Close();
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

if (state is not HandheldRadioBoundUIState msg)
return;

_menu?.Update(msg);
}
}
29 changes: 29 additions & 0 deletions Content.Client/Radio/Ui/HandheldRadioMenu.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'handheld-radio-menu-title'}"
MinSize="200 170"
SetSize="200 170">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True"
VerticalExpand="True"
Margin="5 0 5 0">
<Control MinHeight="10"/>
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150">
<Label Name="CurrentTextFrequency" Text="{Loc 'handheld-radio-current-text-frequency'}" />
<LineEdit Name="FrequencyLineEdit" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" HorizontalAlignment="Right" Margin="5 0 5 5">
<Button Name="MicButton" ToggleMode="True" Text="{Loc 'handheld-radio-button-text-mic'}" StyleClasses="OpenRight" MinWidth="70"/>
<Button Name="SpeakerButton" ToggleMode="True" Text="{Loc 'handheld-radio-button-text-speaker'}" StyleClasses="OpenLeft" MinWidth="70"/>
</BoxContainer>
<BoxContainer Orientation="Vertical">
<PanelContainer StyleClasses="LowDivider" />
<BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
<Label Text="{Loc 'handheld-radio-flavor-text-left'}" StyleClasses="WindowFooterText"
HorizontalAlignment="Left" HorizontalExpand="True" Margin="0 0 5 0" />
<TextureRect StyleClasses="NTLogoDark" Stretch="KeepAspectCentered"
VerticalAlignment="Center" HorizontalAlignment="Right" SetSize="19 19"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
36 changes: 36 additions & 0 deletions Content.Client/Radio/Ui/HandheldRadioMenu.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Radio;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;

namespace Content.Client.Radio.Ui;

[GenerateTypedNameReferences]
public sealed partial class HandheldRadioMenu : FancyWindow
{

public event Action<bool>? OnMicPressed;
public event Action<bool>? OnSpeakerPressed;
public event Action<string>? OnFrequencyChanged;

public HandheldRadioMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

MicButton.OnPressed += args => OnMicPressed?.Invoke(args.Button.Pressed);
SpeakerButton.OnPressed += args => OnSpeakerPressed?.Invoke(args.Button.Pressed);

FrequencyLineEdit.OnTextEntered += e => OnFrequencyChanged?.Invoke(e.Text);
FrequencyLineEdit.OnFocusExit += e => OnFrequencyChanged?.Invoke(e.Text);
}

public void Update(HandheldRadioBoundUIState state)
{
MicButton.Pressed = state.MicEnabled;
SpeakerButton.Pressed = state.SpeakerEnabled;
FrequencyLineEdit.Text = state.Frequency.ToString();
}
}

7 changes: 7 additions & 0 deletions Content.Server/Radio/Components/RadioMicrophoneComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ public sealed partial class RadioMicrophoneComponent : Component
[DataField("toggleOnInteract")]
public bool ToggleOnInteract = true;

// Corvax-Frontier
/// <summary>
// The radio frequency on which the message will be transmitted
/// </summary>
[DataField]
public int Frequency = 1459; // Common channel frequency

/// <summary>
/// Whether or not the speaker must have an
/// unobstructed path to the radio to speak
Expand Down
65 changes: 62 additions & 3 deletions Content.Server/Radio/EntitySystems/RadioDeviceSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ public override void Initialize()
SubscribeLocalEvent<IntercomComponent, ToggleIntercomMicMessage>(OnToggleIntercomMic);
SubscribeLocalEvent<IntercomComponent, ToggleIntercomSpeakerMessage>(OnToggleIntercomSpeaker);
SubscribeLocalEvent<IntercomComponent, SelectIntercomChannelMessage>(OnSelectIntercomChannel);

// Corvax-Frontier-Start
SubscribeLocalEvent<RadioMicrophoneComponent, BeforeActivatableUIOpenEvent>(OnBeforeHandheldRadioUiOpen);
SubscribeLocalEvent<RadioMicrophoneComponent, ToggleHandheldRadioMicMessage>(OnToggleHandheldRadioMic);
SubscribeLocalEvent<RadioMicrophoneComponent, ToggleHandheldRadioSpeakerMessage>(OnToggleHandheldRadioSpeaker);
SubscribeLocalEvent<RadioMicrophoneComponent, SelectHandheldRadioFrequencyMessage>(OnChangeHandheldRadioFrequency);
// Corvax-Frontier-End
}

public override void Update(float frameTime)
Expand Down Expand Up @@ -175,7 +182,7 @@ private void OnExamine(EntityUid uid, RadioMicrophoneComponent component, Examin

using (args.PushGroup(nameof(RadioMicrophoneComponent)))
{
args.PushMarkup(Loc.GetString("handheld-radio-component-on-examine", ("frequency", proto.Frequency)));
args.PushMarkup(Loc.GetString("handheld-radio-component-on-examine", ("frequency", component.Frequency)));
args.PushMarkup(Loc.GetString("handheld-radio-component-chennel-examine",
("channel", proto.LocalizedName)));
}
Expand All @@ -187,7 +194,7 @@ private void OnListen(EntityUid uid, RadioMicrophoneComponent component, ListenE
return; // no feedback loops please.

if (_recentlySent.Add((args.Message, args.Source)))
_radio.SendRadioMessage(args.Source, args.Message, _protoMan.Index<RadioChannelPrototype>(component.BroadcastChannel), uid);
_radio.SendRadioMessage(args.Source, args.Message, _protoMan.Index<RadioChannelPrototype>(component.BroadcastChannel), uid, frequency: component.Frequency);
}

private void OnAttemptListen(EntityUid uid, RadioMicrophoneComponent component, ListenAttemptEvent args)
Expand Down Expand Up @@ -239,11 +246,14 @@ private void OnSelectIntercomChannel(EntityUid uid, IntercomComponent component,
if (component.RequiresPower && !this.IsPowered(uid, EntityManager) || args.Session.AttachedEntity is not { })
return;

if (!_protoMan.TryIndex<RadioChannelPrototype>(args.Channel, out _) || !component.SupportedChannels.Contains(args.Channel))
if (!_protoMan.TryIndex<RadioChannelPrototype>(args.Channel, out var channel) || !component.SupportedChannels.Contains(args.Channel))
return;

if (TryComp<RadioMicrophoneComponent>(uid, out var mic))
{
mic.BroadcastChannel = args.Channel;
mic.Frequency = _radio.GetFrequency(uid, channel); // Corvax-Frontier
}
if (TryComp<RadioSpeakerComponent>(uid, out var speaker))
speaker.Channels = new(){ args.Channel };
UpdateIntercomUi(uid, component);
Expand All @@ -261,4 +271,53 @@ private void UpdateIntercomUi(EntityUid uid, IntercomComponent component)
var state = new IntercomBoundUIState(micEnabled, speakerEnabled, availableChannels, selectedChannel);
_ui.TrySetUiState(uid, IntercomUiKey.Key, state);
}

// Corvax-Frontier-Start
#region Handheld Radio

private void OnBeforeHandheldRadioUiOpen(Entity<RadioMicrophoneComponent> microphone, ref BeforeActivatableUIOpenEvent args)
{
UpdateHandheldRadioUi(microphone);
}

private void OnToggleHandheldRadioMic(Entity<RadioMicrophoneComponent> microphone, ref ToggleHandheldRadioMicMessage args)
{
if (args.Session.AttachedEntity is not { } user)
return;

SetMicrophoneEnabled(microphone, user, args.Enabled, true);
UpdateHandheldRadioUi(microphone);
}

private void OnToggleHandheldRadioSpeaker(Entity<RadioMicrophoneComponent> microphone, ref ToggleHandheldRadioSpeakerMessage args)
{
if (args.Session.AttachedEntity is not { } user)
return;

SetSpeakerEnabled(microphone, user, args.Enabled, true);
UpdateHandheldRadioUi(microphone);
}

private void OnChangeHandheldRadioFrequency(Entity<RadioMicrophoneComponent> microphone, ref SelectHandheldRadioFrequencyMessage args)
{
if (args.Session.AttachedEntity is not { })
return;

microphone.Comp.Frequency = args.Frequency;
UpdateHandheldRadioUi(microphone);
}

private void UpdateHandheldRadioUi(Entity<RadioMicrophoneComponent> radio)
{
var speakerComp = CompOrNull<RadioSpeakerComponent>(radio);
var frequency = radio.Comp.Frequency;

var micEnabled = radio.Comp.Enabled;
var speakerEnabled = speakerComp?.Enabled ?? false;
var state = new HandheldRadioBoundUIState(micEnabled, speakerEnabled, frequency);
_ui.TrySetUiState(radio, HandheldRadioUiKey.Key, state);
}

#endregion
// Corvax-Frontier-End
}
21 changes: 20 additions & 1 deletion Content.Server/Radio/EntitySystems/RadioSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Content.Shared.Radio.Components;
using Robust.Server.GameObjects;
using Content.Shared.Speech;
using Content.Shared.Ghost; // Corvax-Frontier
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Player;
Expand Down Expand Up @@ -65,12 +66,23 @@ public void SendRadioMessage(EntityUid messageSource, string message, ProtoId<Ra
SendRadioMessage(messageSource, message, _prototype.Index(channel), radioSource, escapeMarkup: escapeMarkup);
}

/// <summary>
/// Gets the message frequency, if there is no such frequency, returns the standard channel frequency.
/// </summary>
public int GetFrequency(EntityUid source, RadioChannelPrototype channel)
{
if (TryComp<RadioMicrophoneComponent>(source, out var radioMicrophone))
return radioMicrophone.Frequency;

return channel.Frequency;
} // Corvax-Frontier

/// <summary>
/// Send radio message to all active radio listeners
/// </summary>
/// <param name="messageSource">Entity that spoke the message</param>
/// <param name="radioSource">Entity that picked up the message and will send it, e.g. headset</param>
public void SendRadioMessage(EntityUid messageSource, string message, RadioChannelPrototype channel, EntityUid radioSource, bool escapeMarkup = true)
public void SendRadioMessage(EntityUid messageSource, string message, RadioChannelPrototype channel, EntityUid radioSource, int? frequency = null, bool escapeMarkup = true)
{
// TODO if radios ever garble / modify messages, feedback-prevention needs to be handled better than this.
if (!_messages.Add(message))
Expand Down Expand Up @@ -144,6 +156,10 @@ public void SendRadioMessage(EntityUid messageSource, string message, RadioChann

var speakerQuery = GetEntityQuery<RadioSpeakerComponent>();
var radioQuery = EntityQueryEnumerator<ActiveRadioComponent, TransformComponent>();

if (frequency == null)
frequency = GetFrequency(messageSource, channel);

while (canSend && radioQuery.MoveNext(out var receiver, out var radio, out var transform))
{
if (!radio.ReceiveAllChannels)
Expand All @@ -152,6 +168,9 @@ public void SendRadioMessage(EntityUid messageSource, string message, RadioChann
!intercom.SupportedChannels.Contains(channel.ID)))
continue;
}
// Corvax-Frontier
if (!HasComp<GhostComponent>(receiver) && GetFrequency(receiver, channel) != frequency)
continue;

if (!channel.LongRange && transform.MapID != sourceMapId && !radio.GlobalReceive)
continue;
Expand Down
57 changes: 57 additions & 0 deletions Content.Shared/Radio/SharedHandheldRadio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Robust.Shared.Serialization;

namespace Content.Shared.Radio;

[Serializable, NetSerializable]
public enum HandheldRadioUiKey : byte
{
Key,
}

[Serializable, NetSerializable]
public sealed class HandheldRadioBoundUIState : BoundUserInterfaceState
{
public bool MicEnabled;
public bool SpeakerEnabled;
public int Frequency;

public HandheldRadioBoundUIState(bool micEnabled, bool speakerEnabled, int frequency)
{
MicEnabled = micEnabled;
SpeakerEnabled = speakerEnabled;
Frequency = frequency;
}
}

[Serializable, NetSerializable]
public sealed class ToggleHandheldRadioMicMessage : BoundUserInterfaceMessage
{
public bool Enabled;

public ToggleHandheldRadioMicMessage(bool enabled)
{
Enabled = enabled;
}
}

[Serializable, NetSerializable]
public sealed class ToggleHandheldRadioSpeakerMessage : BoundUserInterfaceMessage
{
public bool Enabled;

public ToggleHandheldRadioSpeakerMessage(bool enabled)
{
Enabled = enabled;
}
}

[Serializable, NetSerializable]
public sealed class SelectHandheldRadioFrequencyMessage : BoundUserInterfaceMessage
{
public int Frequency;

public SelectHandheldRadioFrequencyMessage(string frequency)
{
int.TryParse(frequency.Trim(), out Frequency);
}
}
6 changes: 6 additions & 0 deletions Resources/Locale/en-US/ss14-ru/radio/components/handheld.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
handheld-radio-menu-title = Handheld radio.
handheld-radio-current-text-frequency = Broadcast frequency
handheld-radio-button-text-mic = Mic.
handheld-radio-button-text-speaker = Speak
handheld-radio-flavor-text-left = Wiretapping of closed frequencies
is punishable by law.
6 changes: 6 additions & 0 deletions Resources/Locale/ru-RU/radio/components/handheld.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
handheld-radio-menu-title = Портативная рация.
handheld-radio-current-text-frequency = Частота вещания
handheld-radio-button-text-mic = Микр.
handheld-radio-button-text-speaker = Динам.
handheld-radio-flavor-text-left = Прослушивание закрытых частот
карается законом.
9 changes: 9 additions & 0 deletions Resources/Prototypes/Entities/Objects/Devices/radio.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
components:
- type: RadioMicrophone
broadcastChannel: Handheld
toggleOnInteract: false
frequency: 1330
- type: RadioSpeaker
channels:
- Handheld
toggleOnInteract: false
- type: Speech
speechVerb: Robotic
- type: Sprite
Expand All @@ -20,6 +23,12 @@
- type: Item
sprite: Objects/Devices/communication.rsi
heldPrefix: walkietalkie
- type: ActivatableUI
key: enum.HandheldRadioUiKey.Key
- type: UserInterface
interfaces:
- key: enum.HandheldRadioUiKey.Key
type: HandheldRadioBoundUserInterface
- type: Tag
tags:
- Radio
Expand Down

0 comments on commit 2b99b5e

Please sign in to comment.