Fix station events that use update loops (#15834)

This commit is contained in:
Nemanja
2023-04-28 23:15:06 -04:00
committed by GitHub
parent f028b35ce2
commit 51506e3d30
6 changed files with 41 additions and 19 deletions

View File

@@ -5,21 +5,36 @@ namespace Content.Server.StationEvents.Components;
[RegisterComponent, Access(typeof(MeteorSwarmRule))] [RegisterComponent, Access(typeof(MeteorSwarmRule))]
public sealed class MeteorSwarmRuleComponent : Component public sealed class MeteorSwarmRuleComponent : Component
{ {
public float _cooldown; [DataField("cooldown")]
public float Cooldown;
/// <summary> /// <summary>
/// We'll send a specific amount of waves of meteors towards the station per ending rather than using a timer. /// We'll send a specific amount of waves of meteors towards the station per ending rather than using a timer.
/// </summary> /// </summary>
public int _waveCounter; [DataField("waveCounter")]
public int WaveCounter;
[DataField("minimumWaves")]
public int MinimumWaves = 3; public int MinimumWaves = 3;
[DataField("maximumWaves")]
public int MaximumWaves = 8; public int MaximumWaves = 8;
[DataField("minimumCooldown")]
public float MinimumCooldown = 10f; public float MinimumCooldown = 10f;
[DataField("maximumCooldown")]
public float MaximumCooldown = 60f; public float MaximumCooldown = 60f;
[DataField("meteorsPerWave")]
public int MeteorsPerWave = 5; public int MeteorsPerWave = 5;
[DataField("meteorVelocity")]
public float MeteorVelocity = 10f; public float MeteorVelocity = 10f;
[DataField("maxAngularVelocity")]
public float MaxAngularVelocity = 0.25f; public float MaxAngularVelocity = 0.25f;
[DataField("minAngularVelocity")]
public float MinAngularVelocity = -0.25f; public float MinAngularVelocity = -0.25f;
} }

View File

@@ -52,7 +52,7 @@ public sealed class StationEventComponent : Component
/// How long the event lasts. /// How long the event lasts.
/// </summary> /// </summary>
[DataField("duration")] [DataField("duration")]
public TimeSpan Duration = TimeSpan.FromSeconds(1); public TimeSpan? Duration = TimeSpan.FromSeconds(1);
/// <summary> /// <summary>
/// The max amount of time the event lasts. /// The max amount of time the event lasts.
@@ -85,5 +85,5 @@ public sealed class StationEventComponent : Component
/// When the station event starts. /// When the station event starts.
/// </summary> /// </summary>
[DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer))] [DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan EndTime; public TimeSpan? EndTime;
} }

View File

@@ -36,7 +36,8 @@ public sealed class EventManagerSystem : EntitySystem
private void OnUnpaused(EntityUid uid, StationEventComponent component, ref EntityUnpausedEvent args) private void OnUnpaused(EntityUid uid, StationEventComponent component, ref EntityUnpausedEvent args)
{ {
component.StartTime += args.PausedTime; component.StartTime += args.PausedTime;
component.EndTime += args.PausedTime; if (component.EndTime != null)
component.EndTime = component.EndTime.Value + args.PausedTime;
} }
public override void Shutdown() public override void Shutdown()

View File

@@ -16,13 +16,12 @@ namespace Content.Server.StationEvents.Events
base.Started(uid, component, gameRule, args); base.Started(uid, component, gameRule, args);
var mod = Math.Sqrt(GetSeverityModifier()); var mod = Math.Sqrt(GetSeverityModifier());
component._waveCounter = (int) (RobustRandom.Next(component.MinimumWaves, component.MaximumWaves) * mod); component.WaveCounter = (int) (RobustRandom.Next(component.MinimumWaves, component.MaximumWaves) * mod);
} }
protected override void ActiveTick(EntityUid uid, MeteorSwarmRuleComponent component, GameRuleComponent gameRule, float frameTime) protected override void ActiveTick(EntityUid uid, MeteorSwarmRuleComponent component, GameRuleComponent gameRule, float frameTime)
{ {
base.ActiveTick(uid, component, gameRule, frameTime); if (component.WaveCounter <= 0)
if (component._waveCounter <= 0)
{ {
ForceEndSelf(uid, gameRule); ForceEndSelf(uid, gameRule);
return; return;
@@ -30,14 +29,14 @@ namespace Content.Server.StationEvents.Events
var mod = GetSeverityModifier(); var mod = GetSeverityModifier();
component._cooldown -= frameTime; component.Cooldown -= frameTime;
if (component._cooldown > 0f) if (component.Cooldown > 0f)
return; return;
component._waveCounter--; component.WaveCounter--;
component._cooldown += (component.MaximumCooldown - component.MinimumCooldown) * RobustRandom.NextFloat() / mod + component.MinimumCooldown; component.Cooldown += (component.MaximumCooldown - component.MinimumCooldown) * RobustRandom.NextFloat() / mod + component.MinimumCooldown;
Box2? playableArea = null; Box2? playableArea = null;
var mapId = GameTicker.DefaultMap; var mapId = GameTicker.DefaultMap;
@@ -64,7 +63,7 @@ namespace Content.Server.StationEvents.Events
var angle = new Angle(RobustRandom.NextFloat() * MathF.Tau); var angle = new Angle(RobustRandom.NextFloat() * MathF.Tau);
var offset = angle.RotateVec(new Vector2((maximumDistance - minimumDistance) * RobustRandom.NextFloat() + minimumDistance, 0)); var offset = angle.RotateVec(new Vector2((maximumDistance - minimumDistance) * RobustRandom.NextFloat() + minimumDistance, 0));
var spawnPosition = new MapCoordinates(center + offset, mapId); var spawnPosition = new MapCoordinates(center + offset, mapId);
var meteor = EntityManager.SpawnEntity("MeteorLarge", spawnPosition); var meteor = Spawn("MeteorLarge", spawnPosition);
var physics = EntityManager.GetComponent<PhysicsComponent>(meteor); var physics = EntityManager.GetComponent<PhysicsComponent>(meteor);
_physics.SetBodyStatus(physics, BodyStatus.InAir); _physics.SetBodyStatus(physics, BodyStatus.InAir);
_physics.SetLinearDamping(physics, 0f); _physics.SetLinearDamping(physics, 0f);

View File

@@ -69,12 +69,16 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : Compon
return; return;
AdminLogManager.Add(LogType.EventStarted, LogImpact.High, $"Event started: {ToPrettyString(uid)}"); AdminLogManager.Add(LogType.EventStarted, LogImpact.High, $"Event started: {ToPrettyString(uid)}");
if (stationEvent.Duration != null)
{
var duration = stationEvent.MaxDuration == null var duration = stationEvent.MaxDuration == null
? stationEvent.Duration ? stationEvent.Duration
: TimeSpan.FromSeconds(RobustRandom.NextDouble(stationEvent.Duration.TotalSeconds, : TimeSpan.FromSeconds(RobustRandom.NextDouble(stationEvent.Duration.Value.TotalSeconds,
stationEvent.MaxDuration.Value.TotalSeconds)); stationEvent.MaxDuration.Value.TotalSeconds));
stationEvent.EndTime = _timing.CurTime + duration; stationEvent.EndTime = _timing.CurTime + duration;
} }
}
/// <inheritdoc/> /// <inheritdoc/>
protected override void Ended(EntityUid uid, T component, GameRuleComponent gameRule, GameRuleEndedEvent args) protected override void Ended(EntityUid uid, T component, GameRuleComponent gameRule, GameRuleEndedEvent args)
@@ -101,6 +105,8 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : Compon
/// <inheritdoc/> /// <inheritdoc/>
public override void Update(float frameTime) public override void Update(float frameTime)
{ {
base.Update(frameTime);
var query = EntityQueryEnumerator<StationEventComponent, GameRuleComponent>(); var query = EntityQueryEnumerator<StationEventComponent, GameRuleComponent>();
while (query.MoveNext(out var uid, out var stationEvent, out var ruleData)) while (query.MoveNext(out var uid, out var stationEvent, out var ruleData))
{ {
@@ -111,7 +117,7 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : Compon
{ {
GameTicker.StartGameRule(uid, ruleData); GameTicker.StartGameRule(uid, ruleData);
} }
else if (GameTicker.IsGameRuleActive(uid, ruleData) && _timing.CurTime >= stationEvent.EndTime) else if (stationEvent.EndTime != null && _timing.CurTime >= stationEvent.EndTime && GameTicker.IsGameRuleActive(uid, ruleData))
{ {
GameTicker.EndGameRule(uid, ruleData); GameTicker.EndGameRule(uid, ruleData);
} }

View File

@@ -149,6 +149,7 @@
path: /Audio/Announcements/meteors.ogg path: /Audio/Announcements/meteors.ogg
params: params:
volume: -4 volume: -4
duration: null #ending is handled by MeteorSwarmRule
startAfter: 30 startAfter: 30
- type: MeteorSwarmRule - type: MeteorSwarmRule