Refactor ghost boo to ECS (#4511)
* Moved ghost boo to ecs * Fixed small light exception * No need to inject EM * Moved cooldown and time to fields Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
@@ -18,7 +18,7 @@ namespace Content.Client.Light.Visualizers
|
|||||||
{
|
{
|
||||||
[DataField("minBlinkingTime")] private float _minBlinkingTime = 0.5f;
|
[DataField("minBlinkingTime")] private float _minBlinkingTime = 0.5f;
|
||||||
[DataField("maxBlinkingTime")] private float _maxBlinkingTime = 2;
|
[DataField("maxBlinkingTime")] private float _maxBlinkingTime = 2;
|
||||||
[DataField("blinkingSound", required: true)] private SoundSpecifier _blinkingSound = default!;
|
[DataField("blinkingSound")] private SoundSpecifier? _blinkingSound = default;
|
||||||
|
|
||||||
private bool _wasBlinking;
|
private bool _wasBlinking;
|
||||||
|
|
||||||
@@ -125,13 +125,16 @@ namespace Content.Client.Light.Visualizers
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
blinkingAnim.AnimationTracks.Add(new AnimationTrackPlaySound()
|
if (_blinkingSound != null)
|
||||||
{
|
{
|
||||||
KeyFrames =
|
blinkingAnim.AnimationTracks.Add(new AnimationTrackPlaySound()
|
||||||
|
{
|
||||||
|
KeyFrames =
|
||||||
{
|
{
|
||||||
new AnimationTrackPlaySound.KeyFrame(_blinkingSound.GetSound(), 0.5f)
|
new AnimationTrackPlaySound.KeyFrame(_blinkingSound.GetSound(), 0.5f)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return blinkingAnim;
|
return blinkingAnim;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,11 @@ namespace Content.Server.Actions.Actions
|
|||||||
var booCounter = 0;
|
var booCounter = 0;
|
||||||
foreach (var ent in ents)
|
foreach (var ent in ents)
|
||||||
{
|
{
|
||||||
var boos = ent.GetAllComponents<IGhostBooAffected>().ToList();
|
var ghostBoo = new GhostBooEvent();
|
||||||
foreach (var boo in boos)
|
ent.EntityManager.EventBus.RaiseLocalEvent(ent.Uid, ghostBoo);
|
||||||
{
|
|
||||||
if (boo.AffectedByGhostBoo(args))
|
if (ghostBoo.Handled)
|
||||||
booCounter++;
|
booCounter++;
|
||||||
}
|
|
||||||
|
|
||||||
if (booCounter >= _maxTargets)
|
if (booCounter >= _maxTargets)
|
||||||
break;
|
break;
|
||||||
|
|||||||
9
Content.Server/Ghost/GhostBooEvent.cs
Normal file
9
Content.Server/Ghost/GhostBooEvent.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Ghost
|
||||||
|
{
|
||||||
|
public class GhostBooEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using Content.Shared.Actions.Behaviors;
|
|
||||||
|
|
||||||
namespace Content.Server.Ghost
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Allow ghost to interact with object by boo action
|
|
||||||
/// </summary>
|
|
||||||
public interface IGhostBooAffected
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Invokes when ghost used boo action near entity.
|
|
||||||
/// Use it to blink lights or make something spooky.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">Boo action details</param>
|
|
||||||
/// <returns>Returns true if object was affected</returns>
|
|
||||||
bool AffectedByGhostBoo(InstantActionEventArgs args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.Ghost;
|
|
||||||
using Content.Server.Hands.Components;
|
using Content.Server.Hands.Components;
|
||||||
using Content.Server.Items;
|
using Content.Server.Items;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Temperature.Components;
|
using Content.Server.Temperature.Components;
|
||||||
using Content.Shared.Actions.Behaviors;
|
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Damage.Components;
|
using Content.Shared.Damage.Components;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
@@ -30,22 +28,19 @@ namespace Content.Server.Light.Components
|
|||||||
/// Component that represents a wall light. It has a light bulb that can be replaced when broken.
|
/// Component that represents a wall light. It has a light bulb that can be replaced when broken.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class PoweredLightComponent : Component, IInteractHand, IInteractUsing, IMapInit, IGhostBooAffected
|
public class PoweredLightComponent : Component, IInteractHand, IInteractUsing, IMapInit
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
public override string Name => "PoweredLight";
|
public override string Name => "PoweredLight";
|
||||||
|
|
||||||
private static readonly TimeSpan _thunkDelay = TimeSpan.FromSeconds(2);
|
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]
|
[ComponentDependency]
|
||||||
private readonly AppearanceComponent? _appearance;
|
private readonly AppearanceComponent? _appearance;
|
||||||
|
|
||||||
private TimeSpan _lastThunk;
|
private TimeSpan _lastThunk;
|
||||||
private TimeSpan? _lastGhostBlink;
|
public TimeSpan? LastGhostBlink;
|
||||||
|
|
||||||
[DataField("burnHandSound")]
|
[DataField("burnHandSound")]
|
||||||
private SoundSpecifier _burnHandSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
|
private SoundSpecifier _burnHandSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
|
||||||
@@ -64,11 +59,20 @@ namespace Content.Server.Light.Components
|
|||||||
private bool _currentLit;
|
private bool _currentLit;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private bool _isBlinking;
|
public bool IsBlinking;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
[DataField("ignoreGhostsBoo")]
|
[DataField("ignoreGhostsBoo")]
|
||||||
private bool _ignoreGhostsBoo;
|
public bool IgnoreGhostsBoo;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
[DataField("ghostBlinkingTime")]
|
||||||
|
public TimeSpan GhostBlinkingTime = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
[DataField("ghostBlinkingCooldown")]
|
||||||
|
public TimeSpan GhostBlinkingCooldown = TimeSpan.FromSeconds(60);
|
||||||
|
|
||||||
|
|
||||||
[DataField("bulb")] private LightBulbType _bulbType = LightBulbType.Tube;
|
[DataField("bulb")] private LightBulbType _bulbType = LightBulbType.Tube;
|
||||||
public LightBulbType BulbType => _bulbType;
|
public LightBulbType BulbType => _bulbType;
|
||||||
@@ -312,36 +316,6 @@ namespace Content.Server.Light.Components
|
|||||||
UpdateLight();
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Server.Ghost;
|
||||||
|
using Content.Server.Light.Components;
|
||||||
|
using Content.Shared.Light;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
using Content.Server.Light.Components;
|
using Content.Server.Light.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
using Content.Server.MachineLinking.Events;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -6,13 +14,51 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
{
|
{
|
||||||
public class PoweredLightSystem : EntitySystem
|
public class PoweredLightSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<PoweredLightComponent, GhostBooEvent>(OnGhostBoo);
|
||||||
SubscribeLocalEvent<PoweredLightComponent, SignalReceivedEvent>(OnSignalReceived);
|
SubscribeLocalEvent<PoweredLightComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGhostBoo(EntityUid uid, PoweredLightComponent light, GhostBooEvent args)
|
||||||
|
{
|
||||||
|
if (light.IgnoreGhostsBoo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check cooldown first to prevent abuse
|
||||||
|
var time = _gameTiming.CurTime;
|
||||||
|
if (light.LastGhostBlink != null)
|
||||||
|
{
|
||||||
|
if (time <= light.LastGhostBlink + light.GhostBlinkingCooldown)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
light.LastGhostBlink = time;
|
||||||
|
|
||||||
|
ToggleBlinkingLight(light, true);
|
||||||
|
light.Owner.SpawnTimer(light.GhostBlinkingTime, () =>
|
||||||
|
{
|
||||||
|
ToggleBlinkingLight(light, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleBlinkingLight(PoweredLightComponent light, bool isNowBlinking)
|
||||||
|
{
|
||||||
|
if (light.IsBlinking == isNowBlinking)
|
||||||
|
return;
|
||||||
|
|
||||||
|
light.IsBlinking = isNowBlinking;
|
||||||
|
|
||||||
|
if (!light.Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
return;
|
||||||
|
appearance.SetData(PoweredLightVisuals.Blinking, isNowBlinking);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnSignalReceived(EntityUid uid, PoweredLightComponent component, SignalReceivedEvent args)
|
private void OnSignalReceived(EntityUid uid, PoweredLightComponent component, SignalReceivedEvent args)
|
||||||
{
|
{
|
||||||
switch (args.Port)
|
switch (args.Port)
|
||||||
|
|||||||
Reference in New Issue
Block a user