* Start adding flashy flash * Change slop Might give a smoother decline * flashy flash * Add flashbang and flash projectiles Bang bang bang pull my flash trigger * Add collision check to area flash * Flash cleanupo * flash.ogg mixed to mono * Adjusted flash curve again * Enhancing flashes with unshaded and lights and shit Still a WIP * Add the other ballistic gun types Re-organised some of the gun stuff so the powercell guns share the shooting code with the ballistic guns. * Re-merging branch with master Also fixed some visualizer bugs * Last cleanup Fixed some crashes Fixed Deckard sprite Fixed Hitscan effects Re-applied master changes Re-factor to using soundsystem Add some more audio effects * Cleanup flashes for merge Can put flashbangs in lockers so you don't get blinded Fix some bugs * Fix shotties Also removed some redundant code * Bulldoze some legacycode brrrrrrrrt * Fix clientignore warnings * Add the other Stunnable types to StunnableProjectile * Some gun refactoring * Removed extra visualizers * All casing ejections use the same code * Speed loaders can have their ammo pulled out * Bolt sound less loud * Stop ThrowController from throwing * Fix speed loader visuals * Update hitscan collision mask and fix typo * Cleanup * Fit hitscan and flashbang collisions * Use the new flags support * Update taser placeholder description * Update protonames per style guide * Add yaml flag support for gun firerates * Cleanup crew * Fix Audio up (components, audio file, + remove global sounds) * Add server-side recoil back-in (forgot that I was testing this client-side) * Add Flag support for fire-rate selectors * Wrong int you dolt * Fix AI conflicts Haha ranged bulldozer go BRR (I'll rewrite it after the other AI systems are done). * Mix bang.ogg from stereo to mono * Make sure serializer's reading for guns Fixes integration test * Change EntitySystem calls to use the static function Also removed the Pumpbarrel commented-out code * Change StunnableProjectile defaults to 0 * Fix taser paralyse Apparently removing defaults means you have to specify the values, whodathunkit * Add slowdown to stunnableprojectiles and fix tasers * Remove FlagsFor from gun components Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com> Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com>
150 lines
4.9 KiB
C#
150 lines
4.9 KiB
C#
using System;
|
|
using System.Threading;
|
|
using Content.Shared.GameObjects.Components.Weapons;
|
|
using Robust.Client.Graphics.Drawing;
|
|
using Robust.Client.Graphics.Overlays;
|
|
using Robust.Client.Interfaces.Graphics;
|
|
using Robust.Client.Interfaces.Graphics.Overlays;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Interfaces.Timing;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Maths;
|
|
using Robust.Shared.Utility;
|
|
using Timer = Robust.Shared.Timers.Timer;
|
|
|
|
namespace Content.Client.GameObjects.Components.Weapons
|
|
{
|
|
[RegisterComponent]
|
|
public sealed class ClientFlashableComponent : SharedFlashableComponent
|
|
{
|
|
private CancellationTokenSource _cancelToken;
|
|
private TimeSpan _startTime;
|
|
private double _duration;
|
|
private FlashOverlay _overlay;
|
|
|
|
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
|
{
|
|
if (curState == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var playerManager = IoCManager.Resolve<IPlayerManager>();
|
|
if (playerManager.LocalPlayer.ControlledEntity != Owner)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var newState = (FlashComponentState) curState;
|
|
if (newState.Time == default)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Few things here:
|
|
// 1. If a shorter duration flash is applied then don't do anything
|
|
// 2. If the client-side time is later than when the flash should've ended don't do anything
|
|
var currentTime = IoCManager.Resolve<IGameTiming>().CurTime.TotalSeconds;
|
|
var newEndTime = newState.Time.TotalSeconds + newState.Duration;
|
|
var currentEndTime = _startTime.TotalSeconds + _duration;
|
|
|
|
if (currentEndTime > newEndTime)
|
|
{
|
|
return;
|
|
}
|
|
|
|
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();
|
|
Timer.Spawn((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)
|
|
{
|
|
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) Math.Clamp(slope * (float) Math.Pow(ratio - xOffset, exponent) + yOffset, 0.0, 1.0);
|
|
DebugTools.Assert(!float.IsNaN(result));
|
|
return result;
|
|
}
|
|
}
|
|
}
|