- 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>
55 lines
1.8 KiB
C#
55 lines
1.8 KiB
C#
using Chessistics.Engine.Model;
|
|
|
|
namespace Chessistics.Engine.Rules;
|
|
|
|
public static class CollisionResolver
|
|
{
|
|
/// <summary>
|
|
/// Resolves collisions after movement. For each cell with 2+ pieces,
|
|
/// the strongest piece survives and destroys the others.
|
|
/// Priority: SocialStatus desc → Level desc → mutual destruction on exact tie.
|
|
/// </summary>
|
|
public static List<(PieceState? Survivor, List<PieceState> Destroyed, Coords Cell)> ResolveCollisions(
|
|
IReadOnlyList<PieceState> pieces)
|
|
{
|
|
var results = new List<(PieceState? Survivor, List<PieceState> Destroyed, Coords Cell)>();
|
|
var byCell = new Dictionary<Coords, List<PieceState>>();
|
|
|
|
foreach (var piece in pieces)
|
|
{
|
|
if (!byCell.TryGetValue(piece.CurrentCell, out var list))
|
|
{
|
|
list = [];
|
|
byCell[piece.CurrentCell] = list;
|
|
}
|
|
list.Add(piece);
|
|
}
|
|
|
|
foreach (var (cell, occupants) in byCell)
|
|
{
|
|
if (occupants.Count < 2) continue;
|
|
|
|
// Sort by priority: highest status first, then highest level
|
|
var sorted = occupants
|
|
.OrderByDescending(p => p.SocialStatus)
|
|
.ThenByDescending(p => p.Level)
|
|
.ToList();
|
|
|
|
var top = sorted[0];
|
|
var second = sorted[1];
|
|
|
|
// If top two have same status AND same level → mutual destruction
|
|
if (top.SocialStatus == second.SocialStatus && top.Level == second.Level)
|
|
{
|
|
results.Add((null, sorted, cell));
|
|
}
|
|
else
|
|
{
|
|
var destroyed = sorted.Skip(1).ToList();
|
|
results.Add((top, destroyed, cell));
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
}
|