diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 29792e0fb3..95bde9cc12 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -442,3 +442,17 @@ DEFINE_HOOK(0x454244, BuildingClass_Save_Suffix, 0x7) // Removes setting otherwise unused field (0x6FC) in BuildingClass when building has airstrike applied on it so that it can safely be used to store BuildingExt pointer. DEFINE_JUMP(LJMP, 0x41D9FB, 0x41DA05); + + +void __fastcall BuildingClass_InfiltratedBy_Wrapper(BuildingClass* pThis, void*, HouseClass* pInfiltratorHouse) +{ + int oldBalance = pThis->Owner->Available_Money(); + // explicitly call because Ares rewrote it + reinterpret_cast(0x4571E0)(pThis, pInfiltratorHouse); + + BuildingExt::HandleInfiltrate(pThis, pInfiltratorHouse); + + BuildingExt::ExtMap.Find(pThis)->AccumulatedIncome += pThis->Owner->Available_Money() - oldBalance; +} + +DEFINE_JUMP(CALL, 0x51A00B, GET_OFFSET(BuildingClass_InfiltratedBy_Wrapper)); diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index 41aba7ba09..031566faa1 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -361,49 +361,6 @@ DEFINE_HOOK(0x440EBB, BuildingClass_Unlimbo_NaturalParticleSystem_CampaignSkip, return BuildingExt::ExtMap.Find(pThis)->IsCreatedFromMapFile ? DoNotCreateParticle : 0; } -// Note: -/* -Ares has a hook at 0x4571E0 (the beginning of BuildingClass::Infiltrate) and completely overwrites the function. -Our logic has to be executed at the end (0x4575A2). The hook there assumes that registers have the exact content -they had in the beginning (when Ares hook started, executed, and jumped) in order to work when Ares logic is used. - -However, this will fail if Ares is not involved (either DLL not included or with SpyEffect.Custom=no on BuildingType), -because by the time we reach our hook, the registers will be different and we'll be reading garbage. That's why -there is a second hook at 0x45759D, which is only executed when Ares doesn't jump over this function. There, -we execute our custom logic and then use EAX (which isn't used later, so it's safe to write to it) to "mark" -that we're done with 0x77777777. This way, when we reach the other hook, we check for this very specific value -to prevent spy effects from happening twice. - -The value itself doesn't matter, it just needs to be unique enough to not be accidentally produced by the game there. -*/ -constexpr int INFILTRATE_HOOK_MAGIC = 0x77777777; - -DEFINE_HOOK(0x45759D, BuildingClass_Infiltrate_NoAres, 0x5) -{ - GET_STACK(HouseClass*, pInfiltratorHouse, STACK_OFFSET(0x14, -0x4)); - GET(BuildingClass*, pBuilding, EBP); - - BuildingExt::HandleInfiltrate(pBuilding, pInfiltratorHouse); - R->EAX(INFILTRATE_HOOK_MAGIC); - return 0; -} - -DEFINE_HOOK(0x4575A2, BuildingClass_Infiltrate_AfterAres, 0xE) -{ - // Check if we've handled it already - if (R->EAX() == INFILTRATE_HOOK_MAGIC) - { - R->EAX(0); - return 0; - } - - GET_STACK(HouseClass*, pInfiltratorHouse, -0x4); - GET(BuildingClass*, pBuilding, ECX); - - BuildingExt::HandleInfiltrate(pBuilding, pInfiltratorHouse); - return 0; -} - DEFINE_HOOK(0x4519A2, BuildingClass_UpdateAnim_SetParentBuilding, 0x6) { GET(BuildingClass*, pThis, ESI);