allow to rotate buildings in place

This commit is contained in:
2026-04-29 21:40:00 +02:00
parent 7e0104e9b8
commit 2770bf96be
4 changed files with 395 additions and 7 deletions

View File

@@ -384,6 +384,7 @@ bool GameWorldView::isValidPlacement(BuildingType type, QPoint anchor,
const ParsedSurfaceMask parsed = parseSurfaceMask(def->surfaceMask, rot);
bool anyOccupied = false;
for (const QPoint& relCell : parsed.bodyCells)
{
const QPoint worldCell = anchor + relCell;
@@ -401,8 +402,12 @@ bool GameWorldView::isValidPlacement(BuildingType type, QPoint anchor,
if (isShipDock && worldCell.x() < 0) { return false; }
if (!isShipDock && worldCell.x() >= 0) { return false; }
// Occupancy check
if (m_sim->buildings().isTileOccupied(worldCell)) { return false; }
if (m_sim->buildings().isTileOccupied(worldCell)) { anyOccupied = true; }
}
if (anyOccupied)
{
return m_sim->buildings().findRotateInPlaceTarget(type, anchor, rot).has_value();
}
return true;
}
@@ -481,9 +486,15 @@ void GameWorldView::placeBlueprintAtTile(QPoint center)
if (!isValidPlacement(bb.type, center + bb.offset, bb.rotation)) { return; }
}
// Cost only applies to buildings that are genuinely new (not rotate-in-place).
int totalCost = 0;
for (const BlueprintBuilding& bb : bp.buildings)
{
if (m_sim->buildings().findRotateInPlaceTarget(
bb.type, center + bb.offset, bb.rotation).has_value())
{
continue;
}
const BuildingDef* def = findBuildingDef(bb.type);
if (def) { totalCost += def->cost; }
}
@@ -491,7 +502,16 @@ void GameWorldView::placeBlueprintAtTile(QPoint center)
for (const BlueprintBuilding& bb : bp.buildings)
{
const EntityId id = m_sim->tryPlaceBuilding(bb.type, center + bb.offset, bb.rotation);
const QPoint anchor = center + bb.offset;
const std::optional<EntityId> rotateTarget =
m_sim->buildings().findRotateInPlaceTarget(bb.type, anchor, bb.rotation);
if (rotateTarget.has_value())
{
m_sim->buildings().rotateInPlace(*rotateTarget, bb.rotation);
continue;
}
const EntityId id = m_sim->tryPlaceBuilding(bb.type, anchor, bb.rotation);
if (id == kInvalidEntityId || bb.recipeId.empty()) { continue; }
if (bb.type == BuildingType::Shipyard)
@@ -511,16 +531,24 @@ void GameWorldView::placeBlueprintAtTile(QPoint center)
void GameWorldView::placeAtTile(QPoint tile)
{
if (!m_builderType.has_value())
{
return;
{
return;
}
const BuildingType type = *m_builderType;
if (!isValidPlacement(type, tile, m_ghostRotation))
{
return;
{
return;
}
const std::optional<EntityId> rotateTarget =
m_sim->buildings().findRotateInPlaceTarget(type, tile, m_ghostRotation);
if (rotateTarget.has_value())
{
m_sim->buildings().rotateInPlace(*rotateTarget, m_ghostRotation);
return;
}
if (type == BuildingType::Belt)
{
if (m_beltDragTiles.count(tile) > 0)