Auto-process smelter and reprocessing plant (no recipe selection)
This commit is contained in:
@@ -78,6 +78,25 @@ bool isProductionBuilding(BuildingType type)
|
||||
|| type == BuildingType::Shipyard;
|
||||
}
|
||||
|
||||
// Buildings that expose a player recipe/schematic selection control
|
||||
// (REQ-UI-SELECT-BUTTON): Miner ore type, Assembler recipe, Shipyard schematic.
|
||||
// The Smelter and Reprocessing Plant auto-process and offer no selection
|
||||
// (REQ-BLD-SMELTER, REQ-BLD-REPROCESSING).
|
||||
bool hasRecipeSelection(BuildingType type)
|
||||
{
|
||||
return type == BuildingType::Miner
|
||||
|| type == BuildingType::Assembler
|
||||
|| type == BuildingType::Shipyard;
|
||||
}
|
||||
|
||||
// Auto-recipe buildings have no selected recipe; their production is driven by
|
||||
// whatever inputs they receive.
|
||||
bool isAutoRecipeBuilding(BuildingType type)
|
||||
{
|
||||
return type == BuildingType::Smelter
|
||||
|| type == BuildingType::ReprocessingPlant;
|
||||
}
|
||||
|
||||
bool isBeltLike(BuildingType type)
|
||||
{
|
||||
return type == BuildingType::Belt || type == BuildingType::Splitter
|
||||
@@ -265,7 +284,7 @@ void SelectedBuildingPanel::buildSingle(BuildingId id)
|
||||
m_titleLabel->show();
|
||||
m_buffersLabel->show();
|
||||
|
||||
if (isProductionBuilding(type))
|
||||
if (hasRecipeSelection(type))
|
||||
{
|
||||
const std::vector<RecipeSelectionOption> options =
|
||||
buildRecipeSelectionOptions(type, *m_sim, *m_config);
|
||||
@@ -383,6 +402,21 @@ void SelectedBuildingPanel::refreshBuffers(const Building* b)
|
||||
? findShipDef(b->recipeId)
|
||||
: nullptr;
|
||||
|
||||
// Auto-recipe buildings (Smelter, Reprocessing Plant) have no selected
|
||||
// recipe; while a cycle runs, resolve the recipe actually in production so
|
||||
// the cycle time and progress can be shown (REQ-UI-PRODUCTION-PROGRESS).
|
||||
if (!recipe && isAutoRecipeBuilding(b->type) && b->production.has_value())
|
||||
{
|
||||
for (const RecipeDef& r : m_config->recipes.recipes)
|
||||
{
|
||||
if (r.id == b->production->recipeId && r.building == b->type)
|
||||
{
|
||||
recipe = &r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString bufText;
|
||||
|
||||
if (!b->inputBuffer.counts.empty())
|
||||
@@ -469,41 +503,51 @@ void SelectedBuildingPanel::refreshBuffers(const Building* b)
|
||||
}
|
||||
}
|
||||
|
||||
if (isProductionBuilding(b->type) && (recipe || shipDef))
|
||||
if (isProductionBuilding(b->type)
|
||||
&& (recipe || shipDef || isAutoRecipeBuilding(b->type)))
|
||||
{
|
||||
double durationSeconds = recipe
|
||||
? recipe->durationSeconds
|
||||
: shipDef->schematic.productionTimeSeconds;
|
||||
|
||||
if (shipDef && b->shipLayout.has_value())
|
||||
if (recipe || shipDef)
|
||||
{
|
||||
for (const PlacedModule& pm : b->shipLayout->placedModules)
|
||||
double durationSeconds = recipe
|
||||
? recipe->durationSeconds
|
||||
: shipDef->schematic.productionTimeSeconds;
|
||||
|
||||
if (shipDef && b->shipLayout.has_value())
|
||||
{
|
||||
for (const ModuleDef& modDef : m_config->modules.modules)
|
||||
for (const PlacedModule& pm : b->shipLayout->placedModules)
|
||||
{
|
||||
if (modDef.id == pm.moduleId)
|
||||
for (const ModuleDef& modDef : m_config->modules.modules)
|
||||
{
|
||||
durationSeconds += modDef.productionTimeSeconds;
|
||||
break;
|
||||
if (modDef.id == pm.moduleId)
|
||||
{
|
||||
durationSeconds += modDef.productionTimeSeconds;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bufText += tr("Cycle: %1 s\n").arg(durationSeconds, 0, 'f', 1);
|
||||
bufText += tr("Cycle: %1 s\n").arg(durationSeconds, 0, 'f', 1);
|
||||
|
||||
if (b->production.has_value())
|
||||
{
|
||||
const Tick cycleTicks = secondsToTicks(durationSeconds);
|
||||
const Tick completesAt = b->production->completesAt;
|
||||
const Tick currentTick = m_sim->currentTick();
|
||||
const Tick elapsed = currentTick - (completesAt - cycleTicks);
|
||||
const int pct = static_cast<int>(
|
||||
std::max(Tick(0), std::min(cycleTicks, elapsed)) * 100 / cycleTicks);
|
||||
bufText += tr("Progress: %1%\n").arg(pct);
|
||||
if (b->production.has_value())
|
||||
{
|
||||
const Tick cycleTicks = secondsToTicks(durationSeconds);
|
||||
const Tick completesAt = b->production->completesAt;
|
||||
const Tick currentTick = m_sim->currentTick();
|
||||
const Tick elapsed = currentTick - (completesAt - cycleTicks);
|
||||
const int pct = static_cast<int>(
|
||||
std::max(Tick(0), std::min(cycleTicks, elapsed)) * 100 / cycleTicks);
|
||||
bufText += tr("Progress: %1%\n").arg(pct);
|
||||
}
|
||||
else
|
||||
{
|
||||
bufText += tr("Progress: idle\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Auto-recipe building with no active cycle: no single recipe to
|
||||
// show a cycle time for.
|
||||
bufText += tr("Progress: idle\n");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user