Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
// SPDX-FileCopyrightText: 2025 ImHoks <imhokzzzz@gmail.com>
// SPDX-FileCopyrightText: 2025 KillanGenifer <killangenifer@gmail.com>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

using Content.Shared._CorvaxNext.Silicons.Borgs;

namespace Content.Client._CorvaxNext.Silicons.Borgs;

public sealed partial class AiRemoteControlSystem : SharedAiRemoteControlSystem
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Control xmlns="https://spacestation14.io"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
Margin="0 0 0 10">
<PanelContainer VerticalExpand="True" StyleClasses="BackgroundDark">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True"
VerticalExpand="True"
Margin="5 5 5 5">
Comment on lines +4 to +8
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid vertical expansion on per-device row containers.

Line 4 and Line 7 force row expansion, which can cause oversized entries in a vertical list. Prefer size-to-content rows.

Proposed fix
-    <PanelContainer VerticalExpand="True" StyleClasses="BackgroundDark">
+    <PanelContainer StyleClasses="BackgroundDark">
         <BoxContainer Orientation="Vertical"
                       HorizontalExpand="True"
-                      VerticalExpand="True"
                       Margin="5 5 5 5">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<PanelContainer VerticalExpand="True" StyleClasses="BackgroundDark">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True"
VerticalExpand="True"
Margin="5 5 5 5">
<PanelContainer StyleClasses="BackgroundDark">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True"
Margin="5 5 5 5">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Client/_CorvaxNext/Silicons/Laws/Ui/RemoteDeviceDisplay.xaml` around
lines 4 - 8, The per-device row XAML uses PanelContainer and nested BoxContainer
with VerticalExpand="True", causing rows to stretch; change the per-row
containers (PanelContainer and/or the BoxContainer in RemoteDeviceDisplay.xaml)
to not force vertical expansion—remove VerticalExpand="True" or set
VerticalExpand="False" on those elements so each device row sizes to its content
instead of growing to fill the list. Ensure HorizontalExpand remains as needed
and keep StyleClasses="BackgroundDark" unchanged.

<customControls:HSeparator Margin="0 5 0 5"/>
<RichTextLabel Name="DeviceName"/>
<BoxContainer Name="RemoteControlButtons" Orientation="Horizontal" HorizontalExpand="True" Margin="0 5 0 0">
<Button Name="MoveButton" StyleClasses="chatSelectorOptionButton" Text="{Loc ai-remote-ui-menu-moveto}"/>
<Control Margin="2 0 0 0"/>
<Button Name="TakeControlButton" StyleClasses="chatSelectorOptionButton" Text="{Loc ai-remote-control}"/>
</BoxContainer>
</BoxContainer>
</PanelContainer>
</Control>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
// SPDX-FileCopyrightText: 2025 ImHoks <imhokzzzz@gmail.com>
// SPDX-FileCopyrightText: 2025 KillanGenifer <killangenifer@gmail.com>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

using Robust.Client.UserInterface;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Content.Shared._CorvaxNext.Silicons.Borgs.Components;

namespace Content.Client._CorvaxNext.Silicons.Laws.Ui;

[GenerateTypedNameReferences]
public sealed partial class RemoteDeviceDisplay : Control
{
public event Action<RemoteDeviceActionEvent>? OnRemoteDeviceAction;

public RemoteDeviceDisplay(NetEntity netEntityUid, string displayName)
{
RobustXamlLoader.Load(this);

DeviceName.SetMessage(displayName);

MoveButton.OnPressed += _ =>
{
OnRemoteDeviceAction?.Invoke(new RemoteDeviceActionEvent(
RemoteDeviceActionEvent.RemoteDeviceActionType.MoveToDevice,
netEntityUid));
};

TakeControlButton.OnPressed += _ =>
{
OnRemoteDeviceAction?.Invoke(new RemoteDeviceActionEvent(
RemoteDeviceActionEvent.RemoteDeviceActionType.TakeControl,
netEntityUid));
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
// SPDX-FileCopyrightText: 2025 ImHoks <imhokzzzz@gmail.com>
// SPDX-FileCopyrightText: 2025 KillanGenifer <killangenifer@gmail.com>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

using Content.Shared._CorvaxNext.Silicons.Borgs.Components;
using Robust.Client.UserInterface;
using static Content.Shared._CorvaxNext.Silicons.Borgs.Components.AiRemoteControllerComponent;

namespace Content.Client._CorvaxNext.Silicons.Laws.Ui;

public sealed class RemoteDevicesBoundUserInterface : BoundUserInterface
{
private RemoteDevicesMenu? _menu;
private EntityUid _owner;

public RemoteDevicesBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
_owner = owner;
}

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

_menu = this.CreateWindow<RemoteDevicesMenu>();
_menu.OnRemoteDeviceAction += SendAction;
}

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

if (state is not RemoteDevicesBuiState msg)
return;

_menu?.Update(_owner, msg);
}

public void SendAction(RemoteDeviceActionEvent action)
{
SendMessage(new RemoteDeviceActionMessage(action));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc ai-remote-ui-menu-title}"
MinSize="355 100"
SetSize="355 415">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True"
VerticalExpand="True">
<PanelContainer VerticalExpand="True" Margin="10 10 10 10">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E"/>
</PanelContainer.PanelOverride>
<ScrollContainer
HScrollEnabled="False"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer
Name="RemoteDevicesDisplayContainer"
Orientation="Vertical"
VerticalExpand="True"
Margin="10 10 10 0">
</BoxContainer>
</ScrollContainer>
</PanelContainer>
</BoxContainer>
</controls:FancyWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
// SPDX-FileCopyrightText: 2025 ImHoks <imhokzzzz@gmail.com>
// SPDX-FileCopyrightText: 2025 KillanGenifer <killangenifer@gmail.com>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

using Robust.Client.UserInterface.XAML;
using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
using Robust.Client.AutoGenerated;
using Content.Shared._CorvaxNext.Silicons.Borgs.Components;

namespace Content.Client._CorvaxNext.Silicons.Laws.Ui;

[GenerateTypedNameReferences]
public sealed partial class RemoteDevicesMenu : FancyWindow
{
public event Action<RemoteDeviceActionEvent>? OnRemoteDeviceAction;

public RemoteDevicesMenu()
{
RobustXamlLoader.Load(this);
}

public void Update(EntityUid uid, RemoteDevicesBuiState state)
{
RemoteDevicesDisplayContainer.Children.Clear();

if (state.DeviceList == null)
return;

foreach (var device in state.DeviceList)
{
var control = new RemoteDeviceDisplay(device.NetEntityUid, device.DisplayName);

control.OnRemoteDeviceAction += action =>
{
OnRemoteDeviceAction?.Invoke(action);
};

RemoteDevicesDisplayContainer.AddChild(control);
}
}
}
19 changes: 18 additions & 1 deletion Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Server.Inventory;
using Content.Server.Inventory;
using Content.Shared._CorvaxNext.Silicons.Borgs.Components;
using Content.Shared.Inventory;
using Content.Shared.Radio.Components;
using Content.Shared.Silicons.Borgs;
Expand Down Expand Up @@ -28,6 +29,21 @@ protected override void SelectBorgModule(Entity<BorgSwitchableTypeComponent> ent
if (TryComp(ent, out ActiveRadioComponent? activeRadio))
activeRadio.Channels = [.. radioChannels];

if (TryComp(ent, out AiRemoteControllerComponent? aiRemoteComp))
{
if (TryComp(aiRemoteComp.AiHolder, out IntrinsicRadioTransmitterComponent? stationAiTransmitter) && transmitter != null)
{
aiRemoteComp.PreviouslyTransmitterChannels = [.. radioChannels];
transmitter.Channels = [.. stationAiTransmitter.Channels];
}

if (TryComp(aiRemoteComp.AiHolder, out ActiveRadioComponent? stationAiActiveRadio) && activeRadio != null)
{
aiRemoteComp.PreviouslyActiveRadioChannels = [.. radioChannels];
activeRadio.Channels = [.. stationAiActiveRadio.Channels];
}
}

// Borg transponder for the robotics console
if (TryComp(ent, out BorgTransponderComponent? transponder))
{
Expand Down Expand Up @@ -80,3 +96,4 @@ protected override void SelectBorgModule(Entity<BorgSwitchableTypeComponent> ent
base.SelectBorgModule(ent, borgType);
}
}

4 changes: 3 additions & 1 deletion Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Content.Shared.DeviceNetwork.Components;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared.Emag.Systems;
using Content.Shared._CorvaxNext.Silicons.Borgs.Components;
using Robust.Shared.Utility;

namespace Content.Server.Silicons.Borgs;
Expand Down Expand Up @@ -50,7 +51,8 @@ public void UpdateTransponder(float frameTime)
hpPercent,
chassis.ModuleCount,
hasBrain,
canDisable);
canDisable,
HasComp<AiRemoteControllerComponent>(uid));

var payload = new NetworkPayload()
{
Expand Down
28 changes: 28 additions & 0 deletions Content.Server/Silicons/Laws/SiliconLawSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Server.Administration;
using Content.Server.Chat.Managers;
using Content.Server.Station.Systems;
using Content.Shared._CorvaxNext.Silicons.Borgs.Components;
using Content.Shared.Administration;
using Content.Shared.Chat;
using Content.Shared.Emag.Systems;
Expand All @@ -13,6 +14,8 @@
using Content.Shared.Roles.Components;
using Content.Shared.Silicons.Laws;
using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Silicons.StationAi;
using Content.Shared.Tag;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
Expand All @@ -32,6 +35,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
[Dependency] private readonly EmagSystem _emag = default!;
[Dependency] private readonly TagSystem _tagSystem = default!;

/// <inheritdoc/>
public override void Initialize()
Expand Down Expand Up @@ -61,6 +65,9 @@ private void OnMindAdded(EntityUid uid, SiliconLawBoundComponent component, Mind
if (!TryComp<ActorComponent>(uid, out var actor))
return;

if (HasComp<AiRemoteControllerComponent>(uid) || _tagSystem.HasTag(uid, "StationAi"))
return;

var msg = Loc.GetString("laws-notify");
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));

Expand Down Expand Up @@ -154,6 +161,9 @@ private void OnEmagLawsAdded(EntityUid uid, SiliconLawProviderComponent componen
if (component.Lawset == null)
component.Lawset = GetLawset(component.Laws);

if (HasComp<AiRemoteControllerComponent>(uid))
return;

// Show the silicon has been subverted.
component.Subverted = true;

Expand Down Expand Up @@ -305,8 +315,26 @@ protected override void OnUpdaterInsert(Entity<SiliconLawUpdaterComponent> ent,
while (query.MoveNext(out var update))
{
SetLaws(lawset.Laws, update, provider.LawUploadSound);

if (TryComp<StationAiHeldComponent>(update, out var heldComp)
&& heldComp.CurrentConnectedEntity != null
&& HasComp<SiliconLawProviderComponent>(heldComp.CurrentConnectedEntity))
{
SetLaws(lawset.Laws, heldComp.CurrentConnectedEntity.Value, provider.LawUploadSound);
}
}
}

public void SetLawsSilent(List<SiliconLaw> newLaws, EntityUid target, SoundSpecifier? cue = null)
{
if (!TryComp<SiliconLawProviderComponent>(target, out var component))
return;

if (component.Lawset == null)
component.Lawset = new SiliconLawset();

component.Lawset.Laws = newLaws;
}
Comment on lines +329 to +338
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Unused cue parameter in SetLawsSilent.

The cue parameter is never used in this method. Since the purpose is to set laws without notification, the parameter is misleading and should be removed.

🐛 Remove unused parameter
-    public void SetLawsSilent(List<SiliconLaw> newLaws, EntityUid target, SoundSpecifier? cue = null)
+    public void SetLawsSilent(List<SiliconLaw> newLaws, EntityUid target)
     {
         if (!TryComp<SiliconLawProviderComponent>(target, out var component))
             return;

         if (component.Lawset == null)
             component.Lawset = new SiliconLawset();

         component.Lawset.Laws = newLaws;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void SetLawsSilent(List<SiliconLaw> newLaws, EntityUid target, SoundSpecifier? cue = null)
{
if (!TryComp<SiliconLawProviderComponent>(target, out var component))
return;
if (component.Lawset == null)
component.Lawset = new SiliconLawset();
component.Lawset.Laws = newLaws;
}
public void SetLawsSilent(List<SiliconLaw> newLaws, EntityUid target)
{
if (!TryComp<SiliconLawProviderComponent>(target, out var component))
return;
if (component.Lawset == null)
component.Lawset = new SiliconLawset();
component.Lawset.Laws = newLaws;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Content.Server/Silicons/Laws/SiliconLawSystem.cs` around lines 329 - 338,
Remove the unused SoundSpecifier? cue parameter from the SetLawsSilent method
signature and its declaration (method SetLawsSilent(List<SiliconLaw> newLaws,
EntityUid target) in SiliconLawSystem), and update all call sites to stop
passing a cue; if any callers relied on overloads, replace calls with the new
two-argument form. Ensure the method body remains unchanged (still checks
TryComp<SiliconLawProviderComponent>, initializes Lawset if null, and assigns
component.Lawset.Laws = newLaws) and run a compile to find and fix any remaining
references or tests expecting the old signature.

}

[ToolshedCommand, AdminCommand(AdminFlags.Admin)]
Expand Down
Loading
Loading