Skip to content
2 changes: 2 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
1 change: 1 addition & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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.
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
```
Expand Down
23 changes: 22 additions & 1 deletion src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <Kamikaze.h>
#include <JumpjetLocomotionClass.h>
#include <FlyLocomotionClass.h>
#include <BuildingClass.h>
#include <FactoryClass.h>

#include <Ext/Anim/Body.h>
#include <Ext/Bullet/Body.h>
Expand Down Expand Up @@ -1627,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;
Expand All @@ -1638,6 +1641,24 @@ 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 (underEMP)
{
if (auto const pBuilding = abstract_cast<BuildingClass*, true>(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()
Expand Down
14 changes: 14 additions & 0 deletions src/Ext/Techno/Hooks.Misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

#include <SpawnManagerClass.h>
#include <TunnelLocomotionClass.h>
#include <BuildingClass.h>

#include <Ext/Anim/Body.h>
#include <Ext/TechnoType/Body.h>
#include <Ext/Scenario/Body.h>
#include <Ext/WeaponType/Body.h>
#include <Ext/Bullet/Body.h>

#pragma region SlaveManagerClass

Expand Down Expand Up @@ -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<BuildingClass*, true>(pOwner))
{
if (pBuilding->Type->Powered && !pBuilding->IsPowerOnline())
return 0;
}

if (const auto pOwnerType = pOwner->GetTechnoType(); pOwnerType && pOwnerType->SpawnRegenRate <= 0)
return 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions:

  • I saw in your doc that you want to prevent the respawn of the spawnee in EMP state, but is this necessary? Will the building still launch them in EMP state?
  • And, you used return 0;, it will not affect any of the vanilla logic, but it will cause issues with the Spawns.Queue logic later on.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a clear look at the problem first and do not mark it as resolved at will

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review changes, please

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also have the same concern that your code may not work as you expect because it return 0. Have you tested it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code works fine

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In EMP state, SpawnManagerClass will not make any updates, which means these are unnecessary.
Even if this has any effect, return 0 means continuing to execute the game's vanilla instructions, which will break Spawns.Queue's logic.

What I want to express is that the code here actually has no effect. This approach is no different from the vanilla, as SpawnManagerClass would never work under EMP.
If you want to pause the timer, you can do it like the production. Although this may not be the most efficient approach, it is feasible.

if (pTypeExt->Spawns_Queue.empty())
return 0;

Expand Down