diff --git a/Content.Client/Overlays/StencilOverlay.cs b/Content.Client/Overlays/StencilOverlay.cs index 22064ae609..14a86e5854 100644 --- a/Content.Client/Overlays/StencilOverlay.cs +++ b/Content.Client/Overlays/StencilOverlay.cs @@ -1,6 +1,7 @@ using System.Numerics; using Content.Client.Parallax; using Content.Client.Weather; +using Content.Shared._CP14.DayCycle; using Content.Shared._CP14.WorldEdge; using Content.Shared.Salvage; using Content.Shared.Weather; @@ -73,12 +74,17 @@ public sealed partial class StencilOverlay : Overlay DrawRestrictedRange(args, restrictedRangeComponent, invMatrix); } - //CP14 World Edge overlay + //CP14 Overlays + if (_entManager.TryGetComponent(mapUid, out var shadows)) + { + DrawCloudShadows(args, shadows, invMatrix); + } + if (_entManager.TryGetComponent(mapUid, out var worldEdge)) { DrawWorldEdge(args, worldEdge, invMatrix); } - //CP14 World Edge overlay end + //CP14 Overlays end args.WorldHandle.UseShader(null); args.WorldHandle.SetTransform(Matrix3x2.Identity); diff --git a/Content.Client/_CP14/Overlays/StencilOverlay.CloudShadows.cs b/Content.Client/_CP14/Overlays/StencilOverlay.CloudShadows.cs new file mode 100644 index 0000000000..13950801d3 --- /dev/null +++ b/Content.Client/_CP14/Overlays/StencilOverlay.CloudShadows.cs @@ -0,0 +1,65 @@ +using System.Numerics; +using Content.Shared._CP14.DayCycle; +using Robust.Client.Graphics; +using Robust.Shared.Utility; + +namespace Content.Client.Overlays; + +public sealed partial class StencilOverlay +{ + private void DrawCloudShadows(in OverlayDrawArgs args, CP14CloudShadowsComponent cloudComp, Matrix3x2 invMatrix) + { + var worldHandle = args.WorldHandle; + var mapId = args.MapId; + var worldAABB = args.WorldAABB; + var worldBounds = args.WorldBounds; + var position = args.Viewport.Eye?.Position.Position ?? Vector2.Zero; + + // Cut out the irrelevant bits via stencil + // This is why we don't just use parallax; we might want specific tiles to get drawn over + // particularly for planet maps or stations. + worldHandle.RenderInRenderTarget(_blep!, () => + { + var xformQuery = _entManager.GetEntityQuery(); + _grids.Clear(); + + // idk if this is safe to cache in a field and clear sloth help + _mapManager.FindGridsIntersecting(mapId, worldAABB, ref _grids); + + foreach (var grid in _grids) + { + var matrix = _transform.GetWorldMatrix(grid, xformQuery); + var matty = Matrix3x2.Multiply(matrix, invMatrix); + worldHandle.SetTransform(matty); + + foreach (var tile in grid.Comp.GetTilesIntersecting(worldAABB)) + { + // Ignored tiles for stencil + if (_weather.CanWeatherAffect(grid.Owner, grid, tile)) + { + continue; + } + + var gridTile = new Box2(tile.GridIndices * grid.Comp.TileSize, + (tile.GridIndices + Vector2i.One) * grid.Comp.TileSize); + + worldHandle.DrawRect(gridTile, Color.White); + } + } + + }, Color.Transparent); + + worldHandle.SetTransform(Matrix3x2.Identity); + worldHandle.UseShader(_protoManager.Index("StencilMask").Instance()); + worldHandle.DrawTextureRect(_blep!.Texture, worldBounds); + var curTime = _timing.RealTime; + var sprite = _sprite.GetFrame(new SpriteSpecifier.Texture(new ResPath(cloudComp.ParallaxPath)), curTime); + + // Draw the rain + worldHandle.UseShader(_protoManager.Index("StencilDraw").Instance()); + _parallax.DrawParallax(worldHandle, worldAABB, sprite, curTime, position, cloudComp.CloudSpeed, modulate: Color.White.WithAlpha(cloudComp.Alpha), scale: cloudComp.Scale); + + worldHandle.SetTransform(Matrix3x2.Identity); + worldHandle.UseShader(null); + } +} diff --git a/Content.Server/_CP14/DayCycle/CP14CloudShadowsSystem.cs b/Content.Server/_CP14/DayCycle/CP14CloudShadowsSystem.cs new file mode 100644 index 0000000000..2de54120ec --- /dev/null +++ b/Content.Server/_CP14/DayCycle/CP14CloudShadowsSystem.cs @@ -0,0 +1,24 @@ +using System.Numerics; +using Content.Shared._CP14.DayCycle; +using Robust.Shared.Random; + +namespace Content.Server._CP14.DayCycle; + +public sealed partial class CP14CloudShadowsSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + ent.Comp.CloudSpeed = new Vector2( + _random.NextFloat(-ent.Comp.MaxSpeed, ent.Comp.MaxSpeed), + _random.NextFloat(-ent.Comp.MaxSpeed, ent.Comp.MaxSpeed)); + } +} diff --git a/Content.Shared/_CP14/DayCycle/CP14CloudShadowsComponent.cs b/Content.Shared/_CP14/DayCycle/CP14CloudShadowsComponent.cs new file mode 100644 index 0000000000..2ebfd7f568 --- /dev/null +++ b/Content.Shared/_CP14/DayCycle/CP14CloudShadowsComponent.cs @@ -0,0 +1,26 @@ +using System.Numerics; +using Robust.Shared.GameStates; + +namespace Content.Shared._CP14.DayCycle; + +/// +/// if added to the map, renders cloud shadows on the map +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class CP14CloudShadowsComponent : Component +{ + [DataField, AutoNetworkedField] + public Vector2 CloudSpeed = new Vector2(0.5f, 0f); + + [DataField] + public float MaxSpeed = 1.5f; + + [DataField, AutoNetworkedField] + public float Alpha = 1f; + + [DataField] + public float Scale = 2.5f; + + [DataField] + public string ParallaxPath = "/Textures/_CP14/Parallaxes/Shadows.png"; +} diff --git a/Resources/Maps/_CP14/alchemy_test.yml b/Resources/Maps/_CP14/alchemy_test.yml index 7e5296d4a5..abd82c7106 100644 --- a/Resources/Maps/_CP14/alchemy_test.yml +++ b/Resources/Maps/_CP14/alchemy_test.yml @@ -36,6 +36,7 @@ entities: - type: OccluderTree - type: LoadedMap - type: MapLight + - type: CP14CloudShadows - type: CP14WorldEdge range: 30 - type: CP14DayCycle diff --git a/Resources/Textures/_CP14/Parallaxes/Shadows.png b/Resources/Textures/_CP14/Parallaxes/Shadows.png new file mode 100644 index 0000000000..9181dbc540 Binary files /dev/null and b/Resources/Textures/_CP14/Parallaxes/Shadows.png differ diff --git a/Resources/Textures/_CP14/Parallaxes/attributions.yml b/Resources/Textures/_CP14/Parallaxes/attributions.yml new file mode 100644 index 0000000000..885ce412b8 --- /dev/null +++ b/Resources/Textures/_CP14/Parallaxes/attributions.yml @@ -0,0 +1,4 @@ +- files: ["Shadows.png"] + license: "CC-BY-SA-3.0" + copyright: "Created by TheShuEd for CrystallPunk14" + source: "https://github.com/crystallpunk-14/crystall-punk-14" \ No newline at end of file