using Godot; using System; public class GridCursor : Sprite { [Export] public NodePath Grid { get; set; } private WorldGrid _grid; private ShaderMaterial _material; #region Animation [Export] private Curve _pulseShape; [Export] private float _pulseRate = 1.0f; private float PulsePeriod => 1.0f / _pulseRate; #endregion private float _elapsed = 0.0f; private bool _pulsing = false; private const string T = "t"; public override void _Ready() { _grid = GetNode(Grid); _material = (ShaderMaterial)Material; } public override void _Input(InputEvent @event) { base._Input(@event); if (@event is InputEventMouseMotion mouseMoveEvent) { var pos = mouseMoveEvent.Position; _grid.GetGridPos(pos, out var x, out var y); this.Visible = _grid.IsInBounds(x, y); var position = new Vector2(x + .5f, y + .5f) * _grid.CellSize; this.Position = position; } else if (@event is InputEventMouseButton mouseButtonEvent) { switch ((ButtonList)mouseButtonEvent.ButtonIndex) { case ButtonList.Left: if (mouseButtonEvent.Pressed) { var pos = mouseButtonEvent.Position; _grid.GetGridPos(pos, out var x, out var y); _grid.SetTileValue(x, y, 1.0f); _material.SetShaderParam(T, 1f); } else { _material.SetShaderParam(T, 0f); } break; } } } public override void _Process(float delta) { _elapsed += delta * _pulseRate; if (!_pulsing) { _material.SetShaderParam(T, 1f); return; } var a = _pulseShape.Interpolate(_elapsed % 1.0f); _material.SetShaderParam(T, a); } public void _on_Interaction_Mode_OnInteractionModeChanged(InteractionMode.Mode oldMode, InteractionMode.Mode newMode) { switch (newMode) { case InteractionMode.Mode.SELECT: _pulsing = false; break; case InteractionMode.Mode.BUILD: _pulsing = true; break; } } }