Predict dumping (#32394)
* Predict dumping - This got soaped really fucking hard. - Dumping is predicted, this required disposals to be predicte.d - Disposals required mailing (because it's tightly coupled), and a smidge of other content systems. - I also had to fix a compnetworkgenerator issue at the same time so it wouldn't mispredict. * Fix a bunch of stuff * nasty merge * Some reviews * Some more reviews while I stash * Fix merge * Fix merge * Half of review * Review * re(h)f * lizards * feexes * feex
This commit is contained in:
25
Content.Client/Configurable/ConfigurationSystem.cs
Normal file
25
Content.Client/Configurable/ConfigurationSystem.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Content.Client.Configurable.UI;
|
||||
using Content.Shared.Configurable;
|
||||
|
||||
namespace Content.Client.Configurable;
|
||||
|
||||
public sealed class ConfigurationSystem : SharedConfigurationSystem
|
||||
{
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<ConfigurationComponent, AfterAutoHandleStateEvent>(OnConfigurationState);
|
||||
}
|
||||
|
||||
private void OnConfigurationState(Entity<ConfigurationComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (_uiSystem.TryGetOpenUi<ConfigurationBoundUserInterface>(ent.Owner,
|
||||
ConfigurationComponent.ConfigurationUiKey.Key,
|
||||
out var bui))
|
||||
{
|
||||
bui.Refresh(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Robust.Client.GameObjects;
|
||||
using System.Numerics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Shared.Configurable;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using static Content.Shared.Configurable.ConfigurationComponent;
|
||||
|
||||
namespace Content.Client.Configurable.UI
|
||||
@@ -19,16 +21,53 @@ namespace Content.Client.Configurable.UI
|
||||
base.Open();
|
||||
_menu = this.CreateWindow<ConfigurationMenu>();
|
||||
_menu.OnConfiguration += SendConfiguration;
|
||||
if (EntMan.TryGetComponent(Owner, out ConfigurationComponent? component))
|
||||
Refresh((Owner, component));
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
public void Refresh(Entity<ConfigurationComponent> entity)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not ConfigurationBoundUserInterfaceState configurationState)
|
||||
if (_menu == null)
|
||||
return;
|
||||
|
||||
_menu?.Populate(configurationState);
|
||||
_menu.Column.Children.Clear();
|
||||
_menu.Inputs.Clear();
|
||||
|
||||
foreach (var field in entity.Comp.Config)
|
||||
{
|
||||
var label = new Label
|
||||
{
|
||||
Margin = new Thickness(0, 0, 8, 0),
|
||||
Name = field.Key,
|
||||
Text = field.Key + ":",
|
||||
VerticalAlignment = Control.VAlignment.Center,
|
||||
HorizontalExpand = true,
|
||||
SizeFlagsStretchRatio = .2f,
|
||||
MinSize = new Vector2(60, 0)
|
||||
};
|
||||
|
||||
var input = new LineEdit
|
||||
{
|
||||
Name = field.Key + "-input",
|
||||
Text = field.Value ?? "",
|
||||
IsValid = _menu.Validate,
|
||||
HorizontalExpand = true,
|
||||
SizeFlagsStretchRatio = .8f
|
||||
};
|
||||
|
||||
_menu.Inputs.Add((field.Key, input));
|
||||
|
||||
var row = new BoxContainer
|
||||
{
|
||||
Orientation = BoxContainer.LayoutOrientation.Horizontal
|
||||
};
|
||||
|
||||
ConfigurationMenu.CopyProperties(_menu.Row, row);
|
||||
|
||||
row.AddChild(label);
|
||||
row.AddChild(input);
|
||||
_menu.Column.AddChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Numerics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using static Content.Shared.Configurable.ConfigurationComponent;
|
||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
@@ -14,10 +10,10 @@ namespace Content.Client.Configurable.UI
|
||||
{
|
||||
public sealed class ConfigurationMenu : DefaultWindow
|
||||
{
|
||||
private readonly BoxContainer _column;
|
||||
private readonly BoxContainer _row;
|
||||
public readonly BoxContainer Column;
|
||||
public readonly BoxContainer Row;
|
||||
|
||||
private readonly List<(string name, LineEdit input)> _inputs;
|
||||
public readonly List<(string name, LineEdit input)> Inputs;
|
||||
|
||||
[ViewVariables]
|
||||
public Regex? Validation { get; internal set; }
|
||||
@@ -28,7 +24,7 @@ namespace Content.Client.Configurable.UI
|
||||
{
|
||||
MinSize = SetSize = new Vector2(300, 250);
|
||||
|
||||
_inputs = new List<(string name, LineEdit input)>();
|
||||
Inputs = new List<(string name, LineEdit input)>();
|
||||
|
||||
Title = Loc.GetString("configuration-menu-device-title");
|
||||
|
||||
@@ -39,14 +35,14 @@ namespace Content.Client.Configurable.UI
|
||||
HorizontalExpand = true
|
||||
};
|
||||
|
||||
_column = new BoxContainer
|
||||
Column = new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Vertical,
|
||||
Margin = new Thickness(8),
|
||||
SeparationOverride = 16,
|
||||
};
|
||||
|
||||
_row = new BoxContainer
|
||||
Row = new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Horizontal,
|
||||
SeparationOverride = 16,
|
||||
@@ -69,61 +65,20 @@ namespace Content.Client.Configurable.UI
|
||||
ModulateSelfOverride = Color.FromHex("#202025")
|
||||
};
|
||||
|
||||
outerColumn.AddChild(_column);
|
||||
outerColumn.AddChild(Column);
|
||||
baseContainer.AddChild(outerColumn);
|
||||
baseContainer.AddChild(confirmButton);
|
||||
Contents.AddChild(baseContainer);
|
||||
}
|
||||
|
||||
public void Populate(ConfigurationBoundUserInterfaceState state)
|
||||
{
|
||||
_column.Children.Clear();
|
||||
_inputs.Clear();
|
||||
|
||||
foreach (var field in state.Config)
|
||||
{
|
||||
var label = new Label
|
||||
{
|
||||
Margin = new Thickness(0, 0, 8, 0),
|
||||
Name = field.Key,
|
||||
Text = field.Key + ":",
|
||||
VerticalAlignment = VAlignment.Center,
|
||||
HorizontalExpand = true,
|
||||
SizeFlagsStretchRatio = .2f,
|
||||
MinSize = new Vector2(60, 0)
|
||||
};
|
||||
|
||||
var input = new LineEdit
|
||||
{
|
||||
Name = field.Key + "-input",
|
||||
Text = field.Value ?? "",
|
||||
IsValid = Validate,
|
||||
HorizontalExpand = true,
|
||||
SizeFlagsStretchRatio = .8f
|
||||
};
|
||||
|
||||
_inputs.Add((field.Key, input));
|
||||
|
||||
var row = new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Horizontal
|
||||
};
|
||||
CopyProperties(_row, row);
|
||||
|
||||
row.AddChild(label);
|
||||
row.AddChild(input);
|
||||
_column.AddChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnConfirm(ButtonEventArgs args)
|
||||
{
|
||||
var config = GenerateDictionary(_inputs, "Text");
|
||||
var config = GenerateDictionary(Inputs, "Text");
|
||||
OnConfiguration?.Invoke(config);
|
||||
Close();
|
||||
}
|
||||
|
||||
private bool Validate(string value)
|
||||
public bool Validate(string value)
|
||||
{
|
||||
return Validation?.IsMatch(value) != false;
|
||||
}
|
||||
@@ -140,7 +95,7 @@ namespace Content.Client.Configurable.UI
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private static void CopyProperties<T>(T from, T to) where T : Control
|
||||
public static void CopyProperties<T>(T from, T to) where T : Control
|
||||
{
|
||||
foreach (var property in from.AllAttachedProperties)
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Content.Client.Decals
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprites = default!;
|
||||
|
||||
private DecalOverlay _overlay = default!;
|
||||
private DecalOverlay? _overlay;
|
||||
|
||||
private HashSet<uint> _removedUids = new();
|
||||
private readonly List<Vector2i> _removedChunks = new();
|
||||
@@ -31,6 +31,9 @@ namespace Content.Client.Decals
|
||||
|
||||
public void ToggleOverlay()
|
||||
{
|
||||
if (_overlay == null)
|
||||
return;
|
||||
|
||||
if (_overlayManager.HasOverlay<DecalOverlay>())
|
||||
{
|
||||
_overlayManager.RemoveOverlay(_overlay);
|
||||
@@ -44,6 +47,10 @@ namespace Content.Client.Decals
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
|
||||
if (_overlay == null)
|
||||
return;
|
||||
|
||||
_overlayManager.RemoveOverlay(_overlay);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
|
||||
namespace Content.Client.DeviceNetwork.Systems;
|
||||
|
||||
public sealed class DeviceNetworkSystem : SharedDeviceNetworkSystem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
|
||||
namespace Content.Client.Disposal;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class DisposalUnitComponent : SharedDisposalUnitComponent
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using Content.Client.Disposal.Unit;
|
||||
using Content.Client.Power.EntitySystems;
|
||||
using Content.Shared.Disposal;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.Disposal.Mailing;
|
||||
|
||||
public sealed class MailingUnitBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[ViewVariables]
|
||||
public MailingUnitWindow? MailingUnitWindow;
|
||||
|
||||
public MailingUnitBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private void ButtonPressed(DisposalUnitComponent.UiButton button)
|
||||
{
|
||||
SendMessage(new DisposalUnitComponent.UiButtonPressedMessage(button));
|
||||
// If we get client-side power stuff then we can predict the button presses but for now we won't as it stuffs
|
||||
// the pressure lerp up.
|
||||
}
|
||||
|
||||
private void TargetSelected(ItemList.ItemListSelectedEventArgs args)
|
||||
{
|
||||
var item = args.ItemList[args.ItemIndex];
|
||||
SendMessage(new TargetSelectedMessage(item.Text));
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
MailingUnitWindow = this.CreateWindow<MailingUnitWindow>();
|
||||
MailingUnitWindow.OpenCenteredRight();
|
||||
|
||||
MailingUnitWindow.Eject.OnPressed += _ => ButtonPressed(DisposalUnitComponent.UiButton.Eject);
|
||||
MailingUnitWindow.Engage.OnPressed += _ => ButtonPressed(DisposalUnitComponent.UiButton.Engage);
|
||||
MailingUnitWindow.Power.OnPressed += _ => ButtonPressed(DisposalUnitComponent.UiButton.Power);
|
||||
|
||||
MailingUnitWindow.TargetListContainer.OnItemSelected += TargetSelected;
|
||||
|
||||
if (EntMan.TryGetComponent(Owner, out MailingUnitComponent? component))
|
||||
Refresh((Owner, component));
|
||||
}
|
||||
|
||||
public void Refresh(Entity<MailingUnitComponent> entity)
|
||||
{
|
||||
if (MailingUnitWindow == null)
|
||||
return;
|
||||
|
||||
// TODO: This should be decoupled from disposals
|
||||
if (EntMan.TryGetComponent(entity.Owner, out DisposalUnitComponent? disposals))
|
||||
{
|
||||
var disposalSystem = EntMan.System<DisposalUnitSystem>();
|
||||
|
||||
var disposalState = disposalSystem.GetState(Owner, disposals);
|
||||
var fullPressure = disposalSystem.EstimatedFullPressure(Owner, disposals);
|
||||
|
||||
MailingUnitWindow.UnitState.Text = Loc.GetString($"disposal-unit-state-{disposalState}");
|
||||
MailingUnitWindow.FullPressure = fullPressure;
|
||||
MailingUnitWindow.PressureBar.UpdatePressure(fullPressure);
|
||||
MailingUnitWindow.Power.Pressed = EntMan.System<PowerReceiverSystem>().IsPowered(Owner);
|
||||
MailingUnitWindow.Engage.Pressed = disposals.Engaged;
|
||||
}
|
||||
|
||||
MailingUnitWindow.Title = Loc.GetString("ui-mailing-unit-window-title", ("tag", entity.Comp.Tag ?? " "));
|
||||
//UnitTag.Text = state.Tag;
|
||||
MailingUnitWindow.Target.Text = entity.Comp.Target;
|
||||
|
||||
MailingUnitWindow.TargetListContainer.Clear();
|
||||
foreach (var target in entity.Comp.TargetList)
|
||||
{
|
||||
MailingUnitWindow.TargetListContainer.AddItem(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Content.Client/Disposal/Mailing/MailingUnitSystem.cs
Normal file
22
Content.Client/Disposal/Mailing/MailingUnitSystem.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Content.Shared.Disposal;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.Disposal.Mailing;
|
||||
|
||||
namespace Content.Client.Disposal.Mailing;
|
||||
|
||||
public sealed class MailingUnitSystem : SharedMailingUnitSystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<MailingUnitComponent, AfterAutoHandleStateEvent>(OnMailingState);
|
||||
}
|
||||
|
||||
private void OnMailingState(Entity<MailingUnitComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (UserInterfaceSystem.TryGetOpenUi<MailingUnitBoundUserInterface>(ent.Owner, MailingUnitUiKey.Key, out var bui))
|
||||
{
|
||||
bui.Refresh(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:ui="clr-namespace:Content.Client.Disposal.UI"
|
||||
MinSize="300 400"
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:disposal="clr-namespace:Content.Client.Disposal"
|
||||
MinSize="300 400"
|
||||
SetSize="300 400"
|
||||
Resizable="False">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Orientation="Horizontal" SeparationOverride="8">
|
||||
<Label Text="{Loc 'ui-mailing-unit-target-label'}" />
|
||||
<Label Name="Target"
|
||||
Access="Public"
|
||||
Text="" />
|
||||
</BoxContainer>
|
||||
<ItemList Name="TargetListContainer"
|
||||
@@ -18,14 +20,15 @@
|
||||
</ItemList>
|
||||
<BoxContainer Orientation="Horizontal" SeparationOverride="4">
|
||||
<Label Text="{Loc 'ui-disposal-unit-label-state'}" />
|
||||
<Label Name="UnitState"
|
||||
<Label Name="UnitState" Access="Public"
|
||||
Text="{Loc 'ui-disposal-unit-label-status'}" />
|
||||
</BoxContainer>
|
||||
<Control MinSize="0 5" />
|
||||
<BoxContainer Orientation="Horizontal"
|
||||
SeparationOverride="4">
|
||||
<Label Text="{Loc 'ui-disposal-unit-label-pressure'}" />
|
||||
<ui:PressureBar Name="PressureBar"
|
||||
<disposal:PressureBar Name="PressureBar"
|
||||
Access="Public"
|
||||
MinSize="190 20"
|
||||
HorizontalAlignment="Right"
|
||||
MinValue="0"
|
||||
@@ -50,4 +53,4 @@
|
||||
StyleClasses="OpenLeft" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
</controls:FancyWindow>
|
||||
27
Content.Client/Disposal/Mailing/MailingUnitWindow.xaml.cs
Normal file
27
Content.Client/Disposal/Mailing/MailingUnitWindow.xaml.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Disposal.Mailing
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="Shared.Disposal.Components.MailingUnitComponent"/>
|
||||
/// </summary>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class MailingUnitWindow : FancyWindow
|
||||
{
|
||||
public TimeSpan FullPressure;
|
||||
|
||||
public MailingUnitWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
PressureBar.UpdatePressure(FullPressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using Content.Shared.Disposal;
|
||||
using Content.Shared.Disposal.Unit;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Disposal.UI;
|
||||
namespace Content.Client.Disposal;
|
||||
|
||||
public sealed class PressureBar : ProgressBar
|
||||
{
|
||||
@@ -1,187 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Disposal;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.DragDrop;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
|
||||
|
||||
namespace Content.Client.Disposal.Systems;
|
||||
|
||||
public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
|
||||
private const string AnimationKey = "disposal_unit_animation";
|
||||
|
||||
private const string DefaultFlushState = "disposal-flush";
|
||||
private const string DefaultChargeState = "disposal-charging";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DisposalUnitComponent, ComponentHandleState>(OnHandleState);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, PreventCollideEvent>(OnPreventCollide);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, CanDropTargetEvent>(OnCanDragDropOn);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, GotEmaggedEvent>(OnEmagged);
|
||||
|
||||
SubscribeLocalEvent<DisposalUnitComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
}
|
||||
|
||||
private void OnHandleState(EntityUid uid, DisposalUnitComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not DisposalUnitComponentState state)
|
||||
return;
|
||||
|
||||
component.FlushSound = state.FlushSound;
|
||||
component.State = state.State;
|
||||
component.NextPressurized = state.NextPressurized;
|
||||
component.AutomaticEngageTime = state.AutomaticEngageTime;
|
||||
component.NextFlush = state.NextFlush;
|
||||
component.Powered = state.Powered;
|
||||
component.Engaged = state.Engaged;
|
||||
component.RecentlyEjected.Clear();
|
||||
component.RecentlyEjected.AddRange(EnsureEntityList<DisposalUnitComponent>(state.RecentlyEjected, uid));
|
||||
}
|
||||
|
||||
public override bool HasDisposals(EntityUid? uid)
|
||||
{
|
||||
return HasComp<DisposalUnitComponent>(uid);
|
||||
}
|
||||
|
||||
public override bool ResolveDisposals(EntityUid uid, [NotNullWhen(true)] ref SharedDisposalUnitComponent? component)
|
||||
{
|
||||
if (component != null)
|
||||
return true;
|
||||
|
||||
TryComp<DisposalUnitComponent>(uid, out var storage);
|
||||
component = storage;
|
||||
return component != null;
|
||||
}
|
||||
|
||||
public override void DoInsertDisposalUnit(EntityUid uid, EntityUid toInsert, EntityUid user, SharedDisposalUnitComponent? disposal = null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void OnComponentInit(EntityUid uid, SharedDisposalUnitComponent sharedDisposalUnit, ComponentInit args)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite) || !TryComp<AppearanceComponent>(uid, out var appearance))
|
||||
return;
|
||||
|
||||
UpdateState(uid, sharedDisposalUnit, sprite, appearance);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, SharedDisposalUnitComponent unit, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
UpdateState(uid, unit, args.Sprite, args.Component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update visuals and tick animation
|
||||
/// </summary>
|
||||
private void UpdateState(EntityUid uid, SharedDisposalUnitComponent unit, SpriteComponent sprite, AppearanceComponent appearance)
|
||||
{
|
||||
if (!_appearanceSystem.TryGetData<VisualState>(uid, Visuals.VisualState, out var state, appearance))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Unanchored, state == VisualState.UnAnchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Base, state == VisualState.Anchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFlush, state is VisualState.OverlayFlushing or VisualState.OverlayCharging);
|
||||
|
||||
var chargingState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.BaseCharging, out var chargingLayer)
|
||||
? sprite.LayerGetState(chargingLayer)
|
||||
: new RSI.StateId(DefaultChargeState);
|
||||
|
||||
// This is a transient state so not too worried about replaying in range.
|
||||
if (state == VisualState.OverlayFlushing)
|
||||
{
|
||||
if (!_animationSystem.HasRunningAnimation(uid, AnimationKey))
|
||||
{
|
||||
var flushState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.OverlayFlush, out var flushLayer)
|
||||
? sprite.LayerGetState(flushLayer)
|
||||
: new RSI.StateId(DefaultFlushState);
|
||||
|
||||
// Setup the flush animation to play
|
||||
var anim = new Animation
|
||||
{
|
||||
Length = unit.FlushDelay,
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackSpriteFlick
|
||||
{
|
||||
LayerKey = DisposalUnitVisualLayers.OverlayFlush,
|
||||
KeyFrames =
|
||||
{
|
||||
// Play the flush animation
|
||||
new AnimationTrackSpriteFlick.KeyFrame(flushState, 0),
|
||||
// Return to base state (though, depending on how the unit is
|
||||
// configured we might get an appearance change event telling
|
||||
// us to go to charging state)
|
||||
new AnimationTrackSpriteFlick.KeyFrame(chargingState, (float) unit.FlushDelay.TotalSeconds)
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
if (unit.FlushSound != null)
|
||||
{
|
||||
anim.AnimationTracks.Add(
|
||||
new AnimationTrackPlaySound
|
||||
{
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackPlaySound.KeyFrame(_audioSystem.ResolveSound(unit.FlushSound), 0)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_animationSystem.Play(uid, anim, AnimationKey);
|
||||
}
|
||||
}
|
||||
else if (state == VisualState.OverlayCharging)
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.OverlayFlush, chargingState);
|
||||
else
|
||||
_animationSystem.Stop(uid, AnimationKey);
|
||||
|
||||
if (!_appearanceSystem.TryGetData<HandleState>(uid, Visuals.Handle, out var handleState, appearance))
|
||||
handleState = HandleState.Normal;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayEngaged, handleState != HandleState.Normal);
|
||||
|
||||
if (!_appearanceSystem.TryGetData<LightStates>(uid, Visuals.Light, out var lightState, appearance))
|
||||
lightState = LightStates.Off;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayCharging,
|
||||
(lightState & LightStates.Charging) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayReady,
|
||||
(lightState & LightStates.Ready) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFull,
|
||||
(lightState & LightStates.Full) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
public enum DisposalUnitVisualLayers : byte
|
||||
{
|
||||
Unanchored,
|
||||
Base,
|
||||
BaseCharging,
|
||||
OverlayFlush,
|
||||
OverlayCharging,
|
||||
OverlayReady,
|
||||
OverlayFull,
|
||||
OverlayEngaged
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
namespace Content.Client.Disposal.Tube
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="DisposalRouterWindow"/> and updates it when new server messages are received.
|
||||
@@ -1,11 +1,10 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
namespace Content.Client.Disposal.Tube
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="SharedDisposalRouterComponent"/>
|
||||
@@ -1,9 +1,8 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
namespace Content.Client.Disposal.Tube
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="DisposalTaggerWindow"/> and updates it when new server messages are received.
|
||||
@@ -1,11 +1,10 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
namespace Content.Client.Disposal.Tube
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="SharedDisposalTaggerComponent"/>
|
||||
8
Content.Client/Disposal/Tube/DisposalTubeSystem.cs
Normal file
8
Content.Client/Disposal/Tube/DisposalTubeSystem.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Content.Shared.Disposal.Unit;
|
||||
|
||||
namespace Content.Client.Disposal.Tube;
|
||||
|
||||
public sealed class DisposalTubeSystem : SharedDisposalTubeSystem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
using Content.Client.Disposal.Systems;
|
||||
using Content.Shared.Disposal;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="MailingUnitWindow"/> or a <see cref="DisposalUnitWindow"/> and updates it when new server messages are received.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed class DisposalUnitBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
// What are you doing here
|
||||
[ViewVariables]
|
||||
public MailingUnitWindow? MailingUnitWindow;
|
||||
|
||||
[ViewVariables]
|
||||
public DisposalUnitWindow? DisposalUnitWindow;
|
||||
|
||||
public DisposalUnitBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private void ButtonPressed(UiButton button)
|
||||
{
|
||||
SendMessage(new UiButtonPressedMessage(button));
|
||||
// If we get client-side power stuff then we can predict the button presses but for now we won't as it stuffs
|
||||
// the pressure lerp up.
|
||||
}
|
||||
|
||||
private void TargetSelected(ItemList.ItemListSelectedEventArgs args)
|
||||
{
|
||||
var item = args.ItemList[args.ItemIndex];
|
||||
SendMessage(new TargetSelectedMessage(item.Text));
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
if (UiKey is MailingUnitUiKey)
|
||||
{
|
||||
MailingUnitWindow = new MailingUnitWindow();
|
||||
|
||||
MailingUnitWindow.OpenCenteredRight();
|
||||
MailingUnitWindow.OnClose += Close;
|
||||
|
||||
MailingUnitWindow.Eject.OnPressed += _ => ButtonPressed(UiButton.Eject);
|
||||
MailingUnitWindow.Engage.OnPressed += _ => ButtonPressed(UiButton.Engage);
|
||||
MailingUnitWindow.Power.OnPressed += _ => ButtonPressed(UiButton.Power);
|
||||
|
||||
MailingUnitWindow.TargetListContainer.OnItemSelected += TargetSelected;
|
||||
}
|
||||
else if (UiKey is DisposalUnitUiKey)
|
||||
{
|
||||
DisposalUnitWindow = new DisposalUnitWindow();
|
||||
|
||||
DisposalUnitWindow.OpenCenteredRight();
|
||||
DisposalUnitWindow.OnClose += Close;
|
||||
|
||||
DisposalUnitWindow.Eject.OnPressed += _ => ButtonPressed(UiButton.Eject);
|
||||
DisposalUnitWindow.Engage.OnPressed += _ => ButtonPressed(UiButton.Engage);
|
||||
DisposalUnitWindow.Power.OnPressed += _ => ButtonPressed(UiButton.Power);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not MailingUnitBoundUserInterfaceState && state is not DisposalUnitBoundUserInterfaceState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case MailingUnitBoundUserInterfaceState mailingUnitState:
|
||||
MailingUnitWindow?.UpdateState(mailingUnitState);
|
||||
break;
|
||||
|
||||
case DisposalUnitBoundUserInterfaceState disposalUnitState:
|
||||
DisposalUnitWindow?.UpdateState(disposalUnitState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
MailingUnitWindow?.Dispose();
|
||||
DisposalUnitWindow?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="SharedDisposalUnitComponent"/>
|
||||
/// </summary>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class DisposalUnitWindow : DefaultWindow
|
||||
{
|
||||
public TimeSpan FullPressure;
|
||||
|
||||
public DisposalUnitWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the interface state for the disposals window.
|
||||
/// </summary>
|
||||
/// <returns>true if we should stop updating every frame.</returns>
|
||||
public void UpdateState(DisposalUnitBoundUserInterfaceState state)
|
||||
{
|
||||
Title = state.UnitName;
|
||||
UnitState.Text = state.UnitState;
|
||||
Power.Pressed = state.Powered;
|
||||
Engage.Pressed = state.Engaged;
|
||||
FullPressure = state.FullPressureTime;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
PressureBar.UpdatePressure(FullPressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
using Content.Shared.Disposal;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="MailingUnitComponent"/>
|
||||
/// </summary>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class MailingUnitWindow : DefaultWindow
|
||||
{
|
||||
public TimeSpan FullPressure;
|
||||
|
||||
public MailingUnitWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the interface state for the disposals window.
|
||||
/// </summary>
|
||||
/// <returns>true if we should stop updating every frame.</returns>
|
||||
public bool UpdateState(MailingUnitBoundUserInterfaceState state)
|
||||
{
|
||||
var disposalState = state.DisposalState;
|
||||
|
||||
Title = Loc.GetString("ui-mailing-unit-window-title", ("tag", state.Tag ?? " "));
|
||||
UnitState.Text = disposalState.UnitState;
|
||||
FullPressure = disposalState.FullPressureTime;
|
||||
var pressureReached = PressureBar.UpdatePressure(disposalState.FullPressureTime);
|
||||
Power.Pressed = disposalState.Powered;
|
||||
Engage.Pressed = disposalState.Engaged;
|
||||
|
||||
//UnitTag.Text = state.Tag;
|
||||
Target.Text = state.Target;
|
||||
|
||||
TargetListContainer.Clear();
|
||||
foreach (var target in state.TargetList)
|
||||
{
|
||||
TargetListContainer.AddItem(target);
|
||||
}
|
||||
|
||||
return !disposalState.Powered || pressureReached;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
PressureBar.UpdatePressure(FullPressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using Content.Client.Disposal.Mailing;
|
||||
using Content.Client.Power.EntitySystems;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.Disposal.Unit
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="MailingUnitWindow"/> or a <see cref="_disposalUnitWindow"/> and updates it when new server messages are received.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed class DisposalUnitBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[ViewVariables] private DisposalUnitWindow? _disposalUnitWindow;
|
||||
|
||||
public DisposalUnitBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private void ButtonPressed(DisposalUnitComponent.UiButton button)
|
||||
{
|
||||
SendPredictedMessage(new DisposalUnitComponent.UiButtonPressedMessage(button));
|
||||
// If we get client-side power stuff then we can predict the button presses but for now we won't as it stuffs
|
||||
// the pressure lerp up.
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_disposalUnitWindow = this.CreateWindow<DisposalUnitWindow>();
|
||||
|
||||
_disposalUnitWindow.OpenCenteredRight();
|
||||
|
||||
_disposalUnitWindow.Eject.OnPressed += _ => ButtonPressed(DisposalUnitComponent.UiButton.Eject);
|
||||
_disposalUnitWindow.Engage.OnPressed += _ => ButtonPressed(DisposalUnitComponent.UiButton.Engage);
|
||||
_disposalUnitWindow.Power.OnPressed += _ => ButtonPressed(DisposalUnitComponent.UiButton.Power);
|
||||
|
||||
if (EntMan.TryGetComponent(Owner, out DisposalUnitComponent? component))
|
||||
{
|
||||
Refresh((Owner, component));
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh(Entity<DisposalUnitComponent> entity)
|
||||
{
|
||||
if (_disposalUnitWindow == null)
|
||||
return;
|
||||
|
||||
var disposalSystem = EntMan.System<DisposalUnitSystem>();
|
||||
|
||||
_disposalUnitWindow.Title = EntMan.GetComponent<MetaDataComponent>(entity.Owner).EntityName;
|
||||
|
||||
var state = disposalSystem.GetState(entity.Owner, entity.Comp);
|
||||
|
||||
_disposalUnitWindow.UnitState.Text = Loc.GetString($"disposal-unit-state-{state}");
|
||||
_disposalUnitWindow.Power.Pressed = EntMan.System<PowerReceiverSystem>().IsPowered(Owner);
|
||||
_disposalUnitWindow.Engage.Pressed = entity.Comp.Engaged;
|
||||
_disposalUnitWindow.FullPressure = disposalSystem.EstimatedFullPressure(entity.Owner, entity.Comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
156
Content.Client/Disposal/Unit/DisposalUnitSystem.cs
Normal file
156
Content.Client/Disposal/Unit/DisposalUnitSystem.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.Disposal.Unit;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
|
||||
namespace Content.Client.Disposal.Unit;
|
||||
|
||||
public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
|
||||
private const string AnimationKey = "disposal_unit_animation";
|
||||
|
||||
private const string DefaultFlushState = "disposal-flush";
|
||||
private const string DefaultChargeState = "disposal-charging";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DisposalUnitComponent, AfterAutoHandleStateEvent>(OnHandleState);
|
||||
|
||||
SubscribeLocalEvent<DisposalUnitComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
}
|
||||
|
||||
private void OnHandleState(EntityUid uid, DisposalUnitComponent component, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
UpdateUI((uid, component));
|
||||
}
|
||||
|
||||
protected override void UpdateUI(Entity<DisposalUnitComponent> entity)
|
||||
{
|
||||
if (_uiSystem.TryGetOpenUi<DisposalUnitBoundUserInterface>(entity.Owner, DisposalUnitComponent.DisposalUnitUiKey.Key, out var bui))
|
||||
{
|
||||
bui.Refresh(entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDisposalInit(Entity<DisposalUnitComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
base.OnDisposalInit(ent, ref args);
|
||||
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite) || !TryComp<AppearanceComponent>(ent, out var appearance))
|
||||
return;
|
||||
|
||||
UpdateState(ent, sprite, appearance);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(Entity<DisposalUnitComponent> ent, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
UpdateState(ent, args.Sprite, args.Component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update visuals and tick animation
|
||||
/// </summary>
|
||||
private void UpdateState(Entity<DisposalUnitComponent> ent, SpriteComponent sprite, AppearanceComponent appearance)
|
||||
{
|
||||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.VisualState>(ent, DisposalUnitComponent.Visuals.VisualState, out var state, appearance))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Unanchored, state == DisposalUnitComponent.VisualState.UnAnchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Base, state == DisposalUnitComponent.VisualState.Anchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFlush, state is DisposalUnitComponent.VisualState.OverlayFlushing or DisposalUnitComponent.VisualState.OverlayCharging);
|
||||
|
||||
var chargingState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.BaseCharging, out var chargingLayer)
|
||||
? sprite.LayerGetState(chargingLayer)
|
||||
: new RSI.StateId(DefaultChargeState);
|
||||
|
||||
// This is a transient state so not too worried about replaying in range.
|
||||
if (state == DisposalUnitComponent.VisualState.OverlayFlushing)
|
||||
{
|
||||
if (!_animationSystem.HasRunningAnimation(ent, AnimationKey))
|
||||
{
|
||||
var flushState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.OverlayFlush, out var flushLayer)
|
||||
? sprite.LayerGetState(flushLayer)
|
||||
: new RSI.StateId(DefaultFlushState);
|
||||
|
||||
// Setup the flush animation to play
|
||||
var anim = new Animation
|
||||
{
|
||||
Length = ent.Comp.FlushDelay,
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackSpriteFlick
|
||||
{
|
||||
LayerKey = DisposalUnitVisualLayers.OverlayFlush,
|
||||
KeyFrames =
|
||||
{
|
||||
// Play the flush animation
|
||||
new AnimationTrackSpriteFlick.KeyFrame(flushState, 0),
|
||||
// Return to base state (though, depending on how the unit is
|
||||
// configured we might get an appearance change event telling
|
||||
// us to go to charging state)
|
||||
new AnimationTrackSpriteFlick.KeyFrame(chargingState, (float) ent.Comp.FlushDelay.TotalSeconds)
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
if (ent.Comp.FlushSound != null)
|
||||
{
|
||||
anim.AnimationTracks.Add(
|
||||
new AnimationTrackPlaySound
|
||||
{
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackPlaySound.KeyFrame(_audioSystem.ResolveSound(ent.Comp.FlushSound), 0)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_animationSystem.Play(ent, anim, AnimationKey);
|
||||
}
|
||||
}
|
||||
else if (state == DisposalUnitComponent.VisualState.OverlayCharging)
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.OverlayFlush, chargingState);
|
||||
else
|
||||
_animationSystem.Stop(ent.Owner, AnimationKey);
|
||||
|
||||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.HandleState>(ent, DisposalUnitComponent.Visuals.Handle, out var handleState, appearance))
|
||||
handleState = DisposalUnitComponent.HandleState.Normal;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayEngaged, handleState != DisposalUnitComponent.HandleState.Normal);
|
||||
|
||||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.LightStates>(ent, DisposalUnitComponent.Visuals.Light, out var lightState, appearance))
|
||||
lightState = DisposalUnitComponent.LightStates.Off;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayCharging,
|
||||
(lightState & DisposalUnitComponent.LightStates.Charging) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayReady,
|
||||
(lightState & DisposalUnitComponent.LightStates.Ready) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFull,
|
||||
(lightState & DisposalUnitComponent.LightStates.Full) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
public enum DisposalUnitVisualLayers : byte
|
||||
{
|
||||
Unanchored,
|
||||
Base,
|
||||
BaseCharging,
|
||||
OverlayFlush,
|
||||
OverlayCharging,
|
||||
OverlayReady,
|
||||
OverlayFull,
|
||||
OverlayEngaged
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:ui="clr-namespace:Content.Client.Disposal.UI"
|
||||
MinSize="300 140"
|
||||
SetSize="300 140"
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:disposal="clr-namespace:Content.Client.Disposal"
|
||||
MinSize="300 140"
|
||||
SetSize="300 160"
|
||||
Resizable="False">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Orientation="Vertical" Margin="10">
|
||||
<BoxContainer Orientation="Horizontal"
|
||||
SeparationOverride="4">
|
||||
<Label Text="{Loc 'ui-disposal-unit-label-state'}" />
|
||||
<Label Name="UnitState"
|
||||
<Label Name="UnitState" Access="Public"
|
||||
Text="{Loc 'ui-disposal-unit-label-status'}" />
|
||||
</BoxContainer>
|
||||
<Control MinSize="0 5" />
|
||||
<BoxContainer Orientation="Horizontal"
|
||||
SeparationOverride="4">
|
||||
<Label Text="{Loc 'ui-disposal-unit-label-pressure'}" />
|
||||
<ui:PressureBar Name="PressureBar"
|
||||
<disposal:PressureBar Name="PressureBar"
|
||||
MinSize="190 20"
|
||||
HorizontalAlignment="Right"
|
||||
MinValue="0"
|
||||
@@ -23,7 +24,7 @@
|
||||
Value="0.5" />
|
||||
</BoxContainer>
|
||||
<Control MinSize="0 10" />
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="Engage"
|
||||
Access="Public"
|
||||
Text="{Loc 'ui-disposal-unit-button-flush'}"
|
||||
@@ -39,4 +40,4 @@
|
||||
StyleClasses="OpenLeft" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
</controls:FancyWindow>
|
||||
28
Content.Client/Disposal/Unit/DisposalUnitWindow.xaml.cs
Normal file
28
Content.Client/Disposal/Unit/DisposalUnitWindow.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Disposal.Unit
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="Shared.Disposal.Components.DisposalUnitComponent"/>
|
||||
/// </summary>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class DisposalUnitWindow : FancyWindow
|
||||
{
|
||||
public TimeSpan FullPressure;
|
||||
|
||||
public DisposalUnitWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
PressureBar.UpdatePressure(FullPressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
|
||||
namespace Content.Client.NetworkConfigurator.Systems;
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Client.Power.Components;
|
||||
using Content.Shared.Power.Components;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Power;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Client.Power.EntitySystems;
|
||||
@@ -26,9 +27,20 @@ public sealed class PowerReceiverSystem : SharedPowerReceiverSystem
|
||||
if (args.Current is not ApcPowerReceiverComponentState state)
|
||||
return;
|
||||
|
||||
var powerChanged = component.Powered != state.Powered;
|
||||
component.Powered = state.Powered;
|
||||
component.NeedsPower = state.NeedsPower;
|
||||
component.PowerDisabled = state.PowerDisabled;
|
||||
// SO client systems can handle it. The main reason for this is we can't guarantee compstate ordering.
|
||||
|
||||
if (powerChanged)
|
||||
RaisePower((uid, component));
|
||||
}
|
||||
|
||||
protected override void RaisePower(Entity<SharedApcPowerReceiverComponent> entity)
|
||||
{
|
||||
var ev = new PowerChangedEvent(entity.Comp.Powered, 0f);
|
||||
RaiseLocalEvent(entity.Owner, ref ev);
|
||||
}
|
||||
|
||||
public override bool ResolveApc(EntityUid entity, [NotNullWhen(true)] ref SharedApcPowerReceiverComponent? component)
|
||||
|
||||
@@ -11,9 +11,6 @@ public sealed class StorageFillVisualizerSystem : VisualizerSystem<StorageFillVi
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
if (!TryComp(uid, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
if (!AppearanceSystem.TryGetData<int>(uid, StorageFillVisuals.FillLevel, out var level, args.Component))
|
||||
return;
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.DeviceNetwork
|
||||
{
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Reflection;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.DeviceNetwork
|
||||
namespace Content.IntegrationTests.Tests.DeviceNetwork;
|
||||
|
||||
[Reflect(false)]
|
||||
public sealed class DeviceNetworkTestSystem : EntitySystem
|
||||
{
|
||||
[Reflect(false)]
|
||||
public sealed class DeviceNetworkTestSystem : EntitySystem
|
||||
public NetworkPayload LastPayload = default;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
public NetworkPayload LastPayload = default;
|
||||
base.Initialize();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<DeviceNetworkComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
||||
}
|
||||
|
||||
SubscribeLocalEvent<DeviceNetworkComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
||||
}
|
||||
public void SendBaselineTestEvent(EntityUid uid)
|
||||
{
|
||||
RaiseLocalEvent(uid, new DeviceNetworkPacketEvent(0, "", 0, "", uid, new NetworkPayload()));
|
||||
}
|
||||
|
||||
public void SendBaselineTestEvent(EntityUid uid)
|
||||
{
|
||||
RaiseLocalEvent(uid, new DeviceNetworkPacketEvent(0, "", 0, "", uid, new NetworkPayload()));
|
||||
}
|
||||
|
||||
private void OnPacketReceived(EntityUid uid, DeviceNetworkComponent component, DeviceNetworkPacketEvent args)
|
||||
{
|
||||
LastPayload = args.Data;
|
||||
}
|
||||
private void OnPacketReceived(EntityUid uid, DeviceNetworkComponent component, DeviceNetworkPacketEvent args)
|
||||
{
|
||||
LastPayload = args.Data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#nullable enable annotations
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Disposal.Tube.Components;
|
||||
using Content.Server.Disposal.Unit.Components;
|
||||
using Content.Server.Disposal.Unit.EntitySystems;
|
||||
using Content.Server.Disposal.Unit;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.Disposal;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using NUnit.Framework;
|
||||
using Content.Shared.Disposal.Tube;
|
||||
using Content.Shared.Disposal.Unit;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Reflection;
|
||||
|
||||
@@ -30,7 +29,6 @@ namespace Content.IntegrationTests.Tests.Disposal
|
||||
{
|
||||
var (_, toInsert, unit) = ev;
|
||||
var insertTransform = EntityManager.GetComponent<TransformComponent>(toInsert);
|
||||
var unitTransform = EntityManager.GetComponent<TransformComponent>(unit);
|
||||
// Not in a tube yet
|
||||
Assert.That(insertTransform.ParentUid, Is.EqualTo(unit));
|
||||
}, after: new[] { typeof(SharedDisposalUnitSystem) });
|
||||
@@ -163,6 +161,8 @@ namespace Content.IntegrationTests.Tests.Disposal
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var xformSystem = entityManager.System<SharedTransformSystem>();
|
||||
var disposalSystem = entityManager.System<DisposalUnitSystem>();
|
||||
var power = entityManager.System<PowerReceiverSystem>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
// Spawn the entities
|
||||
@@ -191,7 +191,7 @@ namespace Content.IntegrationTests.Tests.Disposal
|
||||
xformSystem.AnchorEntity(unitUid, entityManager.GetComponent<TransformComponent>(unitUid));
|
||||
|
||||
// No power
|
||||
Assert.That(unitComponent.Powered, Is.False);
|
||||
Assert.That(power.IsPowered(unitUid), Is.False);
|
||||
|
||||
// Can't insert the trunk or the unit into itself
|
||||
UnitInsertContains(unitUid, unitComponent, false, disposalSystem, disposalUnit, disposalTrunk);
|
||||
@@ -227,9 +227,9 @@ namespace Content.IntegrationTests.Tests.Disposal
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
// Remove power need
|
||||
Assert.That(entityManager.TryGetComponent(disposalUnit, out ApcPowerReceiverComponent power));
|
||||
power!.NeedsPower = false;
|
||||
unitComponent.Powered = true; //Power state changed event doesn't get fired smh
|
||||
Assert.That(entityManager.TryGetComponent(disposalUnit, out ApcPowerReceiverComponent powerComp));
|
||||
power.SetNeedsPower(disposalUnit, false);
|
||||
powerComp.Powered = true;
|
||||
|
||||
// Flush with a mob and an item
|
||||
Flush(disposalUnit, unitComponent, true, disposalSystem, human, wrench);
|
||||
|
||||
@@ -2,7 +2,6 @@ using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Administration.UI;
|
||||
using Content.Server.Disposal.Tube;
|
||||
using Content.Server.Disposal.Tube.Components;
|
||||
using Content.Server.EUI;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Ghost.Roles;
|
||||
@@ -24,7 +23,6 @@ using Content.Shared.Verbs;
|
||||
using Robust.Server.Console;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Server.Atmos.Monitor.Components;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Pinpointer;
|
||||
using Content.Server.Power.Components;
|
||||
|
||||
@@ -17,6 +17,7 @@ using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Timing;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Atmos.Consoles;
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
using Content.Server.Atmos.Monitor.Components;
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.DeviceLinking.Systems;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
@@ -22,8 +19,9 @@ using Content.Shared.Interaction;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Wires;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Player;
|
||||
using System.Linq;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Atmos.Monitor.Systems;
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Server.Atmos.Monitor.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Atmos.Monitor.Systems;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Piping.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
using Content.Server.AlertLevel;
|
||||
using Content.Server.Atmos.Monitor.Components;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.AlertLevel;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Server.Atmos.Monitor.Systems;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Content.Server.Atmos.Monitor.Components;
|
||||
using Content.Server.Atmos.Monitor.Systems;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.Wires;
|
||||
using Content.Shared.Atmos.Monitor.Components;
|
||||
using Content.Shared.Wires;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Atmos.Monitor;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Atmos.Monitor.Systems;
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
@@ -12,8 +10,10 @@ using Content.Shared.Atmos.Piping.Binary.Systems;
|
||||
using Content.Shared.Atmos.Piping.Components;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Atmos.Piping.Binary.EntitySystems
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Server.Atmos.Piping.Binary.Components;
|
||||
using Content.Server.Atmos.Piping.Unary.EntitySystems;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Binary.Components;
|
||||
|
||||
@@ -2,10 +2,7 @@ using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Atmos.Monitor.Systems;
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.Atmos.Piping.Unary.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.NodeContainer;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.Power.Components;
|
||||
@@ -18,7 +15,9 @@ using Content.Shared.UserInterface;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
{
|
||||
|
||||
@@ -3,8 +3,6 @@ using Content.Server.Atmos.Monitor.Systems;
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.Atmos.Piping.Unary.Components;
|
||||
using Content.Server.DeviceLinking.Systems;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
@@ -20,7 +18,9 @@ using Content.Shared.Audio;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Power;
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Atmos.Monitor.Components;
|
||||
using Content.Server.Atmos.Monitor.Systems;
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.Atmos.Piping.Unary.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.NodeContainer;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Unary.Visuals;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Piping.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Visuals;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.PDA;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.CartridgeLoader.Cartridges;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.CartridgeLoader.Cartridges;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.AlertLevel;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Interaction;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Screens.Components;
|
||||
@@ -16,6 +14,7 @@ using Content.Shared.Chat;
|
||||
using Content.Shared.Communications;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
@@ -1,91 +1,8 @@
|
||||
using Content.Shared.Configurable;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Tools.Components;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
using static Content.Shared.Configurable.ConfigurationComponent;
|
||||
|
||||
namespace Content.Server.Configurable;
|
||||
|
||||
public sealed class ConfigurationSystem : EntitySystem
|
||||
public sealed class ConfigurationSystem : SharedConfigurationSystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ConfigurationComponent, ConfigurationUpdatedMessage>(OnUpdate);
|
||||
SubscribeLocalEvent<ConfigurationComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<ConfigurationComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<ConfigurationComponent, ContainerIsInsertingAttemptEvent>(OnInsert);
|
||||
}
|
||||
|
||||
private void OnInteractUsing(EntityUid uid, ConfigurationComponent component, InteractUsingEvent args)
|
||||
{
|
||||
// TODO use activatable ui system
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!_toolSystem.HasQuality(args.Used, component.QualityNeeded))
|
||||
return;
|
||||
|
||||
args.Handled = _uiSystem.TryOpenUi(uid, ConfigurationUiKey.Key, args.User);
|
||||
}
|
||||
|
||||
private void OnStartup(EntityUid uid, ConfigurationComponent component, ComponentStartup args)
|
||||
{
|
||||
UpdateUi(uid, component);
|
||||
}
|
||||
|
||||
private void UpdateUi(EntityUid uid, ConfigurationComponent component)
|
||||
{
|
||||
if (_uiSystem.HasUi(uid, ConfigurationUiKey.Key))
|
||||
_uiSystem.SetUiState(uid, ConfigurationUiKey.Key, new ConfigurationBoundUserInterfaceState(component.Config));
|
||||
}
|
||||
|
||||
private void OnUpdate(EntityUid uid, ConfigurationComponent component, ConfigurationUpdatedMessage args)
|
||||
{
|
||||
foreach (var key in component.Config.Keys)
|
||||
{
|
||||
var value = args.Config.GetValueOrDefault(key);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(value) || component.Validation != null && !component.Validation.IsMatch(value))
|
||||
continue;
|
||||
|
||||
component.Config[key] = value;
|
||||
}
|
||||
|
||||
UpdateUi(uid, component);
|
||||
|
||||
var updatedEvent = new ConfigurationUpdatedEvent(component);
|
||||
RaiseLocalEvent(uid, updatedEvent, false);
|
||||
|
||||
// TODO support float (spinbox) and enum (drop-down) configurations
|
||||
// TODO support verbs.
|
||||
}
|
||||
|
||||
private void OnInsert(EntityUid uid, ConfigurationComponent component, ContainerIsInsertingAttemptEvent args)
|
||||
{
|
||||
if (!_toolSystem.HasQuality(args.EntityUid, component.QualityNeeded))
|
||||
return;
|
||||
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sent when configuration values got changes
|
||||
/// </summary>
|
||||
public sealed class ConfigurationUpdatedEvent : EntityEventArgs
|
||||
{
|
||||
public ConfigurationComponent Configuration;
|
||||
|
||||
public ConfigurationUpdatedEvent(ConfigurationComponent configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Shared.Containers;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Throwing;
|
||||
@@ -52,10 +53,3 @@ public sealed class ThrowInsertContainerSystem : EntitySystem
|
||||
_adminLogger.Add(LogType.Landed, LogImpact.Low, $"{ToPrettyString(args.Thrown)} thrown by {ToPrettyString(args.Component.Thrower.Value):player} landed in {ToPrettyString(ent)}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sent before the insertion is made.
|
||||
/// Allows preventing the insertion if any system on the entity should need to.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct BeforeThrowInsertEvent(EntityUid ThrownEntity, bool Cancelled = false);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Content.Server.DeviceLinking.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.DeviceLinking.Systems;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Server.DeviceLinking.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Doors;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.DeviceLinking.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
|
||||
namespace Content.Server.DeviceLinking.Systems;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Server.DeviceLinking.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Popups;
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Server.DeviceLinking.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
|
||||
namespace Content.Server.DeviceLinking.Systems;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Server.NodeContainer.EntitySystems;
|
||||
using JetBrains.Annotations;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Power.Nodes;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems
|
||||
{
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System.Linq;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
using Content.Shared.Interaction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Map.Events;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using System.Buffers;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Numerics;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
using Content.Shared.Examine;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems
|
||||
@@ -16,7 +16,7 @@ namespace Content.Server.DeviceNetwork.Systems
|
||||
/// Device networking allows machines and devices to communicate with each other while adhering to restrictions like range or being connected to the same powernet.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed class DeviceNetworkSystem : EntitySystem
|
||||
public sealed class DeviceNetworkSystem : SharedDeviceNetworkSystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||
@@ -60,16 +60,7 @@ namespace Content.Server.DeviceNetwork.Systems
|
||||
SwapQueues();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the given payload as a device network packet to the entity with the given address and frequency.
|
||||
/// Addresses are given to the DeviceNetworkComponent of an entity when connecting.
|
||||
/// </summary>
|
||||
/// <param name="uid">The EntityUid of the sending entity</param>
|
||||
/// <param name="address">The address of the entity that the packet gets sent to. If null, the message is broadcast to all devices on that frequency (except the sender)</param>
|
||||
/// <param name="frequency">The frequency to send on</param>
|
||||
/// <param name="data">The data to be sent</param>
|
||||
/// <returns>Returns true when the packet was successfully enqueued.</returns>
|
||||
public bool QueuePacket(EntityUid uid, string? address, NetworkPayload data, uint? frequency = null, int? network = null, DeviceNetworkComponent? device = null)
|
||||
public override bool QueuePacket(EntityUid uid, string? address, NetworkPayload data, uint? frequency = null, int? network = null, DeviceNetworkComponent? device = null)
|
||||
{
|
||||
if (!Resolve(uid, ref device, false))
|
||||
return false;
|
||||
@@ -368,96 +359,4 @@ namespace Content.Server.DeviceNetwork.Systems
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event raised before a device network packet is send.
|
||||
/// Subscribed to by other systems to prevent the packet from being sent.
|
||||
/// </summary>
|
||||
public sealed class BeforePacketSentEvent : CancellableEntityEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The EntityUid of the entity the packet was sent from.
|
||||
/// </summary>
|
||||
public readonly EntityUid Sender;
|
||||
|
||||
public readonly TransformComponent SenderTransform;
|
||||
|
||||
/// <summary>
|
||||
/// The senders current position in world coordinates.
|
||||
/// </summary>
|
||||
public readonly Vector2 SenderPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The network the packet will be sent to.
|
||||
/// </summary>
|
||||
public readonly string NetworkId;
|
||||
|
||||
public BeforePacketSentEvent(EntityUid sender, TransformComponent xform, Vector2 senderPosition, string networkId)
|
||||
{
|
||||
Sender = sender;
|
||||
SenderTransform = xform;
|
||||
SenderPosition = senderPosition;
|
||||
NetworkId = networkId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sent to the sending entity before broadcasting network packets to recipients
|
||||
/// </summary>
|
||||
public sealed class BeforeBroadcastAttemptEvent : CancellableEntityEventArgs
|
||||
{
|
||||
public readonly IReadOnlySet<DeviceNetworkComponent> Recipients;
|
||||
public HashSet<DeviceNetworkComponent>? ModifiedRecipients;
|
||||
|
||||
public BeforeBroadcastAttemptEvent(IReadOnlySet<DeviceNetworkComponent> recipients)
|
||||
{
|
||||
Recipients = recipients;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when a device network packet gets sent.
|
||||
/// </summary>
|
||||
public sealed class DeviceNetworkPacketEvent : EntityEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The id of the network that this packet is being sent on.
|
||||
/// </summary>
|
||||
public int NetId;
|
||||
|
||||
/// <summary>
|
||||
/// The frequency the packet is sent on.
|
||||
/// </summary>
|
||||
public readonly uint Frequency;
|
||||
|
||||
/// <summary>
|
||||
/// Address of the intended recipient. Null if the message was broadcast.
|
||||
/// </summary>
|
||||
public string? Address;
|
||||
|
||||
/// <summary>
|
||||
/// The device network address of the sending entity.
|
||||
/// </summary>
|
||||
public readonly string SenderAddress;
|
||||
|
||||
/// <summary>
|
||||
/// The entity that sent the packet.
|
||||
/// </summary>
|
||||
public EntityUid Sender;
|
||||
|
||||
/// <summary>
|
||||
/// The data that is being sent.
|
||||
/// </summary>
|
||||
public readonly NetworkPayload Data;
|
||||
|
||||
public DeviceNetworkPacketEvent(int netId, string? address, uint frequency, string senderAddress, EntityUid sender, NetworkPayload data)
|
||||
{
|
||||
NetId = netId;
|
||||
Address = address;
|
||||
Frequency = frequency;
|
||||
SenderAddress = senderAddress;
|
||||
Sender = sender;
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Components.Devices;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems.Devices
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.DeviceLinking.Systems;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Database;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.Medical.CrewMonitoring;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems
|
||||
|
||||
@@ -1,204 +1,8 @@
|
||||
using Content.Server.Configurable;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Disposal.Unit.EntitySystems;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.Disposal;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Shared.Disposal.Mailing;
|
||||
|
||||
namespace Content.Server.Disposal.Mailing;
|
||||
|
||||
public sealed class MailingUnitSystem : EntitySystem
|
||||
public sealed class MailingUnitSystem : SharedMailingUnitSystem
|
||||
{
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
|
||||
|
||||
private const string MailTag = "mail";
|
||||
|
||||
private const string TagConfigurationKey = "tag";
|
||||
|
||||
private const string NetTag = "tag";
|
||||
private const string NetSrc = "src";
|
||||
private const string NetTarget = "target";
|
||||
private const string NetCmdSent = "mail_sent";
|
||||
private const string NetCmdRequest = "get_mailer_tag";
|
||||
private const string NetCmdResponse = "mailer_tag";
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<MailingUnitComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<MailingUnitComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
||||
SubscribeLocalEvent<MailingUnitComponent, BeforeDisposalFlushEvent>(OnBeforeFlush);
|
||||
SubscribeLocalEvent<MailingUnitComponent, ConfigurationSystem.ConfigurationUpdatedEvent>(OnConfigurationUpdated);
|
||||
SubscribeLocalEvent<MailingUnitComponent, ActivateInWorldEvent>(HandleActivate, before: new[] { typeof(DisposalUnitSystem) });
|
||||
SubscribeLocalEvent<MailingUnitComponent, DisposalUnitUIStateUpdatedEvent>(OnDisposalUnitUIStateChange);
|
||||
SubscribeLocalEvent<MailingUnitComponent, TargetSelectedMessage>(OnTargetSelected);
|
||||
}
|
||||
|
||||
|
||||
private void OnComponentInit(EntityUid uid, MailingUnitComponent component, ComponentInit args)
|
||||
{
|
||||
UpdateTargetList(uid, component);
|
||||
}
|
||||
|
||||
private void OnPacketReceived(EntityUid uid, MailingUnitComponent component, DeviceNetworkPacketEvent args)
|
||||
{
|
||||
if (!args.Data.TryGetValue(DeviceNetworkConstants.Command, out string? command) || !IsPowered(uid))
|
||||
return;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case NetCmdRequest:
|
||||
SendTagRequestResponse(uid, args, component.Tag);
|
||||
break;
|
||||
case NetCmdResponse when args.Data.TryGetValue(NetTag, out string? tag):
|
||||
//Add the received tag request response to the list of targets
|
||||
component.TargetList.Add(tag);
|
||||
UpdateUserInterface(uid, component);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the given tag as a response to a <see cref="NetCmdRequest"/> if it's not null
|
||||
/// </summary>
|
||||
private void SendTagRequestResponse(EntityUid uid, DeviceNetworkPacketEvent args, string? tag)
|
||||
{
|
||||
if (tag == null)
|
||||
return;
|
||||
|
||||
var payload = new NetworkPayload
|
||||
{
|
||||
[DeviceNetworkConstants.Command] = NetCmdResponse,
|
||||
[NetTag] = tag
|
||||
};
|
||||
|
||||
_deviceNetworkSystem.QueuePacket(uid, args.Address, payload, args.Frequency);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents the unit from flushing if no target is selected
|
||||
/// </summary>
|
||||
private void OnBeforeFlush(EntityUid uid, MailingUnitComponent component, BeforeDisposalFlushEvent args)
|
||||
{
|
||||
if (string.IsNullOrEmpty(component.Target))
|
||||
{
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
args.Tags.Add(MailTag);
|
||||
args.Tags.Add(component.Target);
|
||||
|
||||
BroadcastSentMessage(uid, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcast that a mail was sent including the src and target tags
|
||||
/// </summary>
|
||||
private void BroadcastSentMessage(EntityUid uid, MailingUnitComponent component, DeviceNetworkComponent? device = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(component.Tag) || string.IsNullOrEmpty(component.Target) || !Resolve(uid, ref device))
|
||||
return;
|
||||
|
||||
var payload = new NetworkPayload
|
||||
{
|
||||
[DeviceNetworkConstants.Command] = NetCmdSent,
|
||||
[NetSrc] = component.Tag,
|
||||
[NetTarget] = component.Target
|
||||
};
|
||||
|
||||
_deviceNetworkSystem.QueuePacket(uid, null, payload, null, null, device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the units target list and broadcasts a <see cref="NetCmdRequest"/>.
|
||||
/// The target list will then get populated with <see cref="NetCmdResponse"/> responses from all active mailing units on the same grid
|
||||
/// </summary>
|
||||
private void UpdateTargetList(EntityUid uid, MailingUnitComponent component, DeviceNetworkComponent? device = null)
|
||||
{
|
||||
if (!Resolve(uid, ref device, false))
|
||||
return;
|
||||
|
||||
var payload = new NetworkPayload
|
||||
{
|
||||
[DeviceNetworkConstants.Command] = NetCmdRequest
|
||||
};
|
||||
|
||||
component.TargetList.Clear();
|
||||
_deviceNetworkSystem.QueuePacket(uid, null, payload, null, null, device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called when the units tag got updated
|
||||
/// </summary>
|
||||
private void OnConfigurationUpdated(EntityUid uid, MailingUnitComponent component, ConfigurationSystem.ConfigurationUpdatedEvent args)
|
||||
{
|
||||
var configuration = args.Configuration.Config;
|
||||
if (!configuration.ContainsKey(TagConfigurationKey) || configuration[TagConfigurationKey] == string.Empty)
|
||||
{
|
||||
component.Tag = null;
|
||||
return;
|
||||
}
|
||||
|
||||
component.Tag = configuration[TagConfigurationKey];
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
|
||||
private void HandleActivate(EntityUid uid, MailingUnitComponent component, ActivateInWorldEvent args)
|
||||
{
|
||||
if (args.Handled || !args.Complex)
|
||||
return;
|
||||
|
||||
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
args.Handled = true;
|
||||
UpdateTargetList(uid, component);
|
||||
_userInterfaceSystem.OpenUi(uid, MailingUnitUiKey.Key, actor.PlayerSession);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called when the disposal unit components ui state changes. This is required because the mailing unit requires a disposal unit component and overrides its ui
|
||||
/// </summary>
|
||||
private void OnDisposalUnitUIStateChange(EntityUid uid, MailingUnitComponent component, DisposalUnitUIStateUpdatedEvent args)
|
||||
{
|
||||
component.DisposalUnitInterfaceState = args.State;
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
|
||||
private void UpdateUserInterface(EntityUid uid, MailingUnitComponent component)
|
||||
{
|
||||
if (component.DisposalUnitInterfaceState == null)
|
||||
return;
|
||||
|
||||
var state = new MailingUnitBoundUserInterfaceState(component.DisposalUnitInterfaceState, component.Target, component.TargetList.ShallowClone(), component.Tag);
|
||||
_userInterfaceSystem.SetUiState(uid, MailingUnitUiKey.Key, state);
|
||||
}
|
||||
|
||||
private void OnTargetSelected(EntityUid uid, MailingUnitComponent component, TargetSelectedMessage args)
|
||||
{
|
||||
component.Target = args.Target;
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the unit is powered if an <see cref="ApcPowerReceiverComponent"/> is present
|
||||
/// </summary>
|
||||
/// <returns>True if the power receiver component is powered or not present</returns>
|
||||
private bool IsPowered(EntityUid uid, ApcPowerReceiverComponent? powerReceiver = null)
|
||||
{
|
||||
if (Resolve(uid, ref powerReceiver) && !powerReceiver.Powered)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using Content.Server.Disposal.Unit.EntitySystems;
|
||||
|
||||
namespace Content.Server.Disposal.Tube.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[Access(typeof(DisposalTubeSystem), typeof(DisposalUnitSystem))]
|
||||
public sealed partial class DisposalEntryComponent : Component
|
||||
{
|
||||
public const string HolderPrototypeId = "DisposalHolder";
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Server.Disposal.Tube.Components;
|
||||
namespace Content.Server.Disposal.Tube;
|
||||
|
||||
[RegisterComponent]
|
||||
[Access(typeof(DisposalTubeSystem))]
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Server.Disposal.Tube.Components;
|
||||
namespace Content.Server.Disposal.Tube;
|
||||
|
||||
[RegisterComponent]
|
||||
[Access(typeof(DisposalTubeSystem))]
|
||||
@@ -1,12 +1,6 @@
|
||||
using Content.Server.UserInterface;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Player;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
||||
|
||||
namespace Content.Server.Disposal.Tube.Components
|
||||
namespace Content.Server.Disposal.Tube
|
||||
{
|
||||
[RegisterComponent]
|
||||
[Access(typeof(DisposalTubeSystem))]
|
||||
@@ -1,8 +1,7 @@
|
||||
using Content.Server.Disposal.Tube.Systems;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Disposal.Tube.Components;
|
||||
namespace Content.Server.Disposal.Tube;
|
||||
|
||||
/// <summary>
|
||||
/// Requires <see cref="DisposalJunctionComponent"/> to function.
|
||||
@@ -1,8 +1,7 @@
|
||||
using Content.Server.DeviceLinking.Systems;
|
||||
using Content.Server.Disposal.Tube.Components;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
|
||||
namespace Content.Server.Disposal.Tube.Systems;
|
||||
namespace Content.Server.Disposal.Tube;
|
||||
|
||||
/// <summary>
|
||||
/// Handles signals and the routing get next direction event.
|
||||
@@ -1,13 +1,6 @@
|
||||
using Content.Server.Disposal.Unit.Components;
|
||||
using Content.Server.UserInterface;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Player;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
||||
|
||||
namespace Content.Server.Disposal.Tube.Components
|
||||
namespace Content.Server.Disposal.Tube
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class DisposalTaggerComponent : DisposalTransitComponent
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Server.Disposal.Tube.Components
|
||||
namespace Content.Server.Disposal.Tube
|
||||
{
|
||||
// TODO: Different types of tubes eject in random direction with no exit point
|
||||
[RegisterComponent]
|
||||
@@ -1,9 +1,9 @@
|
||||
using Content.Server.Disposal.Unit.EntitySystems;
|
||||
using Content.Server.Disposal.Unit;
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Server.Disposal.Tube.Components;
|
||||
namespace Content.Server.Disposal.Tube;
|
||||
|
||||
[RegisterComponent]
|
||||
[Access(typeof(DisposalTubeSystem), typeof(DisposableSystem))]
|
||||
@@ -2,12 +2,12 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Construction.Completions;
|
||||
using Content.Server.Disposal.Tube.Components;
|
||||
using Content.Server.Disposal.Unit.Components;
|
||||
using Content.Server.Disposal.Unit.EntitySystems;
|
||||
using Content.Server.Disposal.Unit;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Destructible;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.Disposal.Tube;
|
||||
using Content.Shared.Disposal.Unit;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
@@ -16,12 +16,10 @@ using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Random;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
||||
|
||||
namespace Content.Server.Disposal.Tube
|
||||
{
|
||||
public sealed class DisposalTubeSystem : EntitySystem
|
||||
public sealed class DisposalTubeSystem : SharedDisposalTubeSystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||
@@ -49,8 +47,8 @@ namespace Content.Server.Disposal.Tube
|
||||
SubscribeLocalEvent<DisposalBendComponent, GetDisposalsConnectableDirectionsEvent>(OnGetBendConnectableDirections);
|
||||
SubscribeLocalEvent<DisposalBendComponent, GetDisposalsNextDirectionEvent>(OnGetBendNextDirection);
|
||||
|
||||
SubscribeLocalEvent<DisposalEntryComponent, GetDisposalsConnectableDirectionsEvent>(OnGetEntryConnectableDirections);
|
||||
SubscribeLocalEvent<DisposalEntryComponent, GetDisposalsNextDirectionEvent>(OnGetEntryNextDirection);
|
||||
SubscribeLocalEvent<Shared.Disposal.Tube.DisposalEntryComponent, GetDisposalsConnectableDirectionsEvent>(OnGetEntryConnectableDirections);
|
||||
SubscribeLocalEvent<Shared.Disposal.Tube.DisposalEntryComponent, GetDisposalsNextDirectionEvent>(OnGetEntryNextDirection);
|
||||
|
||||
SubscribeLocalEvent<DisposalJunctionComponent, GetDisposalsConnectableDirectionsEvent>(OnGetJunctionConnectableDirections);
|
||||
SubscribeLocalEvent<DisposalJunctionComponent, GetDisposalsNextDirectionEvent>(OnGetJunctionNextDirection);
|
||||
@@ -64,13 +62,13 @@ namespace Content.Server.Disposal.Tube
|
||||
SubscribeLocalEvent<DisposalTaggerComponent, GetDisposalsConnectableDirectionsEvent>(OnGetTaggerConnectableDirections);
|
||||
SubscribeLocalEvent<DisposalTaggerComponent, GetDisposalsNextDirectionEvent>(OnGetTaggerNextDirection);
|
||||
|
||||
Subs.BuiEvents<DisposalRouterComponent>(DisposalRouterUiKey.Key, subs =>
|
||||
Subs.BuiEvents<DisposalRouterComponent>(SharedDisposalRouterComponent.DisposalRouterUiKey.Key, subs =>
|
||||
{
|
||||
subs.Event<BoundUIOpenedEvent>(OnOpenRouterUI);
|
||||
subs.Event<SharedDisposalRouterComponent.UiActionMessage>(OnUiAction);
|
||||
});
|
||||
|
||||
Subs.BuiEvents<DisposalTaggerComponent>(DisposalTaggerUiKey.Key, subs =>
|
||||
Subs.BuiEvents<DisposalTaggerComponent>(SharedDisposalTaggerComponent.DisposalTaggerUiKey.Key, subs =>
|
||||
{
|
||||
subs.Event<BoundUIOpenedEvent>(OnOpenTaggerUI);
|
||||
subs.Event<SharedDisposalTaggerComponent.UiActionMessage>(OnUiAction);
|
||||
@@ -161,12 +159,12 @@ namespace Content.Server.Disposal.Tube
|
||||
args.Next = previousDF == ev.Connectable[0] ? ev.Connectable[1] : ev.Connectable[0];
|
||||
}
|
||||
|
||||
private void OnGetEntryConnectableDirections(EntityUid uid, DisposalEntryComponent component, ref GetDisposalsConnectableDirectionsEvent args)
|
||||
private void OnGetEntryConnectableDirections(EntityUid uid, Shared.Disposal.Tube.DisposalEntryComponent component, ref GetDisposalsConnectableDirectionsEvent args)
|
||||
{
|
||||
args.Connectable = new[] { Transform(uid).LocalRotation.GetDir() };
|
||||
}
|
||||
|
||||
private void OnGetEntryNextDirection(EntityUid uid, DisposalEntryComponent component, ref GetDisposalsNextDirectionEvent args)
|
||||
private void OnGetEntryNextDirection(EntityUid uid, Shared.Disposal.Tube.DisposalEntryComponent component, ref GetDisposalsNextDirectionEvent args)
|
||||
{
|
||||
// Ejects contents when they come from the same direction the entry is facing.
|
||||
if (args.Holder.PreviousDirectionFrom != Direction.Invalid)
|
||||
@@ -283,10 +281,10 @@ namespace Content.Server.Disposal.Tube
|
||||
|
||||
private void OnOpenTaggerUI(EntityUid uid, DisposalTaggerComponent tagger, BoundUIOpenedEvent args)
|
||||
{
|
||||
if (_uiSystem.HasUi(uid, DisposalTaggerUiKey.Key))
|
||||
if (_uiSystem.HasUi(uid, SharedDisposalTaggerComponent.DisposalTaggerUiKey.Key))
|
||||
{
|
||||
_uiSystem.SetUiState(uid, DisposalTaggerUiKey.Key,
|
||||
new DisposalTaggerUserInterfaceState(tagger.Tag));
|
||||
_uiSystem.SetUiState(uid, SharedDisposalTaggerComponent.DisposalTaggerUiKey.Key,
|
||||
new SharedDisposalTaggerComponent.DisposalTaggerUserInterfaceState(tagger.Tag));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +296,7 @@ namespace Content.Server.Disposal.Tube
|
||||
{
|
||||
if (router.Tags.Count <= 0)
|
||||
{
|
||||
_uiSystem.SetUiState(uid, DisposalRouterUiKey.Key, new DisposalRouterUserInterfaceState(""));
|
||||
_uiSystem.SetUiState(uid, SharedDisposalRouterComponent.DisposalRouterUiKey.Key, new SharedDisposalRouterComponent.DisposalRouterUserInterfaceState(""));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -312,7 +310,7 @@ namespace Content.Server.Disposal.Tube
|
||||
|
||||
taglist.Remove(taglist.Length - 2, 2);
|
||||
|
||||
_uiSystem.SetUiState(uid, DisposalRouterUiKey.Key, new DisposalRouterUserInterfaceState(taglist.ToString()));
|
||||
_uiSystem.SetUiState(uid, SharedDisposalRouterComponent.DisposalRouterUiKey.Key, new SharedDisposalRouterComponent.DisposalRouterUserInterfaceState(taglist.ToString()));
|
||||
}
|
||||
|
||||
private void OnAnchorChange(EntityUid uid, DisposalTubeComponent component, ref AnchorStateChangedEvent args)
|
||||
@@ -419,13 +417,13 @@ namespace Content.Server.Disposal.Tube
|
||||
_popups.PopupEntity(Loc.GetString("disposal-tube-component-popup-directions-text", ("directions", directions)), tubeId, recipient);
|
||||
}
|
||||
|
||||
public bool TryInsert(EntityUid uid, DisposalUnitComponent from, IEnumerable<string>? tags = default, DisposalEntryComponent? entry = null)
|
||||
public override bool TryInsert(EntityUid uid, DisposalUnitComponent from, IEnumerable<string>? tags = default, DisposalEntryComponent? entry = null)
|
||||
{
|
||||
if (!Resolve(uid, ref entry))
|
||||
return false;
|
||||
|
||||
var xform = Transform(uid);
|
||||
var holder = Spawn(DisposalEntryComponent.HolderPrototypeId, _transform.GetMapCoordinates(uid, xform: xform));
|
||||
var holder = Spawn(entry.HolderPrototypeId, _transform.GetMapCoordinates(uid, xform: xform));
|
||||
var holderComponent = Comp<DisposalHolderComponent>(holder);
|
||||
|
||||
foreach (var entity in from.Container.ContainedEntities.ToArray())
|
||||
@@ -436,7 +434,7 @@ namespace Content.Server.Disposal.Tube
|
||||
_atmosSystem.Merge(holderComponent.Air, from.Air);
|
||||
from.Air.Clear();
|
||||
|
||||
if (tags != default)
|
||||
if (tags != null)
|
||||
holderComponent.Tags.UnionWith(tags);
|
||||
|
||||
return _disposableSystem.EnterTube(holder, uid, holderComponent);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Server.Disposal.Unit.Components;
|
||||
using Content.Server.Disposal.Unit;
|
||||
|
||||
namespace Content.Server.Disposal.Tube;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Disposal.Tube;
|
||||
using Content.Server.Disposal.Tube.Components;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Server.Disposal.Unit.Components;
|
||||
namespace Content.Server.Disposal.Unit;
|
||||
|
||||
/// <summary>
|
||||
/// A component added to entities that are currently in disposals.
|
||||
@@ -1,8 +1,7 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Disposal.Unit.Components;
|
||||
|
||||
namespace Content.Server.Disposal.Unit.EntitySystems;
|
||||
namespace Content.Server.Disposal.Unit;
|
||||
|
||||
public sealed class BeingDisposedSystem : EntitySystem
|
||||
{
|
||||
@@ -1,13 +0,0 @@
|
||||
using Content.Server.Atmos;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Disposal.Components;
|
||||
|
||||
namespace Content.Server.Disposal.Unit.Components;
|
||||
|
||||
// GasMixture life.
|
||||
[RegisterComponent]
|
||||
public sealed partial class DisposalUnitComponent : SharedDisposalUnitComponent
|
||||
{
|
||||
[DataField("air")]
|
||||
public GasMixture Air = new(Atmospherics.CellVolume);
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Disposal.Tube;
|
||||
using Content.Server.Disposal.Tube.Components;
|
||||
using Content.Server.Disposal.Unit.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Throwing;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
@@ -12,7 +11,7 @@ using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
|
||||
namespace Content.Server.Disposal.Unit.EntitySystems
|
||||
namespace Content.Server.Disposal.Unit
|
||||
{
|
||||
public sealed class DisposableSystem : EntitySystem
|
||||
{
|
||||
@@ -1,9 +1,8 @@
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.Disposal.Tube.Components;
|
||||
using Content.Shared.Atmos;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Server.Disposal.Unit.Components
|
||||
namespace Content.Server.Disposal.Unit
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class DisposalHolderComponent : Component, IGasMixtureHolder
|
||||
44
Content.Server/Disposal/Unit/DisposalUnitSystem.cs
Normal file
44
Content.Server/Disposal/Unit/DisposalUnitSystem.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Destructible;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.Disposal.Unit;
|
||||
using Content.Shared.Explosion;
|
||||
|
||||
namespace Content.Server.Disposal.Unit;
|
||||
|
||||
public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
{
|
||||
[Dependency] private readonly AtmosphereSystem _atmosSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DisposalUnitComponent, DestructionEventArgs>(OnDestruction);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, BeforeExplodeEvent>(OnExploded);
|
||||
}
|
||||
|
||||
protected override void HandleAir(EntityUid uid, DisposalUnitComponent component, TransformComponent xform)
|
||||
{
|
||||
var air = component.Air;
|
||||
var indices = TransformSystem.GetGridTilePositionOrDefault((uid, xform));
|
||||
|
||||
if (_atmosSystem.GetTileMixture(xform.GridUid, xform.MapUid, indices, true) is { Temperature: > 0f } environment)
|
||||
{
|
||||
var transferMoles = 0.1f * (0.25f * Atmospherics.OneAtmosphere * 1.01f - air.Pressure) * air.Volume / (environment.Temperature * Atmospherics.R);
|
||||
|
||||
component.Air = environment.Remove(transferMoles);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestruction(EntityUid uid, DisposalUnitComponent component, DestructionEventArgs args)
|
||||
{
|
||||
TryEjectContents(uid, component);
|
||||
}
|
||||
|
||||
private void OnExploded(Entity<DisposalUnitComponent> ent, ref BeforeExplodeEvent args)
|
||||
{
|
||||
args.Contents.AddRange(ent.Comp.Container.ContainedEntities);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Server.Disposal.Unit.EntitySystems
|
||||
namespace Content.Server.Disposal.Unit
|
||||
{
|
||||
public record DoInsertDisposalUnitEvent(EntityUid? User, EntityUid ToInsert, EntityUid Unit);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Content.Shared.Fax;
|
||||
using Content.Shared.Follower;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Paper;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Fax.AdminUI;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Power.Components;
|
||||
@@ -12,7 +10,7 @@ using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.Emag.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Content.Shared.Fax;
|
||||
using Content.Shared.Fax.Systems;
|
||||
@@ -27,9 +25,9 @@ using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.NameModifier.Components;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Fax;
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ using Robust.Shared.Timing;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Content.Shared.Damage.Systems;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Power;
|
||||
|
||||
namespace Content.Server.Light.EntitySystems
|
||||
|
||||
@@ -2,6 +2,8 @@ using System.Linq;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.PowerCell;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Medical.CrewMonitoring;
|
||||
using Content.Shared.Medical.SuitSensor;
|
||||
using Content.Shared.Pinpointer;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Medical.SuitSensors;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Medical.SuitSensor;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Medical.CrewMonitoring;
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.Access.Systems;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Emp;
|
||||
using Content.Server.Medical.CrewMonitoring;
|
||||
@@ -26,6 +24,7 @@ using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.Medical.SuitSensors;
|
||||
|
||||
|
||||
@@ -2,27 +2,23 @@ using Content.Server.Access.Systems;
|
||||
using Content.Server.AlertLevel;
|
||||
using Content.Server.CartridgeLoader;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.Instruments;
|
||||
using Content.Server.Light.EntitySystems;
|
||||
using Content.Server.PDA.Ringer;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Server.Store.Systems;
|
||||
using Content.Server.Traitor.Uplink;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Light;
|
||||
using Content.Shared.Light.Components;
|
||||
using Content.Shared.Light.EntitySystems;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Shared.Store.Components;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
namespace Content.Server.PDA
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace Content.Server.Power.EntitySystems
|
||||
public sealed class PowerReceiverSystem : SharedPowerReceiverSystem
|
||||
{
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
|
||||
private EntityQuery<ApcPowerReceiverComponent> _recQuery;
|
||||
private EntityQuery<ApcPowerProviderComponent> _provQuery;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.PowerCell;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Radio.EntitySystems;
|
||||
using Content.Shared.Lock;
|
||||
@@ -10,7 +9,7 @@ using Content.Shared.Robotics.Components;
|
||||
using Content.Shared.Robotics.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Timing;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
|
||||
namespace Content.Server.Research.Systems;
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ using Content.Server.AlertLevel;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Screens.Components;
|
||||
@@ -21,6 +19,7 @@ using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Timer = Robust.Shared.Timing.Timer;
|
||||
|
||||
namespace Content.Server.RoundEnd
|
||||
|
||||
@@ -2,6 +2,8 @@ using Content.Shared.TextScreen;
|
||||
using Content.Server.Screens.Components;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
|
||||
@@ -63,7 +65,7 @@ public sealed class ScreenSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Determines if/how a timer packet affects this screen.
|
||||
/// Currently there are 2 broadcast domains: Arrivals, and every other screen.
|
||||
/// Domain is determined by the <see cref="DeviceNetworkComponent.TransmitFrequencyId"/> on each timer.
|
||||
/// Domain is determined by the <see cref="Shared.DeviceNetwork.Components.DeviceNetworkComponent.TransmitFrequencyId"/> on each timer.
|
||||
/// Each broadcast domain is divided into subnets. Screen MapUid determines subnet.
|
||||
/// Subnets are the shuttle, source, and dest. Source/dest change each jump.
|
||||
/// This is required to send different timers to the shuttle/terminal/station.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Events;
|
||||
|
||||
namespace Content.Server.SensorMonitoring;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user