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
This commit is contained in:
committed by
Pieter-Jan Briers
parent
58e8aef5d8
commit
b3aa1f6dcd
@@ -86,6 +86,7 @@
|
||||
<Compile Include="GameObjects\Components\Mobs\DamageThresholdTemplates\HumanTemplate.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\MindComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Mobs\SpeciesComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\LightBulbComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\PowerCellComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\PowerStorageComponent.cs" />
|
||||
<Compile Include="GameObjects\Components\Power\PowerGeneratorComponent.cs" />
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace Content.Server
|
||||
factory.RegisterReference<PowerCellComponent, PowerStorageComponent>();
|
||||
factory.Register<PowerDeviceComponent>();
|
||||
factory.Register<PowerGeneratorComponent>();
|
||||
factory.Register<LightBulbComponent>();
|
||||
|
||||
//Tools
|
||||
factory.Register<MultitoolComponent>();
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component that represents a light bulb. Can be broken, or burned, which turns them mostly useless.
|
||||
/// </summary>
|
||||
public class LightBulbComponent : Component
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Invoked whenever the state of the light bulb changes.
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> OnLightBulbStateChange;
|
||||
|
||||
public override string Name => "LightBulb";
|
||||
|
||||
public LightBulbType Type = LightBulbType.Tube;
|
||||
|
||||
/// <summary>
|
||||
/// The current state of the light bulb. Invokes the OnLightBulbStateChange event when set.
|
||||
/// It also updates the bulb's sprite accordingly.
|
||||
/// </summary>
|
||||
public LightBulbState State
|
||||
{
|
||||
get { return _state; }
|
||||
set
|
||||
{
|
||||
var sprite = Owner.GetComponent<SpriteComponent>();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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.GameObjects;
|
||||
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
|
||||
/// <summary>
|
||||
/// Component that represents a wall light. It has a light bulb that can be replaced when broken.
|
||||
/// </summary>
|
||||
public class PoweredLightComponent : Component, IAttackHand, IAttackby
|
||||
{
|
||||
public override string Name => "PoweredLight";
|
||||
|
||||
@@ -18,17 +30,111 @@ namespace Content.Server.GameObjects.Components.Power
|
||||
|
||||
private TimeSpan _lastThunk;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
private LightBulbType BulbType = LightBulbType.Tube;
|
||||
|
||||
[ViewVariables] private float Load = 40;
|
||||
|
||||
[ViewVariables] private ContainerSlot LightBulbContainer;
|
||||
|
||||
[ViewVariables]
|
||||
private LightBulbComponent LightBulb
|
||||
{
|
||||
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<LightBulbComponent>()) return false;
|
||||
|
||||
if (LightBulb != null) return false;
|
||||
|
||||
user.GetComponent<IHandsComponent>().Drop(attackwith, LightBulbContainer);
|
||||
|
||||
var inserted = LightBulbContainer.Insert(attackwith);
|
||||
|
||||
UpdateLight();
|
||||
|
||||
return inserted;
|
||||
}
|
||||
|
||||
bool IAttackHand.Attackhand(IEntity user)
|
||||
{
|
||||
if (user.GetComponent<InventoryComponent>().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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ejects the bulb to a mob's hand if possible.
|
||||
/// </summary>
|
||||
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<ItemComponent>()))
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For attaching UpdateLight() to events.
|
||||
/// </summary>
|
||||
public void UpdateLight(object sender, EventArgs e)
|
||||
{
|
||||
UpdateLight();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the light's power drain, sprite and actual light state.
|
||||
/// </summary>
|
||||
public void UpdateLight()
|
||||
{
|
||||
var device = Owner.GetComponent<PowerDeviceComponent>();
|
||||
var sprite = Owner.GetComponent<SpriteComponent>();
|
||||
var light = Owner.GetComponent<PointLightComponent>();
|
||||
device.OnPowerStateChanged += (sender, args) =>
|
||||
if (LightBulb == null) // No light bulb.
|
||||
{
|
||||
if (args.Powered)
|
||||
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<IGameTiming>().CurTime;
|
||||
@@ -40,10 +146,38 @@ namespace Content.Server.GameObjects.Components.Power
|
||||
}
|
||||
else
|
||||
{
|
||||
device.Load = 0;
|
||||
sprite.LayerSetState(0, "off");
|
||||
light.State = LightState.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<PowerDeviceComponent>();
|
||||
device.OnPowerStateChanged += UpdateLight;
|
||||
|
||||
LightBulbContainer = ContainerManagerComponent.Ensure<ContainerSlot>("light_bulb", Owner, out var existed);
|
||||
|
||||
if (!existed) // Insert a light tube if there wasn't any.
|
||||
{
|
||||
LightBulbContainer.Insert(Owner.EntityManager.SpawnEntity("LightTube"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
BIN
Resources/Textures/Objects/light_tube.rsi/broken.png
Normal file
BIN
Resources/Textures/Objects/light_tube.rsi/broken.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 162 B |
BIN
Resources/Textures/Objects/light_tube.rsi/burned.png
Normal file
BIN
Resources/Textures/Objects/light_tube.rsi/burned.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 236 B |
44
Resources/Textures/Objects/light_tube.rsi/meta.json
Normal file
44
Resources/Textures/Objects/light_tube.rsi/meta.json
Normal file
@@ -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
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/Objects/light_tube.rsi/normal.png
Normal file
BIN
Resources/Textures/Objects/light_tube.rsi/normal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 160 B |
Reference in New Issue
Block a user