2021-04-19 09:52:40 +02:00
using System ;
2021-06-09 22:19:39 +02:00
using Content.Client.Parallax.Managers ;
2022-05-04 17:55:21 +01:00
using Content.Shared.CCVar ;
2019-04-15 21:11:38 -06:00
using Robust.Client.Graphics ;
2022-05-04 17:55:21 +01:00
using Robust.Shared.Configuration ;
2021-03-09 04:33:41 -06:00
using Robust.Shared.Enums ;
2019-04-15 21:11:38 -06:00
using Robust.Shared.IoC ;
using Robust.Shared.Maths ;
using Robust.Shared.Prototypes ;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
namespace Content.Client.Parallax ;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
public sealed class ParallaxOverlay : Overlay
{
[Dependency] private readonly IParallaxManager _parallaxManager = default ! ;
[Dependency] private readonly IPrototypeManager _prototypeManager = default ! ;
[Dependency] private readonly IConfigurationManager _configurationManager = default ! ;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
public override OverlaySpace Space = > OverlaySpace . WorldSpaceBelowWorld ;
private readonly ShaderInstance _shader ;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
public ParallaxOverlay ( )
{
IoCManager . InjectDependencies ( this ) ;
_shader = _prototypeManager . Index < ShaderPrototype > ( "unshaded" ) . Instance ( ) ;
}
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
protected override void Draw ( in OverlayDrawArgs args )
{
if ( args . Viewport . Eye = = null )
2018-11-30 21:54:30 +01:00
{
2022-05-04 17:55:21 +01:00
return ;
}
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
if ( ! _configurationManager . GetCVar ( CCVars . ParallaxEnabled ) )
{
return ;
2018-11-30 21:54:30 +01:00
}
2022-05-04 17:55:21 +01:00
var screenHandle = args . WorldHandle ;
screenHandle . UseShader ( _shader ) ;
foreach ( var layer in _parallaxManager . ParallaxLayers )
2018-11-30 21:54:30 +01:00
{
2022-05-04 17:55:21 +01:00
var tex = layer . Texture ;
// Size of the texture in world units.
var size = ( tex . Size / ( float ) EyeManager . PixelsPerMeter ) * layer . Config . Scale ;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
// The "home" position is the effective origin of this layer.
// Parallax shifting is relative to the home, and shifts away from the home and towards the Eye centre.
// The effects of this are such that a slowness of 1 anchors the layer to the centre of the screen, while a slowness of 0 anchors the layer to the world.
// (For values 0.0 to 1.0 this is in effect a lerp, but it's deliberately unclamped.)
// The ParallaxAnchor adapts the parallax for station positioning and possibly map-specific tweaks.
var home = layer . Config . WorldHomePosition + _parallaxManager . ParallaxAnchor ;
2019-07-06 19:20:20 +02:00
2022-05-04 17:55:21 +01:00
// Origin - start with the parallax shift itself.
var originBL = ( args . Viewport . Eye . Position . Position - home ) * layer . Config . Slowness ;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
// Place at the home.
originBL + = home ;
2021-04-19 09:52:40 +02:00
2022-05-04 17:55:21 +01:00
// Adjust.
originBL + = layer . Config . WorldAdjustPosition ;
2021-04-19 09:52:40 +02:00
2022-05-04 17:55:21 +01:00
// Centre the image.
originBL - = size / 2 ;
2021-04-19 09:52:40 +02:00
2022-05-04 17:55:21 +01:00
if ( layer . Config . Tiled )
2021-04-19 09:52:40 +02:00
{
2022-05-04 17:55:21 +01:00
// Remove offset so we can floor.
var flooredBL = args . WorldAABB . BottomLeft - originBL ;
// Floor to background size.
flooredBL = ( flooredBL / size ) . Floored ( ) * size ;
// Re-offset.
flooredBL + = originBL ;
for ( var x = flooredBL . X ; x < args . WorldAABB . Right ; x + = size . X )
2021-04-19 09:52:40 +02:00
{
2022-05-04 17:55:21 +01:00
for ( var y = flooredBL . Y ; y < args . WorldAABB . Top ; y + = size . Y )
{
screenHandle . DrawTextureRect ( tex , Box2 . FromDimensions ( ( x , y ) , size ) ) ;
}
2020-01-26 05:02:12 -08:00
}
}
2022-05-04 17:55:21 +01:00
else
{
screenHandle . DrawTextureRect ( tex , Box2 . FromDimensions ( originBL , size ) ) ;
}
2018-11-30 21:54:30 +01:00
}
}
}
2022-05-04 17:55:21 +01:00