Ghosts do booo (spooky) (#3363)

* Light now use visualizer

* Added ghost actions

* Add hotkey input for ghosts

* no message

* Testing blinking animation

* Better animation

* Better customization

* No abuse

* Reversed sln

* No fun for ghosts

* No fun for ghosts x2

* Cooldown for lights

* Moved to component deps

* This tollist is unnecessary

* Enums to byte

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Some lights can ignore ghosts now

Co-authored-by: Alex Evgrashin <evgrashin.adl@gmail.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
Alex Evgrashin
2021-02-26 04:31:06 +03:00
committed by GitHub
parent d177f0fd07
commit 0fa219365e
11 changed files with 360 additions and 35 deletions

View File

@@ -6,8 +6,11 @@ using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.MachineLinking;
using Content.Server.GameObjects.Components.MachineLinking.Signals;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Observer;
using Content.Shared.Actions;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.Components.Power.ApcNetComponents.PowerReceiverUsers;
using Content.Shared.Interfaces;
using Content.Shared.Interfaces.GameObjects.Components;
using Robust.Server.GameObjects;
@@ -15,6 +18,7 @@ using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using Robust.Shared.ViewVariables;
@@ -25,17 +29,27 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
/// Component that represents a wall light. It has a light bulb that can be replaced when broken.
/// </summary>
[RegisterComponent]
public class PoweredLightComponent : Component, IInteractHand, IInteractUsing, IMapInit, ISignalReceiver<bool>, ISignalReceiver<ToggleSignal>
public class PoweredLightComponent : Component, IInteractHand, IInteractUsing, IMapInit, ISignalReceiver<bool>, ISignalReceiver<ToggleSignal>, IGhostBooAffected
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
public override string Name => "PoweredLight";
private static readonly TimeSpan _thunkDelay = TimeSpan.FromSeconds(2);
// time to blink light when ghost made boo nearby
private static readonly TimeSpan ghostBlinkingTime = TimeSpan.FromSeconds(10);
private static readonly TimeSpan ghostBlinkingCooldown = TimeSpan.FromSeconds(60);
[ComponentDependency]
private readonly AppearanceComponent? _appearance;
private TimeSpan _lastThunk;
private TimeSpan? _lastGhostBlink;
private bool _hasLampOnSpawn;
[ViewVariables] private bool _on;
[ViewVariables] private bool _isBlinking;
[ViewVariables] private bool _ignoreGhostsBoo;
private LightBulbType BulbType = LightBulbType.Tube;
[ViewVariables] private ContainerSlot _lightBulbContainer = default!;
@@ -145,6 +159,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
serializer.DataField(ref BulbType, "bulb", LightBulbType.Tube);
serializer.DataField(ref _on, "on", true);
serializer.DataField(ref _hasLampOnSpawn, "hasLampOnSpawn", true);
serializer.DataField(ref _ignoreGhostsBoo, "ignoreGhostsBoo", false);
}
/// <summary>
@@ -163,13 +178,11 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
public void UpdateLight()
{
var powerReceiver = Owner.GetComponent<PowerReceiverComponent>();
var sprite = Owner.GetComponent<SpriteComponent>();
var light = Owner.GetComponent<PointLightComponent>();
if (LightBulb == null) // No light bulb.
{
powerReceiver.Load = 0;
sprite.LayerSetState(0, "empty");
light.Enabled = false;
_appearance?.SetData(PoweredLightVisuals.BulbState, PoweredLightState.Empty);
return;
}
@@ -179,9 +192,8 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
if (powerReceiver.Powered && _on)
{
powerReceiver.Load = LightBulb.PowerUse;
sprite.LayerSetState(0, "on");
light.Enabled = true;
light.Color = LightBulb.Color;
_appearance?.SetData(PoweredLightVisuals.BulbState, PoweredLightState.On);
_appearance?.SetData(PoweredLightVisuals.BulbColor, LightBulb.Color);
var time = _gameTiming.CurTime;
if (time > _lastThunk + _thunkDelay)
{
@@ -191,17 +203,14 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
}
else
{
sprite.LayerSetState(0, "off");
light.Enabled = false;
_appearance?.SetData(PoweredLightVisuals.BulbState, PoweredLightState.Off);
}
break;
case LightBulbState.Broken:
sprite.LayerSetState(0, "broken");
light.Enabled = false;
_appearance?.SetData(PoweredLightVisuals.BulbState, PoweredLightState.Broken);
break;
case LightBulbState.Burned:
sprite.LayerSetState(0, "burned");
light.Enabled = false;
_appearance?.SetData(PoweredLightVisuals.BulbState, PoweredLightState.Burned);
break;
}
}
@@ -268,5 +277,36 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
_on = !_on;
UpdateLight();
}
public void ToggleBlinkingLight(bool isNowBlinking)
{
if (_isBlinking == isNowBlinking)
return;
_isBlinking = isNowBlinking;
_appearance?.SetData(PoweredLightVisuals.Blinking, _isBlinking);
}
public bool AffectedByGhostBoo(InstantActionEventArgs args)
{
if (_ignoreGhostsBoo)
return false;
// check cooldown first to prevent abuse
var time = _gameTiming.CurTime;
if (_lastGhostBlink != null)
{
if (time <= _lastGhostBlink + ghostBlinkingCooldown)
return false;
}
_lastGhostBlink = time;
ToggleBlinkingLight(true);
Owner.SpawnTimer(ghostBlinkingTime, () => {
ToggleBlinkingLight(false);
});
return true;
}
}
}