Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Content.Server._ES.StationEvents.LightOverload.Components;

[RegisterComponent]
[Access(typeof(ESLightOverloadRule))]
public sealed partial class ESApcVoteComponent : Component
{
[DataField]
public int Count = 4;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Content.Server._ES.StationEvents.LightOverload.Components;

[RegisterComponent]
[Access(typeof(ESLightOverloadRule))]
public sealed partial class ESLightOverloadRuleComponent : Component
{
[DataField]
public List<EntityUid> Apcs = [];

[DataField]
public float Radius = 8f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Content.Server._ES.StationEvents.LightOverload.Components;
using Content.Server.Light.EntitySystems;
using Content.Server.Power.Components;
using Content.Server.StationEvents.Events;
using Content.Shared._ES.Voting.Components;
using Content.Shared._ES.Voting.Results;
using Content.Shared.GameTicking.Components;
using Content.Shared.Light.Components;
using Robust.Shared.Random;

namespace Content.Server._ES.StationEvents.LightOverload;

public sealed class ESLightOverloadRule : StationEventSystem<ESLightOverloadRuleComponent>
{
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
[Dependency] private readonly PoweredLightSystem _poweredLight = default!;

/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ESLightOverloadRuleComponent, ESSynchronizedVotesCompletedEvent>(OnSynchronizedVotesCompleted);
SubscribeLocalEvent<ESApcVoteComponent, ESGetVoteOptionsEvent>(OnGetVoteOptions);
}

private void OnSynchronizedVotesCompleted(Entity<ESLightOverloadRuleComponent> ent, ref ESSynchronizedVotesCompletedEvent args)
{
for (var i = 0; i < args.Results.Count; ++i)
{
if (args.TryGetResult<ESEntityVoteOption>(i, out var result) &&
TryGetEntity(result.Entity, out var apc))
{
ent.Comp.Apcs.Add(apc.Value);
}
}
}

private void OnGetVoteOptions(Entity<ESApcVoteComponent> ent, ref ESGetVoteOptionsEvent args)
{
var apcs = new List<EntityUid>();
var query = EntityQueryEnumerator<ApcComponent>();
while (query.MoveNext(out var uid, out _))
{
apcs.Add(uid);
}

foreach (var apc in RobustRandom.GetItems(apcs, Math.Min(apcs.Count, ent.Comp.Count)))
{
args.Options.Add(new ESEntityVoteOption
{
DisplayString = Name(apc),
Entity = GetNetEntity(apc),
});
}
}

protected override void Started(EntityUid uid,
ESLightOverloadRuleComponent component,
GameRuleComponent gameRule,
GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);

foreach (var apc in component.Apcs)
{
if (TerminatingOrDeleted(apc))
return;


var coords = Transform(apc).Coordinates;
foreach (var light in _entityLookup.GetEntitiesInRange<PoweredLightComponent>(coords, component.Radius))
{
_poweredLight.TryDestroyBulb(light);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Shared._ES.Sparks;
using Content.Shared.Audio;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
Expand Down Expand Up @@ -39,6 +40,7 @@ public abstract class SharedPoweredLightSystem : EntitySystem
[Dependency] private readonly SharedDeviceLinkSystem _deviceLink = default!;
// ES START
[Dependency] private readonly SharedGameTicker _gameTicker = default!;
[Dependency] private readonly ESSparksSystem _sparks = default!;
// ES END

private static readonly TimeSpan ThunkDelay = TimeSpan.FromSeconds(2);
Expand Down Expand Up @@ -249,6 +251,9 @@ public bool TryDestroyBulb(EntityUid uid, PoweredLightComponent? light = null, E
return false;

// break it
// ES START
_sparks.DoSparks(uid, user: user, tileFireChance: 0.05f);
// ES END
_bulbSystem.SetState(bulbUid.Value, LightBulbState.Broken, lightBulb);
_bulbSystem.PlayBreakSound(bulbUid.Value, lightBulb, user);
UpdateLight(uid, light);
Expand Down
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/_ES/station-events/light-overload.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
es-station-event-light-overload-start-announcement = An anomalous power surge has been detected in station's powernet. Low-voltage lighting equipment may be affected.

es-voter-query-string-light-overload-location = The APC that will be overloaded is:
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@
collection: GlassBreak
- type: PlacementReplacement
key: lights
# ES START
- type: ESSparkOnHit
tileFireChance: 0.05
# ES END
placement:
mode: SnapgridCenter
snap:
Expand Down
28 changes: 28 additions & 0 deletions Resources/Prototypes/_ES/GameRules/station_events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
- id: ESStationEventPowerGridCheck
- id: ESStationEventSolarFlare
- id: ESStationEventVentClog
- id: ESStationEventLightOverload
- id: ESStationEventMeteorSwarm
- id: ESStationEventElectricalFire

Expand Down Expand Up @@ -273,3 +274,30 @@
- type: ESRandomLocationVote
count: 6
checkLOS: false

## Light Overload
- type: entity
parent: ESBaseStationEvent
id: ESStationEventLightOverload
name: Light Overload
description: Overload several APCs across the station, breaking all lights attached to them.
components:
- type: StationEvent
startAudio:
path: /Audio/_ES/Announcements/attention_medium.ogg
params:
volume: -4
startAnnouncement: es-station-event-light-overload-start-announcement
- type: ESLightOverloadRule
- type: ESSynchronizedVoteManager
votes:
- ESVoteLightOverloadAPC

- type: entity
id: ESVoteLightOverloadAPC
name: Which APC should be overloaded?
components:
- type: ESVote
queryString: es-voter-query-string-light-overload-location
duration: 30
- type: ESApcVote
Loading