Allow creating blueprints from construction sites
This commit is contained in:
@@ -146,60 +146,10 @@ void BlueprintPanel::onBlueprintButtonClicked(int index)
|
||||
|
||||
Blueprint BlueprintPanel::createBlueprintFromSelection() const
|
||||
{
|
||||
struct Entry
|
||||
{
|
||||
const Building* building;
|
||||
};
|
||||
std::vector<Entry> entries;
|
||||
entries.reserve(m_selectedBuildingIds.size());
|
||||
|
||||
for (const BuildingId id : m_selectedBuildingIds)
|
||||
{
|
||||
const Building* b = m_sim->buildings().findBuilding(id);
|
||||
if (!b) { continue; }
|
||||
const BuildingDef* def = m_config->buildings.findBuildingDef(b->type);
|
||||
if (def && def->playerPlaceable) { entries.push_back({ b }); }
|
||||
}
|
||||
|
||||
if (entries.empty()) { return Blueprint{}; }
|
||||
|
||||
int minX = INT_MAX, maxX = INT_MIN;
|
||||
int minY = INT_MAX, maxY = INT_MIN;
|
||||
for (const Entry& e : entries)
|
||||
{
|
||||
for (const QPoint& cell : e.building->bodyCells)
|
||||
{
|
||||
minX = std::min(minX, cell.x());
|
||||
maxX = std::max(maxX, cell.x());
|
||||
minY = std::min(minY, cell.y());
|
||||
maxY = std::max(maxY, cell.y());
|
||||
}
|
||||
}
|
||||
|
||||
const QPoint center((minX + maxX) / 2, (minY + maxY) / 2);
|
||||
|
||||
Blueprint bp;
|
||||
bp.buildings.reserve(entries.size());
|
||||
for (const Entry& e : entries)
|
||||
{
|
||||
BlueprintBuilding bb;
|
||||
bb.type = e.building->type;
|
||||
bb.rotation = e.building->rotation;
|
||||
bb.offset = e.building->anchor - center;
|
||||
// Recipe / schematic / layout / splitter-filter capture is shared with the
|
||||
// copy-settings gesture (REQ-BLD-COPY-CONFIG) via readBuildingConfig.
|
||||
const std::optional<BuildingConfig> config =
|
||||
readBuildingConfig(*m_sim, e.building->id);
|
||||
if (config.has_value())
|
||||
{
|
||||
bb.recipeId = config->recipeId.value_or(std::string());
|
||||
bb.shipLayout = config->shipLayout;
|
||||
bb.splitterFilterA = config->splitterFilterA;
|
||||
bb.splitterFilterB = config->splitterFilterB;
|
||||
}
|
||||
bp.buildings.push_back(bb);
|
||||
}
|
||||
return bp;
|
||||
// Capture is shared, testable logic in lib/sim: it resolves each selected id as an
|
||||
// operational building or a construction site alike (REQ-UI-BLUEPRINT-CREATE,
|
||||
// REQ-UI-BLUEPRINT-STORAGE).
|
||||
return captureBlueprintFromSelection(*m_sim, m_selectedBuildingIds);
|
||||
}
|
||||
|
||||
int BlueprintPanel::computeBlueprintCost(const Blueprint& bp) const
|
||||
@@ -295,19 +245,8 @@ void BlueprintPanel::loadFromDisk()
|
||||
|
||||
void BlueprintPanel::refreshButtonStates()
|
||||
{
|
||||
const bool anyPlaceable = [&]() {
|
||||
for (const BuildingId id : m_selectedBuildingIds)
|
||||
{
|
||||
const Building* b = m_sim->buildings().findBuilding(id);
|
||||
if (!b) { continue; }
|
||||
for (const BuildingDef& def : m_config->buildings.buildings)
|
||||
{
|
||||
if (def.type == b->type) { return def.playerPlaceable; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
m_createBtn->setEnabled(anyPlaceable);
|
||||
// A construction site counts the same as an operational building (REQ-UI-BLUEPRINT-CREATE).
|
||||
m_createBtn->setEnabled(selectionHasPlaceableBuilding(*m_sim, m_selectedBuildingIds));
|
||||
|
||||
for (int i = 0; i < static_cast<int>(m_blueprintButtons.size()); ++i)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user