Merge remote-tracking branch 'upstream/stable' into ed-21-07-2025-upstream-sync

# Conflicts:
#	Content.Client/Overlays/StencilOverlay.Weather.cs
#	Content.IntegrationTests/Tests/Atmos/AlarmThresholdTest.cs
#	Content.IntegrationTests/Tests/VendingMachineRestockTest.cs
#	Content.Server/Chat/Systems/ChatSystem.cs
#	Content.Server/Fluids/EntitySystems/PuddleSystem.cs
#	Content.Shared/Damage/Systems/SharedStaminaSystem.cs
#	Content.Shared/Fluids/Components/EvaporationComponent.cs
#	Content.Shared/GameTicking/SharedGameTicker.cs
This commit is contained in:
Ed
2025-07-21 11:27:53 +03:00
1242 changed files with 21543 additions and 15530 deletions

View File

@@ -20,26 +20,27 @@ using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
namespace Content.Shared.Damage.Systems;
public abstract partial class SharedStaminaSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly MetaDataSystem _metadata = default!;
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] protected readonly SharedStunSystem StunSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
/// <summary>
/// How much of a buffer is there between the stun duration and when stuns can be re-applied.
/// </summary>
private static readonly TimeSpan StamCritBufferTime = TimeSpan.FromSeconds(3f);
protected static readonly TimeSpan StamCritBufferTime = TimeSpan.FromSeconds(3f);
public float UniversalStaminaDamageModifier { get; private set; } = 1f;
@@ -66,31 +67,31 @@ public abstract partial class SharedStaminaSystem : EntitySystem
Subs.CVar(_config, CCVars.PlaytestStaminaDamageModifier, value => UniversalStaminaDamageModifier = value, true);
}
private void OnStamHandleState(EntityUid uid, StaminaComponent component, ref AfterAutoHandleStateEvent args)
protected virtual void OnStamHandleState(Entity<StaminaComponent> entity, ref AfterAutoHandleStateEvent args)
{
if (component.Critical)
EnterStamCrit(uid, component);
if (entity.Comp.Critical)
EnterStamCrit(entity);
else
{
if (component.StaminaDamage > 0f)
EnsureComp<ActiveStaminaComponent>(uid);
if (entity.Comp.StaminaDamage > 0f)
EnsureComp<ActiveStaminaComponent>(entity);
ExitStamCrit(uid, component);
ExitStamCrit(entity);
}
}
private void OnShutdown(EntityUid uid, StaminaComponent component, ComponentShutdown args)
protected virtual void OnShutdown(Entity<StaminaComponent> entity, ref ComponentShutdown args)
{
if (MetaData(uid).EntityLifeStage < EntityLifeStage.Terminating)
if (MetaData(entity).EntityLifeStage < EntityLifeStage.Terminating)
{
RemCompDeferred<ActiveStaminaComponent>(uid);
RemCompDeferred<ActiveStaminaComponent>(entity);
}
_alerts.ClearAlert(uid, component.StaminaAlert);
_alerts.ClearAlert(entity, entity.Comp.StaminaAlert);
}
private void OnStartup(EntityUid uid, StaminaComponent component, ComponentStartup args)
private void OnStartup(Entity<StaminaComponent> entity, ref ComponentStartup args)
{
SetStaminaAlert(uid, component);
UpdateStaminaVisuals(entity);
}
[PublicAPI]
@@ -99,23 +100,23 @@ public abstract partial class SharedStaminaSystem : EntitySystem
if (!Resolve(uid, ref component))
return 0f;
var curTime = _timing.CurTime;
var curTime = Timing.CurTime;
var pauseTime = _metadata.GetPauseTime(uid);
return MathF.Max(0f, component.StaminaDamage - MathF.Max(0f, (float) (curTime - (component.NextUpdate + pauseTime)).TotalSeconds * component.Decay));
}
private void OnRejuvenate(EntityUid uid, StaminaComponent component, RejuvenateEvent args)
private void OnRejuvenate(Entity<StaminaComponent> entity, ref RejuvenateEvent args)
{
if (component.StaminaDamage >= component.CritThreshold)
if (entity.Comp.StaminaDamage >= entity.Comp.CritThreshold)
{
ExitStamCrit(uid, component);
ExitStamCrit(entity, entity.Comp);
}
component.StaminaDamage = 0;
//AdjustSlowdown(uid); //CP14 - no stamina slowdown
RemComp<ActiveStaminaComponent>(uid);
SetStaminaAlert(uid, component);
Dirty(uid, component);
entity.Comp.StaminaDamage = 0;
//AdjustSlowdown(entity.Owner);
RemComp<ActiveStaminaComponent>(entity);
UpdateStaminaVisuals(entity);
Dirty(entity);
}
private void OnDisarmed(EntityUid uid, StaminaComponent component, ref DisarmedEvent args)
@@ -212,6 +213,15 @@ public abstract partial class SharedStaminaSystem : EntitySystem
TakeStaminaDamage(target, component.Damage, source: uid, sound: component.Sound);
}
private void UpdateStaminaVisuals(Entity<StaminaComponent> entity)
{
SetStaminaAlert(entity, entity.Comp);
SetStaminaAnimation(entity);
}
// Here so server can properly tell all clients in PVS range to start the animation
protected virtual void SetStaminaAnimation(Entity<StaminaComponent> entity){}
public void SetStaminaAlert(EntityUid uid, StaminaComponent? component = null) //CP14 public. Need proper RestoreStaminaFunction in upstream.
{
if (!Resolve(uid, ref component, false) || component.Deleted)
@@ -268,7 +278,7 @@ public abstract partial class SharedStaminaSystem : EntitySystem
// Reset the decay cooldown upon taking damage.
if (oldDamage < component.StaminaDamage)
{
var nextUpdate = _timing.CurTime + TimeSpan.FromSeconds(component.Cooldown);
var nextUpdate = Timing.CurTime + TimeSpan.FromSeconds(component.Cooldown);
if (component.NextUpdate < nextUpdate)
component.NextUpdate = nextUpdate;
@@ -276,7 +286,7 @@ public abstract partial class SharedStaminaSystem : EntitySystem
//AdjustSlowdown(uid); //CP14 - no stamina slowdown
SetStaminaAlert(uid, component);
UpdateStaminaVisuals((uid, component));
// Checking if the stamina damage has decreased to zero after exiting the stamcrit
if (component.AfterCritical && oldDamage > component.StaminaDamage && component.StaminaDamage <= 0f)
@@ -330,7 +340,7 @@ public abstract partial class SharedStaminaSystem : EntitySystem
var stamQuery = GetEntityQuery<StaminaComponent>();
var query = EntityQueryEnumerator<ActiveStaminaComponent>();
var curTime = _timing.CurTime;
var curTime = Timing.CurTime;
while (query.MoveNext(out var uid, out _))
{
@@ -371,16 +381,14 @@ public abstract partial class SharedStaminaSystem : EntitySystem
return;
}
// To make the difference between a stun and a stamcrit clear
// TODO: Mask?
component.Critical = true;
component.StaminaDamage = component.CritThreshold;
_stunSystem.TryParalyze(uid, component.StunTime, true);
if (StunSystem.TryParalyze(uid, component.StunTime, true))
StunSystem.TrySeeingStars(uid);
// Give them buffer before being able to be re-stunned
component.NextUpdate = _timing.CurTime + component.StunTime + StamCritBufferTime;
component.NextUpdate = Timing.CurTime + component.StunTime + StamCritBufferTime;
EnsureComp<ActiveStaminaComponent>(uid);
Dirty(uid, component);
_adminLogger.Add(LogType.Stamina, LogImpact.Medium, $"{ToPrettyString(uid):user} entered stamina crit");
@@ -396,9 +404,9 @@ public abstract partial class SharedStaminaSystem : EntitySystem
component.Critical = false;
component.AfterCritical = true; // Set to true to indicate that stamina will be restored after exiting stamcrit
component.NextUpdate = _timing.CurTime;
component.NextUpdate = Timing.CurTime;
SetStaminaAlert(uid, component);
UpdateStaminaVisuals((uid, component));
Dirty(uid, component);
_adminLogger.Add(LogType.Stamina, LogImpact.Low, $"{ToPrettyString(uid):user} recovered from stamina crit");
}
@@ -427,6 +435,12 @@ public abstract partial class SharedStaminaSystem : EntitySystem
closest = thres.Key;
}
_stunSystem.UpdateStunModifiers(ent, ent.Comp.StunModifierThresholds[closest]);
StunSystem.UpdateStunModifiers(ent, ent.Comp.StunModifierThresholds[closest]);
}
[Serializable, NetSerializable]
public sealed class StaminaAnimationEvent(NetEntity entity) : EntityEventArgs
{
public NetEntity Entity = entity;
}
}