Files
OldThink/Content.Client/GameObjects/Components/Weapons/ClientFlashableComponent.cs

150 lines
4.9 KiB
C#
Raw Normal View History

Add a LOT more dakka (#1033) * 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>
2020-06-22 05:47:15 +10:00
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;
}
}
}