Files
OldThink/Content.Server/GameObjects/Components/Interactable/HandheldLightComponent.cs

189 lines
5.8 KiB
C#
Raw Normal View History

2018-11-21 20:58:11 +01:00
using Content.Server.GameObjects.Components.Power;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects;
using Content.Shared.GameObjects;
using Robust.Server.GameObjects;
using Robust.Server.GameObjects.Components.Container;
using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
namespace Content.Server.GameObjects.Components.Interactable
{
/// <summary>
2018-11-21 20:58:11 +01:00
/// Component that represents a handheld lightsource which can be toggled on and off.
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
/// </summary>
internal class HandheldLightComponent : Component, IUse, IExamine, IAttackBy, IMapInit
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
{
2018-11-21 20:58:11 +01:00
public const float Wattage = 10;
[ViewVariables] private ContainerSlot _cellContainer;
private PointLightComponent _pointLight;
private SpriteComponent _spriteComponent;
private ClothingComponent _clothingComponent;
2018-11-21 20:58:11 +01:00
[ViewVariables]
private PowerCellComponent Cell
{
get
{
2018-11-21 20:58:11 +01:00
if (_cellContainer.ContainedEntity == null) return null;
_cellContainer.ContainedEntity.TryGetComponent(out PowerCellComponent cell);
return cell;
}
}
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
public override string Name => "HandheldLight";
/// <summary>
2018-11-21 20:58:11 +01:00
/// Status of light, whether or not it is emitting light.
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
/// </summary>
2018-09-09 15:34:43 +02:00
[ViewVariables]
2018-11-21 20:58:11 +01:00
public bool Activated { get; private set; }
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
bool IAttackBy.AttackBy(AttackByEventArgs eventArgs)
2018-11-21 20:58:11 +01:00
{
if (!eventArgs.AttackWith.HasComponent<PowerCellComponent>()) return false;
2018-11-21 20:58:11 +01:00
if (Cell != null) return false;
eventArgs.User.GetComponent<IHandsComponent>().Drop(eventArgs.AttackWith, _cellContainer);
2018-11-21 20:58:11 +01:00
return _cellContainer.Insert(eventArgs.AttackWith);
2018-11-21 20:58:11 +01:00
}
void IExamine.Examine(FormattedMessage message)
2018-11-21 20:58:11 +01:00
{
if (Activated)
{
message.AddText("The light is currently on.");
}
2018-11-21 20:58:11 +01:00
}
bool IUse.UseEntity(UseEntityEventArgs eventArgs)
2018-11-21 20:58:11 +01:00
{
return ToggleStatus();
}
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
public override void Initialize()
{
base.Initialize();
_pointLight = Owner.GetComponent<PointLightComponent>();
_spriteComponent = Owner.GetComponent<SpriteComponent>();
Owner.TryGetComponent(out _clothingComponent);
_cellContainer =
ContainerManagerComponent.Ensure<ContainerSlot>("flashlight_cell_container", Owner, out var existed);
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
}
/// <summary>
2018-11-21 20:58:11 +01:00
/// Illuminates the light if it is not active, extinguishes it if it is active.
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
/// </summary>
/// <returns>True if the light's status was toggled, false otherwise.</returns>
public bool ToggleStatus()
{
// Update the activation state.
Activated = !Activated;
// Update sprite and light states to match the activation.
if (Activated)
{
SetState(LightState.On);
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
}
else
{
SetState(LightState.Off);
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
}
// Toggle always succeeds.
return true;
}
public void TurnOff()
{
2018-11-21 20:58:11 +01:00
if (!Activated) return;
SetState(LightState.Off);
Activated = false;
}
public void TurnOn()
{
2018-11-21 20:58:11 +01:00
if (Activated) return;
var cell = Cell;
2018-11-21 20:58:11 +01:00
if (cell == null) return;
// To prevent having to worry about frame time in here.
// Let's just say you need a whole second of charge before you can turn it on.
// Simple enough.
2018-11-21 20:58:11 +01:00
if (cell.AvailableCharge(1) < Wattage) return;
SetState(LightState.On);
}
private void SetState(LightState newState)
{
_spriteComponent.LayerSetVisible(1, newState == LightState.On);
_pointLight.State = newState;
if (_clothingComponent != null)
{
_clothingComponent.ClothingEquippedPrefix = newState.ToString();
}
}
2018-11-21 20:58:11 +01:00
public void OnUpdate(float frameTime)
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
{
2018-11-21 20:58:11 +01:00
if (!Activated) return;
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
2018-11-21 20:58:11 +01:00
var cell = Cell;
if (cell == null || !cell.TryDeductWattage(Wattage, frameTime)) TurnOff();
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
}
2018-11-21 20:58:11 +01:00
private void EjectCell(IEntity user)
{
if (Cell == null) return;
var cell = Cell;
if (!_cellContainer.Remove(cell.Owner)) return;
if (!user.TryGetComponent(out HandsComponent hands)
|| !hands.PutInHand(cell.Owner.GetComponent<ItemComponent>()))
cell.Owner.Transform.GridPosition = user.Transform.GridPosition;
2018-11-21 20:58:11 +01:00
}
[Verb]
public sealed class EjectCellVerb : Verb<HandheldLightComponent>
{
2018-11-21 20:58:11 +01:00
protected override string GetText(IEntity user, HandheldLightComponent component)
{
2018-11-21 20:58:11 +01:00
return component.Cell == null ? "Eject cell (cell missing)" : "Eject cell";
}
2018-11-21 20:58:11 +01:00
protected override bool IsDisabled(IEntity user, HandheldLightComponent component)
{
return component.Cell == null;
}
protected override void Activate(IEntity user, HandheldLightComponent component)
{
2018-11-21 20:58:11 +01:00
component.EjectCell(user);
}
}
void IMapInit.MapInit()
{
if (_cellContainer.ContainedEntity != null)
{
return;
}
var cell = Owner.EntityManager.SpawnEntity("PowerCellSmallHyper");
_cellContainer.Insert(cell);
}
Toggleable flashlight (#106) Fixes second half of #92 Regarding the first half, Digitalis explained in discord that when an entity is picked up, visible components are made invisible by making the entire Godot scene node for the entity (based on the GodotTransformComponent) not visible. It's probably possible to exempt the pointlight from that invisibility, but that seems hacky and it seems like something that should be covered by a generic "items equipped in hands are visible" design. Adds: - Handheld light component for toggling light activation - Lantern sprite with on and off layers - Lantern prototype updates Known issues: - When light is on and on the ground, hovering over it with the cursor does not produce the outline effect. I'm not sure, but I think this is caused by the way I implemented the illuminated layer as an entire sprite rather than just the illuminated part. The outline only works on the first layer maybe? I checked it against the welder in its on state and it doesn't seem to outline the flame. - Illuminated sprite (layer 1) is an entire flashlight, so to make it look okay, the whole first layer is turned off. Would be better / more correct to follow the example of the welder and just create an illuminated "cap" to overlay on the dark extinguished layer. I'd whip up some coder art myself, but I don't have the right tools to handle transparency. - Illuminated sprite is slightly different from the extinguished sprite, so turning on the light makes it a little bit shorter.
2018-08-28 08:39:20 -07:00
}
}