151 lines
6.4 KiB
C#
151 lines
6.4 KiB
C#
using System.Numerics;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.Enums;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Map.Components;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Client._DV.CosmicCult.Visuals;
|
|
|
|
public sealed class MonumentPlacementPreviewOverlay : Overlay
|
|
{
|
|
private readonly IEntityManager _ent;
|
|
private readonly IPlayerManager _player;
|
|
private readonly SpriteSystem _sprite;
|
|
private readonly SharedMapSystem _map;
|
|
private readonly MonumentPlacementPreviewSystem _preview;
|
|
private readonly IGameTiming _timing;
|
|
public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities;
|
|
|
|
private readonly ShaderInstance _saturationShader;
|
|
private readonly ShaderInstance _unshadedShader;
|
|
private readonly ShaderInstance _starsShader;
|
|
|
|
public bool LockPlacement = false;
|
|
private EntityCoordinates _lastPos = new();
|
|
|
|
//for a slight fade in / out
|
|
//ss14's formatting settings can take my needlessly public variables away from my cold, dead hands
|
|
public float FadeInProgress = 0;
|
|
public float FadeInTime = 0.25f;
|
|
public bool FadingIn = true;
|
|
|
|
public float FadeOutProgress = 0;
|
|
public float FadeOutTime = 0.25f;
|
|
public bool FadingOut = false;
|
|
|
|
public float Alpha = 0;
|
|
|
|
private readonly SpriteSpecifier _mainTex;
|
|
private readonly SpriteSpecifier _outlineTex;
|
|
private readonly SpriteSpecifier _starTex;
|
|
|
|
//todo arbitrary sprite drawing overlay at some point
|
|
//I don't want to have to make a new overlay for every "draw a sprite at x" thing
|
|
//also I kinda want wrappers around the dog ass existing arbitrary rendering methods
|
|
|
|
//evil huge ctor because doing iocmanager stuff was killing the client for some reason
|
|
public MonumentPlacementPreviewOverlay(IEntityManager entityManager, IPlayerManager playerManager, IPrototypeManager protoMan, IGameTiming timing, int tier)
|
|
{
|
|
_ent = entityManager;
|
|
_player = playerManager;
|
|
_sprite = _ent.System<SpriteSystem>();
|
|
_map = _ent.System<SharedMapSystem>();
|
|
_preview = _ent.System<MonumentPlacementPreviewSystem>();
|
|
_timing = timing;
|
|
|
|
_saturationShader = protoMan.Index<ShaderPrototype>("SaturationShuffle").InstanceUnique();
|
|
_saturationShader.SetParameter("tileSize", new Vector2(96, 96));
|
|
_saturationShader.SetParameter("hsv", new Vector3(1.0f, 0.25f, 0.2f));
|
|
|
|
_starsShader = protoMan.Index<ShaderPrototype>("MonumentPulse").InstanceUnique();
|
|
_starsShader.SetParameter("tileSize", new Vector2(96, 96));
|
|
|
|
_unshadedShader = protoMan.Index<ShaderPrototype>("unshaded").Instance(); //doesn't need a unique instance
|
|
|
|
ZIndex = (int) Shared.DrawDepth.DrawDepth.Mobs; //make the overlay render at the same depth as the actual sprite. might want to make it 1 lower if things get wierd with it.
|
|
|
|
//will fuck up if the wrong tier is passed in but it's not my problem if that happens
|
|
_mainTex = new SpriteSpecifier.Rsi(new ResPath("_DV/CosmicCult/Tileset/monument.rsi"), $"stage{tier}");
|
|
_outlineTex = new SpriteSpecifier.Rsi(new ResPath("_DV/CosmicCult/Tileset/monument.rsi"), $"stage{tier}-placement-ghost-1");
|
|
_starTex = new SpriteSpecifier.Rsi(new ResPath("_DV/CosmicCult/Tileset/monument.rsi"), $"stage{tier}-placement-ghost-2");
|
|
}
|
|
|
|
//this might get wierd if the player managed to leave the grid they put the monument on? theoretically not a concern because it can't be placed too close to space.
|
|
//shouldn't crash due to the comp checks, though.
|
|
protected override void Draw(in OverlayDrawArgs args)
|
|
{
|
|
if (!_ent.TryGetComponent<TransformComponent>(_player.LocalEntity, out var transformComp))
|
|
return;
|
|
|
|
if (!_ent.TryGetComponent<MapGridComponent>(transformComp.GridUid, out var grid))
|
|
return;
|
|
|
|
if (!_ent.TryGetComponent<TransformComponent>(transformComp.ParentUid, out var parentTransform))
|
|
return;
|
|
|
|
var worldHandle = args.WorldHandle;
|
|
|
|
//make effects look more nicer
|
|
var time = (float) _timing.FrameTime.TotalSeconds;
|
|
//make the fade in / out progress
|
|
if (FadingIn)
|
|
{
|
|
FadeInProgress += time;
|
|
if (FadeInProgress >= FadeInTime)
|
|
{
|
|
FadingIn = false;
|
|
FadeInProgress = FadeInTime;
|
|
}
|
|
Alpha = FadeInProgress / FadeInTime;
|
|
}
|
|
|
|
if (FadingOut)
|
|
{
|
|
FadeOutProgress += time;
|
|
if (FadeOutProgress >= FadeOutTime)
|
|
{
|
|
FadingOut = false;
|
|
FadeOutProgress = FadeOutTime;
|
|
}
|
|
Alpha = 1 - FadeOutProgress / FadeOutTime;
|
|
}
|
|
|
|
//have the outline's alpha slightly "breathe"
|
|
var outlineAlphaModulate = 0.75f + 0.25f * (float) Math.Sin(_timing.CurTime.TotalSeconds);
|
|
|
|
//stuff to make the monument preview stick in place once the ability is confirmed
|
|
Color color;
|
|
if (!LockPlacement)
|
|
{
|
|
//set the colour based on if the target tile is valid or not
|
|
color = _preview.VerifyPlacement(transformComp, out var snappedCoords) ? Color.White.WithAlpha(outlineAlphaModulate * Alpha) : Color.Gray.WithAlpha(outlineAlphaModulate * 0.5f * Alpha);
|
|
_lastPos = snappedCoords; //update the position
|
|
}
|
|
else
|
|
{
|
|
//if the position is locked, then it has to be valid so always use the valid colour
|
|
color = Color.White.WithAlpha(outlineAlphaModulate * Alpha);
|
|
}
|
|
|
|
worldHandle.SetTransform(parentTransform.LocalMatrix);
|
|
|
|
//for the desaturated monument "shadow"
|
|
worldHandle.UseShader(_saturationShader);
|
|
worldHandle.DrawTexture(_sprite.Frame0(_mainTex), _lastPos.Position - new Vector2(1.5f, 0.5f), Color.White.WithAlpha(Alpha)); //needs the offset to render in the proper position. does not inherit the extra modulate
|
|
|
|
//for the outline to pop
|
|
worldHandle.UseShader(_unshadedShader);
|
|
worldHandle.DrawTexture(_sprite.Frame0(_outlineTex), _lastPos.Position - new Vector2(1.5f, 0.5f), color);
|
|
|
|
//some fancy schmancy things for the inside of the monument
|
|
worldHandle.UseShader(_starsShader);
|
|
worldHandle.DrawTexture(_sprite.Frame0(_starTex), _lastPos.Position - new Vector2(1.5f, 0.5f), color);
|
|
worldHandle.UseShader(null);
|
|
}
|
|
}
|