Merge remote-tracking branch 'space-station-14/master' into ed-25-05-2024-upstream

# Conflicts:
#	Content.Server/Atmos/Components/FlammableComponent.cs
#	Content.Shared/Lock/LockSystem.cs
#	Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs
This commit is contained in:
Ed
2024-05-25 18:49:49 +03:00
123 changed files with 1291 additions and 1076 deletions

View File

@@ -1,3 +1,4 @@
using Content.Shared.Alert;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -47,5 +48,12 @@ namespace Content.Server.Abilities.Mime
/// </summary>
[DataField("vowCooldown")]
public TimeSpan VowCooldown = TimeSpan.FromMinutes(5);
[DataField]
public ProtoId<AlertPrototype> VowAlert = "VowOfSilence";
[DataField]
public ProtoId<AlertPrototype> VowBrokenAlert = "VowBroken";
}
}

View File

@@ -1,5 +1,4 @@
using Content.Server.Popups;
using Content.Server.Speech.Muting;
using Content.Shared.Actions;
using Content.Shared.Actions.Events;
using Content.Shared.Alert;
@@ -54,7 +53,7 @@ namespace Content.Server.Abilities.Mime
private void OnComponentInit(EntityUid uid, MimePowersComponent component, ComponentInit args)
{
EnsureComp<MutedComponent>(uid);
_alertsSystem.ShowAlert(uid, AlertType.VowOfSilence);
_alertsSystem.ShowAlert(uid, component.VowAlert);
_actionsSystem.AddAction(uid, ref component.InvisibleWallActionEntity, component.InvisibleWallAction, uid);
}
@@ -115,8 +114,8 @@ namespace Content.Server.Abilities.Mime
mimePowers.VowBroken = true;
mimePowers.VowRepentTime = _timing.CurTime + mimePowers.VowCooldown;
RemComp<MutedComponent>(uid);
_alertsSystem.ClearAlert(uid, AlertType.VowOfSilence);
_alertsSystem.ShowAlert(uid, AlertType.VowBroken);
_alertsSystem.ClearAlert(uid, mimePowers.VowAlert);
_alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert);
_actionsSystem.RemoveAction(uid, mimePowers.InvisibleWallActionEntity);
}
@@ -138,8 +137,8 @@ namespace Content.Server.Abilities.Mime
mimePowers.ReadyToRepent = false;
mimePowers.VowBroken = false;
AddComp<MutedComponent>(uid);
_alertsSystem.ClearAlert(uid, AlertType.VowBroken);
_alertsSystem.ShowAlert(uid, AlertType.VowOfSilence);
_alertsSystem.ClearAlert(uid, mimePowers.VowAlert);
_alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert);
_actionsSystem.AddAction(uid, ref mimePowers.InvisibleWallActionEntity, mimePowers.InvisibleWallAction, uid);
}
}

View File

@@ -40,13 +40,13 @@ namespace Content.Server.Alert.Commands
var alertType = args[0];
var alertsSystem = _e.System<AlertsSystem>();
if (!alertsSystem.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
if (!alertsSystem.TryGet(alertType, out var alert))
{
shell.WriteLine("unrecognized alertType " + alertType);
return;
}
alertsSystem.ClearAlert(attachedEntity, alert.AlertType);
alertsSystem.ClearAlert(attachedEntity, alert.ID);
}
}
}

View File

@@ -41,7 +41,7 @@ namespace Content.Server.Alert.Commands
var alertType = args[0];
var severity = args[1];
var alertsSystem = _e.System<AlertsSystem>();
if (!alertsSystem.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
if (!alertsSystem.TryGet(alertType, out var alert))
{
shell.WriteLine("unrecognized alertType " + alertType);
return;
@@ -53,7 +53,7 @@ namespace Content.Server.Alert.Commands
}
short? severity1 = sevint == -1 ? null : sevint;
alertsSystem.ShowAlert(attachedEntity, alert.AlertType, severity1, null);
alertsSystem.ShowAlert(attachedEntity, alert.ID, severity1, null);
}
}
}

View File

@@ -1,5 +1,7 @@
using Content.Shared.Alert;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
namespace Content.Server.Atmos.Components
{
@@ -46,5 +48,13 @@ namespace Content.Server.Atmos.Components
[ViewVariables(VVAccess.ReadWrite)]
public bool HasImmunity = false;
[DataField]
public ProtoId<AlertPrototype> HighPressureAlert = "HighPressure";
[DataField]
public ProtoId<AlertPrototype> LowPressureAlert = "LowPressure";
[DataField]
public ProtoId<AlertCategoryPrototype> PressureAlertCategory = "Pressure";
}
}

View File

@@ -1,5 +1,7 @@
using Content.Shared.Alert;
using Content.Shared.Damage;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Prototypes;
namespace Content.Server.Atmos.Components
{
@@ -78,6 +80,9 @@ namespace Content.Server.Atmos.Components
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float FirestackFade = -0.1f;
[DataField]
public ProtoId<AlertPrototype> FireAlert = "Fire";
/// <summary>
/// CrystallPunk fireplace fuel
/// </summary>

View File

@@ -245,7 +245,7 @@ namespace Content.Server.Atmos.EntitySystems
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking low pressure damage");
}
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 2);
_alertsSystem.ShowAlert(uid, barotrauma.LowPressureAlert, 2);
}
else if (pressure >= Atmospherics.HazardHighPressure)
{
@@ -260,7 +260,7 @@ namespace Content.Server.Atmos.EntitySystems
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage");
}
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 2);
_alertsSystem.ShowAlert(uid, barotrauma.HighPressureAlert, 2);
}
else
{
@@ -275,13 +275,13 @@ namespace Content.Server.Atmos.EntitySystems
switch (pressure)
{
case <= Atmospherics.WarningLowPressure:
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 1);
_alertsSystem.ShowAlert(uid, barotrauma.LowPressureAlert, 1);
break;
case >= Atmospherics.WarningHighPressure:
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 1);
_alertsSystem.ShowAlert(uid, barotrauma.HighPressureAlert, 1);
break;
default:
_alertsSystem.ClearAlertCategory(uid, AlertCategory.Pressure);
_alertsSystem.ClearAlertCategory(uid, barotrauma.PressureAlertCategory);
break;
}
}

View File

@@ -427,11 +427,11 @@ namespace Content.Server.Atmos.EntitySystems
if (!flammable.OnFire)
{
_alertsSystem.ClearAlert(uid, AlertType.Fire);
_alertsSystem.ClearAlert(uid, flammable.FireAlert);
continue;
}
_alertsSystem.ShowAlert(uid, AlertType.Fire);
_alertsSystem.ShowAlert(uid, flammable.FireAlert);
if (flammable.FireStacks > 0)
{

View File

@@ -1,5 +1,6 @@
using Content.Server.Body.Systems;
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Alert;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
@@ -171,5 +172,8 @@ namespace Content.Server.Body.Components
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan StatusTime;
[DataField]
public ProtoId<AlertPrototype> BleedingAlert = "Bleed";
}
}

View File

@@ -1,3 +1,6 @@
using Content.Shared.Alert;
using Robust.Shared.Prototypes;
namespace Content.Server.Body.Components
{
/// <summary>
@@ -18,5 +21,8 @@ namespace Content.Server.Body.Components
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(3);
[DataField]
public ProtoId<AlertPrototype> InternalsAlert = "Internals";
}
}

View File

@@ -1,8 +1,8 @@
using Content.Server.Atmos;
using Content.Server.Body.Systems;
using Content.Shared.Alert;
using Content.Shared.Atmos;
using Content.Shared.Chemistry.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.Body.Components;
@@ -33,5 +33,5 @@ public sealed partial class LungComponent : Component
/// The type of gas this lung needs. Used only for the breathing alerts, not actual metabolism.
/// </summary>
[DataField]
public AlertType Alert = AlertType.LowOxygen;
public ProtoId<AlertPrototype> Alert = "LowOxygen";
}

View File

@@ -392,11 +392,11 @@ public sealed class BloodstreamSystem : EntitySystem
component.BleedAmount = Math.Clamp(component.BleedAmount, 0, component.MaxBleedAmount);
if (component.BleedAmount == 0)
_alertsSystem.ClearAlert(uid, AlertType.Bleed);
_alertsSystem.ClearAlert(uid, component.BleedingAlert);
else
{
var severity = (short) Math.Clamp(Math.Round(component.BleedAmount, MidpointRounding.ToZero), 0, 10);
_alertsSystem.ShowAlert(uid, AlertType.Bleed, severity);
_alertsSystem.ShowAlert(uid, component.BleedingAlert, severity);
}
return true;

View File

@@ -144,12 +144,12 @@ public sealed class InternalsSystem : EntitySystem
private void OnInternalsStartup(Entity<InternalsComponent> ent, ref ComponentStartup args)
{
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
}
private void OnInternalsShutdown(Entity<InternalsComponent> ent, ref ComponentShutdown args)
{
_alerts.ClearAlert(ent, AlertType.Internals);
_alerts.ClearAlert(ent, ent.Comp.InternalsAlert);
}
private void OnInhaleLocation(Entity<InternalsComponent> ent, ref InhaleLocationEvent args)
@@ -159,7 +159,7 @@ public sealed class InternalsSystem : EntitySystem
var gasTank = Comp<GasTankComponent>(ent.Comp.GasTankEntity!.Value);
args.Gas = _gasTank.RemoveAirVolume((ent.Comp.GasTankEntity.Value, gasTank), Atmospherics.BreathVolume);
// TODO: Should listen to gas tank updates instead I guess?
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
}
}
public void DisconnectBreathTool(Entity<InternalsComponent> ent)
@@ -173,7 +173,7 @@ public sealed class InternalsSystem : EntitySystem
DisconnectTank(ent);
}
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
}
public void ConnectBreathTool(Entity<InternalsComponent> ent, EntityUid toolEntity)
@@ -184,7 +184,7 @@ public sealed class InternalsSystem : EntitySystem
}
ent.Comp.BreathToolEntity = toolEntity;
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
}
public void DisconnectTank(InternalsComponent? component)
@@ -196,7 +196,7 @@ public sealed class InternalsSystem : EntitySystem
_gasTank.DisconnectFromInternals((component.GasTankEntity.Value, tank));
component.GasTankEntity = null;
_alerts.ShowAlert(component.Owner, AlertType.Internals, GetSeverity(component));
_alerts.ShowAlert(component.Owner, component.InternalsAlert, GetSeverity(component));
}
public bool TryConnectTank(Entity<InternalsComponent> ent, EntityUid tankEntity)
@@ -208,7 +208,7 @@ public sealed class InternalsSystem : EntitySystem
_gasTank.DisconnectFromInternals((ent.Comp.GasTankEntity.Value, tank));
ent.Comp.GasTankEntity = tankEntity;
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
return true;
}

View File

@@ -10,8 +10,8 @@ public sealed partial class AdjustAlert : ReagentEffect
/// <summary>
/// The specific Alert that will be adjusted
/// </summary>
[DataField("alertType", required: true)]
public AlertType Type;
[DataField(required: true)]
public ProtoId<AlertPrototype> AlertType;
/// <summary>
/// If true, the alert is removed after Time seconds. If Time was not specified the alert is removed immediately.
@@ -42,7 +42,7 @@ public sealed partial class AdjustAlert : ReagentEffect
if (Clear && Time <= 0)
{
alertSys.ClearAlert(args.SolutionEntity, Type);
alertSys.ClearAlert(args.SolutionEntity, AlertType);
}
else
{
@@ -52,7 +52,7 @@ public sealed partial class AdjustAlert : ReagentEffect
if ((ShowCooldown || Clear) && Time > 0)
cooldown = (timing.CurTime, timing.CurTime + TimeSpan.FromSeconds(Time));
alertSys.ShowAlert(args.SolutionEntity, Type, cooldown: cooldown, autoRemove: Clear, showCooldown: ShowCooldown);
alertSys.ShowAlert(args.SolutionEntity, AlertType, cooldown: cooldown, autoRemove: Clear, showCooldown: ShowCooldown);
}
}

View File

@@ -29,11 +29,11 @@ public sealed class MagbootsSystem : SharedMagbootsSystem
if (state)
{
_alerts.ShowAlert(parent, AlertType.Magboots);
_alerts.ShowAlert(parent, component.MagbootsAlert);
}
else
{
_alerts.ClearAlert(parent, AlertType.Magboots);
_alerts.ClearAlert(parent, component.MagbootsAlert);
}
}

View File

@@ -24,6 +24,7 @@ public sealed class ConfigurationSystem : EntitySystem
private void OnInteractUsing(EntityUid uid, ConfigurationComponent component, InteractUsingEvent args)
{
// TODO use activatable ui system
if (args.Handled)
return;

View File

@@ -1,67 +1,54 @@
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Monitor.Systems;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Shuttles.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Doors;
using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Popups;
using Content.Shared.Prying.Components;
using Robust.Shared.Map.Components;
namespace Content.Server.Doors.Systems
{
public sealed class FirelockSystem : EntitySystem
public sealed class FirelockSystem : SharedFirelockSystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedDoorSystem _doorSystem = default!;
[Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!;
[Dependency] private readonly AtmosphereSystem _atmosSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
[Dependency] private readonly SharedMapSystem _mapping = default!;
private static float _visualUpdateInterval = 0.5f;
private float _accumulatedFrameTime;
private const int UpdateInterval = 30;
private int _accumulatedTicks;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FirelockComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
SubscribeLocalEvent<FirelockComponent, GetPryTimeModifierEvent>(OnDoorGetPryTimeModifier);
SubscribeLocalEvent<FirelockComponent, DoorStateChangedEvent>(OnUpdateState);
SubscribeLocalEvent<FirelockComponent, BeforeDoorAutoCloseEvent>(OnBeforeDoorAutoclose);
SubscribeLocalEvent<FirelockComponent, AtmosAlarmEvent>(OnAtmosAlarm);
// Visuals
SubscribeLocalEvent<FirelockComponent, MapInitEvent>(UpdateVisuals);
SubscribeLocalEvent<FirelockComponent, ComponentStartup>(UpdateVisuals);
SubscribeLocalEvent<FirelockComponent, PowerChangedEvent>(PowerChanged);
}
private void PowerChanged(EntityUid uid, FirelockComponent component, ref PowerChangedEvent args)
{
// TODO this should REALLLLY not be door specific appearance thing.
_appearance.SetData(uid, DoorVisuals.Powered, args.Powered);
component.Powered = args.Powered;
Dirty(uid, component);
}
#region Visuals
private void UpdateVisuals(EntityUid uid, FirelockComponent component, EntityEventArgs args) => UpdateVisuals(uid, component);
public override void Update(float frameTime)
{
_accumulatedFrameTime += frameTime;
if (_accumulatedFrameTime < _visualUpdateInterval)
_accumulatedTicks += 1;
if (_accumulatedTicks < UpdateInterval)
return;
_accumulatedFrameTime -= _visualUpdateInterval;
_accumulatedTicks = 0;
var airtightQuery = GetEntityQuery<AirtightComponent>();
var appearanceQuery = GetEntityQuery<AppearanceComponent>();
@@ -84,107 +71,13 @@ namespace Content.Server.Doors.Systems
{
var (fire, pressure) = CheckPressureAndFire(uid, firelock, xform, airtight, airtightQuery);
_appearance.SetData(uid, DoorVisuals.ClosedLights, fire || pressure, appearance);
firelock.Temperature = fire;
firelock.Pressure = pressure;
Dirty(uid, firelock);
}
}
}
private void UpdateVisuals(EntityUid uid,
FirelockComponent? firelock = null,
DoorComponent? door = null,
AirtightComponent? airtight = null,
AppearanceComponent? appearance = null,
TransformComponent? xform = null)
{
if (!Resolve(uid, ref door, ref appearance, false))
return;
// only bother to check pressure on doors that are some variation of closed.
if (door.State != DoorState.Closed
&& door.State != DoorState.Welded
&& door.State != DoorState.Denying)
{
_appearance.SetData(uid, DoorVisuals.ClosedLights, false, appearance);
return;
}
var query = GetEntityQuery<AirtightComponent>();
if (!Resolve(uid, ref firelock, ref airtight, ref appearance, ref xform, false) || !query.Resolve(uid, ref airtight, false))
return;
var (fire, pressure) = CheckPressureAndFire(uid, firelock, xform, airtight, query);
_appearance.SetData(uid, DoorVisuals.ClosedLights, fire || pressure, appearance);
}
#endregion
public bool EmergencyPressureStop(EntityUid uid, FirelockComponent? firelock = null, DoorComponent? door = null)
{
if (!Resolve(uid, ref firelock, ref door))
return false;
if (door.State == DoorState.Open)
{
if (_doorSystem.TryClose(uid, door))
{
return _doorSystem.OnPartialClose(uid, door);
}
}
return false;
}
private void OnBeforeDoorOpened(EntityUid uid, FirelockComponent component, BeforeDoorOpenedEvent args)
{
// Give the Door remote the ability to force a firelock open even if it is holding back dangerous gas
var overrideAccess = (args.User != null) && _accessReaderSystem.IsAllowed(args.User.Value, uid);
if (!this.IsPowered(uid, EntityManager) || (!overrideAccess && IsHoldingPressureOrFire(uid, component)))
args.Cancel();
}
private void OnDoorGetPryTimeModifier(EntityUid uid, FirelockComponent component, ref GetPryTimeModifierEvent args)
{
var state = CheckPressureAndFire(uid, component);
if (state.Fire)
{
_popupSystem.PopupEntity(Loc.GetString("firelock-component-is-holding-fire-message"),
uid, args.User, PopupType.MediumCaution);
}
else if (state.Pressure)
{
_popupSystem.PopupEntity(Loc.GetString("firelock-component-is-holding-pressure-message"),
uid, args.User, PopupType.MediumCaution);
}
if (state.Fire || state.Pressure)
args.PryTimeModifier *= component.LockedPryTimeModifier;
}
private void OnUpdateState(EntityUid uid, FirelockComponent component, DoorStateChangedEvent args)
{
var ev = new BeforeDoorAutoCloseEvent();
RaiseLocalEvent(uid, ev);
UpdateVisuals(uid, component, args);
if (ev.Cancelled)
{
return;
}
_doorSystem.SetNextStateChange(uid, component.AutocloseDelay);
}
private void OnBeforeDoorAutoclose(EntityUid uid, FirelockComponent component, BeforeDoorAutoCloseEvent args)
{
if (!this.IsPowered(uid, EntityManager))
args.Cancel();
// Make firelocks autoclose, but only if the last alarm type it
// remembers was a danger. This is to prevent people from
// flooding hallways with endless bad air/fire.
if (component.AlarmAutoClose &&
(_atmosAlarmable.TryGetHighestAlert(uid, out var alarm) && alarm != AtmosAlarmType.Danger || alarm == null))
args.Cancel();
}
private void OnAtmosAlarm(EntityUid uid, FirelockComponent component, AtmosAlarmEvent args)
{
if (!this.IsPowered(uid, EntityManager))
@@ -204,12 +97,6 @@ namespace Content.Server.Doors.Systems
}
}
public bool IsHoldingPressureOrFire(EntityUid uid, FirelockComponent firelock)
{
var result = CheckPressureAndFire(uid, firelock);
return result.Pressure || result.Fire;
}
public (bool Pressure, bool Fire) CheckPressureAndFire(EntityUid uid, FirelockComponent firelock)
{
var query = GetEntityQuery<AirtightComponent>();
@@ -234,17 +121,17 @@ namespace Content.Server.Doors.Systems
return (false, false);
}
if (!TryComp(xform.ParentUid, out GridAtmosphereComponent? gridAtmosphere))
if (!HasComp<GridAtmosphereComponent>(xform.ParentUid))
return (false, false);
var grid = Comp<MapGridComponent>(xform.ParentUid);
var pos = grid.CoordinatesToTile(xform.Coordinates);
var pos = _mapping.CoordinatesToTile(xform.ParentUid, grid, xform.Coordinates);
var minPressure = float.MaxValue;
var maxPressure = float.MinValue;
var minTemperature = float.MaxValue;
var maxTemperature = float.MinValue;
bool holdingFire = false;
bool holdingPressure = false;
var holdingFire = false;
var holdingPressure = false;
// We cannot simply use `_atmosSystem.GetAdjacentTileMixtures` because of how the `includeBlocked` option
// works, we want to ignore the firelock's blocking, while including blockers on other tiles.
@@ -284,7 +171,7 @@ namespace Content.Server.Doors.Systems
{
// Is there some airtight entity blocking this direction? If yes, don't include this direction in the
// pressure differential
if (HasAirtightBlocker(grid.GetAnchoredEntities(adjacentPos), dir.GetOpposite(), airtightQuery))
if (HasAirtightBlocker(_mapping.GetAnchoredEntities(xform.ParentUid, grid, adjacentPos), dir.GetOpposite(), airtightQuery))
continue;
var p = gas.Pressure;

View File

@@ -163,8 +163,8 @@ public sealed partial class EnsnareableSystem
public void UpdateAlert(EntityUid target, EnsnareableComponent component)
{
if (!component.IsEnsnared)
_alerts.ClearAlert(target, AlertType.Ensnared);
_alerts.ClearAlert(target, component.EnsnaredAlert);
else
_alerts.ShowAlert(target, AlertType.Ensnared);
_alerts.ShowAlert(target, component.EnsnaredAlert);
}
}

View File

@@ -7,31 +7,6 @@ using Robust.Shared.Player;
namespace Content.Server.Interaction
{
/// <summary>
/// Governs interactions during clicking on entities
/// </summary>
[UsedImplicitly]
public sealed partial class InteractionSystem : SharedInteractionSystem
{
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
public override bool CanAccessViaStorage(EntityUid user, EntityUid target)
{
if (Deleted(target))
return false;
if (!_container.TryGetContainingContainer(target, out var container))
return false;
if (!TryComp(container.Owner, out StorageComponent? storage))
return false;
if (storage.Container?.ID != container.ID)
return false;
// we don't check if the user can access the storage entity itself. This should be handed by the UI system.
return _uiSystem.IsUiOpen(container.Owner, StorageComponent.StorageUiKey.Key, user);
}
}
// TODO Remove Shared prefix
public sealed class InteractionSystem : SharedInteractionSystem;
}

View File

@@ -102,20 +102,23 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
/// </summary>
public void SetSuitPowerAlert(EntityUid uid, SpaceNinjaComponent? comp = null)
{
if (!Resolve(uid, ref comp, false) || comp.Deleted || comp.Suit == null)
if (!Resolve(uid, ref comp, false))
return;
if (comp.Deleted || comp.Suit == null)
{
_alerts.ClearAlert(uid, AlertType.SuitPower);
_alerts.ClearAlert(uid, comp.SuitPowerAlert);
return;
}
if (GetNinjaBattery(uid, out _, out var battery))
{
var severity = ContentHelpers.RoundToLevels(MathF.Max(0f, battery.CurrentCharge), battery.MaxCharge, 8);
_alerts.ShowAlert(uid, AlertType.SuitPower, (short) severity);
_alerts.ShowAlert(uid, comp.SuitPowerAlert, (short) severity);
}
else
{
_alerts.ClearAlert(uid, AlertType.SuitPower);
_alerts.ClearAlert(uid, comp.SuitPowerAlert);
}
}

View File

@@ -141,7 +141,7 @@ public sealed partial class RevenantSystem : EntitySystem
if (TryComp<StoreComponent>(uid, out var store))
_store.UpdateUserInterface(uid, uid, store);
_alerts.ShowAlert(uid, AlertType.Essence);
_alerts.ShowAlert(uid, component.EssenceAlert);
if (component.Essence <= 0)
{

View File

@@ -317,7 +317,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
component.SubscribedPilots.Add(entity);
_alertsSystem.ShowAlert(entity, AlertType.PilotingShuttle);
_alertsSystem.ShowAlert(entity, pilotComponent.PilotingAlert);
pilotComponent.Console = uid;
ActionBlockerSystem.UpdateCanMove(entity);
@@ -339,7 +339,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
if (!helm.SubscribedPilots.Remove(pilotUid))
return;
_alertsSystem.ClearAlert(pilotUid, AlertType.PilotingShuttle);
_alertsSystem.ClearAlert(pilotUid, pilotComponent.PilotingAlert);
_popup.PopupEntity(Loc.GetString("shuttle-pilot-end"), pilotUid, pilotUid);

View File

@@ -84,7 +84,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
private void OnMapInit(EntityUid uid, BorgChassisComponent component, MapInitEvent args)
{
UpdateBatteryAlert(uid);
UpdateBatteryAlert((uid, component));
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
}
@@ -183,7 +183,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
private void OnPowerCellChanged(EntityUid uid, BorgChassisComponent component, PowerCellChangedEvent args)
{
UpdateBatteryAlert(uid);
UpdateBatteryAlert((uid, component));
if (!TryComp<PowerCellDrawComponent>(uid, out var draw))
return;
@@ -256,12 +256,12 @@ public sealed partial class BorgSystem : SharedBorgSystem
args.Cancel();
}
private void UpdateBatteryAlert(EntityUid uid, PowerCellSlotComponent? slotComponent = null)
private void UpdateBatteryAlert(Entity<BorgChassisComponent> ent, PowerCellSlotComponent? slotComponent = null)
{
if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery, slotComponent))
if (!_powerCell.TryGetBatteryFromSlot(ent, out var battery, slotComponent))
{
_alerts.ClearAlert(uid, AlertType.BorgBattery);
_alerts.ShowAlert(uid, AlertType.BorgBatteryNone);
_alerts.ClearAlert(ent, ent.Comp.BatteryAlert);
_alerts.ShowAlert(ent, ent.Comp.NoBatteryAlert);
return;
}
@@ -269,13 +269,13 @@ public sealed partial class BorgSystem : SharedBorgSystem
// we make sure 0 only shows if they have absolutely no battery.
// also account for floating point imprecision
if (chargePercent == 0 && _powerCell.HasDrawCharge(uid, cell: slotComponent))
if (chargePercent == 0 && _powerCell.HasDrawCharge(ent, cell: slotComponent))
{
chargePercent = 1;
}
_alerts.ClearAlert(uid, AlertType.BorgBatteryNone);
_alerts.ShowAlert(uid, AlertType.BorgBattery, chargePercent);
_alerts.ClearAlert(ent, ent.Comp.NoBatteryAlert);
_alerts.ShowAlert(ent, ent.Comp.BatteryAlert, chargePercent);
}
/// <summary>

View File

@@ -28,7 +28,9 @@ public sealed class ImmovableRodRule : StationEventSystem<ImmovableRodRuleCompon
if (proto.TryGetComponent<ImmovableRodComponent>(out var rod) && proto.TryGetComponent<TimedDespawnComponent>(out var despawn))
{
TryFindRandomTile(out _, out _, out _, out var targetCoords);
if (!TryFindRandomTile(out _, out _, out _, out var targetCoords))
return;
var speed = RobustRandom.NextFloat(rod.MinSpeed, rod.MaxSpeed);
var angle = RobustRandom.NextAngle();
var direction = angle.ToVec();

View File

@@ -1,7 +1,9 @@
using Content.Server.Temperature.Systems;
using Content.Shared.Alert;
using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
namespace Content.Server.Temperature.Components;
@@ -78,4 +80,10 @@ public sealed partial class TemperatureComponent : Component
/// </summary>
[DataField]
public bool TakingDamage = false;
[DataField]
public ProtoId<AlertPrototype> HotAlert = "Hot";
[DataField]
public ProtoId<AlertPrototype> ColdAlert = "Cold";
}

View File

@@ -12,6 +12,7 @@ using Content.Shared.Inventory;
using Content.Shared.Rejuvenate;
using Content.Shared.Temperature;
using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.Temperature.Systems;
@@ -33,6 +34,9 @@ public sealed class TemperatureSystem : EntitySystem
private float _accumulatedFrametime;
[ValidatePrototypeId<AlertCategoryPrototype>]
public const string TemperatureAlertCategory = "Temperature";
public override void Initialize()
{
SubscribeLocalEvent<TemperatureComponent, OnTemperatureChangeEvent>(EnqueueDamage);
@@ -184,13 +188,13 @@ public sealed class TemperatureSystem : EntitySystem
private void ServerAlert(EntityUid uid, AlertsComponent status, OnTemperatureChangeEvent args)
{
AlertType type;
ProtoId<AlertPrototype> type;
float threshold;
float idealTemp;
if (!TryComp<TemperatureComponent>(uid, out var temperature))
{
_alerts.ClearAlertCategory(uid, AlertCategory.Temperature);
_alerts.ClearAlertCategory(uid, TemperatureAlertCategory);
return;
}
@@ -207,12 +211,12 @@ public sealed class TemperatureSystem : EntitySystem
if (args.CurrentTemperature <= idealTemp)
{
type = AlertType.Cold;
type = temperature.ColdAlert;
threshold = temperature.ColdDamageThreshold;
}
else
{
type = AlertType.Hot;
type = temperature.HotAlert;
threshold = temperature.HeatDamageThreshold;
}
@@ -234,7 +238,7 @@ public sealed class TemperatureSystem : EntitySystem
break;
case > 0.66f:
_alerts.ClearAlertCategory(uid, AlertCategory.Temperature);
_alerts.ClearAlertCategory(uid, TemperatureAlertCategory);
break;
}
}

View File

@@ -187,15 +187,10 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem
if (session is { } pSession)
{
(targetCoordinates, targetLocalAngle) = _lag.GetCoordinatesAngle(target, pSession);
}
else
{
var xform = Transform(target);
targetCoordinates = xform.Coordinates;
targetLocalAngle = xform.LocalRotation;
return Interaction.InRangeUnobstructed(user, target, targetCoordinates, targetLocalAngle, range);
}
return Interaction.InRangeUnobstructed(user, target, targetCoordinates, targetLocalAngle, range);
return Interaction.InRangeUnobstructed(user, target, range);
}
protected override void DoDamageEffect(List<EntityUid> targets, EntityUid? user, TransformComponent targetXform)