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:
Alex Evgrashin
2021-08-31 11:33:55 +03:00
committed by GitHub
parent 4b4c8a41d7
commit 4c873e53f2
6 changed files with 82 additions and 69 deletions

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -0,0 +1,9 @@
using Robust.Shared.GameObjects;
namespace Content.Server.Ghost
{
public class GhostBooEvent : HandledEntityEventArgs
{
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
} }
} }

View File

@@ -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)