Files
OldThink/Content.Client/Parallax/ParallaxOverlay.cs

119 lines
4.3 KiB
C#
Raw Permalink Normal View History

using System.Numerics;
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;
using Content.Shared.Parallax.Biomes;
using Robust.Client.Graphics;
2022-05-04 17:55:21 +01:00
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
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 IEntityManager _entManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
2022-05-04 17:55:21 +01:00
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IParallaxManager _manager = default!;
private readonly ParallaxSystem _parallax;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowWorld;
2018-11-30 21:54:30 +01:00
2022-05-04 17:55:21 +01:00
public ParallaxOverlay()
{
ZIndex = ParallaxSystem.ParallaxZIndex;
2022-05-04 17:55:21 +01:00
IoCManager.InjectDependencies(this);
_parallax = _entManager.System<ParallaxSystem>();
}
protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (args.MapId == MapId.Nullspace || _entManager.HasComponent<BiomeComponent>(_mapManager.GetMapEntityId(args.MapId)))
return false;
return true;
2022-05-04 17:55:21 +01:00
}
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.MapId == MapId.Nullspace)
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
var position = args.Viewport.Eye?.Position.Position ?? Vector2.Zero;
2023-06-28 21:22:03 +10:00
var worldHandle = args.WorldHandle;
2022-05-04 17:55:21 +01:00
var layers = _parallax.GetParallaxLayers(args.MapId);
var realTime = (float) _timing.RealTime.TotalSeconds;
foreach (var layer in layers)
2018-11-30 21:54:30 +01:00
{
ShaderInstance? shader;
if (!string.IsNullOrEmpty(layer.Config.Shader))
shader = _prototypeManager.Index<ShaderPrototype>(layer.Config.Shader).Instance();
else
shader = null;
2023-06-28 21:22:03 +10:00
worldHandle.UseShader(shader);
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 + _manager.ParallaxAnchor;
var scrolled = layer.Config.Scrolling * realTime;
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 = (position - home) * layer.Config.Slowness + scrolled;
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)
{
worldHandle.DrawTextureRect(tex, Box2.FromDimensions(new Vector2(x, y), size));
2022-05-04 17:55:21 +01:00
}
}
}
2022-05-04 17:55:21 +01:00
else
{
2023-06-28 21:22:03 +10:00
worldHandle.DrawTextureRect(tex, Box2.FromDimensions(originBL, size));
2022-05-04 17:55:21 +01:00
}
2018-11-30 21:54:30 +01:00
}
2023-06-28 21:22:03 +10:00
worldHandle.UseShader(null);
2018-11-30 21:54:30 +01:00
}
}
2022-05-04 17:55:21 +01:00