Rework emergency lights (#1830)
* Implement emergency lights reacting to lost power * Add emergency light sprites Remove shared emergency light component * Remove unused import * Remove EmergencyLight NetID * Add rich description Change comments Add license Implement ExposeData Co-authored-by: Julian Giebel <j.giebel@netrocks.info>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Robust.Client.Animations;
|
using Robust.Client.Animations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.GameObjects.Components.Animations;
|
using Robust.Client.GameObjects.Components.Animations;
|
||||||
@@ -13,6 +13,7 @@ namespace Content.Client.GameObjects.Components
|
|||||||
{
|
{
|
||||||
public override string Name => "EmergencyLight";
|
public override string Name => "EmergencyLight";
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
base.Startup();
|
base.Startup();
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerReceiverUsers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Component that represents an emergency light, it has an internal battery that charges when the power is on.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public class EmergencyLightComponent : Component, IExamine
|
||||||
|
{
|
||||||
|
public override string Name => "EmergencyLight";
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private EmergencyLightState _lightState = EmergencyLightState.Charging;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private BatteryComponent Battery => Owner.GetComponent<BatteryComponent>();
|
||||||
|
[ViewVariables]
|
||||||
|
private PointLightComponent Light => Owner.GetComponent<PointLightComponent>();
|
||||||
|
[ViewVariables]
|
||||||
|
private PowerReceiverComponent PowerReceiver => Owner.GetComponent<PowerReceiverComponent>();
|
||||||
|
private SpriteComponent Sprite => Owner.GetComponent<SpriteComponent>();
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
private float _wattage;
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
private float _chargingWattage;
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
private float _chargingEfficiency;
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
serializer.DataField(ref _wattage, "wattage", 5);
|
||||||
|
serializer.DataField(ref _chargingWattage, "chargingWattage", 60);
|
||||||
|
serializer.DataField(ref _chargingEfficiency, "chargingEfficiency", 0.85f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For attaching UpdateState() to events.
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateState(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the light's power drain, battery drain, sprite and actual light state.
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateState()
|
||||||
|
{
|
||||||
|
if (PowerReceiver.Powered)
|
||||||
|
{
|
||||||
|
PowerReceiver.Load = (int) Math.Abs(_wattage);
|
||||||
|
TurnOff();
|
||||||
|
_lightState = EmergencyLightState.Charging;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TurnOn();
|
||||||
|
_lightState = EmergencyLightState.On;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUpdate(float frameTime)
|
||||||
|
{
|
||||||
|
if (_lightState == EmergencyLightState.Empty
|
||||||
|
|| _lightState == EmergencyLightState.Full) return;
|
||||||
|
|
||||||
|
if(_lightState == EmergencyLightState.On)
|
||||||
|
{
|
||||||
|
if (!Battery.TryUseCharge(_wattage * frameTime))
|
||||||
|
{
|
||||||
|
_lightState = EmergencyLightState.Empty;
|
||||||
|
TurnOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Battery.CurrentCharge += _chargingWattage * frameTime * _chargingEfficiency;
|
||||||
|
if (Battery.BatteryState == BatteryState.Full)
|
||||||
|
{
|
||||||
|
PowerReceiver.Load = 1;
|
||||||
|
_lightState = EmergencyLightState.Full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TurnOff()
|
||||||
|
{
|
||||||
|
Sprite.LayerSetState(0, "emergency_light_off");
|
||||||
|
Light.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TurnOn()
|
||||||
|
{
|
||||||
|
Sprite.LayerSetState(0, "emergency_light_on");
|
||||||
|
Light.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
Owner.GetComponent<PowerReceiverComponent>().OnPowerStateChanged += UpdateState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
Owner.GetComponent<PowerReceiverComponent>().OnPowerStateChanged -= UpdateState;
|
||||||
|
base.OnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IExamine.Examine(FormattedMessage message, bool inDetailsRange)
|
||||||
|
{
|
||||||
|
message.AddMarkup(Loc.GetString($"The battery indicator displays: {BatteryStateText[_lightState]}."));
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EmergencyLightState
|
||||||
|
{
|
||||||
|
Charging,
|
||||||
|
Full,
|
||||||
|
Empty,
|
||||||
|
On
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<EmergencyLightState, string> BatteryStateText = new Dictionary<EmergencyLightState, String>
|
||||||
|
{
|
||||||
|
{ EmergencyLightState.Full, "[color=darkgreen]Full[/color]"},
|
||||||
|
{ EmergencyLightState.Empty, "[color=darkred]Empty[/color]"},
|
||||||
|
{ EmergencyLightState.Charging, "[color=darkorange]Charging[/color]"},
|
||||||
|
{ EmergencyLightState.On, "[color=darkorange]Discharging[/color]"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerReceiverUsers;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
internal sealed class EmergencyLightSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
foreach (var comp in ComponentManager.EntityQuery<EmergencyLightComponent>())
|
||||||
|
{
|
||||||
|
comp.OnUpdate(frameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
"AnimationsTest",
|
"AnimationsTest",
|
||||||
"ItemStatus",
|
"ItemStatus",
|
||||||
"Marker",
|
"Marker",
|
||||||
"EmergencyLight",
|
|
||||||
"Clickable",
|
"Clickable",
|
||||||
"RadiatingLight",
|
"RadiatingLight",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,27 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: EmergencyLight
|
id: EmergencyLight
|
||||||
name: "emergency light"
|
name: "emergency light"
|
||||||
|
description: A small red light with an internal battery that turns on as soon as it stops receiving any power.
|
||||||
parent: WallLight
|
parent: WallLight
|
||||||
components:
|
components:
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
|
enabled: false
|
||||||
radius: 10
|
radius: 10
|
||||||
energy: 2.5
|
energy: 2.5
|
||||||
offset: "0.5, 0"
|
offset: "0.5, 0"
|
||||||
color: "#FF4020"
|
color: "#FF4020"
|
||||||
mask: /Textures/emergency_mask.png
|
mask: /Textures/emergency_mask.png
|
||||||
|
|
||||||
- type: EmergencyLight
|
- type: EmergencyLight
|
||||||
|
- type: PowerReceiver
|
||||||
|
- type: Battery
|
||||||
|
maxCharge: 30000
|
||||||
|
startingCharge: 0
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Constructible/Lighting/emergency_light.rsi
|
||||||
|
state: emergency_light_off
|
||||||
|
- type: Icon
|
||||||
|
sprite: Constructible/Lighting/emergency_light.rsi
|
||||||
|
state: emergency_light_off
|
||||||
placement:
|
placement:
|
||||||
snap:
|
snap:
|
||||||
- Wallmount
|
- Wallmount
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 336 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "emergency_light_off",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "emergency_light_on",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user