From 9a109a4cba91a94971c31a678366cde47301a50b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Sat, 28 Mar 2026 10:49:31 +0800 Subject: [PATCH 1/9] core --- .gitignore | 1 + CREDITS.md | 1 + YRpp | 2 +- docs/Fixed-or-Improved-Logics.md | 11 +++++++++++ docs/Whats-New.md | 1 + src/Ext/Rules/Body.cpp | 3 +++ src/Ext/Rules/Body.h | 4 ++++ src/Ext/Unit/Hooks.Harvester.cpp | 28 ++++++++++++++++++++++++++++ 8 files changed, 50 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c7875aa55b..d2ef0950e6 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ out # Python virtual environment for docs .venv/ +debug.log diff --git a/CREDITS.md b/CREDITS.md index 9026457bf8..e52fa692a9 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -732,6 +732,7 @@ This page lists all the individual contributions to the project by their author. - Fix the issue that the Jumpjet must end its movement before starting the next mission - Taunt warhead - Fix the bug where non-Teleporter miners would not return to work after minerals are depleted and then regenerated + - Miners back to work when ore regenerated - **solar-III (凤九歌)** - Target scanning delay customization (documentation) - Skip target scanning function calling for unarmed technos (documentation) diff --git a/YRpp b/YRpp index 1dde1af4d5..66e688c83b 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 1dde1af4d58f630a07a313f8c0460a401e511270 +Subproject commit 66e688c83b9df8be78b3500ac3563fb1f6cd846f diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 3f42622b1d..c288625240 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -2229,6 +2229,17 @@ HarvesterScanAfterUnload=false ; boolean HarvesterScanAfterUnload= ; boolean, default to [General] -> HarvesterScanAfterUnload ``` +### Miners back to work when ore regenerated + +- In vanilla, miners will idle after all ore are gathered. When the ore regenerated, only miners beside the refinery will back to work. +- Now you can make the miners do so no matter where they are. + +In `rulesmd.ini`: +```ini +[General] +MinerAutoBackToWork=false ; boolean +``` + ### Preserve Iron Curtain / Force Shield status on type conversion ![image](_static/images/preserve-ic.gif) diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 486c6cc179..ec2d41e947 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -633,6 +633,7 @@ Vanilla fixes: - Fixed an issue where a unit might cause the target to fall from above its own head when using a locomotor warhead with `Locomotor=Jumpjet` to pull a target with `BalloonHover=yes` (by NetsuNegi) - Fixed the [EIP#007120F7](https://modenc.renegadeprojects.com/Internal_Error#eip_007120F7) caused when the `Strength` value is lower than `RepairStep` (by NetsuNegi) - 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) Phobos fixes: - Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi) diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 7ff7fad425..3df8dbd431 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -376,6 +376,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->UnitsUnsellable.Read(exINI, GameStrings::General, "UnitsUnsellable"); + this->MinerAutoBackToWork.Read(exINI, GameStrings::General, "MinerAutoBackToWork"); + // Section AITargetTypes int itemsCount = pINI->GetKeyCount("AITargetTypes"); for (int i = 0; i < itemsCount; ++i) @@ -683,6 +685,7 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->CylinderRangefinding) .Process(this->PenetratesTransport_Level) .Process(this->UnitsUnsellable) + .Process(this->MinerAutoBackToWork) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index b5ccf7e18b..a450e8f8e8 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -325,6 +325,8 @@ class RulesExt Valueable UnitsUnsellable; + Valueable MinerAutoBackToWork; + ExtData(RulesClass* OwnerObject) : Extension(OwnerObject) , Storage_TiberiumIndex { -1 } , HarvesterDumpAmount { 0.0f } @@ -592,6 +594,8 @@ class RulesExt , PenetratesTransport_Level { 10 } , UnitsUnsellable { false } + + , MinerAutoBackToWork { false } { } virtual ~ExtData() = default; diff --git a/src/Ext/Unit/Hooks.Harvester.cpp b/src/Ext/Unit/Hooks.Harvester.cpp index dcd679d3fe..3fa4db5583 100644 --- a/src/Ext/Unit/Hooks.Harvester.cpp +++ b/src/Ext/Unit/Hooks.Harvester.cpp @@ -240,3 +240,31 @@ DEFINE_HOOK(0x738A3E, UnitClass_EnterIdleMode_SubterraneanHarvester, 0x5) // Skip the check for Teleporter here; this is an unreasonable check. // This check determines whether miners on a Guard mission near the refinery should return to the Harvest mission. DEFINE_JUMP(LJMP, 0x740943, 0x740957); + +// Now, miners will no longer actively withdraw from the Harvest mission due to mineral depletion. +DEFINE_HOOK(0x73EEA6, UnitClass_MissionHarvest_AllOreGathered, 0x6) +{ + enum { SkipGameCode = 0x73EFA4 }; + + if (!RulesExt::Global()->MinerAutoBackToWork) + return 0; + + GET(UnitClass*, pThis, EBP); + + auto pBuilding = MapClass::Instance.GetCellAt(pThis->GetCoords())->GetBuilding(); + if (pBuilding && (pBuilding->Type->Refinery || pBuilding->Type->Weeder)) + { + CellStruct buffer = CellStruct::Empty; + pThis->NearbyLocation(&buffer, pBuilding); + auto pDest = MapClass::Instance.GetCellAt(buffer); + pThis->SetDestination(pDest, false); + R->EAX(15); + } + else + { + pThis->MissionStatus = 0; + R->EAX(100); + } + + return SkipGameCode; +} From 92695a0e8db862edaf3b9155feaa1f9b9ec5c978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Sat, 28 Mar 2026 20:58:55 +0800 Subject: [PATCH 2/9] update --- src/Ext/Rules/Body.cpp | 3 --- src/Ext/Rules/Body.h | 4 ---- src/Ext/Unit/Hooks.Harvester.cpp | 3 --- 3 files changed, 10 deletions(-) diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 3df8dbd431..7ff7fad425 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -376,8 +376,6 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->UnitsUnsellable.Read(exINI, GameStrings::General, "UnitsUnsellable"); - this->MinerAutoBackToWork.Read(exINI, GameStrings::General, "MinerAutoBackToWork"); - // Section AITargetTypes int itemsCount = pINI->GetKeyCount("AITargetTypes"); for (int i = 0; i < itemsCount; ++i) @@ -685,7 +683,6 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->CylinderRangefinding) .Process(this->PenetratesTransport_Level) .Process(this->UnitsUnsellable) - .Process(this->MinerAutoBackToWork) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index a450e8f8e8..b5ccf7e18b 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -325,8 +325,6 @@ class RulesExt Valueable UnitsUnsellable; - Valueable MinerAutoBackToWork; - ExtData(RulesClass* OwnerObject) : Extension(OwnerObject) , Storage_TiberiumIndex { -1 } , HarvesterDumpAmount { 0.0f } @@ -594,8 +592,6 @@ class RulesExt , PenetratesTransport_Level { 10 } , UnitsUnsellable { false } - - , MinerAutoBackToWork { false } { } virtual ~ExtData() = default; diff --git a/src/Ext/Unit/Hooks.Harvester.cpp b/src/Ext/Unit/Hooks.Harvester.cpp index 3fa4db5583..33c9e2a622 100644 --- a/src/Ext/Unit/Hooks.Harvester.cpp +++ b/src/Ext/Unit/Hooks.Harvester.cpp @@ -246,9 +246,6 @@ DEFINE_HOOK(0x73EEA6, UnitClass_MissionHarvest_AllOreGathered, 0x6) { enum { SkipGameCode = 0x73EFA4 }; - if (!RulesExt::Global()->MinerAutoBackToWork) - return 0; - GET(UnitClass*, pThis, EBP); auto pBuilding = MapClass::Instance.GetCellAt(pThis->GetCoords())->GetBuilding(); From 583a794cab29bfbc2ecda8db3c7410b9c1d9bbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:22:18 +0800 Subject: [PATCH 3/9] Update Fixed-or-Improved-Logics.md --- docs/Fixed-or-Improved-Logics.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index c288625240..6e8c173921 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -317,6 +317,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Fixed the [EIP#007120F7](https://modenc.renegadeprojects.com/Internal_Error#eip_007120F7) that was triggered when repairing because the `Strength` value was lower than `RepairStep`. - Fixed the bug where non-Teleporter miners would not return to work after minerals are depleted and then regenerated. - Fixed a desync due to an inconsistent shroud state caused by `GapGenerator` and `SpySat` interaction. +- Now, miners will no longer withdraw from the Harvest mission due to mineral depletion and will periodically attempt to return to work. ## Fixes / interactions with other extensions @@ -2229,17 +2230,6 @@ HarvesterScanAfterUnload=false ; boolean HarvesterScanAfterUnload= ; boolean, default to [General] -> HarvesterScanAfterUnload ``` -### Miners back to work when ore regenerated - -- In vanilla, miners will idle after all ore are gathered. When the ore regenerated, only miners beside the refinery will back to work. -- Now you can make the miners do so no matter where they are. - -In `rulesmd.ini`: -```ini -[General] -MinerAutoBackToWork=false ; boolean -``` - ### Preserve Iron Curtain / Force Shield status on type conversion ![image](_static/images/preserve-ic.gif) From f922beb2ba14cafad7029cab33c3e6ba0816ab2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Sat, 28 Mar 2026 10:49:31 +0800 Subject: [PATCH 4/9] core --- docs/Fixed-or-Improved-Logics.md | 11 +++++++++++ src/Ext/Rules/Body.cpp | 3 +++ src/Ext/Rules/Body.h | 4 ++++ src/Ext/Unit/Hooks.Harvester.cpp | 5 ++++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 6e8c173921..651b7c71e8 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -2230,6 +2230,17 @@ HarvesterScanAfterUnload=false ; boolean HarvesterScanAfterUnload= ; boolean, default to [General] -> HarvesterScanAfterUnload ``` +### Miners back to work when ore regenerated + +- In vanilla, miners will idle after all ore are gathered. When the ore regenerated, only miners beside the refinery will back to work. +- Now you can make the miners do so no matter where they are. + +In `rulesmd.ini`: +```ini +[General] +MinerAutoBackToWork=false ; boolean +``` + ### Preserve Iron Curtain / Force Shield status on type conversion ![image](_static/images/preserve-ic.gif) diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 7ff7fad425..3df8dbd431 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -376,6 +376,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->UnitsUnsellable.Read(exINI, GameStrings::General, "UnitsUnsellable"); + this->MinerAutoBackToWork.Read(exINI, GameStrings::General, "MinerAutoBackToWork"); + // Section AITargetTypes int itemsCount = pINI->GetKeyCount("AITargetTypes"); for (int i = 0; i < itemsCount; ++i) @@ -683,6 +685,7 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->CylinderRangefinding) .Process(this->PenetratesTransport_Level) .Process(this->UnitsUnsellable) + .Process(this->MinerAutoBackToWork) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index b5ccf7e18b..a450e8f8e8 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -325,6 +325,8 @@ class RulesExt Valueable UnitsUnsellable; + Valueable MinerAutoBackToWork; + ExtData(RulesClass* OwnerObject) : Extension(OwnerObject) , Storage_TiberiumIndex { -1 } , HarvesterDumpAmount { 0.0f } @@ -592,6 +594,8 @@ class RulesExt , PenetratesTransport_Level { 10 } , UnitsUnsellable { false } + + , MinerAutoBackToWork { false } { } virtual ~ExtData() = default; diff --git a/src/Ext/Unit/Hooks.Harvester.cpp b/src/Ext/Unit/Hooks.Harvester.cpp index 33c9e2a622..e57b2a8113 100644 --- a/src/Ext/Unit/Hooks.Harvester.cpp +++ b/src/Ext/Unit/Hooks.Harvester.cpp @@ -1,4 +1,4 @@ -#include +#include #pragma region EnterRefineryFix @@ -246,6 +246,9 @@ DEFINE_HOOK(0x73EEA6, UnitClass_MissionHarvest_AllOreGathered, 0x6) { enum { SkipGameCode = 0x73EFA4 }; + if (!RulesExt::Global()->MinerAutoBackToWork) + return 0; + GET(UnitClass*, pThis, EBP); auto pBuilding = MapClass::Instance.GetCellAt(pThis->GetCoords())->GetBuilding(); From 6d5337aaa5565a7416bde6b283e8d01d7a9af585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Sat, 28 Mar 2026 20:58:55 +0800 Subject: [PATCH 5/9] update --- src/Ext/Rules/Body.cpp | 3 --- src/Ext/Rules/Body.h | 4 ---- src/Ext/Unit/Hooks.Harvester.cpp | 3 --- 3 files changed, 10 deletions(-) diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 3df8dbd431..7ff7fad425 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -376,8 +376,6 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->UnitsUnsellable.Read(exINI, GameStrings::General, "UnitsUnsellable"); - this->MinerAutoBackToWork.Read(exINI, GameStrings::General, "MinerAutoBackToWork"); - // Section AITargetTypes int itemsCount = pINI->GetKeyCount("AITargetTypes"); for (int i = 0; i < itemsCount; ++i) @@ -685,7 +683,6 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->CylinderRangefinding) .Process(this->PenetratesTransport_Level) .Process(this->UnitsUnsellable) - .Process(this->MinerAutoBackToWork) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index a450e8f8e8..b5ccf7e18b 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -325,8 +325,6 @@ class RulesExt Valueable UnitsUnsellable; - Valueable MinerAutoBackToWork; - ExtData(RulesClass* OwnerObject) : Extension(OwnerObject) , Storage_TiberiumIndex { -1 } , HarvesterDumpAmount { 0.0f } @@ -594,8 +592,6 @@ class RulesExt , PenetratesTransport_Level { 10 } , UnitsUnsellable { false } - - , MinerAutoBackToWork { false } { } virtual ~ExtData() = default; diff --git a/src/Ext/Unit/Hooks.Harvester.cpp b/src/Ext/Unit/Hooks.Harvester.cpp index e57b2a8113..79fcf84f56 100644 --- a/src/Ext/Unit/Hooks.Harvester.cpp +++ b/src/Ext/Unit/Hooks.Harvester.cpp @@ -246,9 +246,6 @@ DEFINE_HOOK(0x73EEA6, UnitClass_MissionHarvest_AllOreGathered, 0x6) { enum { SkipGameCode = 0x73EFA4 }; - if (!RulesExt::Global()->MinerAutoBackToWork) - return 0; - GET(UnitClass*, pThis, EBP); auto pBuilding = MapClass::Instance.GetCellAt(pThis->GetCoords())->GetBuilding(); From ab8c17d2e629744f659cb4444d8fdf2413aaaf69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Wed, 1 Apr 2026 11:15:19 +0800 Subject: [PATCH 6/9] Update Fixed-or-Improved-Logics.md --- docs/Fixed-or-Improved-Logics.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 651b7c71e8..c7f49dbc33 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -317,7 +317,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Fixed the [EIP#007120F7](https://modenc.renegadeprojects.com/Internal_Error#eip_007120F7) that was triggered when repairing because the `Strength` value was lower than `RepairStep`. - Fixed the bug where non-Teleporter miners would not return to work after minerals are depleted and then regenerated. - Fixed a desync due to an inconsistent shroud state caused by `GapGenerator` and `SpySat` interaction. -- Now, miners will no longer withdraw from the Harvest mission due to mineral depletion and will periodically attempt to return to work. +- Now miners will no longer withdraw from the Harvest mission due to mineral depletion and will periodically attempt to return to work. ## Fixes / interactions with other extensions @@ -2230,17 +2230,6 @@ HarvesterScanAfterUnload=false ; boolean HarvesterScanAfterUnload= ; boolean, default to [General] -> HarvesterScanAfterUnload ``` -### Miners back to work when ore regenerated - -- In vanilla, miners will idle after all ore are gathered. When the ore regenerated, only miners beside the refinery will back to work. -- Now you can make the miners do so no matter where they are. - -In `rulesmd.ini`: -```ini -[General] -MinerAutoBackToWork=false ; boolean -``` - ### Preserve Iron Curtain / Force Shield status on type conversion ![image](_static/images/preserve-ic.gif) From f88fc3eb320e06504bc04d69045cd1bc5a2af21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Fri, 3 Apr 2026 11:32:16 +0800 Subject: [PATCH 7/9] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index d2ef0950e6..c7875aa55b 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,3 @@ out # Python virtual environment for docs .venv/ -debug.log From f6ba96bf0dc5a1453f5a18295885db6f43b75a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Sat, 4 Apr 2026 16:51:22 +0800 Subject: [PATCH 8/9] Update YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index 66e688c83b..bf3ddabfc4 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 66e688c83b9df8be78b3500ac3563fb1f6cd846f +Subproject commit bf3ddabfc466e0fb4b9f9c40bfc7ff3e2252b397 From d857c3ff78981c99a8f79fe4a7f7f5683ca4e704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=88=AA=E5=91=B3=E9=BA=BB=E9=85=B1?= <93972760+TaranDahl@users.noreply.github.com> Date: Sat, 4 Apr 2026 16:58:49 +0800 Subject: [PATCH 9/9] Update YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index bf3ddabfc4..044629acb4 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit bf3ddabfc466e0fb4b9f9c40bfc7ff3e2252b397 +Subproject commit 044629acb47a4e2b8eefb440ca19754f40a43d7c