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