Emergency Lights now changes color depending on alert level and whether or not the light is powered. (#26932)

* Emergency Lights now change color depending on alert level and whether or not they are powered.

* Made a condition for null alert level, added summary doc.

* Refactored uid and emergencylightcomponent into Entity<EmergencyLightComponent>
This commit is contained in:
superjj18
2024-04-18 06:50:08 -04:00
committed by GitHub
parent 7b94e244b3
commit ebf87be9f2
4 changed files with 80 additions and 35 deletions

View File

@@ -14,7 +14,7 @@ public sealed partial class EmergencyLightComponent : SharedEmergencyLightCompon
/// <summary> /// <summary>
/// Is this emergency light forced on for some reason and cannot be disabled through normal means /// Is this emergency light forced on for some reason and cannot be disabled through normal means
/// (i.e. delta alert level?) /// (i.e. blue alert or higher?)
/// </summary> /// </summary>
public bool ForciblyEnabled = false; public bool ForciblyEnabled = false;

View File

@@ -31,9 +31,9 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
SubscribeLocalEvent<EmergencyLightComponent, PowerChangedEvent>(OnEmergencyPower); SubscribeLocalEvent<EmergencyLightComponent, PowerChangedEvent>(OnEmergencyPower);
} }
private void OnEmergencyPower(EntityUid uid, EmergencyLightComponent component, ref PowerChangedEvent args) private void OnEmergencyPower(Entity<EmergencyLightComponent> entity, ref PowerChangedEvent args)
{ {
var meta = MetaData(uid); var meta = MetaData(entity.Owner);
// TODO: PowerChangedEvent shouldn't be issued for paused ents but this is the world we live in. // TODO: PowerChangedEvent shouldn't be issued for paused ents but this is the world we live in.
if (meta.EntityLifeStage >= EntityLifeStage.Terminating || if (meta.EntityLifeStage >= EntityLifeStage.Terminating ||
@@ -42,7 +42,7 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
return; return;
} }
UpdateState(uid, component); UpdateState(entity);
} }
private void OnEmergencyExamine(EntityUid uid, EmergencyLightComponent component, ExaminedEvent args) private void OnEmergencyExamine(EntityUid uid, EmergencyLightComponent component, ExaminedEvent args)
@@ -111,13 +111,13 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
if (details.ForceEnableEmergencyLights && !light.ForciblyEnabled) if (details.ForceEnableEmergencyLights && !light.ForciblyEnabled)
{ {
light.ForciblyEnabled = true; light.ForciblyEnabled = true;
TurnOn(uid, light); TurnOn((uid, light));
} }
else if (!details.ForceEnableEmergencyLights && light.ForciblyEnabled) else if (!details.ForceEnableEmergencyLights && light.ForciblyEnabled)
{ {
// Previously forcibly enabled, and we went down an alert level. // Previously forcibly enabled, and we went down an alert level.
light.ForciblyEnabled = false; light.ForciblyEnabled = false;
UpdateState(uid, light); UpdateState((uid, light));
} }
} }
} }
@@ -135,31 +135,31 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
var query = EntityQueryEnumerator<ActiveEmergencyLightComponent, EmergencyLightComponent, BatteryComponent>(); var query = EntityQueryEnumerator<ActiveEmergencyLightComponent, EmergencyLightComponent, BatteryComponent>();
while (query.MoveNext(out var uid, out _, out var emergencyLight, out var battery)) while (query.MoveNext(out var uid, out _, out var emergencyLight, out var battery))
{ {
Update(uid, emergencyLight, battery, frameTime); Update((uid, emergencyLight), battery, frameTime);
} }
} }
private void Update(EntityUid uid, EmergencyLightComponent component, BatteryComponent battery, float frameTime) private void Update(Entity<EmergencyLightComponent> entity, BatteryComponent battery, float frameTime)
{ {
if (component.State == EmergencyLightState.On) if (entity.Comp.State == EmergencyLightState.On)
{ {
if (!_battery.TryUseCharge(uid, component.Wattage * frameTime, battery)) if (!_battery.TryUseCharge(entity.Owner, entity.Comp.Wattage * frameTime, battery))
{ {
SetState(uid, component, EmergencyLightState.Empty); SetState(entity.Owner, entity.Comp, EmergencyLightState.Empty);
TurnOff(uid, component); TurnOff(entity);
} }
} }
else else
{ {
_battery.SetCharge(uid, battery.CurrentCharge + component.ChargingWattage * frameTime * component.ChargingEfficiency, battery); _battery.SetCharge(entity.Owner, battery.CurrentCharge + entity.Comp.ChargingWattage * frameTime * entity.Comp.ChargingEfficiency, battery);
if (battery.IsFullyCharged) if (battery.IsFullyCharged)
{ {
if (TryComp<ApcPowerReceiverComponent>(uid, out var receiver)) if (TryComp<ApcPowerReceiverComponent>(entity.Owner, out var receiver))
{ {
receiver.Load = 1; receiver.Load = 1;
} }
SetState(uid, component, EmergencyLightState.Full); SetState(entity.Owner, entity.Comp, EmergencyLightState.Full);
} }
} }
} }
@@ -167,35 +167,73 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
/// <summary> /// <summary>
/// Updates the light's power drain, battery drain, sprite and actual light state. /// Updates the light's power drain, battery drain, sprite and actual light state.
/// </summary> /// </summary>
public void UpdateState(EntityUid uid, EmergencyLightComponent component) public void UpdateState(Entity<EmergencyLightComponent> entity)
{ {
if (!TryComp<ApcPowerReceiverComponent>(uid, out var receiver)) if (!TryComp<ApcPowerReceiverComponent>(entity.Owner, out var receiver))
return; return;
if (receiver.Powered && !component.ForciblyEnabled) if (!TryComp<AlertLevelComponent>(_station.GetOwningStation(entity.Owner), out var alerts))
return;
if (alerts.AlertLevels == null || !alerts.AlertLevels.Levels.TryGetValue(alerts.CurrentLevel, out var details))
{ {
receiver.Load = (int) Math.Abs(component.Wattage); TurnOff(entity, Color.Red); // if no alert, default to off red state
TurnOff(uid, component); return;
SetState(uid, component, EmergencyLightState.Charging);
} }
else
if (receiver.Powered && !entity.Comp.ForciblyEnabled) // Green alert
{ {
TurnOn(uid, component); receiver.Load = (int) Math.Abs(entity.Comp.Wattage);
SetState(uid, component, EmergencyLightState.On); TurnOff(entity, details.Color);
SetState(entity.Owner, entity.Comp, EmergencyLightState.Charging);
}
else if (!receiver.Powered) // If internal battery runs out it will end in off red state
{
TurnOn(entity, Color.Red);
SetState(entity.Owner, entity.Comp, EmergencyLightState.On);
}
else // Powered and enabled
{
TurnOn(entity, details.Color);
SetState(entity.Owner, entity.Comp, EmergencyLightState.On);
} }
} }
private void TurnOff(EntityUid uid, EmergencyLightComponent component) private void TurnOff(Entity<EmergencyLightComponent> entity)
{ {
_pointLight.SetEnabled(uid, false); _pointLight.SetEnabled(entity.Owner, false);
_appearance.SetData(uid, EmergencyLightVisuals.On, false); _appearance.SetData(entity.Owner, EmergencyLightVisuals.On, false);
_ambient.SetAmbience(uid, false); _ambient.SetAmbience(entity.Owner, false);
} }
private void TurnOn(EntityUid uid, EmergencyLightComponent component) /// <summary>
/// Turn off emergency light and set color.
/// </summary>
private void TurnOff(Entity<EmergencyLightComponent> entity, Color color)
{ {
_pointLight.SetEnabled(uid, true); _pointLight.SetEnabled(entity.Owner, false);
_appearance.SetData(uid, EmergencyLightVisuals.On, true); _pointLight.SetColor(entity.Owner, color);
_ambient.SetAmbience(uid, true); _appearance.SetData(entity.Owner, EmergencyLightVisuals.Color, color);
_appearance.SetData(entity.Owner, EmergencyLightVisuals.On, false);
_ambient.SetAmbience(entity.Owner, false);
}
private void TurnOn(Entity<EmergencyLightComponent> entity)
{
_pointLight.SetEnabled(entity.Owner, true);
_appearance.SetData(entity.Owner, EmergencyLightVisuals.On, true);
_ambient.SetAmbience(entity.Owner, true);
}
/// <summary>
/// Turn on emergency light and set color.
/// </summary>
private void TurnOn(Entity<EmergencyLightComponent> entity, Color color)
{
_pointLight.SetEnabled(entity.Owner, true);
_pointLight.SetColor(entity.Owner, color);
_appearance.SetData(entity.Owner, EmergencyLightVisuals.Color, color);
_appearance.SetData(entity.Owner, EmergencyLightVisuals.On, true);
_ambient.SetAmbience(entity.Owner, true);
} }
} }

View File

@@ -5,28 +5,35 @@
green: green:
announcement: alert-level-green-announcement announcement: alert-level-green-announcement
color: Green color: Green
emergencyLightColor: LawnGreen
shuttleTime: 600 shuttleTime: 600
blue: blue:
announcement: alert-level-blue-announcement announcement: alert-level-blue-announcement
sound: /Audio/Misc/bluealert.ogg sound: /Audio/Misc/bluealert.ogg
color: DodgerBlue color: DodgerBlue
forceEnableEmergencyLights: true
emergencyLightColor: DodgerBlue
shuttleTime: 600 shuttleTime: 600
violet: violet:
announcement: alert-level-violet-announcement announcement: alert-level-violet-announcement
sound: /Audio/Misc/notice1.ogg sound: /Audio/Misc/notice1.ogg
color: Violet color: Violet
emergencyLightColor: Violet emergencyLightColor: Violet
forceEnableEmergencyLights: true
shuttleTime: 600 shuttleTime: 600
yellow: yellow:
announcement: alert-level-yellow-announcement announcement: alert-level-yellow-announcement
sound: /Audio/Misc/notice1.ogg sound: /Audio/Misc/notice1.ogg
color: Yellow color: Yellow
emergencyLightColor: Goldenrod emergencyLightColor: Goldenrod
forceEnableEmergencyLights: true
shuttleTime: 600 shuttleTime: 600
red: red:
announcement: alert-level-red-announcement announcement: alert-level-red-announcement
sound: /Audio/Misc/redalert.ogg sound: /Audio/Misc/redalert.ogg
color: Red color: Red
emergencyLightColor: Red
forceEnableEmergencyLights: true
shuttleTime: 600 #No reduction in time as we don't have swiping for red alert like in /tg/. Shuttle times are intended to create friction, so having a way to brainlessly bypass that would be dumb. shuttleTime: 600 #No reduction in time as we don't have swiping for red alert like in /tg/. Shuttle times are intended to create friction, so having a way to brainlessly bypass that would be dumb.
gamma: gamma:
announcement: alert-level-gamma-announcement announcement: alert-level-gamma-announcement

View File

@@ -360,7 +360,7 @@
radius: 5 radius: 5
energy: 0.6 energy: 0.6
offset: "0, 0.4" offset: "0, 0.4"
color: "#FF4020" color: "#7CFC00"
mask: /Textures/Effects/LightMasks/double_cone.png mask: /Textures/Effects/LightMasks/double_cone.png
- type: ApcPowerReceiver - type: ApcPowerReceiver
- type: ExtensionCableReceiver - type: ExtensionCableReceiver
@@ -377,10 +377,10 @@
map: [ "enum.EmergencyLightVisualLayers.Base" ] map: [ "enum.EmergencyLightVisualLayers.Base" ]
- state: emergency_light_off - state: emergency_light_off
map: [ "enum.EmergencyLightVisualLayers.LightOff" ] map: [ "enum.EmergencyLightVisualLayers.LightOff" ]
color: "#FF4020" color: "#7CFC00"
- state: emergency_light_on - state: emergency_light_on
map: [ "enum.EmergencyLightVisualLayers.LightOn" ] map: [ "enum.EmergencyLightVisualLayers.LightOn" ]
color: "#FF4020" color: "#7CFC00"
shader: "unshaded" shader: "unshaded"
visible: false visible: false
- type: Appearance - type: Appearance