Merge remote-tracking branch 'upstream/stable' into ed-30-04-2025-upstream-sync

# Conflicts:
#	Content.Client/Parallax/ParallaxControl.cs
#	Content.Client/UserInterface/Systems/Storage/Controls/ItemGridPiece.cs
#	Content.IntegrationTests/Tests/PostMapInitTest.cs
#	Content.Server/Chat/Managers/ChatManager.cs
#	Content.Server/Fluids/EntitySystems/PuddleSystem.Evaporation.cs
#	Content.Server/Labels/Label/LabelSystem.cs
#	Content.Shared/Actions/SharedActionsSystem.cs
#	Content.Shared/Fluids/Components/EvaporationComponent.cs
#	Content.Shared/Labels/EntitySystems/SharedLabelSystem.cs
#	README.md
#	Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml
#	Resources/Prototypes/Maps/Pools/deathmatch.yml
#	Resources/Prototypes/Maps/arenas.yml
This commit is contained in:
Ed
2025-04-30 20:31:50 +03:00
2053 changed files with 113995 additions and 38376 deletions

View File

@@ -13,7 +13,7 @@ namespace Content.Server.Power.Components
[DataField("transferRange")]
public int TransferRange { get; set; } = 3;
[ViewVariables] public List<ExtensionCableReceiverComponent> LinkedReceivers { get; } = new();
[ViewVariables] public List<Entity<ExtensionCableReceiverComponent>> LinkedReceivers { get; } = new();
/// <summary>
/// If <see cref="ExtensionCableReceiverComponent"/>s should consider connecting to this.

View File

@@ -7,7 +7,7 @@ namespace Content.Server.Power.Components
public sealed partial class ExtensionCableReceiverComponent : Component
{
[ViewVariables]
public ExtensionCableProviderComponent? Provider { get; set; }
public Entity<ExtensionCableProviderComponent>? Provider { get; set; }
[ViewVariables]
public bool Connectable = false;

View File

@@ -13,7 +13,7 @@ namespace Content.Server.Power.EntitySystems
[UsedImplicitly]
public sealed class BatterySystem : EntitySystem
{
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize()
{
@@ -92,7 +92,7 @@ namespace Content.Server.Power.EntitySystems
if (comp.AutoRechargePause)
{
if (comp.NextAutoRecharge > Timing.CurTime)
if (comp.NextAutoRecharge > _timing.CurTime)
continue;
}
@@ -179,7 +179,7 @@ namespace Content.Server.Power.EntitySystems
if (value < 0)
value = batteryself.AutoRechargePauseTime;
if (Timing.CurTime + TimeSpan.FromSeconds(value) <= batteryself.NextAutoRecharge)
if (_timing.CurTime + TimeSpan.FromSeconds(value) <= batteryself.NextAutoRecharge)
return;
SetChargeCooldown(uid, batteryself.AutoRechargePauseTime, batteryself);
@@ -194,9 +194,9 @@ namespace Content.Server.Power.EntitySystems
return;
if (value >= 0)
batteryself.NextAutoRecharge = Timing.CurTime + TimeSpan.FromSeconds(value);
batteryself.NextAutoRecharge = _timing.CurTime + TimeSpan.FromSeconds(value);
else
batteryself.NextAutoRecharge = Timing.CurTime;
batteryself.NextAutoRecharge = _timing.CurTime;
}
/// <summary>

View File

@@ -28,17 +28,18 @@ public sealed partial class CableSystem
if (component.CablePrototypeId == null)
return;
if(!TryComp<MapGridComponent>(_transform.GetGrid(args.ClickLocation), out var grid))
if (!TryComp<MapGridComponent>(_transform.GetGrid(args.ClickLocation), out var grid))
return;
var gridUid = _transform.GetGrid(args.ClickLocation)!.Value;
var snapPos = grid.TileIndicesFor(args.ClickLocation);
var tileDef = (ContentTileDefinition) _tileManager[_map.GetTileRef(gridUid, grid,snapPos).Tile.TypeId];
var snapPos = _map.TileIndicesFor((gridUid, grid), args.ClickLocation);
var tileDef = (ContentTileDefinition)_tileManager[_map.GetTileRef(gridUid, grid, snapPos).Tile.TypeId];
if (!tileDef.IsSubFloor || !tileDef.Sturdy)
return;
foreach (var anchored in grid.GetAnchoredEntities(snapPos))
foreach (var anchored in _map.GetAnchoredEntities((gridUid, grid), snapPos))
{
if (TryComp<CableComponent>(anchored, out var wire) && wire.CableType == component.BlockingCableType)
return;
@@ -47,7 +48,7 @@ public sealed partial class CableSystem
if (TryComp<StackComponent>(placer, out var stack) && !_stack.Use(placer, 1, stack))
return;
var newCable = EntityManager.SpawnEntity(component.CablePrototypeId, grid.GridTileToLocal(snapPos));
var newCable = EntityManager.SpawnEntity(component.CablePrototypeId, _map.GridTileToLocal(gridUid, grid, snapPos));
_adminLogger.Add(LogType.Construction, LogImpact.Low,
$"{ToPrettyString(args.User):player} placed {ToPrettyString(newCable):cable} at {Transform(newCable).Coordinates}");
args.Handled = true;

View File

@@ -69,7 +69,7 @@ public sealed partial class CableSystem : EntitySystem
// anchor state can change as a result of deletion (detach to null).
// We don't want to spawn an entity when deleted.
if (!TryLifeStage(uid, out var life) || life >= EntityLifeStage.Terminating)
if (TerminatingOrDeleted(uid))
return;
// This entity should not be un-anchorable. But this can happen if the grid-tile is deleted (RCD, explosion,

View File

@@ -8,6 +8,8 @@ namespace Content.Server.Power.EntitySystems
{
public sealed class ExtensionCableSystem : EntitySystem
{
[Dependency] private readonly SharedMapSystem _map = default!;
public override void Initialize()
{
base.Initialize();
@@ -34,17 +36,17 @@ namespace Content.Server.Power.EntitySystems
return;
provider.TransferRange = range;
ResetReceivers(provider);
ResetReceivers((uid, provider));
}
private void OnProviderStarted(EntityUid uid, ExtensionCableProviderComponent provider, ComponentStartup args)
private void OnProviderStarted(Entity<ExtensionCableProviderComponent> provider, ref ComponentStartup args)
{
Connect(uid, provider);
Connect(provider);
}
private void OnProviderShutdown(EntityUid uid, ExtensionCableProviderComponent provider, ComponentShutdown args)
private void OnProviderShutdown(Entity<ExtensionCableProviderComponent> provider, ref ComponentShutdown args)
{
var xform = Transform(uid);
var xform = Transform(provider);
// If grid deleting no need to update power.
if (HasComp<MapGridComponent>(xform.GridUid) &&
@@ -53,54 +55,54 @@ namespace Content.Server.Power.EntitySystems
return;
}
Disconnect(uid, provider);
Disconnect(provider);
}
private void OnProviderAnchorStateChanged(EntityUid uid, ExtensionCableProviderComponent provider, ref AnchorStateChangedEvent args)
private void OnProviderAnchorStateChanged(Entity<ExtensionCableProviderComponent> provider, ref AnchorStateChangedEvent args)
{
if (args.Anchored)
Connect(uid, provider);
Connect(provider);
else
Disconnect(uid, provider);
Disconnect(provider);
}
private void Connect(EntityUid uid, ExtensionCableProviderComponent provider)
private void Connect(Entity<ExtensionCableProviderComponent> provider)
{
provider.Connectable = true;
provider.Comp.Connectable = true;
foreach (var receiver in FindAvailableReceivers(uid, provider.TransferRange))
foreach (var receiver in FindAvailableReceivers(provider.Owner, provider.Comp.TransferRange))
{
receiver.Comp.Provider?.LinkedReceivers.Remove(receiver);
receiver.Comp.Provider?.Comp.LinkedReceivers.Remove(receiver);
receiver.Comp.Provider = provider;
provider.LinkedReceivers.Add(receiver);
provider.Comp.LinkedReceivers.Add(receiver);
RaiseLocalEvent(receiver, new ProviderConnectedEvent(provider), broadcast: false);
RaiseLocalEvent(uid, new ReceiverConnectedEvent(receiver), broadcast: false);
RaiseLocalEvent(provider, new ReceiverConnectedEvent(receiver), broadcast: false);
}
}
private void Disconnect(EntityUid uid, ExtensionCableProviderComponent provider)
private void Disconnect(Entity<ExtensionCableProviderComponent> provider)
{
// same as OnProviderShutdown
provider.Connectable = false;
provider.Comp.Connectable = false;
ResetReceivers(provider);
}
private void OnProviderReAnchor(EntityUid uid, ExtensionCableProviderComponent component, ref ReAnchorEvent args)
private void OnProviderReAnchor(Entity<ExtensionCableProviderComponent> provider, ref ReAnchorEvent args)
{
Disconnect(uid, component);
Connect(uid, component);
Disconnect(provider);
Connect(provider);
}
private void ResetReceivers(ExtensionCableProviderComponent provider)
private void ResetReceivers(Entity<ExtensionCableProviderComponent> provider)
{
var providerId = provider.Owner;
var receivers = provider.LinkedReceivers.ToArray();
provider.LinkedReceivers.Clear();
var receivers = provider.Comp.LinkedReceivers.ToArray();
provider.Comp.LinkedReceivers.Clear();
foreach (var receiver in receivers)
{
var receiverId = receiver.Owner;
receiver.Provider = null;
receiver.Comp.Provider = null;
RaiseLocalEvent(receiverId, new ProviderDisconnectedEvent(provider), broadcast: false);
RaiseLocalEvent(providerId, new ReceiverDisconnectedEvent((receiverId, receiver)), broadcast: false);
}
@@ -126,7 +128,7 @@ namespace Content.Server.Power.EntitySystems
if (!TryComp(xform.GridUid, out MapGridComponent? grid))
yield break;
var nearbyEntities = grid.GetCellsInSquareArea(coordinates, (int) Math.Ceiling(range / grid.TileSize));
var nearbyEntities = _map.GetCellsInSquareArea(xform.GridUid.Value, grid, coordinates, (int)Math.Ceiling(range / grid.TileSize));
foreach (var entity in nearbyEntities)
{
@@ -162,88 +164,88 @@ namespace Content.Server.Power.EntitySystems
if (provider != null)
{
RaiseLocalEvent(provider.Owner, new ReceiverDisconnectedEvent((uid, receiver)), broadcast: false);
provider.LinkedReceivers.Remove(receiver);
RaiseLocalEvent(provider.Value, new ReceiverDisconnectedEvent((uid, receiver)), broadcast: false);
provider.Value.Comp.LinkedReceivers.Remove((uid, receiver));
}
receiver.ReceptionRange = range;
TryFindAndSetProvider(receiver);
TryFindAndSetProvider((uid, receiver));
}
private void OnReceiverStarted(EntityUid uid, ExtensionCableReceiverComponent receiver, ComponentStartup args)
private void OnReceiverStarted(Entity<ExtensionCableReceiverComponent> receiver, ref ComponentStartup args)
{
if (EntityManager.TryGetComponent(receiver.Owner, out PhysicsComponent? physicsComponent))
{
receiver.Connectable = physicsComponent.BodyType == BodyType.Static;
receiver.Comp.Connectable = physicsComponent.BodyType == BodyType.Static;
}
if (receiver.Provider == null)
if (receiver.Comp.Provider == null)
{
TryFindAndSetProvider(receiver);
}
}
private void OnReceiverShutdown(EntityUid uid, ExtensionCableReceiverComponent receiver, ComponentShutdown args)
private void OnReceiverShutdown(Entity<ExtensionCableReceiverComponent> receiver, ref ComponentShutdown args)
{
Disconnect(uid, receiver);
Disconnect(receiver);
}
private void OnReceiverAnchorStateChanged(EntityUid uid, ExtensionCableReceiverComponent receiver, ref AnchorStateChangedEvent args)
private void OnReceiverAnchorStateChanged(Entity<ExtensionCableReceiverComponent> receiver, ref AnchorStateChangedEvent args)
{
if (args.Anchored)
{
Connect(uid, receiver);
Connect(receiver);
}
else
{
Disconnect(uid, receiver);
Disconnect(receiver);
}
}
private void OnReceiverReAnchor(EntityUid uid, ExtensionCableReceiverComponent receiver, ref ReAnchorEvent args)
private void OnReceiverReAnchor(Entity<ExtensionCableReceiverComponent> receiver, ref ReAnchorEvent args)
{
Disconnect(uid, receiver);
Connect(uid, receiver);
Disconnect(receiver);
Connect(receiver);
}
private void Connect(EntityUid uid, ExtensionCableReceiverComponent receiver)
private void Connect(Entity<ExtensionCableReceiverComponent> receiver)
{
receiver.Connectable = true;
if (receiver.Provider == null)
receiver.Comp.Connectable = true;
if (receiver.Comp.Provider == null)
{
TryFindAndSetProvider(receiver);
}
}
private void Disconnect(EntityUid uid, ExtensionCableReceiverComponent receiver)
private void Disconnect(Entity<ExtensionCableReceiverComponent> receiver)
{
receiver.Connectable = false;
RaiseLocalEvent(uid, new ProviderDisconnectedEvent(receiver.Provider), broadcast: false);
if (receiver.Provider != null)
receiver.Comp.Connectable = false;
RaiseLocalEvent(receiver, new ProviderDisconnectedEvent(receiver.Comp.Provider), broadcast: false);
if (receiver.Comp.Provider != null)
{
RaiseLocalEvent(receiver.Provider.Owner, new ReceiverDisconnectedEvent((uid, receiver)), broadcast: false);
receiver.Provider.LinkedReceivers.Remove(receiver);
RaiseLocalEvent(receiver.Comp.Provider.Value, new ReceiverDisconnectedEvent(receiver), broadcast: false);
receiver.Comp.Provider.Value.Comp.LinkedReceivers.Remove(receiver);
}
receiver.Provider = null;
receiver.Comp.Provider = null;
}
private void TryFindAndSetProvider(ExtensionCableReceiverComponent receiver, TransformComponent? xform = null)
private void TryFindAndSetProvider(Entity<ExtensionCableReceiverComponent> receiver, TransformComponent? xform = null)
{
var uid = receiver.Owner;
if (!receiver.Connectable)
if (!receiver.Comp.Connectable)
return;
if (!TryFindAvailableProvider(uid, receiver.ReceptionRange, out var provider, xform))
if (!TryFindAvailableProvider(uid, receiver.Comp.ReceptionRange, out var provider, xform))
return;
receiver.Provider = provider;
provider.LinkedReceivers.Add(receiver);
receiver.Comp.Provider = provider;
provider.Value.Comp.LinkedReceivers.Add(receiver);
RaiseLocalEvent(uid, new ProviderConnectedEvent(provider), broadcast: false);
RaiseLocalEvent(provider.Owner, new ReceiverConnectedEvent((uid, receiver)), broadcast: false);
RaiseLocalEvent(provider.Value, new ReceiverConnectedEvent((uid, receiver)), broadcast: false);
}
private bool TryFindAvailableProvider(EntityUid owner, float range, [NotNullWhen(true)] out ExtensionCableProviderComponent? foundProvider, TransformComponent? xform = null)
private bool TryFindAvailableProvider(EntityUid owner, float range, [NotNullWhen(true)] out Entity<ExtensionCableProviderComponent>? foundProvider, TransformComponent? xform = null)
{
if (!Resolve(owner, ref xform) || !TryComp(xform.GridUid, out MapGridComponent? grid))
{
@@ -252,12 +254,12 @@ namespace Content.Server.Power.EntitySystems
}
var coordinates = xform.Coordinates;
var nearbyEntities = grid.GetCellsInSquareArea(coordinates, (int) Math.Ceiling(range / grid.TileSize));
var nearbyEntities = _map.GetCellsInSquareArea(xform.GridUid.Value, grid, coordinates, (int)Math.Ceiling(range / grid.TileSize));
var cableQuery = GetEntityQuery<ExtensionCableProviderComponent>();
var metaQuery = GetEntityQuery<MetaDataComponent>();
var xformQuery = GetEntityQuery<TransformComponent>();
ExtensionCableProviderComponent? closestCandidate = null;
Entity<ExtensionCableProviderComponent>? closestCandidate = null;
var closestDistanceFound = float.MaxValue;
foreach (var entity in nearbyEntities)
{
@@ -277,12 +279,12 @@ namespace Content.Server.Power.EntitySystems
if (distance >= closestDistanceFound)
continue;
closestCandidate = provider;
closestCandidate = (entity, provider);
closestDistanceFound = distance;
}
// Make sure the provider is in range before claiming success
if (closestCandidate != null && closestDistanceFound <= Math.Min(range, closestCandidate.TransferRange))
if (closestCandidate != null && closestDistanceFound <= Math.Min(range, closestCandidate.Value.Comp.TransferRange))
{
foundProvider = closestCandidate;
return true;

View File

@@ -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;

View File

@@ -9,12 +9,14 @@ 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;
using Content.Shared.Power.Generation.Teg;
using Content.Shared.Rounding;
using Robust.Server.GameObjects;
using Robust.Shared.Utility;
namespace Content.Server.Power.Generation.Teg;
@@ -260,13 +262,16 @@ public sealed class TegSystem : EntitySystem
// Otherwise, make sure circulator is set to nothing.
if (!group.IsFullyBuilt)
{
UpdateCirculatorAppearance(uid, false);
UpdateCirculatorAppearance((uid, component), false);
}
}
private void UpdateCirculatorAppearance(EntityUid uid, bool powered)
private void UpdateCirculatorAppearance(Entity<TegCirculatorComponent?> ent, bool powered)
{
var circ = Comp<TegCirculatorComponent>(uid);
if (!Resolve(ent, ref ent.Comp))
return;
var circ = ent.Comp;
TegCirculatorSpeed speed;
if (powered && circ.LastPressureDelta > 0 && circ.LastMolesTransferred > 0)
@@ -281,13 +286,13 @@ public sealed class TegSystem : EntitySystem
speed = TegCirculatorSpeed.SpeedStill;
}
_appearance.SetData(uid, TegVisuals.CirculatorSpeed, speed);
_appearance.SetData(uid, TegVisuals.CirculatorPower, powered);
_appearance.SetData(ent, TegVisuals.CirculatorSpeed, speed);
_appearance.SetData(ent, TegVisuals.CirculatorPower, powered);
if (_pointLight.TryGetLight(uid, out var pointLight))
if (_pointLight.TryGetLight(ent, out var pointLight))
{
_pointLight.SetEnabled(uid, powered, pointLight);
_pointLight.SetColor(uid, speed == TegCirculatorSpeed.SpeedFast ? circ.LightColorFast : circ.LightColorSlow, pointLight);
_pointLight.SetEnabled(ent, powered, pointLight);
_pointLight.SetColor(ent, speed == TegCirculatorSpeed.SpeedFast ? circ.LightColorFast : circ.LightColorSlow, pointLight);
}
}