From b3aa1f6dcd6d036e9b313e92696d0147b7603105 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?=
<6766154+Zumorica@users.noreply.github.com>
Date: Fri, 22 Mar 2019 23:59:13 +0100
Subject: [PATCH] Wall lights now require light bulbs. (#151)
* Adds light_tube.rsi
Sprites taken from CEV Eris!
* Adds LightBulbComponent
* Wall lights now use light bulbs!
* Light bulb now updates its sprite when it changes.
* Comments the code.
* Adds license and copyright to new sprites
---
Content.Server/Content.Server.csproj | 1 +
Content.Server/EntryPoint.cs | 1 +
.../Components/Power/LightBulbComponent.cs | 71 ++++++++
.../Components/Power/PoweredLightComponent.cs | 170 ++++++++++++++++--
Resources/Prototypes/Entities/Lights.yml | 29 ++-
.../Objects/light_tube.rsi/broken.png | Bin 0 -> 162 bytes
.../Objects/light_tube.rsi/burned.png | Bin 0 -> 236 bytes
.../Textures/Objects/light_tube.rsi/meta.json | 44 +++++
.../Objects/light_tube.rsi/normal.png | Bin 0 -> 160 bytes
9 files changed, 296 insertions(+), 20 deletions(-)
create mode 100644 Content.Server/GameObjects/Components/Power/LightBulbComponent.cs
create mode 100644 Resources/Textures/Objects/light_tube.rsi/broken.png
create mode 100644 Resources/Textures/Objects/light_tube.rsi/burned.png
create mode 100644 Resources/Textures/Objects/light_tube.rsi/meta.json
create mode 100644 Resources/Textures/Objects/light_tube.rsi/normal.png
diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj
index 67ac7871d163e0..79820211c87d4f 100644
--- a/Content.Server/Content.Server.csproj
+++ b/Content.Server/Content.Server.csproj
@@ -86,6 +86,7 @@
+
diff --git a/Content.Server/EntryPoint.cs b/Content.Server/EntryPoint.cs
index 96353380fc9158..8016d35a2fca8a 100644
--- a/Content.Server/EntryPoint.cs
+++ b/Content.Server/EntryPoint.cs
@@ -86,6 +86,7 @@ public override void Init()
factory.RegisterReference();
factory.Register();
factory.Register();
+ factory.Register();
//Tools
factory.Register();
diff --git a/Content.Server/GameObjects/Components/Power/LightBulbComponent.cs b/Content.Server/GameObjects/Components/Power/LightBulbComponent.cs
new file mode 100644
index 00000000000000..1ff15d02235abb
--- /dev/null
+++ b/Content.Server/GameObjects/Components/Power/LightBulbComponent.cs
@@ -0,0 +1,71 @@
+using System;
+using SS14.Server.GameObjects;
+using SS14.Shared.Enums;
+using SS14.Shared.GameObjects;
+using SS14.Shared.Serialization;
+
+namespace Content.Server.GameObjects.Components.Power
+{
+ public enum LightBulbState
+ {
+ Normal,
+ Broken,
+ Burned,
+ }
+
+ public enum LightBulbType
+ {
+ Tube,
+ }
+
+ ///
+ /// Component that represents a light bulb. Can be broken, or burned, which turns them mostly useless.
+ ///
+ public class LightBulbComponent : Component
+ {
+
+ ///
+ /// Invoked whenever the state of the light bulb changes.
+ ///
+ public event EventHandler OnLightBulbStateChange;
+
+ public override string Name => "LightBulb";
+
+ public LightBulbType Type = LightBulbType.Tube;
+
+ ///
+ /// The current state of the light bulb. Invokes the OnLightBulbStateChange event when set.
+ /// It also updates the bulb's sprite accordingly.
+ ///
+ public LightBulbState State
+ {
+ get { return _state; }
+ set
+ {
+ var sprite = Owner.GetComponent();
+ OnLightBulbStateChange?.Invoke(this, EventArgs.Empty);
+ _state = value;
+ switch (value)
+ {
+ case LightBulbState.Normal:
+ sprite.LayerSetState(0, "normal");
+ break;
+ case LightBulbState.Broken:
+ sprite.LayerSetState(0, "broken");
+ break;
+ case LightBulbState.Burned:
+ sprite.LayerSetState(0, "burned");
+ break;
+ }
+ }
+ }
+
+ private LightBulbState _state = LightBulbState.Normal;
+
+ public override void ExposeData(ObjectSerializer serializer)
+ {
+ serializer.DataField(ref Type, "bulb", LightBulbType.Tube);
+ }
+
+ }
+}
diff --git a/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs b/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs
index db0e8b861b77e5..dddbae410b90fa 100644
--- a/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs
+++ b/Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs
@@ -1,5 +1,10 @@
using System;
+using Content.Server.GameObjects.EntitySystems;
+using Content.Server.Interfaces.GameObjects;
+using Content.Shared.GameObjects;
+using Content.Shared.GameObjects.Components.Inventory;
using SS14.Server.GameObjects;
+using SS14.Server.GameObjects.Components.Container;
using SS14.Server.GameObjects.EntitySystems;
using SS14.Shared.Audio;
using SS14.Shared.Enums;
@@ -7,10 +12,17 @@
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Timing;
using SS14.Shared.IoC;
+using SS14.Shared.Log;
+using SS14.Shared.Map;
+using SS14.Shared.Serialization;
+using SS14.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Power
{
- public class PoweredLightComponent : Component
+ ///
+ /// Component that represents a wall light. It has a light bulb that can be replaced when broken.
+ ///
+ public class PoweredLightComponent : Component, IAttackHand, IAttackby
{
public override string Name => "PoweredLight";
@@ -18,32 +30,154 @@ public class PoweredLightComponent : Component
private TimeSpan _lastThunk;
- public override void Initialize()
+ private LightBulbType BulbType = LightBulbType.Tube;
+
+ [ViewVariables] private float Load = 40;
+
+ [ViewVariables] private ContainerSlot LightBulbContainer;
+
+ [ViewVariables]
+ private LightBulbComponent LightBulb
{
- base.Initialize();
+ get
+ {
+ if (LightBulbContainer.ContainedEntity == null) return null;
+
+ LightBulbContainer.ContainedEntity.TryGetComponent(out LightBulbComponent bulb);
+
+ return bulb;
+ }
+ }
+
+ bool IAttackby.Attackby(IEntity user, IEntity attackwith)
+ {
+ if (!attackwith.HasComponent()) return false;
+
+ if (LightBulb != null) return false;
+
+ user.GetComponent().Drop(attackwith, LightBulbContainer);
+
+ var inserted = LightBulbContainer.Insert(attackwith);
+
+ UpdateLight();
+
+ return inserted;
+ }
+
+ bool IAttackHand.Attackhand(IEntity user)
+ {
+ if (user.GetComponent().GetSlotItem(EquipmentSlotDefines.Slots.GLOVES) != null)
+ {
+ EjectBulb(user);
+ UpdateLight();
+ return true;
+ }
+ else
+ {
+ if (!user.TryGetComponent(out DamageableComponent damageableComponent)) return false;
+ damageableComponent.TakeDamage(DamageType.Heat, 20);
+ }
+
+ UpdateLight();
+
+ return false;
+ }
+
+ ///
+ /// Ejects the bulb to a mob's hand if possible.
+ ///
+ private void EjectBulb(IEntity user)
+ {
+ if (LightBulb == null) return;
+
+ var bulb = LightBulb;
+ if (!LightBulbContainer.Remove(bulb.Owner)) return;
+
+ if (!user.TryGetComponent(out HandsComponent hands)
+ || !hands.PutInHand(bulb.Owner.GetComponent()))
+ bulb.Owner.Transform.GridPosition = user.Transform.GridPosition;
+ }
+
+ public override void ExposeData(ObjectSerializer serializer)
+ {
+ serializer.DataField(ref Load, "load", 40);
+ serializer.DataField(ref BulbType, "bulb", LightBulbType.Tube);
+ }
+
+ ///
+ /// For attaching UpdateLight() to events.
+ ///
+ public void UpdateLight(object sender, EventArgs e)
+ {
+ UpdateLight();
+ }
+
+ ///
+ /// Updates the light's power drain, sprite and actual light state.
+ ///
+ public void UpdateLight()
+ {
var device = Owner.GetComponent();
var sprite = Owner.GetComponent();
var light = Owner.GetComponent();
- device.OnPowerStateChanged += (sender, args) =>
+ if (LightBulb == null) // No light bulb.
{
- if (args.Powered)
- {
- sprite.LayerSetState(0, "on");
- light.State = LightState.On;
- var time = IoCManager.Resolve().CurTime;
- if (time > _lastThunk + _thunkDelay)
+ device.Load = 0;
+ sprite.LayerSetState(0, "empty");
+ light.State = LightState.Off;
+ return;
+ }
+
+ switch (LightBulb.State)
+ {
+ case LightBulbState.Normal:
+ if (device.Powered)
+ {
+ device.Load = Load;
+ sprite.LayerSetState(0, "on");
+ light.State = LightState.On;
+ var time = IoCManager.Resolve().CurTime;
+ if (time > _lastThunk + _thunkDelay)
+ {
+ IoCManager.Resolve().GetEntitySystem()
+ .Play("/Audio/machines/light_tube_on.ogg", Owner, AudioParams.Default.WithVolume(-10f));
+ }
+ }
+ else
{
- IoCManager.Resolve().GetEntitySystem()
- .Play("/Audio/machines/light_tube_on.ogg", Owner, AudioParams.Default.WithVolume(-10f));
+ device.Load = 0;
+ sprite.LayerSetState(0, "off");
+ light.State = LightState.Off;
}
- }
- else
- {
- sprite.LayerSetState(0, "off");
+
+ break;
+ case LightBulbState.Broken:
+ device.Load = 0;
+ sprite.LayerSetState(0, "broken");
light.State = LightState.Off;
- }
- };
+ break;
+ case LightBulbState.Burned:
+ device.Load = 0;
+ sprite.LayerSetState(0, "burned");
+ light.State = LightState.Off;
+ break;
+ }
+ }
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ var device = Owner.GetComponent();
+ device.OnPowerStateChanged += UpdateLight;
+
+ LightBulbContainer = ContainerManagerComponent.Ensure("light_bulb", Owner, out var existed);
+
+ if (!existed) // Insert a light tube if there wasn't any.
+ {
+ LightBulbContainer.Insert(Owner.EntityManager.SpawnEntity("LightTube"));
+ }
}
}
}
diff --git a/Resources/Prototypes/Entities/Lights.yml b/Resources/Prototypes/Entities/Lights.yml
index 599ef10734a3a9..c93e9463e36d20 100644
--- a/Resources/Prototypes/Entities/Lights.yml
+++ b/Resources/Prototypes/Entities/Lights.yml
@@ -3,7 +3,6 @@
name: "Unpowered Light"
components:
- type: Clickable
- # So we can click on it for deletion.
- type: BoundingBox
- type: Sprite
sprite: Buildings/light_tube.rsi
@@ -28,6 +27,8 @@
id: poweredlight
parent: wall_light
components:
+ - type: Clickable
+ - type: BoundingBox
- type: Sprite
sprite: Buildings/light_tube.rsi
state: off
@@ -40,7 +41,31 @@
state: Off
- type: PowerDevice
- load: 50
priority: Low
- type: PoweredLight
+ load: 40
+ bulb: Tube
+
+- type: entity
+ parent: BaseItem
+ name: BaseLightbulb
+ id: BaseLightbulb
+ components:
+ - type: LightBulb
+
+- type: entity
+ parent: BaseLightbulb
+ name: Light Tube
+ id: LightTube
+ components:
+ - type: LightBulb
+ bulb: Tube
+
+ - type: Sprite
+ sprite: Objects/light_tube.rsi
+ state: normal
+
+ - type: Icon
+ sprite: Objects/light_tube.rsi
+ state: normal
\ No newline at end of file
diff --git a/Resources/Textures/Objects/light_tube.rsi/broken.png b/Resources/Textures/Objects/light_tube.rsi/broken.png
new file mode 100644
index 0000000000000000000000000000000000000000..5df9e7166eb0ea3e80074cdf7ff641d64f8e89d4
GIT binary patch
literal 162
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv=>VS)*Z&O-uV24Dbm-8wZQK6;
z|KHfyXk%kDfByW*lPAB}P__}MjIkuhFPOpM*^M+H$JEosF+^ixa)LyS14Hlnj$`R2
z4#EPQ91fumUbHN8a7p~2ZQvGsVA{QwRSk-38GRdi8?P}i{BC8xd4m0n63_q!Pgg&e
IbxsLQ0DV0=_5c6?
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Objects/light_tube.rsi/burned.png b/Resources/Textures/Objects/light_tube.rsi/burned.png
new file mode 100644
index 0000000000000000000000000000000000000000..d79b43f72f18d16a390a20f410524de9e871caaa
GIT binary patch
literal 236
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv-2k5u*Z&O-Ha0ffwrzX;`t|(z
z^L2D|{{R0!dGh3
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Objects/light_tube.rsi/meta.json b/Resources/Textures/Objects/light_tube.rsi/meta.json
new file mode 100644
index 00000000000000..e5ffb23a14d814
--- /dev/null
+++ b/Resources/Textures/Objects/light_tube.rsi/meta.json
@@ -0,0 +1,44 @@
+{
+ "version": 1,
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit ad7c8621e5567b1b3b2b609f699b3b80cca785f2",
+ "states": [
+ {
+ "name": "normal",
+ "select": [],
+ "flags": {},
+ "directions": 1,
+ "delays": [
+ [
+ 1.0
+ ]
+ ]
+ },
+ {
+ "name": "burned",
+ "select": [],
+ "flags": {},
+ "directions": 1,
+ "delays": [
+ [
+ 1.0
+ ]
+ ]
+ },
+ {
+ "name": "broken",
+ "select": [],
+ "flags": {},
+ "directions": 1,
+ "delays": [
+ [
+ 1.0
+ ]
+ ]
+ }
+ ]
+}
diff --git a/Resources/Textures/Objects/light_tube.rsi/normal.png b/Resources/Textures/Objects/light_tube.rsi/normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..981a40378337bf20441728b229affd4940e7cbb2
GIT binary patch
literal 160
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvi2$Dv*Z&O-Ha0ffwrzX;`t|(z
z^Z)<{W6njK5|)d!
z68Zd`Lld&18kQ;4SZD<}1s~9u)VHd^(SXsnVPfMo28L=W-jnTfgiV1aFnGH9xvX