start the next production cycle in the tick the last one completed
This commit is contained in:
@@ -513,17 +513,22 @@ void BuildingSystem::tickProduction(FactoryState& state, Tick currentTick)
|
||||
// recipe is selected or auto-chosen.
|
||||
if (building.production)
|
||||
{
|
||||
if (currentTick >= building.production->completesAt)
|
||||
if (currentTick < building.production->completesAt)
|
||||
{
|
||||
for (const Item& item : building.production->chosenOutputs)
|
||||
{
|
||||
building.outputBuffer.items.push_back(item);
|
||||
}
|
||||
building.production = std::nullopt;
|
||||
continue;
|
||||
}
|
||||
// Whether we just completed or are still running, do not start
|
||||
// another cycle in the same tick.
|
||||
continue;
|
||||
for (const Item& item : building.production->chosenOutputs)
|
||||
{
|
||||
building.outputBuffer.items.push_back(item);
|
||||
}
|
||||
building.production = std::nullopt;
|
||||
// Fall through to the start attempt below rather than idling for a tick,
|
||||
// so a cycle takes exactly its recipe duration and a building fed to
|
||||
// capacity produces at the configured rate (REQ-MAT-CYCLE). The start
|
||||
// code runs once per building per tick, so at most one cycle begins here
|
||||
// even when a duration rounds to zero ticks. The outputs just deposited
|
||||
// count against the space check, so a cycle whose output no longer fits
|
||||
// waits, exactly as it would have on the following tick.
|
||||
}
|
||||
|
||||
// Idle: gather the candidate recipes to try. Auto-recipe buildings
|
||||
@@ -612,26 +617,29 @@ void BuildingSystem::tickShipyardProduction(FactoryState& state, Tick currentTic
|
||||
// If a cycle is in progress, check for completion.
|
||||
if (building.production)
|
||||
{
|
||||
if (currentTick >= building.production->completesAt)
|
||||
if (currentTick < building.production->completesAt)
|
||||
{
|
||||
if (!building.outputPorts.empty())
|
||||
{
|
||||
const Port& p = building.outputPorts[0];
|
||||
const QVector2D spawnPos(p.tile.x() + 0.5f, p.tile.y() + 0.5f);
|
||||
// A shipyard builds exactly what the player configured and
|
||||
// paid for. When no layout is set it produces a bare hull, so
|
||||
// pass an explicit empty layout rather than nullopt: the latter
|
||||
// would make ShipSystem fall back to the schematic's
|
||||
// defaultModules (a wave-only loadout) and yield free weapons.
|
||||
const std::optional<ShipLayoutConfig> layout =
|
||||
building.shipLayout.has_value()
|
||||
? building.shipLayout
|
||||
: std::make_optional<ShipLayoutConfig>();
|
||||
m_spawnShip(building.recipeId, spawnPos, layout);
|
||||
}
|
||||
building.production = std::nullopt;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
if (!building.outputPorts.empty())
|
||||
{
|
||||
const Port& p = building.outputPorts[0];
|
||||
const QVector2D spawnPos(p.tile.x() + 0.5f, p.tile.y() + 0.5f);
|
||||
// A shipyard builds exactly what the player configured and
|
||||
// paid for. When no layout is set it produces a bare hull, so
|
||||
// pass an explicit empty layout rather than nullopt: the latter
|
||||
// would make ShipSystem fall back to the schematic's
|
||||
// defaultModules (a wave-only loadout) and yield free weapons.
|
||||
const std::optional<ShipLayoutConfig> layout =
|
||||
building.shipLayout.has_value()
|
||||
? building.shipLayout
|
||||
: std::make_optional<ShipLayoutConfig>();
|
||||
m_spawnShip(building.recipeId, spawnPos, layout);
|
||||
}
|
||||
building.production = std::nullopt;
|
||||
// Fall through and start the next cycle in this same tick, so a ship takes
|
||||
// exactly its computed production time (REQ-BLD-SHIPYARD), as for the
|
||||
// recipe buildings in tickProduction.
|
||||
}
|
||||
|
||||
// Build combined materials list (base + modules).
|
||||
|
||||
Reference in New Issue
Block a user