From f6d2f2137eb8f71ed62269def16099678bcf43e8 Mon Sep 17 00:00:00 2001 From: lvjia Date: Fri, 29 Aug 2025 15:00:16 +0800 Subject: [PATCH 01/12] Implement freeze for AI factory production under EMP Added functionality to freeze AI-controlled factory production when under EMP. --- src/Ext/Techno/Body.Update.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index 8d2d91efb1..4265b32393 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include // TechnoClass_AI_0x6F9E50 @@ -1638,6 +1640,23 @@ void TechnoExt::ExtData::UpdateRearmInEMPState() if (pThis->ReloadTimer.InProgress() && pTypeExt->NoReload_UnderEMP.Get(RulesExt::Global()->NoReload_UnderEMP)) pThis->ReloadTimer.StartTime++; + + // Freeze AI-controlled factory production while building is EMPed + if (pThis->IsUnderEMP() && pThis->WhatAmI() == AbstractType::Building) + { + auto const pBuilding = static_cast(pThis); + + if (pBuilding->Owner && !pBuilding->Owner->IsControlledByHuman()) + { + if (auto const pFactory = pBuilding->Factory) + { + if (pFactory->Object && pFactory->Production.Rate > 0) + { + pFactory->Production.Timer.StartTime++; + } + } + } + } } void TechnoExt::ExtData::UpdateRearmInTemporal() From 621e05321a4fc09d015475a03ef2fb43c67df6cf Mon Sep 17 00:00:00 2001 From: lvjia Date: Fri, 29 Aug 2025 15:15:45 +0800 Subject: [PATCH 02/12] doc --- docs/Fixed-or-Improved-Logics.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 2663b2e295..5608fb26d0 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -17,6 +17,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Fixed building and defense tab hotkeys not enabling the placement mode after *Cannot build here.* triggered and the placement mode cancelled. - Fixed buildings with `UndeployInto` playing `EVA_NewRallypointEstablished` on undeploying. - Fixed buildings with `Naval=yes` ignoring `WaterBound=no` to be forced to place onto water. +- Fixed AI-controlled buildings continuing production while under EMP effect. Now freezes factory production progress for AI-owned buildings during EMP until the effect wears off. - Fixed AI Aircraft docks bug when Ares tag `[GlobalControls] -> AllowParallelAIQueues=no` is set. - Fixed laser drawing code to allow for thicker lasers in house color draw mode. - Fixed `DeathWeapon` not detonating properly. From 1813f5452c27950e5ddda3e24c5145514b8436c0 Mon Sep 17 00:00:00 2001 From: lvjia Date: Fri, 29 Aug 2025 16:00:36 +0800 Subject: [PATCH 03/12] Refactor EMP state checks and building production logic --- src/Ext/Techno/Body.Update.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index 4265b32393..d0c1e4864c 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include @@ -18,8 +20,6 @@ #include #include #include -#include -#include // TechnoClass_AI_0x6F9E50 @@ -1629,8 +1629,9 @@ void TechnoExt::ExtData::UpdateTemporal() void TechnoExt::ExtData::UpdateRearmInEMPState() { const auto pThis = this->OwnerObject(); + const bool underEMP = pThis->IsUnderEMP(); - if (!pThis->IsUnderEMP() && !pThis->Deactivated) + if (!underEMP && !pThis->Deactivated) return; const auto pTypeExt = this->TypeExtData; @@ -1642,17 +1643,18 @@ void TechnoExt::ExtData::UpdateRearmInEMPState() pThis->ReloadTimer.StartTime++; // Freeze AI-controlled factory production while building is EMPed - if (pThis->IsUnderEMP() && pThis->WhatAmI() == AbstractType::Building) + if (underEMP) { - auto const pBuilding = static_cast(pThis); - - if (pBuilding->Owner && !pBuilding->Owner->IsControlledByHuman()) + if (auto const pBuilding = abstract_cast(pThis)) { - if (auto const pFactory = pBuilding->Factory) + if (pBuilding->Owner && !pBuilding->Owner->IsControlledByHuman()) { - if (pFactory->Object && pFactory->Production.Rate > 0) + if (auto const pFactory = pBuilding->Factory) { - pFactory->Production.Timer.StartTime++; + if (pFactory->Object && pFactory->Production.Rate > 0) + { + pFactory->Production.Timer.StartTime++; + } } } } From a4f09b7b7981d83db4ba590d127953d5afc1fc21 Mon Sep 17 00:00:00 2001 From: lvjia Date: Fri, 29 Aug 2025 16:00:56 +0800 Subject: [PATCH 04/12] Enhance spawn logic with building power checks Added checks for building power status and spawn regeneration rate. --- src/Ext/Techno/Hooks.Misc.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Ext/Techno/Hooks.Misc.cpp b/src/Ext/Techno/Hooks.Misc.cpp index 517110b81a..aa766b01e4 100644 --- a/src/Ext/Techno/Hooks.Misc.cpp +++ b/src/Ext/Techno/Hooks.Misc.cpp @@ -2,8 +2,13 @@ #include #include +#include #include +#include +#include +#include +#include #pragma region SlaveManagerClass @@ -155,6 +160,15 @@ DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6) auto const pOwner = pThis->Owner; auto const pTypeExt = TechnoExt::ExtMap.Find(pOwner)->TypeExtData; + if (auto const pBuilding = abstract_cast(pOwner)) + { + if (pBuilding->Type->Powered && !pBuilding->IsPowerOnline()) + return 0; + } + + if (const auto pOwnerType = pOwner->GetTechnoType(); pOwnerType && pOwnerType->SpawnRegenRate <= 0) + return 0; + if (pTypeExt->Spawns_Queue.empty()) return 0; From 70b3df8e14b6c0da6ff7fdec064624fd57e5aa92 Mon Sep 17 00:00:00 2001 From: lvjia Date: Fri, 29 Aug 2025 16:03:37 +0800 Subject: [PATCH 05/12] Fix EMP effects on AI production for buildings Enhanced EMP handling for AI-owned buildings, ensuring production is paused during EMP effects based on immunity settings. --- docs/Fixed-or-Improved-Logics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 5608fb26d0..5ba3177a5c 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -17,7 +17,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Fixed building and defense tab hotkeys not enabling the placement mode after *Cannot build here.* triggered and the placement mode cancelled. - Fixed buildings with `UndeployInto` playing `EVA_NewRallypointEstablished` on undeploying. - Fixed buildings with `Naval=yes` ignoring `WaterBound=no` to be forced to place onto water. -- Fixed AI-controlled buildings continuing production while under EMP effect. Now freezes factory production progress for AI-owned buildings during EMP until the effect wears off. +- Fixed EMP immunity respect for production/spawner: AI-owned buildings with `ImmuneToEMP=no` no longer continue production (and carrier-like spawner behaviour) while under EMP; production is paused for the EMP duration. Buildings with `ImmuneToEMP=yes` are unaffected and continue producing/spawning as before. - Fixed AI Aircraft docks bug when Ares tag `[GlobalControls] -> AllowParallelAIQueues=no` is set. - Fixed laser drawing code to allow for thicker lasers in house color draw mode. - Fixed `DeathWeapon` not detonating properly. From 03d8e5a6476e146066a8a19becebe951a2bbfac5 Mon Sep 17 00:00:00 2001 From: lvjia Date: Fri, 29 Aug 2025 16:08:40 +0800 Subject: [PATCH 06/12] doc --- docs/Whats-New.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 787d5253bc..2eb02a863d 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -457,6 +457,7 @@ Phobos fixes: - Fixed an issue that `FireAngle` was not taken into account when drawing barrel in `TurretShadow` (by CrimRecya) Fixes / interactions with other extensions: +- Pause AI building production and spawner aircraft under EMP (by ahasasjeb) - Allowed `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades (by Ollerus) - Taking over Ares' AlphaImage respawn logic to reduce lags from it (by NetsuNegi) ``` From 69f19c398dedfe3ffe41fb7c3241ab664860f8e0 Mon Sep 17 00:00:00 2001 From: lvjia Date: Fri, 29 Aug 2025 19:04:45 +0800 Subject: [PATCH 07/12] Update CREDITS.md --- CREDITS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CREDITS.md b/CREDITS.md index 59b2dc7b82..3cd4ec0b30 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -642,3 +642,5 @@ This page lists all the individual contributions to the project by their author. - **Damfoos** - extensive and thorough testing - **Dmitry Volkov** - extensive and thorough testing - **Rise of the East community** - extensive playtesting of in-dev features +- **ahasasjeb** + - fix:Pause AI building production and spawner aircraft under EMP (respect ImmuneToEMP) From 82b85f51cf347deb6f848a4c24ca41a8f4ad98a9 Mon Sep 17 00:00:00 2001 From: lvjia Date: Sat, 30 Aug 2025 15:22:41 +0800 Subject: [PATCH 08/12] Add EMP.PausesSpawning toggle and fix AI production under EMP --- CREDITS.md | 3 ++- docs/Fixed-or-Improved-Logics.md | 13 ++++++++++++- src/Ext/Rules/Body.cpp | 2 ++ src/Ext/Rules/Body.h | 2 ++ src/Ext/Techno/Hooks.Misc.cpp | 3 ++- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index 3cd4ec0b30..3f2850a71c 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -643,4 +643,5 @@ This page lists all the individual contributions to the project by their author. - **Dmitry Volkov** - extensive and thorough testing - **Rise of the East community** - extensive playtesting of in-dev features - **ahasasjeb** - - fix:Pause AI building production and spawner aircraft under EMP (respect ImmuneToEMP) + - fix: Pause AI building production under EMP (respect ImmuneToEMP) + - EMP effect on spawner aircraft generation with toggle control diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 5ba3177a5c..ed91b9b80f 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -17,7 +17,8 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Fixed building and defense tab hotkeys not enabling the placement mode after *Cannot build here.* triggered and the placement mode cancelled. - Fixed buildings with `UndeployInto` playing `EVA_NewRallypointEstablished` on undeploying. - Fixed buildings with `Naval=yes` ignoring `WaterBound=no` to be forced to place onto water. -- Fixed EMP immunity respect for production/spawner: AI-owned buildings with `ImmuneToEMP=no` no longer continue production (and carrier-like spawner behaviour) while under EMP; production is paused for the EMP duration. Buildings with `ImmuneToEMP=yes` are unaffected and continue producing/spawning as before. +- Fixed AI buildings with `ImmuneToEMP=no` continuing production (infantry, vehicles, buildings) while under EMP; production is now paused for the EMP duration. Buildings with `ImmuneToEMP=yes` are unaffected and continue producing as before. +- EMP effect on spawner aircraft generation can now be controlled via `EMP.PausesSpawning`. When enabled (default), buildings with `ImmuneToEMP=no` no longer continue spawner aircraft generation while under EMP; spawning is paused for the EMP duration. Buildings with `ImmuneToEMP=yes` are unaffected and continue spawning as before. - Fixed AI Aircraft docks bug when Ares tag `[GlobalControls] -> AllowParallelAIQueues=no` is set. - Fixed laser drawing code to allow for thicker lasers in house color draw mode. - Fixed `DeathWeapon` not detonating properly. @@ -511,6 +512,16 @@ AINodeWallsOnly=false ; boolean AICleanWallNode=false ; boolean ``` +### EMP effect on spawner aircraft generation + +- By default buildings with spawner functionality (aircraft carriers) and `ImmuneToEMP=no` pause aircraft spawning while under EMP. This behavior can be disabled to restore vanilla behavior where EMP does not affect spawner aircraft generation. + +In `rulesmd.ini`: +```ini +[General] +EMP.PausesSpawning=yes ; boolean +``` + ### Aircraft docking direction - It is now possible to customize the landing direction for docking aircraft via `AircraftDockingDir(N)` (`N` optionally replaced by 0-based index for each `DockingOffset` separately, `AircraftDockingDir` and `AircraftDockingDir0` are synonymous and will be used if direction is not set for a specific offset) on the dock building. This overrides the aircraft's own [landing direction](#landing-direction) setting and defaults to `[AudioVisual] -> PoseDir`. diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 3096023aa4..d3839a8efa 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -310,6 +310,7 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->DistributeTargetingFrame_AIOnly.Read(exINI, GameStrings::General, "DistributeTargetingFrame.AIOnly"); this->InfantryAutoDeploy.Read(exINI, GameStrings::General, "InfantryAutoDeploy"); + this->EMP_PausesSpawning.Read(exINI, GameStrings::General, "EMP.PausesSpawning"); // Section AITargetTypes int itemsCount = pINI->GetKeyCount("AITargetTypes"); @@ -572,6 +573,7 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->AttackMove_StopWhenTargetAcquired) .Process(this->Parasite_GrappleAnim) .Process(this->InfantryAutoDeploy) + .Process(this->EMP_PausesSpawning) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index 2584a189dc..1ac5b2c5e7 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -263,6 +263,7 @@ class RulesExt int TintColorBerserk; Valueable InfantryAutoDeploy; + Valueable EMP_PausesSpawning; ExtData(RulesClass* OwnerObject) : Extension(OwnerObject) , Storage_TiberiumIndex { -1 } @@ -468,6 +469,7 @@ class RulesExt , Parasite_GrappleAnim {} , InfantryAutoDeploy { false } + , EMP_PausesSpawning { true } { } virtual ~ExtData() = default; diff --git a/src/Ext/Techno/Hooks.Misc.cpp b/src/Ext/Techno/Hooks.Misc.cpp index aa766b01e4..d59e5372f4 100644 --- a/src/Ext/Techno/Hooks.Misc.cpp +++ b/src/Ext/Techno/Hooks.Misc.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #pragma region SlaveManagerClass @@ -162,7 +163,7 @@ DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6) if (auto const pBuilding = abstract_cast(pOwner)) { - if (pBuilding->Type->Powered && !pBuilding->IsPowerOnline()) + if (pBuilding->Type->Powered && !pBuilding->IsPowerOnline() && RulesExt::Global()->EMP_PausesSpawning) return 0; } From ee75e097283b9b2becf783e0fc80294bdb817e47 Mon Sep 17 00:00:00 2001 From: lvjia Date: Sat, 30 Aug 2025 15:49:48 +0800 Subject: [PATCH 09/12] code optimization --- src/Ext/Techno/Body.Update.cpp | 13 +++++-------- src/Ext/Techno/Hooks.cpp | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index d0c1e4864c..cb68bb0a42 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -1643,18 +1643,15 @@ void TechnoExt::ExtData::UpdateRearmInEMPState() pThis->ReloadTimer.StartTime++; // Freeze AI-controlled factory production while building is EMPed - if (underEMP) + if (auto const pBuilding = abstract_cast(pThis)) { - if (auto const pBuilding = abstract_cast(pThis)) + if (pBuilding->Owner && !pBuilding->Owner->IsControlledByHuman()) { - if (pBuilding->Owner && !pBuilding->Owner->IsControlledByHuman()) + if (auto const pFactory = pBuilding->Factory) { - if (auto const pFactory = pBuilding->Factory) + if (pFactory->Object && pFactory->Production.Rate > 0) { - if (pFactory->Object && pFactory->Production.Rate > 0) - { - pFactory->Production.Timer.StartTime++; - } + pFactory->Production.Timer.StartTime++; } } } diff --git a/src/Ext/Techno/Hooks.cpp b/src/Ext/Techno/Hooks.cpp index 247e2f2a0b..64782f193d 100644 --- a/src/Ext/Techno/Hooks.cpp +++ b/src/Ext/Techno/Hooks.cpp @@ -160,7 +160,7 @@ DEFINE_HOOK(0x6F9FA9, TechnoClass_AI_PromoteAnim, 0x6) if (pThis->Veterancy.GetRemainingLevel() == Rank::Veteran && pVeteranAnim) promAnim = GameCreate(pVeteranAnim, pThis->GetCenterCoords()); - else if (pEliteAnim) + else if (pThis->Veterancy.GetRemainingLevel() == Rank::Elite && pEliteAnim) promAnim = GameCreate(pEliteAnim, pThis->GetCenterCoords()); if (promAnim) From 1624721d1610b0158ea1af2c94c2c5c122b98b7f Mon Sep 17 00:00:00 2001 From: lvjia Date: Sat, 30 Aug 2025 16:16:08 +0800 Subject: [PATCH 10/12] code optimization --- src/Ext/Techno/Hooks.Misc.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Ext/Techno/Hooks.Misc.cpp b/src/Ext/Techno/Hooks.Misc.cpp index d59e5372f4..f255ad75dc 100644 --- a/src/Ext/Techno/Hooks.Misc.cpp +++ b/src/Ext/Techno/Hooks.Misc.cpp @@ -161,12 +161,6 @@ DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6) auto const pOwner = pThis->Owner; auto const pTypeExt = TechnoExt::ExtMap.Find(pOwner)->TypeExtData; - if (auto const pBuilding = abstract_cast(pOwner)) - { - if (pBuilding->Type->Powered && !pBuilding->IsPowerOnline() && RulesExt::Global()->EMP_PausesSpawning) - return 0; - } - if (const auto pOwnerType = pOwner->GetTechnoType(); pOwnerType && pOwnerType->SpawnRegenRate <= 0) return 0; @@ -188,6 +182,13 @@ DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6) if (vec.empty() || !vec[0]) return 0; + // Check if building is powered and EMP pausing is enabled, but don't skip queue logic + if (auto const pBuilding = abstract_cast(pOwner)) + { + if (pBuilding->Type->Powered && !pBuilding->IsPowerOnline() && RulesExt::Global()->EMP_PausesSpawning) + return 0; + } + R->EAX(vec[0]->CreateObject(pOwner->Owner)); return 0x6B78EA; } From 906c771dbe504a9a657503485ad8063f3d2781f9 Mon Sep 17 00:00:00 2001 From: lvjia Date: Sun, 31 Aug 2025 05:16:38 +0800 Subject: [PATCH 11/12] code optimization --- src/Ext/Techno/Hooks.Misc.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Ext/Techno/Hooks.Misc.cpp b/src/Ext/Techno/Hooks.Misc.cpp index f255ad75dc..7a3f860178 100644 --- a/src/Ext/Techno/Hooks.Misc.cpp +++ b/src/Ext/Techno/Hooks.Misc.cpp @@ -182,13 +182,6 @@ DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6) if (vec.empty() || !vec[0]) return 0; - // Check if building is powered and EMP pausing is enabled, but don't skip queue logic - if (auto const pBuilding = abstract_cast(pOwner)) - { - if (pBuilding->Type->Powered && !pBuilding->IsPowerOnline() && RulesExt::Global()->EMP_PausesSpawning) - return 0; - } - R->EAX(vec[0]->CreateObject(pOwner->Owner)); return 0x6B78EA; } From 9c7afb093a6579d99644c546fa4c44d95541cff4 Mon Sep 17 00:00:00 2001 From: lvjia Date: Sun, 31 Aug 2025 05:18:33 +0800 Subject: [PATCH 12/12] code optimization --- src/Ext/Techno/Hooks.Misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Techno/Hooks.Misc.cpp b/src/Ext/Techno/Hooks.Misc.cpp index 7a3f860178..d5d8b84b70 100644 --- a/src/Ext/Techno/Hooks.Misc.cpp +++ b/src/Ext/Techno/Hooks.Misc.cpp @@ -179,7 +179,7 @@ DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6) } } - if (vec.empty() || !vec[0]) + if (vec.empty()) return 0; R->EAX(vec[0]->CreateObject(pOwner->Owner));