diff --git a/src/droiddef.h b/src/droiddef.h index b9e0fd6e559..034edf957c0 100644 --- a/src/droiddef.h +++ b/src/droiddef.h @@ -85,6 +85,7 @@ struct DROID_TEMPLATE : public BASE_STATS bool prefab; ///< Not player designed, not saved, never delete or change bool stored; ///< Stored template bool enabled; ///< Has been enabled + DROID_TEMPLATE* next; }; static inline DROID_TEMPLATE *castDroidTemplate(BASE_STATS *stats) diff --git a/src/hci/manufacture.cpp b/src/hci/manufacture.cpp index 22fd363eda1..511c31080a1 100644 --- a/src/hci/manufacture.cpp +++ b/src/hci/manufacture.cpp @@ -419,7 +419,10 @@ class ManufactureStatsButton: public StatsButton auto productionRemaining = getProduction(factory, droidTemplate).numRemaining(); if (productionRemaining > 0 && factory && StructureIsManufacturingPending(factory)) { - productionRunSizeLabel->setString(WzString::fromUtf8(astringf("%d", productionRemaining))); + auto manufacture = StructureGetFactory(factory); + productionRunSizeLabel->setString((manufacture->psSubject && manufacture->psSubject->next) ? + WzString::fromUtf8(astringf("1+%d", productionRemaining)) : + WzString::fromUtf8(astringf("%d", productionRemaining))); productionRunSizeLabel->show(); } else diff --git a/src/structure.cpp b/src/structure.cpp index f0db55cb980..391902ee04c 100644 --- a/src/structure.cpp +++ b/src/structure.cpp @@ -6234,6 +6234,21 @@ void doNextProduction(STRUCTURE *psStructure, DROID_TEMPLATE *current, QUEUE_MOD { DROID_TEMPLATE *psNextTemplate = factoryProdUpdate(psStructure, current); + if (current) + { + auto it = std::find_if(apsTemplateList.begin(), apsTemplateList.end(), [current](const auto &templ) { + return *templ == *current; + }); + + if (it == apsTemplateList.end() && current->next) + { + structSetManufacture(psStructure, current->next, ModeImmediate); + // Increase the production counter, because we produced the old template + factoryProdAdjust(psStructure, current->next, true); + return; + } + } + if (psNextTemplate != nullptr) { structSetManufacture(psStructure, psNextTemplate, ModeQueue); // ModeQueue instead of mode, since production lists aren't currently synchronised. @@ -6329,24 +6344,16 @@ void factoryProdAdjust(STRUCTURE *psStructure, DROID_TEMPLATE *psTemplate, bool FACTORY *psFactory = &psStructure->pFunctionality->factory; // the droid template being produced is different from the one we want to make, - // cancel the current production instead of increasing the counter + // update the current production instead of increasing the counter if (psFactory->psSubject && *psFactory->psSubject != *psTemplate) { - bool bFound = false; - for (auto templ : apsTemplateList) - { - if (*templ == *psFactory->psSubject) - { - bFound = true; - break; - } - } + auto it = std::find_if(apsTemplateList.begin(), apsTemplateList.end(), [psFactory](const auto &templ) { + return *templ == *psFactory->psSubject; + }); - if (!bFound) + if (it == apsTemplateList.end()) { - cancelProduction(psStructure, ModeImmediate, false); - factoryProdAdjust(psStructure, psTemplate, add); - return; + psFactory->psSubject->next = psTemplate; } } diff --git a/src/template.cpp b/src/template.cpp index bbf83dae293..3c6ec424508 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -519,6 +519,7 @@ DROID_TEMPLATE::DROID_TEMPLATE() // This constructor replaces a memset in scrAs , prefab(false) , stored(false) , enabled(false) + , next(nullptr) { std::fill_n(asParts, DROID_MAXCOMP, static_cast(0)); std::fill_n(asWeaps, MAX_WEAPONS, 0);