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

@@ -1,5 +1,4 @@
using Content.Server.Chemistry.Components;
using Content.Server.Labels;
using Content.Server.Popups;
using Content.Server.Storage.EntitySystems;
using Content.Shared.Administration.Logs;
@@ -10,6 +9,7 @@ using Content.Shared.Chemistry.Reagent;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Labels.EntitySystems;
using Content.Shared.Storage;
using JetBrains.Annotations;
using Robust.Server.Audio;

View File

@@ -30,8 +30,6 @@ namespace Content.Server.Chemistry.EntitySystems
[Dependency] private readonly ReactiveSystem _reactive = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
private const float ReactTime = 0.125f;
public override void Initialize()
{
base.Initialize();
@@ -50,13 +48,19 @@ namespace Content.Server.Chemistry.EntitySystems
}
// Check for collision with a impassable object (e.g. wall) and stop
if ((args.OtherFixture.CollisionLayer & (int) CollisionGroup.Impassable) != 0 && args.OtherFixture.Hard)
if ((args.OtherFixture.CollisionLayer & (int)CollisionGroup.Impassable) != 0 && args.OtherFixture.Hard)
{
EntityManager.QueueDeleteEntity(entity);
}
}
public void Start(Entity<VaporComponent> vapor, TransformComponent vaporXform, Vector2 dir, float speed, MapCoordinates target, float aliveTime, EntityUid? user = null)
public void Start(Entity<VaporComponent> vapor,
TransformComponent vaporXform,
Vector2 dir,
float speed,
MapCoordinates target,
float aliveTime,
EntityUid? user = null)
{
vapor.Comp.Active = true;
var despawn = EnsureComp<TimedDespawnComponent>(vapor);
@@ -83,7 +87,9 @@ namespace Content.Server.Chemistry.EntitySystems
return false;
}
if (!_solutionContainerSystem.TryGetSolution(vapor.Owner, VaporComponent.SolutionName, out var vaporSolution))
if (!_solutionContainerSystem.TryGetSolution(vapor.Owner,
VaporComponent.SolutionName,
out var vaporSolution))
{
return false;
}
@@ -93,53 +99,71 @@ namespace Content.Server.Chemistry.EntitySystems
public override void Update(float frameTime)
{
base.Update(frameTime);
// Enumerate over all VaporComponents
var query = EntityQueryEnumerator<VaporComponent, SolutionContainerManagerComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var vaporComp, out var container, out var xform))
{
foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((uid, container)))
// Return early if we're not active
if (!vaporComp.Active)
continue;
// Get the current location of the vapor entity first
if (TryComp(xform.GridUid, out MapGridComponent? gridComp))
{
Update(frameTime, (uid, vaporComp), soln, xform);
}
}
}
var tile = _map.GetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates);
private void Update(float frameTime, Entity<VaporComponent> ent, Entity<SolutionComponent> soln, TransformComponent xform)
{
var (entity, vapor) = ent;
if (!vapor.Active)
return;
// Check if the tile is a tile we've reacted with previously. If so, skip it.
// If we have no previous tile reference, we don't return so we can save one.
if (vaporComp.PreviousTileRef != null && tile == vaporComp.PreviousTileRef)
continue;
vapor.ReactTimer += frameTime;
var contents = soln.Comp.Solution;
if (vapor.ReactTimer >= ReactTime && TryComp(xform.GridUid, out MapGridComponent? gridComp))
{
vapor.ReactTimer = 0;
var tile = _map.GetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates);
foreach (var reagentQuantity in contents.Contents.ToArray())
{
if (reagentQuantity.Quantity == FixedPoint2.Zero) continue;
var reagent = _protoManager.Index<ReagentPrototype>(reagentQuantity.Reagent.Prototype);
var reaction =
reagent.ReactionTile(tile, (reagentQuantity.Quantity / vapor.TransferAmount) * 0.25f, EntityManager, reagentQuantity.Reagent.Data);
if (reaction > reagentQuantity.Quantity)
// Enumerate over all the reagents in the vapor entity solution
foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((uid, container)))
{
Log.Error($"Tried to tile react more than we have for reagent {reagentQuantity}. Found {reaction} and we only have {reagentQuantity.Quantity}");
reaction = reagentQuantity.Quantity;
// Iterate over the reagents in the solution
// Reason: Each reagent in our solution may have a unique TileReaction
// In this instance, we check individually for each reagent's TileReaction
// This is not doing chemical reactions!
var contents = soln.Comp.Solution;
foreach (var reagentQuantity in contents.Contents.ToArray())
{
// Check if the reagent is empty
if (reagentQuantity.Quantity == FixedPoint2.Zero)
continue;
var reagent = _protoManager.Index<ReagentPrototype>(reagentQuantity.Reagent.Prototype);
// Limit the reaction amount to a minimum value to ensure no floating point funnies.
// Ex: A solution with a low percentage transfer amount will slowly approach 0.01... and never get deleted
var clampedAmount = Math.Max(
(float)reagentQuantity.Quantity * vaporComp.TransferAmountPercentage,
vaporComp.MinimumTransferAmount);
// Preform the reagent's TileReaction
var reaction =
reagent.ReactionTile(tile,
clampedAmount,
EntityManager,
reagentQuantity.Reagent.Data);
if (reaction > reagentQuantity.Quantity)
reaction = reagentQuantity.Quantity;
_solutionContainerSystem.RemoveReagent(soln, reagentQuantity.Reagent, reaction);
}
// Delete the vapor entity if it has no contents
if (contents.Volume == 0)
EntityManager.QueueDeleteEntity(uid);
}
_solutionContainerSystem.RemoveReagent(soln, reagentQuantity.Reagent, reaction);
// Set the previous tile reference to the current tile
vaporComp.PreviousTileRef = tile;
}
}
if (contents.Volume == 0)
{
// Delete this
EntityManager.QueueDeleteEntity(entity);
}
}
}
}