Перенос 2D → 3D без потерь (расчистка места, очередь «ждут места»); DEV «Камера» -- ползунки наклона, перспективы и отдаления

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alexander
2026-11-05 17:56:38 +01:00
co-authored by Claude Opus 5.5
parent 8a5f7253db
commit f78eb7ea7e
7 changed files with 260 additions and 20 deletions
@@ -152,6 +152,29 @@ namespace Bogatyri.Settlement.Placement
// Проверить место: прямоугольник sizeW x sizeH с поворотом rotation, левый нижний угол (x, y).
// ignoreId -- здание, которое переносят: его прежний след не мешает. foundationMm -- высота фундамента
public PlaceError Validate(int x, int y, int sizeW, int sizeH, int rotation, int townHallLevel, string ignoreId, out int foundationMm)
=> ValidateCore(x, y, sizeW, sizeH, rotation, townHallLevel, ignoreId, false, out foundationMm);
// То же, но деревья и валуны не мешают: можно ли поставить здесь, если расчистить (перенос 2D-города, 05.11)
public PlaceError ValidateIfCleared(int x, int y, int sizeW, int sizeH, int rotation, int townHallLevel, string ignoreId, out int foundationMm)
=> ValidateCore(x, y, sizeW, sizeH, rotation, townHallLevel, ignoreId, true, out foundationMm);
// Деревья и валуны (id) под прямоугольником -- что придётся расчистить. Каждый -- один раз
public List<string> ObstaclesUnder(int x, int y, int sizeW, int sizeH, int rotation)
{
rotation = NormalizeRotation(rotation);
int w = rotation == 90 || rotation == 270 ? sizeH : sizeW;
int h = rotation == 90 || rotation == 270 ? sizeW : sizeH;
var ids = new List<string>();
for (int cy = y; cy < y + h; cy++)
for (int cx = x; cx < x + w; cx++)
{
string id = ObstacleAt(cx, cy);
if (id != null && !ids.Contains(id)) ids.Add(id);
}
return ids;
}
PlaceError ValidateCore(int x, int y, int sizeW, int sizeH, int rotation, int townHallLevel, string ignoreId, bool ignoreObstacles, out int foundationMm)
{
foundationMm = 0;
rotation = NormalizeRotation(rotation);
@@ -167,7 +190,7 @@ namespace Bogatyri.Settlement.Placement
if (kind[i] == CellKind.Water) return PlaceError.Water;
if (kind[i] == CellKind.Mountain) return PlaceError.Mountain;
if (!IsOpen(cx, cy, townHallLevel)) return PlaceError.ZoneLocked;
if (obstacleAt.ContainsKey(i)) return PlaceError.Obstacle;
if (!ignoreObstacles && obstacleAt.ContainsKey(i)) return PlaceError.Obstacle;
min = Math.Min(min, heightMm[i]);
max = Math.Max(max, heightMm[i]);
}