Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
9 changed files
with
296 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
Content.Server/GameObjects/Components/Power/LightBulbComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
|
||
} | ||
} |
170 changes: 152 additions & 18 deletions
170
Content.Server/GameObjects/Components/Power/PoweredLightComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,183 @@ | ||
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; | ||
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"; | ||
|
||
private static readonly TimeSpan _thunkDelay = TimeSpan.FromSeconds(2); | ||
|
||
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<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) | ||
{ | ||
sprite.LayerSetState(0, "on"); | ||
light.State = LightState.On; | ||
var time = IoCManager.Resolve<IGameTiming>().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<IGameTiming>().CurTime; | ||
if (time > _lastThunk + _thunkDelay) | ||
{ | ||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>() | ||
.Play("/Audio/machines/light_tube_on.ogg", Owner, AudioParams.Default.WithVolume(-10f)); | ||
} | ||
} | ||
else | ||
{ | ||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>() | ||
.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<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")); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
] | ||
] | ||
} | ||
] | ||
} |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.