implement ship modules

This commit is contained in:
2026-05-18 08:49:51 +02:00
parent b59e392461
commit d08bf5d37b
33 changed files with 1911 additions and 56 deletions

View File

@@ -17,7 +17,9 @@
#include "BuildingSystem.h"
#include "BuildingType.h"
#include "ItemType.h"
#include "ModulesConfig.h"
#include "Rotation.h"
#include "ShipLayoutPreview.h"
#include "Simulation.h"
namespace
@@ -99,6 +101,8 @@ SelectedBuildingPanel::SelectedBuildingPanel(Simulation* sim,
m_filterAList = new QListWidget(this);
m_filterBLabel = new QLabel(this);
m_filterBList = new QListWidget(this);
m_layoutPreview = new ShipLayoutPreview(this);
m_configureLayoutBtn = new QPushButton("Configure Layout", this);
m_buffersLabel = new QLabel(this);
m_buffersLabel->setWordWrap(true);
@@ -107,6 +111,8 @@ SelectedBuildingPanel::SelectedBuildingPanel(Simulation* sim,
m_layout->addWidget(m_titleLabel);
m_layout->addWidget(m_recipeCombo);
m_layout->addWidget(m_layoutPreview);
m_layout->addWidget(m_configureLayoutBtn);
m_layout->addWidget(m_clearBeltBtn);
m_layout->addWidget(m_filterALabel);
m_layout->addWidget(m_filterAList);
@@ -118,6 +124,12 @@ SelectedBuildingPanel::SelectedBuildingPanel(Simulation* sim,
this, &SelectedBuildingPanel::onRecipeChanged);
connect(m_clearBeltBtn, &QPushButton::clicked,
this, &SelectedBuildingPanel::onClearBelt);
connect(m_configureLayoutBtn, &QPushButton::clicked, this, [this]() {
if (m_singleId != kInvalidEntityId)
{
emit layoutDialogRequested(m_singleId);
}
});
connect(m_filterAList, &QListWidget::itemChanged,
this, &SelectedBuildingPanel::onSplitterFilterChanged);
connect(m_filterBList, &QListWidget::itemChanged,
@@ -153,6 +165,8 @@ void SelectedBuildingPanel::buildEmpty()
m_singleId = kInvalidEntityId;
m_titleLabel->hide();
m_recipeCombo->hide();
m_layoutPreview->hide();
m_configureLayoutBtn->hide();
m_clearBeltBtn->hide();
m_filterALabel->hide();
m_filterAList->hide();
@@ -248,10 +262,39 @@ void SelectedBuildingPanel::buildSingle(EntityId id)
m_recipeCombo->setCurrentIndex(currentIdx >= 0 ? currentIdx : 0);
m_recipeCombo->blockSignals(false);
m_recipeCombo->show();
if (b->type == BuildingType::Shipyard && !b->recipeId.empty())
{
const ShipDef* sDef = findShipDef(b->recipeId);
if (sDef && !sDef->layout.empty())
{
ShipLayoutConfig layout;
if (b->shipLayout.has_value())
{
layout = *b->shipLayout;
}
m_layoutPreview->setShipAndLayout(
sDef->layout, layout, &m_config->modules.modules);
m_layoutPreview->show();
m_configureLayoutBtn->show();
}
else
{
m_layoutPreview->hide();
m_configureLayoutBtn->hide();
}
}
else
{
m_layoutPreview->hide();
m_configureLayoutBtn->hide();
}
}
else
{
m_recipeCombo->hide();
m_layoutPreview->hide();
m_configureLayoutBtn->hide();
}
if (isBeltLike(b->type))
@@ -307,6 +350,26 @@ void SelectedBuildingPanel::refreshBuffers(const Building* b)
{
if (mat.item == entry.first.id) { perCycle = mat.amount; break; }
}
if (b->shipLayout.has_value())
{
for (const PlacedModule& pm : b->shipLayout->placedModules)
{
for (const ModuleDef& modDef : m_config->modules.modules)
{
if (modDef.id == pm.moduleId)
{
for (const RecipeIngredient& ing : modDef.materials)
{
if (ing.item == entry.first.id)
{
perCycle += ing.amount;
}
}
break;
}
}
}
}
}
bufText += QString::fromStdString(entry.first.id)
+ ": " + QString::number(entry.second);
@@ -354,10 +417,25 @@ void SelectedBuildingPanel::refreshBuffers(const Building* b)
if (isProductionBuilding(b->type) && (recipe || shipDef))
{
const double durationSeconds = recipe
double durationSeconds = recipe
? recipe->durationSeconds
: shipDef->schematic.productionTimeSeconds;
if (shipDef && b->shipLayout.has_value())
{
for (const PlacedModule& pm : b->shipLayout->placedModules)
{
for (const ModuleDef& modDef : m_config->modules.modules)
{
if (modDef.id == pm.moduleId)
{
durationSeconds += modDef.productionTimeSeconds;
break;
}
}
}
}
bufText += QString("Cycle: %1 s\n").arg(durationSeconds, 0, 'f', 1);
if (b->production.has_value())
@@ -377,6 +455,17 @@ void SelectedBuildingPanel::refreshBuffers(const Building* b)
}
m_buffersLabel->setText(bufText);
if (b->type == BuildingType::Shipyard && shipDef && !shipDef->layout.empty())
{
ShipLayoutConfig layout;
if (b->shipLayout.has_value())
{
layout = *b->shipLayout;
}
m_layoutPreview->setShipAndLayout(
shipDef->layout, layout, &m_config->modules.modules);
}
}
const RecipeDef* SelectedBuildingPanel::findRecipe(const Building* b) const
@@ -481,6 +570,7 @@ void SelectedBuildingPanel::onRecipeChanged(int comboIndex)
}
const QString recipeId = m_recipeCombo->itemData(comboIndex).toString();
m_sim->buildings().setRecipe(m_singleId, recipeId.toStdString());
rebuild();
}
void SelectedBuildingPanel::buildSplitterFilters(QPoint splitterTile)