94 lines
3.6 KiB
C++
94 lines
3.6 KiB
C++
#include "ShipyardContent.h"
|
|
|
|
#include <QPushButton>
|
|
#include <QVBoxLayout>
|
|
|
|
#include "BuildingTarget.h"
|
|
#include "EventManager.h"
|
|
#include "GameConfig.h"
|
|
#include "LayoutDialogRequestedEvent.h"
|
|
#include "ProductionRules.h"
|
|
#include "RecipeSelectionControl.h"
|
|
#include "SectionBox.h"
|
|
#include "ShipLayoutPreview.h"
|
|
|
|
ShipyardContent::ShipyardContent(const SelectionContext& context,
|
|
const SelectionRequest& request, QWidget* parent)
|
|
: BufferedBuildingContent(context, request.buildings.front(), parent)
|
|
{
|
|
m_schematicControl = new RecipeSelectionControl(context, getBuildingId(),
|
|
BuildingType::Shipyard, this);
|
|
|
|
m_layoutSection = new SectionBox(tr("Layout"), this);
|
|
m_layoutPreview = new ShipLayoutPreview(m_layoutSection);
|
|
m_configureButton = new QPushButton(tr("Configure Layout"), m_layoutSection);
|
|
m_layoutSection->getContentLayout()->addWidget(m_layoutPreview);
|
|
m_layoutSection->getContentLayout()->addWidget(m_configureButton);
|
|
|
|
// Ahead of the recipe summary the base adds, so the card reads schematic, layout,
|
|
// then what one ship costs.
|
|
getConfigurationLayout()->insertWidget(0, m_schematicControl);
|
|
getConfigurationLayout()->insertWidget(1, m_layoutSection);
|
|
|
|
const BuildingId id = getBuildingId();
|
|
connect(m_configureButton, &QPushButton::clicked, this, [id]() {
|
|
EventManager::getInstance()->sendEventImmediately(
|
|
std::make_shared<LayoutDialogRequestedEvent>(id));
|
|
});
|
|
}
|
|
|
|
void ShipyardContent::refreshControls(const BuildingTarget& target)
|
|
{
|
|
m_schematicControl->setRecipeId(target.recipeId);
|
|
|
|
// The preview and Configure button are always shown for a shipyard and are only
|
|
// enabled once a schematic is selected (REQ-MOD-UI-PREVIEW). The schematic arrives
|
|
// by queued command, so this refresh is what picks it up rather than the click that
|
|
// chose it.
|
|
const ShipDef* shipDef = target.recipeId.empty()
|
|
? nullptr
|
|
: getContext().config->ships.findShipDef(target.recipeId);
|
|
const bool hasSchematic = shipDef && !shipDef->layout.empty();
|
|
if (hasSchematic)
|
|
{
|
|
m_layoutPreview->setShipAndLayout(
|
|
shipDef->layout,
|
|
target.shipLayout.has_value() ? *target.shipLayout : ShipLayoutConfig(),
|
|
&getContext().config->modules);
|
|
}
|
|
else
|
|
{
|
|
m_layoutPreview->showPlaceholder();
|
|
}
|
|
m_layoutPreview->setEnabled(hasSchematic);
|
|
m_configureButton->setEnabled(hasSchematic);
|
|
}
|
|
|
|
BufferedBuildingContent::CycleInfo ShipyardContent::getCycleInfo(
|
|
const BuildingTarget& target) const
|
|
{
|
|
CycleInfo info;
|
|
const ShipDef* shipDef = target.recipeId.empty()
|
|
? nullptr
|
|
: getContext().config->ships.findShipDef(target.recipeId);
|
|
if (!shipDef)
|
|
{
|
|
return info;
|
|
}
|
|
|
|
// The schematic's materials plus every placed module's, which is also what sized the
|
|
// input buffers (REQ-BLD-SHIPYARD). The simulation owns that sum, so the panel asks
|
|
// it rather than adding the modules up a second time.
|
|
info.perCycleInputs = computeShipyardRequiredMaterials(
|
|
*getContext().config, target.recipeId, target.shipLayout);
|
|
|
|
// A shipyard's output is the ship itself, which never lands in an item buffer -- so
|
|
// the summary shows no output item at all. The time is the schematic's plus its
|
|
// modules', from the same place the layout dialog's build cost reads it
|
|
// (REQ-MOD-PRODUCTION-TIME).
|
|
info.durationSeconds = computeShipyardProductionTimeSeconds(
|
|
*getContext().config, target.recipeId, target.shipLayout);
|
|
info.runsProduction = true;
|
|
return info;
|
|
}
|