diff --git a/Content.Client/Parallax/ParallaxControl.cs b/Content.Client/Parallax/ParallaxControl.cs index 8f56857214a..922d5998da9 100644 --- a/Content.Client/Parallax/ParallaxControl.cs +++ b/Content.Client/Parallax/ParallaxControl.cs @@ -1,10 +1,13 @@ using System.Numerics; +using System.Linq; // Sunrise-Edit using Content.Client.Parallax.Managers; using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Shared.Random; using Robust.Shared.Timing; using Robust.Shared.ViewVariables; +using Robust.Shared.Prototypes; // Sunrise-Edit +using Content.Shared._Sunrise.Lobby; // Sunrise-Edit namespace Content.Client.Parallax; @@ -16,8 +19,12 @@ public sealed class ParallaxControl : Control [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IParallaxManager _parallaxManager = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; // Sunrise-Edit [ViewVariables(VVAccess.ReadWrite)] public Vector2 Offset { get; set; } + [ViewVariables(VVAccess.ReadWrite)] public string CurrentParallax { get; private set; } = "FastSpace"; // Sunrise-Edit + + private readonly HashSet _invalidParallaxes = new(); // Sunrise-Edit public ParallaxControl() { @@ -25,32 +32,74 @@ public ParallaxControl() Offset = new Vector2(_random.Next(0, 1000), _random.Next(0, 1000)); RectClipContent = true; - _parallaxManager.LoadParallaxByName("FastSpace"); + // Sunrise-Edit-Start + SelectRandomParallax(); + } + + private void SelectRandomParallax() + { + var parallaxes = _prototypeManager.EnumeratePrototypes() + .Where(p => !_invalidParallaxes.Contains(p.Parallax)) + .ToList(); + + if (parallaxes.Any()) + { + var selectedParallax = _random.Pick(parallaxes); + CurrentParallax = selectedParallax.Parallax; + } + else + { + CurrentParallax = "FastSpace"; + } + + _parallaxManager.LoadParallaxByName(CurrentParallax); + // Sunrise-Edit-End } protected override void Draw(DrawingHandleScreen handle) { - foreach (var layer in _parallaxManager.GetParallaxLayers("FastSpace")) + if (Size.X <= 0 || Size.Y <= 0) + return; + // Sunrise-Edit-Start + var layers = _parallaxManager.GetParallaxLayers(CurrentParallax).ToList(); + if (!layers.Any()) + { + _invalidParallaxes.Add(CurrentParallax); + SelectRandomParallax(); + return; + } + + var hasValidLayers = false; + foreach (var layer in layers) { var tex = layer.Texture; - var texSize = (tex.Size.X * (int) Size.X, tex.Size.Y * (int) Size.X) * layer.Config.Scale.Floored() / 1920; - var ourSize = PixelSize; + if (tex.Size.X <= 0 || tex.Size.Y <= 0) + continue; + + var scale = layer.Config.Scale.Floored(); + if (scale.X <= 0 || scale.Y <= 0) + continue; + + var texSize = new Vector2i( + (tex.Size.X * (int)Size.X) / 1920, + (tex.Size.Y * (int)Size.X) / 1920 + ) * scale; + + if (texSize.X <= 0 || texSize.Y <= 0) + continue; - var currentTime = (float) _timing.RealTime.TotalSeconds; + hasValidLayers = true; + var ourSize = PixelSize; + var currentTime = (float)_timing.RealTime.TotalSeconds; + // Sunrise-Edit-End var offset = Offset + new Vector2(currentTime * 100f, currentTime * 0f); if (layer.Config.Tiled) { - // Multiply offset by slowness to match normal parallax var scaledOffset = (offset * layer.Config.Slowness).Floored(); - - // Then modulo the scaled offset by the size to prevent drawing a bunch of offscreen tiles for really small images. scaledOffset.X %= texSize.X; scaledOffset.Y %= texSize.Y; - // Note: scaledOffset must never be below 0 or there will be visual issues. - // It could be allowed to be >= texSize on a given axis but that would be wasteful. - for (var x = -scaledOffset.X; x < ourSize.X; x += texSize.X) { for (var y = -scaledOffset.Y; y < ourSize.Y; y += texSize.Y) @@ -65,6 +114,13 @@ protected override void Draw(DrawingHandleScreen handle) handle.DrawTextureRect(tex, UIBox2.FromDimensions(origin, texSize)); } } + // Sunrise-Edit-Start + if (!hasValidLayers) + { + _invalidParallaxes.Add(CurrentParallax); + SelectRandomParallax(); + } + // Sunrise-Edit-End } }