diff --git a/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h b/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h index a2eda17c68..64707ce084 100644 --- a/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h +++ b/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h @@ -42,8 +42,14 @@ #undef SPARSEMATCH_DEBUG #endif +typedef UnsignedInt SparseMatchFinderFlags; +enum SparseMatchFinderFlags_ CPP_11(: SparseMatchFinderFlags) +{ + SparseMatchFinderFlags_NoCopy = 1<<0, +}; + //------------------------------------------------------------------------------------------------- -template +template class SparseMatchFinder { private: @@ -183,9 +189,29 @@ class SparseMatchFinder return result; } - //------------------------------------------------------------------------------------------------- public: + + //------------------------------------------------------------------------------------------------- + SparseMatchFinder() {} + SparseMatchFinder(const SparseMatchFinder& other) + { + *this = other; + } + + //------------------------------------------------------------------------------------------------- + SparseMatchFinder& operator=(const SparseMatchFinder& other) + { + if CONSTEXPR ((FLAGS & SparseMatchFinderFlags_NoCopy) == 0) + { + if (this != &other) + { + m_bestMatches = other.m_bestMatches; + } + } + return *this; + } + //------------------------------------------------------------------------------------------------- void clear() { diff --git a/Generals/Code/GameEngine/Include/Common/ThingTemplate.h b/Generals/Code/GameEngine/Include/Common/ThingTemplate.h index 4b123c6573..8c61465ec9 100644 --- a/Generals/Code/GameEngine/Include/Common/ThingTemplate.h +++ b/Generals/Code/GameEngine/Include/Common/ThingTemplate.h @@ -681,6 +681,11 @@ class ThingTemplate : public Overridable //Code renderer handles these states now. //AsciiString m_inventoryImage[ INV_IMAGE_NUM_IMAGES ]; ///< portrait inventory pictures + // TheSuperHackers @bugfix Caball009/xezon 06/07/2025 No longer copy SparseMatchFinder to prevent copied instances linking to unrelated data. + // This avoids mismatching in certain maps, for example those that spawn units with veterancy. + typedef SparseMatchFinder WeaponTemplateSetFinder; + typedef SparseMatchFinder ArmorTemplateSetFinder; + // ---- STL-sized things std::vector m_prereqInfo; ///< the unit Prereqs for this tech std::vector m_buildVariations; /**< if we build a unit of this type via script or ui, randomly choose one diff --git a/Generals/Code/GameEngine/Include/GameLogic/ArmorSet.h b/Generals/Code/GameEngine/Include/GameLogic/ArmorSet.h index e4e969db2b..7f8b2a7761 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/ArmorSet.h +++ b/Generals/Code/GameEngine/Include/GameLogic/ArmorSet.h @@ -94,7 +94,4 @@ class ArmorTemplateSet //------------------------------------------------------------------------------------------------- typedef std::vector ArmorTemplateSetVector; -//------------------------------------------------------------------------------------------------- -typedef SparseMatchFinder ArmorTemplateSetFinder; - #endif // _ArmorSet_H_ diff --git a/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h b/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h index 450d9fa34d..783758145b 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h +++ b/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h @@ -146,9 +146,6 @@ class WeaponTemplateSet //------------------------------------------------------------------------------------------------- typedef std::vector WeaponTemplateSetVector; -//------------------------------------------------------------------------------------------------- -typedef SparseMatchFinder WeaponTemplateSetFinder; - //------------------------------------------------------------------------------------------------- enum WeaponChoiceCriteria CPP_11(: Int) { diff --git a/GeneralsMD/Code/GameEngine/Include/Common/SparseMatchFinder.h b/GeneralsMD/Code/GameEngine/Include/Common/SparseMatchFinder.h index ff1aeb557d..8c03e3f81f 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/SparseMatchFinder.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/SparseMatchFinder.h @@ -42,8 +42,14 @@ #undef SPARSEMATCH_DEBUG #endif +typedef UnsignedInt SparseMatchFinderFlags; +enum SparseMatchFinderFlags_ CPP_11(: SparseMatchFinderFlags) +{ + SparseMatchFinderFlags_NoCopy = 1<<0, +}; + //------------------------------------------------------------------------------------------------- -template +template class SparseMatchFinder { private: @@ -185,9 +191,29 @@ class SparseMatchFinder return result; } - //------------------------------------------------------------------------------------------------- public: + + //------------------------------------------------------------------------------------------------- + SparseMatchFinder() {} + SparseMatchFinder(const SparseMatchFinder& other) + { + *this = other; + } + + //------------------------------------------------------------------------------------------------- + SparseMatchFinder& operator=(const SparseMatchFinder& other) + { + if CONSTEXPR ((FLAGS & SparseMatchFinderFlags_NoCopy) == 0) + { + if (this != &other) + { + m_bestMatches = other.m_bestMatches; + } + } + return *this; + } + //------------------------------------------------------------------------------------------------- void clear() { diff --git a/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h b/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h index 76554e821b..8f026a86dd 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h @@ -698,6 +698,11 @@ class ThingTemplate : public Overridable //Code renderer handles these states now. //AsciiString m_inventoryImage[ INV_IMAGE_NUM_IMAGES ]; ///< portrait inventory pictures + // TheSuperHackers @bugfix Caball009/xezon 06/07/2025 No longer copy SparseMatchFinder to prevent copied instances linking to unrelated data. + // This avoids mismatching in certain maps, for example those that spawn units with veterancy. + typedef SparseMatchFinder WeaponTemplateSetFinder; + typedef SparseMatchFinder ArmorTemplateSetFinder; + // ---- STL-sized things std::vector m_prereqInfo; ///< the unit Prereqs for this tech std::vector m_buildVariations; /**< if we build a unit of this type via script or ui, randomly choose one diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/ArmorSet.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/ArmorSet.h index 1a8441e192..8cf82998e1 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/ArmorSet.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/ArmorSet.h @@ -97,7 +97,4 @@ class ArmorTemplateSet //------------------------------------------------------------------------------------------------- typedef std::vector ArmorTemplateSetVector; -//------------------------------------------------------------------------------------------------- -typedef SparseMatchFinder ArmorTemplateSetFinder; - #endif // _ArmorSet_H_ diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h index be43a6ebae..9239845132 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h @@ -166,9 +166,6 @@ class WeaponTemplateSet //------------------------------------------------------------------------------------------------- typedef std::vector WeaponTemplateSetVector; -//------------------------------------------------------------------------------------------------- -typedef SparseMatchFinder WeaponTemplateSetFinder; - //------------------------------------------------------------------------------------------------- enum WeaponChoiceCriteria CPP_11(: Int) {