diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index 5430cf9711..621bc145a2 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -829,6 +829,7 @@ class TechnoTypeExt : public ObjectTypeExt void ApplyTurretOffset(Matrix3D* mtx, double factor = 1.0); void CalculateSpawnerRange(); bool IsSecondary(int nWeaponIndex) const; + const std::string GetGunnerID(int idx) const; int SelectForceWeapon(TechnoClass* pThis, AbstractClass* pTarget) const; int SelectMultiWeapon(TechnoClass* const pThis, AbstractClass* const pTarget) const; diff --git a/src/Misc/Selection.cpp b/src/Misc/Selection.cpp index 2bdfbb5ae7..d44bf3a0b6 100644 --- a/src/Misc/Selection.cpp +++ b/src/Misc/Selection.cpp @@ -1,6 +1,8 @@ #include #include +#include + class ExtSelection { public: @@ -26,7 +28,7 @@ class ExtSelection } Array {}; static inline bool ProcessingIDMatches = false; - static inline std::vector IFVGroups; + static inline std::vector IFVGroups; // Reversed from Is_Selectable, w/o Select call static bool ObjectClass_IsSelectable(ObjectClass* pThis) @@ -135,12 +137,9 @@ class ExtSelection if (pTechnoType->Gunner && !ExtSelection::IFVGroups.empty()) { - char* gunnerID = pTypeExt->WeaponGroupAs[pTechno->CurrentWeaponNumber]; - - if (!GeneralUtils::IsValidString(gunnerID)) - sprintf_s(gunnerID, 0x20, "%d", RulesExt::Global()->TypeSelectUseIFVMode && Phobos::Config::TypeSelectUseIFVMode ? pTechno->CurrentWeaponNumber + 1 : 0); + const std::string gunnerID = pTypeExt->GetGunnerID(pTechno->CurrentWeaponNumber); - if (std::ranges::none_of(ExtSelection::IFVGroups, [gunnerID](const char* pID) { return !_stricmp(pID, gunnerID); })) + if (std::ranges::none_of(ExtSelection::IFVGroups, [gunnerID](const std::string& id) { return !_stricmp(id.c_str(), gunnerID.c_str()); })) break; } @@ -186,10 +185,21 @@ DEFINE_FUNCTION_JUMP(CALL, 0x4ABCEB, ExtSelection::Tactical_MakeFilteredSelectio // Replace vanilla function. For in case another module tries to call the vanilla function at offset DEFINE_FUNCTION_JUMP(LJMP, 0x6D9FF0, ExtSelection::Tactical_MakeFilteredSelection) -DEFINE_HOOK(0x73298D, TypeSelectExecute_UseIFVMode, 0x5) +const std::string TechnoTypeExt::GetGunnerID(int idx) const { - const bool useIFVMode = RulesExt::Global()->TypeSelectUseIFVMode && Phobos::Config::TypeSelectUseIFVMode; + if (idx < static_cast(this->WeaponGroupAs.size())) + { + const char* pWeaponGroup = this->WeaponGroupAs[idx]; + + if (GeneralUtils::IsValidString(pWeaponGroup)) + return std::string(pWeaponGroup); + } + return std::format("{}", RulesExt::Global()->TypeSelectUseIFVMode && Phobos::Config::TypeSelectUseIFVMode ? idx + 1 : 0); +} + +DEFINE_HOOK(0x73298D, TypeSelectExecute_UseIFVMode, 0x5) +{ for (const auto pObject : ObjectClass::CurrentObjects) { const auto pTechno = abstract_cast(pObject); @@ -203,12 +213,9 @@ DEFINE_HOOK(0x73298D, TypeSelectExecute_UseIFVMode, 0x5) continue; const auto pTypeExt = TechnoTypeExt::Fetch(pTechnoType); - char* gunnerID = pTypeExt->WeaponGroupAs[pTechno->CurrentWeaponNumber]; - - if (!GeneralUtils::IsValidString(gunnerID)) - sprintf_s(gunnerID, 0x20, "%d", useIFVMode ? pTechno->CurrentWeaponNumber + 1 : 0); + const std::string gunnerID = pTypeExt->GetGunnerID(pTechno->CurrentWeaponNumber); - if (std::ranges::none_of(ExtSelection::IFVGroups, [gunnerID](const char* pID) { return !_stricmp(pID, gunnerID); })) + if (std::ranges::none_of(ExtSelection::IFVGroups, [gunnerID](const std::string& id) { return !_stricmp(id.c_str(), gunnerID.c_str()); })) ExtSelection::IFVGroups.emplace_back(gunnerID); }