mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 18:31:17 +03:00
* fix vent critters spawning off station * I polish the code * add utility to get entities ONLY on the station. use in vent critters rule. * fix station events affecting outside grids * better argument names for GetEntitiesWithComponentOnStation * BreakerFlipRule * \n * fix doc in GetEntitiesWithComponentOnStation * keep the comments * remove BreakerFlipRuleComponent Blacklist * minor cleanup * review * format --------- Co-authored-by: Pok245 <113675512+Pok27@users.noreply.github.com>
93 lines
3.3 KiB
C#
93 lines
3.3 KiB
C#
using System.Linq;
|
|
using Content.Server.Light.EntitySystems;
|
|
using Content.Server.StationEvents.Components;
|
|
using Content.Shared.Doors.Components;
|
|
using Content.Shared.Doors.Systems;
|
|
using Content.Shared.GameTicking.Components;
|
|
using Content.Shared.Light.Components;
|
|
using Content.Shared.Radio;
|
|
using Content.Shared.Radio.Components;
|
|
using Robust.Shared.Random;
|
|
|
|
namespace Content.Server.StationEvents.Events;
|
|
|
|
/// <summary>
|
|
/// Handler for events that cause a solar flare for some amount of time.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// When a solar flare is active, radio communications are disabled on a random set of channels,
|
|
/// doors can randomly open and close, and lights can explode.
|
|
/// </remarks>
|
|
/// <seealso cref="SolarFlareRuleComponent"/>
|
|
public sealed partial class SolarFlareRule : StationEventSystem<SolarFlareRuleComponent>
|
|
{
|
|
[Dependency] private PoweredLightSystem _poweredLight = default!;
|
|
[Dependency] private SharedDoorSystem _door = default!;
|
|
|
|
[Dependency] private EntityQuery<HeadsetComponent> _headsetQuery;
|
|
|
|
private float _effectTimer;
|
|
|
|
protected override void Started(Entity<SolarFlareRuleComponent, GameRuleComponent> ent, ref GameRuleStartedEvent args)
|
|
{
|
|
base.Started(ent, ref args);
|
|
|
|
for (var i = 0; i < ent.Comp1.ExtraCount; i++)
|
|
{
|
|
var channel = RobustRandom.Pick(ent.Comp1.ExtraChannels);
|
|
ent.Comp1.AffectedChannels.Add(channel);
|
|
}
|
|
|
|
ent.Comp1.AffectedLights = Station.GetEntitiesWithComponentOnStation<PoweredLightComponent>(true)
|
|
.Select(e => (e.Owner, e.Comp))
|
|
.ToHashSet();
|
|
ent.Comp1.AffectedAirlocks = Station.GetEntitiesWithComponentOnStation<AirlockComponent>(true)
|
|
.Select(e => (e.Owner, e.Comp))
|
|
.ToHashSet();
|
|
}
|
|
|
|
protected override void ActiveTick(EntityUid uid, SolarFlareRuleComponent component, GameRuleComponent gameRule, float frameTime)
|
|
{
|
|
base.ActiveTick(uid, component, gameRule, frameTime);
|
|
|
|
_effectTimer -= frameTime;
|
|
if (!(_effectTimer < 0))
|
|
return;
|
|
|
|
_effectTimer += 1;
|
|
foreach (var light in component.AffectedLights)
|
|
{
|
|
if (RobustRandom.Prob(component.LightBreakChancePerSecond))
|
|
_poweredLight.TryDestroyBulb(light.Item1, light.Item2);
|
|
}
|
|
|
|
foreach (var airlockEnt in component.AffectedAirlocks)
|
|
{
|
|
if (airlockEnt.Item2.AutoClose && RobustRandom.Prob(component.DoorToggleChancePerSecond))
|
|
_door.TryToggleDoor(airlockEnt.Item1);
|
|
}
|
|
}
|
|
|
|
[SubscribeLocalEvent]
|
|
private void OnRadioReceiveAttempt(ref RadioReceiveAttemptEvent args)
|
|
{
|
|
if (args.Cancelled)
|
|
return;
|
|
|
|
var query = EntityQueryEnumerator<SolarFlareRuleComponent, GameRuleComponent>();
|
|
while (query.MoveNext(out var uid, out var flare, out var gameRule))
|
|
{
|
|
if (!GameTicker.IsGameRuleActive((uid, gameRule)))
|
|
continue;
|
|
|
|
if (!flare.AffectedChannels.Contains(args.Channel.ID))
|
|
continue;
|
|
|
|
if (!flare.OnlyJamHeadsets || _headsetQuery.HasComp(args.RadioReceiver) || _headsetQuery.HasComp(args.RadioSource))
|
|
{
|
|
args.Cancelled = true;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|