- New turn order: produce -> transfer -> move -> collision resolution - Collisions now destroy weaker pieces (status > level > mutual destruction) instead of halting the simulation. SimPhase.Collision removed. - Add piece Level property (all level 1 in proto, prepared for future) - Production fires every turn (interval concept removed), buffer = Amount (default 1, future 2-4), leftovers overwritten each turn - Transfer tiebreaker: status > level > clockwise direction (alternating even/odd turns in y-up coords), replaces distance-to-production - Demands always accept matching cargo even when already satisfied - TurnNumber added to all turn events for animation grouping - Simultaneous animations: produce flash, cargo slide, parallel piece moves - Camera centering fix + middle-click pan - GDD updated with new rules + lore section added Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
141 lines
4.4 KiB
C#
141 lines
4.4 KiB
C#
using Godot;
|
|
using Chessistics.Engine.Model;
|
|
|
|
namespace Chessistics.Scripts.Board;
|
|
|
|
public partial class CellView : Node2D
|
|
{
|
|
private ColorRect _background = null!;
|
|
private ColorRect _highlight = null!;
|
|
private Label _label = null!;
|
|
|
|
// Hover outline (4 thin rects forming a border)
|
|
private ColorRect _hoverTop = null!;
|
|
private ColorRect _hoverBottom = null!;
|
|
private ColorRect _hoverLeft = null!;
|
|
private ColorRect _hoverRight = null!;
|
|
|
|
public Coords Coords { get; private set; }
|
|
|
|
private static readonly Color LightColor = new("#F0D9B5");
|
|
private static readonly Color DarkColor = new("#B58863");
|
|
private static readonly Color WallColor = new("#555555");
|
|
private static readonly Color ProductionColor = new("#6B8E5A");
|
|
private static readonly Color DemandColor = new("#C9A833");
|
|
private static readonly Color HighlightColor = new("#44FF4444");
|
|
private static readonly Color HoverOutlineColor = new("#FFFFFFAA");
|
|
|
|
private const int OutlineWidth = 2;
|
|
|
|
public void Setup(Coords coords, CellType cellType, int cellSize)
|
|
{
|
|
Coords = coords;
|
|
Position = new Vector2(coords.Col * cellSize, -coords.Row * cellSize);
|
|
|
|
_background = new ColorRect
|
|
{
|
|
Size = new Vector2(cellSize, cellSize),
|
|
Position = Vector2.Zero,
|
|
MouseFilter = Control.MouseFilterEnum.Ignore
|
|
};
|
|
|
|
var baseColor = coords.IsLight ? LightColor : DarkColor;
|
|
_background.Color = cellType switch
|
|
{
|
|
CellType.Wall => WallColor,
|
|
CellType.Production => ProductionColor,
|
|
CellType.Demand => DemandColor,
|
|
_ => baseColor
|
|
};
|
|
AddChild(_background);
|
|
|
|
_highlight = new ColorRect
|
|
{
|
|
Size = new Vector2(cellSize, cellSize),
|
|
Position = Vector2.Zero,
|
|
Color = HighlightColor,
|
|
Visible = false,
|
|
MouseFilter = Control.MouseFilterEnum.Ignore
|
|
};
|
|
AddChild(_highlight);
|
|
|
|
// Hover outline (4 border rects)
|
|
_hoverTop = new ColorRect
|
|
{
|
|
Size = new Vector2(cellSize, OutlineWidth),
|
|
Position = Vector2.Zero,
|
|
Color = HoverOutlineColor,
|
|
Visible = false,
|
|
MouseFilter = Control.MouseFilterEnum.Ignore
|
|
};
|
|
AddChild(_hoverTop);
|
|
|
|
_hoverBottom = new ColorRect
|
|
{
|
|
Size = new Vector2(cellSize, OutlineWidth),
|
|
Position = new Vector2(0, cellSize - OutlineWidth),
|
|
Color = HoverOutlineColor,
|
|
Visible = false,
|
|
MouseFilter = Control.MouseFilterEnum.Ignore
|
|
};
|
|
AddChild(_hoverBottom);
|
|
|
|
_hoverLeft = new ColorRect
|
|
{
|
|
Size = new Vector2(OutlineWidth, cellSize),
|
|
Position = Vector2.Zero,
|
|
Color = HoverOutlineColor,
|
|
Visible = false,
|
|
MouseFilter = Control.MouseFilterEnum.Ignore
|
|
};
|
|
AddChild(_hoverLeft);
|
|
|
|
_hoverRight = new ColorRect
|
|
{
|
|
Size = new Vector2(OutlineWidth, cellSize),
|
|
Position = new Vector2(cellSize - OutlineWidth, 0),
|
|
Color = HoverOutlineColor,
|
|
Visible = false,
|
|
MouseFilter = Control.MouseFilterEnum.Ignore
|
|
};
|
|
AddChild(_hoverRight);
|
|
|
|
_label = new Label
|
|
{
|
|
Position = new Vector2(2, 2),
|
|
Text = "",
|
|
MouseFilter = Control.MouseFilterEnum.Ignore
|
|
};
|
|
_label.AddThemeFontSizeOverride("font_size", 10);
|
|
AddChild(_label);
|
|
}
|
|
|
|
public void SetLabel(string text) => _label.Text = text;
|
|
public void SetHighlight(bool on) => _highlight.Visible = on;
|
|
|
|
public void SetHover(bool on)
|
|
{
|
|
_hoverTop.Visible = on;
|
|
_hoverBottom.Visible = on;
|
|
_hoverLeft.Visible = on;
|
|
_hoverRight.Visible = on;
|
|
}
|
|
|
|
public void SetHighlightColor(Color color)
|
|
{
|
|
_highlight.Color = color;
|
|
_highlight.Visible = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Brief white flash on the cell to signal production.
|
|
/// </summary>
|
|
public void FlashProduce(float duration = 0.3f)
|
|
{
|
|
_highlight.Color = new Color(1, 1, 1, 0.5f);
|
|
_highlight.Visible = true;
|
|
var tween = CreateTween();
|
|
tween.TweenProperty(_highlight, "color", new Color(1, 1, 1, 0f), duration);
|
|
tween.TweenCallback(Callable.From(() => _highlight.Visible = false));
|
|
}
|
|
}
|