- 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>
101 lines
2.8 KiB
C#
101 lines
2.8 KiB
C#
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Chessistics.Engine.Model;
|
|
|
|
namespace Chessistics.Scripts.UI;
|
|
|
|
public partial class PieceStockPanel : VBoxContainer
|
|
{
|
|
[Signal]
|
|
public delegate void PieceSelectedEventHandler(int kindIndex);
|
|
|
|
private readonly Dictionary<PieceKind, (Button button, Label countLabel, int remaining)> _entries = new();
|
|
private PieceKind? _selectedKind;
|
|
|
|
public PieceKind? SelectedKind => _selectedKind;
|
|
|
|
public void Setup(IReadOnlyList<PieceStock> stock)
|
|
{
|
|
foreach (var child in GetChildren())
|
|
child.QueueFree();
|
|
_entries.Clear();
|
|
_selectedKind = null;
|
|
|
|
var title = new Label { Text = "PIECES" };
|
|
title.AddThemeFontSizeOverride("font_size", 16);
|
|
title.AddThemeColorOverride("font_color", new Color("#FFD700"));
|
|
AddChild(title);
|
|
|
|
AddChild(new HSeparator());
|
|
|
|
foreach (var entry in stock)
|
|
{
|
|
var hbox = new HBoxContainer();
|
|
|
|
var button = new Button
|
|
{
|
|
Text = GetPieceName(entry.Kind),
|
|
CustomMinimumSize = new Vector2(120, 32),
|
|
ToggleMode = true
|
|
};
|
|
|
|
var countLabel = new Label { Text = $"x{entry.Count}" };
|
|
countLabel.AddThemeFontSizeOverride("font_size", 14);
|
|
|
|
var kind = entry.Kind;
|
|
button.Pressed += () => OnPieceButtonPressed(kind);
|
|
|
|
hbox.AddChild(button);
|
|
hbox.AddChild(countLabel);
|
|
AddChild(hbox);
|
|
|
|
_entries[entry.Kind] = (button, countLabel, entry.Count);
|
|
}
|
|
}
|
|
|
|
private void OnPieceButtonPressed(PieceKind kind)
|
|
{
|
|
if (_selectedKind == kind)
|
|
{
|
|
_selectedKind = null;
|
|
UpdateButtonStates();
|
|
return;
|
|
}
|
|
|
|
_selectedKind = kind;
|
|
UpdateButtonStates();
|
|
EmitSignal(SignalName.PieceSelected, (int)kind);
|
|
}
|
|
|
|
private void UpdateButtonStates()
|
|
{
|
|
foreach (var (k, (button, _, remaining)) in _entries)
|
|
{
|
|
button.ButtonPressed = k == _selectedKind;
|
|
button.Disabled = remaining <= 0;
|
|
}
|
|
}
|
|
|
|
public void UpdateCount(PieceKind kind, int remaining)
|
|
{
|
|
if (!_entries.TryGetValue(kind, out var entry)) return;
|
|
_entries[kind] = (entry.button, entry.countLabel, remaining);
|
|
entry.countLabel.Text = $"x{remaining}";
|
|
entry.button.Disabled = remaining <= 0;
|
|
}
|
|
|
|
public void ClearSelection()
|
|
{
|
|
_selectedKind = null;
|
|
UpdateButtonStates();
|
|
}
|
|
|
|
private static string GetPieceName(PieceKind kind) => kind switch
|
|
{
|
|
PieceKind.Rook => "Tour II",
|
|
PieceKind.Bishop => "Fou II",
|
|
PieceKind.Knight => "Cavalier",
|
|
_ => kind.ToString()
|
|
};
|
|
}
|