From bbb3284187aaae6b4483d761b2db800cb17687f5 Mon Sep 17 00:00:00 2001 From: handama <55939089+handama@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:58:30 +0800 Subject: [PATCH 1/5] Fix AI team recruitment inconsistency causing underfilled teams --- YRpp | 2 +- src/Ext/Techno/Body.cpp | 31 ++++++++++++++++++++++++++++++- src/Ext/Techno/Body.h | 3 ++- src/Ext/Techno/Hooks.cpp | 12 ++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/YRpp b/YRpp index d512ac7ff5..85ecc24065 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit d512ac7ff5a65cfb72e2bca775f13c797304afb1 +Subproject commit 85ecc240657a918fd3e54b4cf7548fb44c7e8b35 diff --git a/src/Ext/Techno/Body.cpp b/src/Ext/Techno/Body.cpp index a1a5987a1a..3d202a1da5 100644 --- a/src/Ext/Techno/Body.cpp +++ b/src/Ext/Techno/Body.cpp @@ -1,4 +1,4 @@ -#include "Body.h" +#include "Body.h" #include @@ -884,6 +884,35 @@ void TechnoExt::ClickedApproachObject(FootClass* pThis, ObjectClass* pObject) event.AddEvent(); } +bool TechnoExt::CanBeRecruitedFix(FootClass* pThis, HouseClass* pHouse) +{ + if (!pThis || !pHouse) return false; + + const bool inTeam = pThis->Team != nullptr; + const bool available = pThis->IsAlive && pThis->Health > 0 && !pThis->InLimbo; + const bool wrongOwner = pThis->Owner != pHouse; + + if (inTeam || !available || wrongOwner) + return false; + + const bool canRecruit = pThis->RecruitableA && pThis->RecruitableB; + if (!canRecruit) + return false; + + const Mission mission = pThis->GetCurrentMission(); + + if (!MissionClass::IsRecruitableMission(mission)) + return false; + + const bool validState = + !(pThis->ShouldEnterAbsorber || pThis->ShouldEnterOccupiable || pThis->ShouldGarrisonStructure) && + pThis->DrainTarget == nullptr && + !pThis->BunkerLinkedItem && + pThis->LocomotorSource == nullptr; + + return validState; +} + bool TechnoExt::EjectRandomly(FootClass* pEjectee, const CoordStruct& coords, int distance, bool select) { std::vector usableCoords; diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index bfc21c09d1..38a0527ca8 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -309,6 +309,7 @@ class TechnoExt static bool SimpleDeployerAllowedToDeploy(UnitClass* pThis, bool defaultValue, bool alwaysCheckLandTypes); static void ShowPromoteAnim(TechnoClass* pThis); static void ClickedApproachObject(FootClass* pThis, ObjectClass* pObject); + static bool CanBeRecruitedFix(FootClass* pThis, HouseClass* pHouse); static bool EjectRandomly(FootClass* pEjectee, const CoordStruct& coords, int distance, bool select); static bool EjectSurvivor(FootClass* pSurvivor, CoordStruct coords, bool select); diff --git a/src/Ext/Techno/Hooks.cpp b/src/Ext/Techno/Hooks.cpp index 96c7d24059..6429d9316c 100644 --- a/src/Ext/Techno/Hooks.cpp +++ b/src/Ext/Techno/Hooks.cpp @@ -1971,3 +1971,15 @@ DEFINE_HOOK(0x4D4B43, FootClass_Mission_Capture, 0x6) return LosesDestination; } + +DEFINE_HOOK(0x4DA230, FootClass_CanBeRecruited, 0x5) +{ + enum { SkipGameCode = 0x4DA294 }; + + GET(FootClass*, pThis, ECX); + GET_STACK(HouseClass*, pHouse, 0x4); + + R->AL(TechnoExt::CanBeRecruitedFix(pThis, pHouse)); + + return SkipGameCode; +} From 500adfd31a4becf2e05b410dc072018f51f43c5c Mon Sep 17 00:00:00 2001 From: handama <55939089+handama@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:04:10 +0800 Subject: [PATCH 2/5] update document --- CREDITS.md | 4 +++- docs/Whats-New.md | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CREDITS.md b/CREDITS.md index a9fdc39683..14bfef5c2a 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -660,7 +660,9 @@ This page lists all the individual contributions to the project by their author. - Maximum amount for power plant enhancer - Return warhead - **NaotoYuuki** - Vertical & meteor trajectory projectile prototypes -- **handama** - AI script action to `16005 Jump Back To Previous Script` +- **handama**: + - AI script action to `16005 Jump Back To Previous Script` + - Fix AI team recruitment inconsistency causing underfilled teams - **TaranDahl (航味麻酱)**: - Skirmish AI "sell all buildings and set all technos to hunt" behavior dehardcode - Skirmish AI "gather when MCV deploy" behavior dehardcode diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 0b109974ed..e30b02a792 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -638,6 +638,7 @@ Vanilla fixes: - Fixed the bug where non-Teleporter miners would not return to work after minerals are depleted and then regenerated (by TaranDahl) - Miners back to work when ore regenerated (by TaranDahl) - Fixed the incorrect mission switching in infantry EnterIdleMode (by TaranDahl) +- Fixed AI team recruitment inconsistency causing underfilled teams (by handama) Phobos fixes: - Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi) From 76a529eaa39653a2716447ffafec53140cf721f2 Mon Sep 17 00:00:00 2001 From: Noble_Fish <1065703286@qq.com> Date: Wed, 15 Apr 2026 17:58:16 +0800 Subject: [PATCH 3/5] Supplement the document to pass the check --- docs/AI-Scripting-and-Mapping.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/AI-Scripting-and-Mapping.md b/docs/AI-Scripting-and-Mapping.md index e5d82cfd1a..ef4402c666 100644 --- a/docs/AI-Scripting-and-Mapping.md +++ b/docs/AI-Scripting-and-Mapping.md @@ -13,6 +13,7 @@ This page describes all AI scripting and mapping related additions and changes i - Teams spawned by trigger action 7,80,107 can use IFV and opentopped logic normally. - If a pre-placed building has a `NaturalParticleSystem`, it used to always be created when the game starts. This has been removed. - Superweapons used by AI for script actions `56 Chronoshift to Building`, `57 Chronoshift to a Target Type` and `10104 Chronoshift to Enemy Base` can now be explicitly set via `[General] -> AIChronoSphereSW` & `AIChronoWarpSW` respectively. If `AIChronoSphereSW` is set but `AIChronoWarpSW` is not, game will check former's `SW.PostDependent` for a second superweapon to use. Otherwise if not set, last superweapon listed in `[SuperWeaponTypes]` with `Type=ChronoSphere` or `Type=ChronoWarp` will be used, respectively. +- Fixed AI team recruitment inconsistency causing underfilled teams. ### Increased Overlay Limit From 65a396f9d0febbd00185f7347751c207631f613c Mon Sep 17 00:00:00 2001 From: Noble_Fish <1065703286@qq.com> Date: Wed, 15 Apr 2026 17:58:42 +0800 Subject: [PATCH 4/5] Remove extra spaces --- docs/Whats-New.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Whats-New.md b/docs/Whats-New.md index e30b02a792..2addd81127 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -638,7 +638,7 @@ Vanilla fixes: - Fixed the bug where non-Teleporter miners would not return to work after minerals are depleted and then regenerated (by TaranDahl) - Miners back to work when ore regenerated (by TaranDahl) - Fixed the incorrect mission switching in infantry EnterIdleMode (by TaranDahl) -- Fixed AI team recruitment inconsistency causing underfilled teams (by handama) +- Fixed AI team recruitment inconsistency causing underfilled teams (by handama) Phobos fixes: - Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi) From 85c264c4c06c73334759ccb8b258f8f67b95eb1f Mon Sep 17 00:00:00 2001 From: handama <55939089+handama@users.noreply.github.com> Date: Sat, 18 Apr 2026 20:11:57 +0800 Subject: [PATCH 5/5] remove unnecessary check --- src/Ext/Techno/Body.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Ext/Techno/Body.cpp b/src/Ext/Techno/Body.cpp index 3d202a1da5..4f41545154 100644 --- a/src/Ext/Techno/Body.cpp +++ b/src/Ext/Techno/Body.cpp @@ -886,8 +886,6 @@ void TechnoExt::ClickedApproachObject(FootClass* pThis, ObjectClass* pObject) bool TechnoExt::CanBeRecruitedFix(FootClass* pThis, HouseClass* pHouse) { - if (!pThis || !pHouse) return false; - const bool inTeam = pThis->Team != nullptr; const bool available = pThis->IsAlive && pThis->Health > 0 && !pThis->InLimbo; const bool wrongOwner = pThis->Owner != pHouse;