Files
tbd-station-14/Content.Server/Atmos/Components/BaseComputerUserInterfaceComponent.cs
Vera Aguilera Puerto a2b737d945 Atmos pipe rework (#3833)
* Initial

* Cleanup a bunch of things

* some changes dunno

* RequireAnchored

* a

* stuff

* more work

* Lots of progress

* delete pipe visualizer

* a

* b

* pipenet and pipenode cleanup

* Fixes

* Adds GasValve

* Adds GasMiner

* Fix stuff, maybe?

* More fixes

* Ignored components on the client

* Adds thermomachine behavior, change a bunch of stuff

* Remove Anchored

* some work, but it's shitcode

* significantly more ECS

* ECS AtmosDevices

* Cleanup

* fix appearance

* when the pipe direction is sus

* Gas tanks and canisters

* pipe anchoring and stuff

* coding is my passion

* Unsafe pipes take longer to unanchor

* turns out we're no longer using eris canisters

* Gas canister inserted tank appearance, improvements

* Work on a bunch of appearances

* Scrubber appearance

* Reorganize AtmosphereSystem.Piping into a bunch of different systems

* Appearance for vent/scrubber/pump turns off when leaving atmosphere

* ThermoMachine appearance

* Cleanup gas tanks

* Remove passive gate unused imports

* remove old canister UI functionality

* PipeNode environment air, make everything use AssumeAir instead of merging manually

* a

* Reorganize atmos to follow new structure

* ?????

* Canister UI, restructure client

* Restructure shared

* Fix build tho

* listen, at least the canister UI works entirely...

* fix build : )

* Atmos device prototypes have names and descriptions

* gas canister ui slider doesn't jitter

* trinary prototypes

* sprite for miners

* ignore components

* fix YAML

* Fix port system doing useless thing

* Fix build

* fix thinking moment

* fix build again because

* canister direction

* pipenode is a word

* GasTank Air will throw on invalid states

* fix build....

* Unhardcode volume pump thresholds

* Volume pump and filter take time into account

* Rename Join/Leave atmosphere events to AtmosDeviceEnabled/Disabled Event

* Gas tank node volume is set by initial mixtuer

* I love node container
2021-06-19 13:25:05 +02:00

139 lines
5.3 KiB
C#

using Content.Server.Power.Components;
using Content.Server.UserInterface;
using Content.Shared.ActionBlocker;
using Content.Shared.Interaction;
using Content.Shared.Notification.Managers;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components
{
/// <summary>
/// This component is used as a base class for classes like SolarControlConsoleComponent.
/// These components operate the server-side logic for the "primary UI" of a computer.
/// That means showing the UI when a user activates it, for example.
/// </summary>
public abstract class BaseComputerUserInterfaceComponent : Component
{
protected readonly object UserInterfaceKey;
[ViewVariables] protected BoundUserInterface? UserInterface => Owner.GetUIOrNull(UserInterfaceKey);
[ViewVariables] public bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
public BaseComputerUserInterfaceComponent(object key)
{
UserInterfaceKey = key;
}
public override void Initialize()
{
base.Initialize();
if (UserInterface != null)
UserInterface.OnReceiveMessage += OnReceiveUIMessageCallback;
}
/// <summary>
/// Internal callback used to grab session and session attached entity before any more work is done.
/// This is so that sessionEntity is always available to checks up and down the line.
/// </summary>
private void OnReceiveUIMessageCallback(ServerBoundUserInterfaceMessage obj)
{
var session = obj.Session;
var sessionEntity = session.AttachedEntity;
if (sessionEntity == null)
return; // No session entity, so we're probably not able to touch this.
OnReceiveUnfilteredUserInterfaceMessage(obj, sessionEntity);
}
/// <summary>
/// Override this to handle messages from the UI before filtering them.
/// Calling base is necessary if you want this class to have any meaning.
/// </summary>
protected void OnReceiveUnfilteredUserInterfaceMessage(ServerBoundUserInterfaceMessage obj, IEntity sessionEntity)
{
// "Across all computers" "anti-cheats" ought to be put here or at some parent level (BaseDeviceUserInterfaceComponent?)
// Determine some facts about the session.
// Powered?
if (!Powered)
{
sessionEntity.PopupMessageCursor(Loc.GetString("base-computer-ui-component-not-powered"));
return; // Not powered, so this computer should probably do nothing.
}
// Can we interact?
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(sessionEntity))
{
sessionEntity.PopupMessageCursor(Loc.GetString("base-computer-ui-component-cannot-interact"));
return;
}
// Good to go!
OnReceiveUserInterfaceMessage(obj);
}
/// <summary>
/// Override this to handle messages from the UI.
/// Calling base is unnecessary.
/// These messages will automatically be blocked if the user shouldn't be able to access this computer, or if the computer has lost power.
/// </summary>
protected virtual void OnReceiveUserInterfaceMessage(ServerBoundUserInterfaceMessage obj)
{
// Nothing!
}
public override void HandleMessage(ComponentMessage message, IComponent? component)
{
base.HandleMessage(message, component);
switch (message)
{
case PowerChangedMessage powerChanged:
PowerReceiverOnOnPowerStateChanged(powerChanged);
break;
}
}
private void PowerReceiverOnOnPowerStateChanged(PowerChangedMessage e)
{
if (!e.Powered)
{
// We need to kick off users who are using it when it loses power.
UserInterface?.CloseAll();
// Now alert subclass.
ComputerLostPower();
}
}
/// <summary>
/// Override this if you want the computer to do something when it loses power (i.e. reset state)
/// All UIs should have been closed by the time this is called.
/// Calling base is unnecessary.
/// </summary>
public virtual void ComputerLostPower()
{
}
/// <summary>
/// This is called from ComputerUIActivatorSystem.
/// Override this to add additional activation conditions of some sort.
/// Calling base runs standard activation logic.
/// *This remains inside the component for overridability.*
/// </summary>
public virtual void ActivateThunk(ActivateInWorldEvent eventArgs)
{
if (!eventArgs.User.TryGetComponent(out ActorComponent? actor))
{
return;
}
if (!Powered)
{
Owner.PopupMessage(eventArgs.User, Loc.GetString("base-computer-ui-component-not-powered"));
return;
}
UserInterface?.Open(actor.PlayerSession);
}
}
}