* move MinMax to shared * cleanup MinMax * move other ticking components to shared just because * remove unused prototype file * update everything to use shared components * test * test 2 * test 3 --------- Co-authored-by: deltanedas <@deltanedas:kde.org>
91 lines
4.1 KiB
C#
91 lines
4.1 KiB
C#
using Content.Server.Atmos.EntitySystems;
|
|
using Content.Server.GameTicking.Rules.Components;
|
|
using Content.Server.StationEvents.Components;
|
|
using Content.Shared.GameTicking.Components;
|
|
using Robust.Shared.Audio;
|
|
using Robust.Shared.Random;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Server.StationEvents.Events
|
|
{
|
|
internal sealed class GasLeakRule : StationEventSystem<GasLeakRuleComponent>
|
|
{
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
|
|
|
protected override void Started(EntityUid uid, GasLeakRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
|
|
{
|
|
base.Started(uid, component, gameRule, args);
|
|
|
|
if (!TryComp<StationEventComponent>(uid, out var stationEvent))
|
|
return;
|
|
|
|
// Essentially we'll pick out a target amount of gas to leak, then a rate to leak it at, then work out the duration from there.
|
|
if (TryFindRandomTile(out component.TargetTile, out var target, out component.TargetGrid, out component.TargetCoords))
|
|
{
|
|
component.TargetStation = target.Value;
|
|
component.FoundTile = true;
|
|
|
|
component.LeakGas = RobustRandom.Pick(component.LeakableGases);
|
|
// Was 50-50 on using normal distribution.
|
|
var totalGas = RobustRandom.Next(component.MinimumGas, component.MaximumGas);
|
|
component.MolesPerSecond = RobustRandom.Next(component.MinimumMolesPerSecond, component.MaximumMolesPerSecond);
|
|
|
|
if (gameRule.Delay is {} startAfter)
|
|
stationEvent.EndTime = _timing.CurTime + TimeSpan.FromSeconds(totalGas / component.MolesPerSecond + startAfter.Next(RobustRandom));
|
|
}
|
|
|
|
// Look technically if you wanted to guarantee a leak you'd do this in announcement but having the announcement
|
|
// there just to fuck with people even if there is no valid tile is funny.
|
|
}
|
|
|
|
protected override void ActiveTick(EntityUid uid, GasLeakRuleComponent component, GameRuleComponent gameRule, float frameTime)
|
|
{
|
|
base.ActiveTick(uid, component, gameRule, frameTime);
|
|
component.TimeUntilLeak -= frameTime;
|
|
|
|
if (component.TimeUntilLeak > 0f)
|
|
return;
|
|
component.TimeUntilLeak += component.LeakCooldown;
|
|
|
|
if (!component.FoundTile ||
|
|
component.TargetGrid == default ||
|
|
Deleted(component.TargetGrid) ||
|
|
!_atmosphere.IsSimulatedGrid(component.TargetGrid))
|
|
{
|
|
ForceEndSelf(uid, gameRule);
|
|
return;
|
|
}
|
|
|
|
var environment = _atmosphere.GetTileMixture(component.TargetGrid, null, component.TargetTile, true);
|
|
|
|
environment?.AdjustMoles(component.LeakGas, component.LeakCooldown * component.MolesPerSecond);
|
|
}
|
|
|
|
protected override void Ended(EntityUid uid, GasLeakRuleComponent component, GameRuleComponent gameRule, GameRuleEndedEvent args)
|
|
{
|
|
base.Ended(uid, component, gameRule, args);
|
|
Spark(uid, component);
|
|
}
|
|
|
|
private void Spark(EntityUid uid, GasLeakRuleComponent component)
|
|
{
|
|
if (RobustRandom.NextFloat() <= component.SparkChance)
|
|
{
|
|
if (!component.FoundTile ||
|
|
component.TargetGrid == default ||
|
|
(!Exists(component.TargetGrid) ? EntityLifeStage.Deleted : MetaData(component.TargetGrid).EntityLifeStage) >= EntityLifeStage.Deleted ||
|
|
!_atmosphere.IsSimulatedGrid(component.TargetGrid))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Don't want it to be so obnoxious as to instantly murder anyone in the area but enough that
|
|
// it COULD start potentially start a bigger fire.
|
|
_atmosphere.HotspotExpose(component.TargetGrid, component.TargetTile, 700f, 50f, null, true);
|
|
Audio.PlayPvs(new SoundPathSpecifier("/Audio/Effects/sparks4.ogg"), component.TargetCoords);
|
|
}
|
|
}
|
|
}
|
|
}
|