Get rid of the OverlayEffectsComponent stuff (#3010)
* Get rid of the OverlayEffectsComponent stuff because it just ended up creating workarounds for it's bugs, without removing any functionality * Flashes and Flashbangs use the same code now (the Flashable path because it's better)
This commit is contained in:
@@ -1,169 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics.Overlays;
|
||||
using Robust.Client.Interfaces.Graphics.Overlays;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Mobs
|
||||
{
|
||||
/// <summary>
|
||||
/// A character UI component which shows the current damage state of the mob (living/dead)
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedOverlayEffectsComponent))]
|
||||
public sealed class ClientOverlayEffectsComponent : SharedOverlayEffectsComponent//, ICharacterUI
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
|
||||
[Dependency] private readonly IClientNetManager _netManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// A list of overlay containers representing the current overlays applied
|
||||
/// </summary>
|
||||
private List<OverlayContainer> _currentEffects = new();
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public List<OverlayContainer> ActiveOverlays
|
||||
{
|
||||
get => _currentEffects;
|
||||
set => SetEffects(value);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
UpdateOverlays();
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, IComponent component)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg _:
|
||||
UpdateOverlays();
|
||||
break;
|
||||
case PlayerDetachedMsg _:
|
||||
ActiveOverlays.ForEach(o => _overlayManager.RemoveOverlay(o.ID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession session = null)
|
||||
{
|
||||
base.HandleNetworkMessage(message, netChannel, session);
|
||||
if (message is OverlayEffectComponentMessage overlayMessage)
|
||||
{
|
||||
SetEffects(overlayMessage.Overlays);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateOverlays()
|
||||
{
|
||||
_currentEffects = _overlayManager.AllOverlays
|
||||
.Where(overlay => Enum.IsDefined(typeof(SharedOverlayID), overlay.ID))
|
||||
.Select(overlay => new OverlayContainer(overlay.ID))
|
||||
.ToList();
|
||||
|
||||
foreach (var overlayContainer in ActiveOverlays)
|
||||
{
|
||||
if (!_overlayManager.HasOverlay(overlayContainer.ID))
|
||||
{
|
||||
if (TryCreateOverlay(overlayContainer, out var overlay))
|
||||
{
|
||||
_overlayManager.AddOverlay(overlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendNetworkMessage(new ResendOverlaysMessage(), _netManager.ServerChannel);
|
||||
}
|
||||
|
||||
private void SetEffects(List<OverlayContainer> newOverlays)
|
||||
{
|
||||
foreach (var container in ActiveOverlays.ToArray())
|
||||
{
|
||||
if (!newOverlays.Contains(container))
|
||||
{
|
||||
RemoveOverlay(container);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var container in newOverlays)
|
||||
{
|
||||
if (!ActiveOverlays.Contains(container))
|
||||
{
|
||||
AddOverlay(container);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOverlayConfiguration(container, _overlayManager.GetOverlay(container.ID));
|
||||
}
|
||||
}
|
||||
|
||||
_currentEffects = newOverlays;
|
||||
}
|
||||
|
||||
private void RemoveOverlay(OverlayContainer container)
|
||||
{
|
||||
ActiveOverlays.Remove(container);
|
||||
_overlayManager.RemoveOverlay(container.ID);
|
||||
}
|
||||
|
||||
private void AddOverlay(OverlayContainer container)
|
||||
{
|
||||
if (_overlayManager.HasOverlay(container.ID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ActiveOverlays.Add(container);
|
||||
if (TryCreateOverlay(container, out var overlay))
|
||||
{
|
||||
_overlayManager.AddOverlay(overlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.ErrorS("overlay", $"Could not add overlay {container.ID}");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateOverlayConfiguration(OverlayContainer container, Overlay overlay)
|
||||
{
|
||||
if (overlay is IConfigurableOverlay configurable)
|
||||
{
|
||||
foreach (var param in container.Parameters)
|
||||
{
|
||||
configurable.Configure(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryCreateOverlay(OverlayContainer container, out Overlay overlay)
|
||||
{
|
||||
var overlayTypes = _reflectionManager.GetAllChildren<Overlay>();
|
||||
var overlayType = overlayTypes.FirstOrDefault(t => t.Name == container.ID);
|
||||
|
||||
if (overlayType != null)
|
||||
{
|
||||
overlay = IoCManager.Resolve<IDynamicTypeFactory>().CreateInstance<Overlay>(overlayType);
|
||||
UpdateOverlayConfiguration(container, overlay);
|
||||
return true;
|
||||
}
|
||||
|
||||
overlay = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Content.Client.Graphics.Overlays;
|
||||
using Content.Shared.GameObjects.Components.Weapons;
|
||||
using Robust.Client.Graphics.Drawing;
|
||||
using Robust.Client.Graphics.Overlays;
|
||||
@@ -19,10 +20,8 @@ namespace Content.Client.GameObjects.Components.Weapons
|
||||
[RegisterComponent]
|
||||
public sealed class FlashableComponent : SharedFlashableComponent
|
||||
{
|
||||
private CancellationTokenSource _cancelToken;
|
||||
private TimeSpan _startTime;
|
||||
private double _duration;
|
||||
private FlashOverlay _overlay;
|
||||
|
||||
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||
{
|
||||
@@ -57,94 +56,15 @@ namespace Content.Client.GameObjects.Components.Weapons
|
||||
|
||||
if (currentTime > newEndTime)
|
||||
{
|
||||
DisableOverlay();
|
||||
return;
|
||||
}
|
||||
|
||||
_startTime = newState.Time;
|
||||
_duration = newState.Duration;
|
||||
|
||||
EnableOverlay(newEndTime - currentTime);
|
||||
}
|
||||
|
||||
private void EnableOverlay(double duration)
|
||||
{
|
||||
// If the timer gets reset
|
||||
if (_overlay != null)
|
||||
{
|
||||
_overlay.Duration = _duration;
|
||||
_overlay.StartTime = _startTime;
|
||||
_cancelToken.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
var overlayManager = IoCManager.Resolve<IOverlayManager>();
|
||||
_overlay = new FlashOverlay(_duration);
|
||||
overlayManager.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
_cancelToken = new CancellationTokenSource();
|
||||
Owner.SpawnTimer((int) duration * 1000, DisableOverlay, _cancelToken.Token);
|
||||
}
|
||||
|
||||
private void DisableOverlay()
|
||||
{
|
||||
if (_overlay == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var overlayManager = IoCManager.Resolve<IOverlayManager>();
|
||||
overlayManager.RemoveOverlay(_overlay.ID);
|
||||
_overlay = null;
|
||||
_cancelToken.Cancel();
|
||||
_cancelToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class FlashOverlay : Overlay
|
||||
{
|
||||
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
|
||||
private readonly IGameTiming _timer;
|
||||
private readonly IClyde _displayManager;
|
||||
public TimeSpan StartTime { get; set; }
|
||||
public double Duration { get; set; }
|
||||
public FlashOverlay(double duration) : base(nameof(FlashOverlay))
|
||||
{
|
||||
_timer = IoCManager.Resolve<IGameTiming>();
|
||||
_displayManager = IoCManager.Resolve<IClyde>();
|
||||
StartTime = _timer.CurTime;
|
||||
Duration = duration;
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleBase handle, OverlaySpace currentSpace)
|
||||
{
|
||||
var elapsedTime = (_timer.CurTime - StartTime).TotalSeconds;
|
||||
if (elapsedTime > Duration)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var screenHandle = (DrawingHandleScreen) handle;
|
||||
|
||||
screenHandle.DrawRect(
|
||||
new UIBox2(0.0f, 0.0f, _displayManager.ScreenSize.X, _displayManager.ScreenSize.Y),
|
||||
Color.White.WithAlpha(GetAlpha(elapsedTime / Duration))
|
||||
);
|
||||
}
|
||||
|
||||
private float GetAlpha(double ratio)
|
||||
{
|
||||
// Ideally you just want a smooth slope to finish it so it's not jarring at the end
|
||||
// By all means put in a better curve
|
||||
const float slope = -9.0f;
|
||||
const float exponent = 0.1f;
|
||||
const float yOffset = 9.0f;
|
||||
const float xOffset = 0.0f;
|
||||
|
||||
// Overkill but easy to adjust if you want to mess around with the design
|
||||
var result = (float) MathHelper.Clamp(slope * (float) Math.Pow(ratio - xOffset, exponent) + yOffset, 0.0, 1.0);
|
||||
DebugTools.Assert(!float.IsNaN(result));
|
||||
return result;
|
||||
var overlay = overlayManager.GetOverlay<FlashOverlay>(nameof(FlashOverlay));
|
||||
overlay.ReceiveFlash(_duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user