Adds Gas Analyzer (#1591)
* -Started Gas Analyzer -TemperatureHelpers * Formatting * Adds PopupTooltip to NotifyManager * Revert Tooltip fuckery * Gas Analyzer gives proper error messages * Localization * Added a very wip gas analyzer ui * UI works, doesn't look good but hey * Safety checks * Fancy WIP gas mix bar * Gas Color * Gas Amount shows only 2 decimal places * -Made bar full width -Moved gas list into a table -Some gas bar things * IDropped something * Description * -Percentage -Padding * ItemStatus * -Proper Danger Warnings -Added Warning danger state * Pressure unit Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com>
This commit is contained in:
@@ -1,39 +1,190 @@
|
||||
#nullable enable
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Atmos
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class GasAnalyzerComponent : Component, IExamine
|
||||
public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped
|
||||
{
|
||||
public override string Name => "GasAnalyzer";
|
||||
public void Examine(FormattedMessage message, bool inDetailsRange)
|
||||
{
|
||||
if (!inDetailsRange) return;
|
||||
#pragma warning disable 649
|
||||
[Dependency] private IServerNotifyManager _notifyManager = default!;
|
||||
#pragma warning restore 649
|
||||
|
||||
private BoundUserInterface _userInterface = default!;
|
||||
private GasAnalyzerDanger _pressureDanger;
|
||||
private float _timeSinceSync;
|
||||
private const float TimeBetweenSyncs = 10f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
||||
.GetBoundUserInterface(GasAnalyzerUiKey.Key);
|
||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||
}
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
return new GasAnalyzerComponentState(_pressureDanger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this from other components to open the gas analyzer UI.
|
||||
/// </summary>
|
||||
public void OpenInterface(IPlayerSession session)
|
||||
{
|
||||
_userInterface.Open(session);
|
||||
UpdateUserInterface();
|
||||
Resync();
|
||||
}
|
||||
|
||||
public void CloseInterface(IPlayerSession session)
|
||||
{
|
||||
_userInterface.Close(session);
|
||||
Resync();
|
||||
}
|
||||
|
||||
public void Update(float frameTime)
|
||||
{
|
||||
_timeSinceSync += frameTime;
|
||||
if (_timeSinceSync > TimeBetweenSyncs)
|
||||
{
|
||||
Resync();
|
||||
}
|
||||
}
|
||||
|
||||
private void Resync()
|
||||
{
|
||||
// Already get the pressure before Dirty(), because we can't get the EntitySystem in that thread or smth
|
||||
var pressure = 0f;
|
||||
var gam = EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID);
|
||||
var tile = gam?.GetTile(Owner.Transform.GridPosition).Air;
|
||||
if (tile != null)
|
||||
{
|
||||
pressure = tile.Pressure;
|
||||
}
|
||||
|
||||
if (pressure >= Atmospherics.HazardHighPressure || pressure <= Atmospherics.HazardLowPressure)
|
||||
{
|
||||
_pressureDanger = GasAnalyzerDanger.Hazard;
|
||||
}
|
||||
else if (pressure >= Atmospherics.WarningHighPressure || pressure <= Atmospherics.WarningLowPressure)
|
||||
{
|
||||
_pressureDanger = GasAnalyzerDanger.Warning;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pressureDanger = GasAnalyzerDanger.Nominal;
|
||||
}
|
||||
|
||||
Dirty();
|
||||
_timeSinceSync = 0f;
|
||||
}
|
||||
|
||||
private void UpdateUserInterface()
|
||||
{
|
||||
string? error = null;
|
||||
var gam = EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID);
|
||||
|
||||
var tile = gam?.GetTile(Owner.Transform.GridPosition).Air;
|
||||
if (tile == null)
|
||||
{
|
||||
error = "No Atmosphere!";
|
||||
_userInterface.SetState(
|
||||
new GasAnalyzerBoundUserInterfaceState(
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (tile == null) return;
|
||||
|
||||
message.AddText($"Pressure: {tile.Pressure}\n");
|
||||
message.AddText($"Temperature: {tile.Temperature}\n");
|
||||
|
||||
var gases = new List<GasEntry>();
|
||||
for (int i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
||||
{
|
||||
var gas = Atmospherics.GetGas(i);
|
||||
|
||||
if (tile.Gases[i] <= Atmospherics.GasMinMoles) continue;
|
||||
|
||||
message.AddText(gas.Name);
|
||||
message.AddText($"\n Moles: {tile.Gases[i]}\n");
|
||||
gases.Add(new GasEntry(gas.Name, tile.Gases[i], gas.Color));
|
||||
}
|
||||
|
||||
_userInterface.SetState(
|
||||
new GasAnalyzerBoundUserInterfaceState(
|
||||
tile.Pressure,
|
||||
tile.Temperature,
|
||||
gases.ToArray(),
|
||||
error));
|
||||
}
|
||||
|
||||
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg)
|
||||
{
|
||||
var message = serverMsg.Message;
|
||||
switch (message)
|
||||
{
|
||||
case GasAnalyzerRefreshMessage msg:
|
||||
var player = serverMsg.Session.AttachedEntity;
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.TryGetComponent(out IHandsComponent handsComponent))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player,
|
||||
Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
var activeHandEntity = handsComponent.GetActiveHand?.Owner;
|
||||
if (activeHandEntity == null || !activeHandEntity.TryGetComponent(out GasAnalyzerComponent gasAnalyzer))
|
||||
{
|
||||
_notifyManager.PopupMessage(serverMsg.Session.AttachedEntity,
|
||||
serverMsg.Session.AttachedEntity,
|
||||
Loc.GetString("You need a Gas Analyzer in your hand!"));
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateUserInterface();
|
||||
Resync();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.User.TryGetComponent(out IActorComponent actor))
|
||||
{
|
||||
OpenInterface(actor.playerSession);
|
||||
//TODO: show other sprite when ui open?
|
||||
}
|
||||
}
|
||||
|
||||
void IDropped.Dropped(DroppedEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.User.TryGetComponent(out IActorComponent actor))
|
||||
{
|
||||
CloseInterface(actor.playerSession);
|
||||
//TODO: if other sprite is shown, change again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user