From 1feb8fe7dfc7988da962d7c16ab0330629f746b2 Mon Sep 17 00:00:00 2001 From: Nikolay Borodin Date: Fri, 13 Dec 2024 17:38:10 +0200 Subject: [PATCH] Cancel previous template when producing a new template in factories --- src/droiddef.h | 2 ++ src/structure.cpp | 23 +++++++++++++++++++++++ src/template.cpp | 16 ++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/droiddef.h b/src/droiddef.h index d84255fd1fe..b9e0fd6e559 100644 --- a/src/droiddef.h +++ b/src/droiddef.h @@ -56,6 +56,8 @@ typedef std::vector OrderList; struct DROID_TEMPLATE : public BASE_STATS { DROID_TEMPLATE(); + bool operator==(const DROID_TEMPLATE& other) const; + bool operator!=(const DROID_TEMPLATE& other) const; BODY_STATS* getBodyStats() const; BRAIN_STATS* getBrainStats() const; diff --git a/src/structure.cpp b/src/structure.cpp index 6e5b4477a58..c163f77d3d6 100644 --- a/src/structure.cpp +++ b/src/structure.cpp @@ -6327,6 +6327,29 @@ void factoryProdAdjust(STRUCTURE *psStructure, DROID_TEMPLATE *psTemplate, bool ASSERT_OR_RETURN(, psTemplate != nullptr, "NULL template"); 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 + if (psFactory->psSubject && *psFactory->psSubject != *psTemplate) + { + bool bFound = false; + for (auto &templ : localTemplates) + { + if (templ == *psFactory->psSubject) + { + bFound = true; + break; + } + } + + if (!bFound) + { + cancelProduction(psStructure, ModeImmediate); + factoryProdAdjust(psStructure, psTemplate, add); + return; + } + } + if (psFactory->psAssemblyPoint->factoryInc >= asProductionRun[psFactory->psAssemblyPoint->factoryType].size()) { asProductionRun[psFactory->psAssemblyPoint->factoryType].resize(psFactory->psAssemblyPoint->factoryInc + 1); // Don't have a production list, create it. diff --git a/src/template.cpp b/src/template.cpp index b7e2e317911..bbf83dae293 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -524,6 +524,22 @@ DROID_TEMPLATE::DROID_TEMPLATE() // This constructor replaces a memset in scrAs std::fill_n(asWeaps, MAX_WEAPONS, 0); } +bool DROID_TEMPLATE::operator==(const DROID_TEMPLATE &other) const +{ + return numWeaps == other.numWeaps && + droidType == other.droidType && + multiPlayerID == other.multiPlayerID && + prefab == other.prefab && + enabled == other.enabled && + std::equal(std::begin(asParts), std::end(asParts), std::begin(other.asParts)) && + std::equal(std::begin(asWeaps), std::end(asWeaps), std::begin(other.asWeaps)); +} + +bool DROID_TEMPLATE::operator!=(const DROID_TEMPLATE &other) const +{ + return !(*this == other); +} + BODY_STATS* DROID_TEMPLATE::getBodyStats() const { return &asBodyStats[asParts[COMP_BODY]];