diff --git a/src/Ext/Bullet/Hooks.cpp b/src/Ext/Bullet/Hooks.cpp index 16f71674b0..9008fcdea6 100644 --- a/src/Ext/Bullet/Hooks.cpp +++ b/src/Ext/Bullet/Hooks.cpp @@ -505,11 +505,8 @@ DEFINE_HOOK(0x415F25, AircraftClass_Fire_TrajectorySkipInertiaEffect, 0x6) GET(BulletClass*, pThis, ESI); - if (auto const pExt = BulletExt::ExtMap.Find(pThis)) - { - if (pExt->Trajectory) - return SkipCheck; - } + if (BulletExt::ExtMap.Find(pThis)->Trajectory) + return SkipCheck; return 0; } diff --git a/src/Ext/Techno/Hooks.Harvester.cpp b/src/Ext/Techno/Hooks.Harvester.cpp index b66c9dced4..5a620d1b16 100644 --- a/src/Ext/Techno/Hooks.Harvester.cpp +++ b/src/Ext/Techno/Hooks.Harvester.cpp @@ -139,7 +139,7 @@ DEFINE_HOOK(0x73EB2C, UnitClass_MissionHarvest_Status2, 0x6) const auto pType = pThis->Type; const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pType); - if (!pTypeExt || !pTypeExt->HarvesterQuickUnloader) + if (!pTypeExt->HarvesterQuickUnloader) return 0; std::vector docks; @@ -316,11 +316,8 @@ DEFINE_HOOK(0x441226, BuildingClass_Unlimbo_RecheckRefinery, 0x6) { GET(BuildingClass* const, pThis, ESI); - if (pThis->Type->Refinery) - { - if (const auto pHouseExt = HouseExt::ExtMap.Find(pThis->Owner)) - pHouseExt->LastRefineryBuildFrame = Unsorted::CurrentFrame; - } + if (pThis->Type->Refinery && pThis->Owner) + HouseExt::ExtMap.Find(pThis->Owner)->LastRefineryBuildFrame = Unsorted::CurrentFrame; return 0; } diff --git a/src/Ext/Techno/Hooks.Others.cpp b/src/Ext/Techno/Hooks.Others.cpp index 40d22a96f7..308ec3045b 100644 --- a/src/Ext/Techno/Hooks.Others.cpp +++ b/src/Ext/Techno/Hooks.Others.cpp @@ -24,29 +24,26 @@ DEFINE_HOOK(0x5209EE, InfantryClass_UpdateFiring_BurstNoDelay, 0x5) { if (pWeapon->Burst > 1) { - if (const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon)) + if (WeaponTypeExt::ExtMap.Find(pWeapon)->Burst_NoDelay) { - if (pWeaponExt->Burst_NoDelay) + if (pThis->Fire(pTarget, wpIdx)) { - if (pThis->Fire(pTarget, wpIdx)) - { - if (!pThis->CurrentBurstIndex) - return SkipVanillaFire; - - auto rof = pThis->RearmTimer.TimeLeft; - pThis->RearmTimer.Start(0); + if (!pThis->CurrentBurstIndex) + return SkipVanillaFire; - for (auto i = pThis->CurrentBurstIndex; i != pWeapon->Burst && pThis->GetFireError(pTarget, wpIdx, true) == FireError::OK && pThis->Fire(pTarget, wpIdx); ++i) - { - rof = pThis->RearmTimer.TimeLeft; - pThis->RearmTimer.Start(0); - } + auto rof = pThis->RearmTimer.TimeLeft; + pThis->RearmTimer.Start(0); - pThis->RearmTimer.Start(rof); + for (auto i = pThis->CurrentBurstIndex; i != pWeapon->Burst && pThis->GetFireError(pTarget, wpIdx, true) == FireError::OK && pThis->Fire(pTarget, wpIdx); ++i) + { + rof = pThis->RearmTimer.TimeLeft; + pThis->RearmTimer.Start(0); } - return SkipVanillaFire; + pThis->RearmTimer.Start(rof); } + + return SkipVanillaFire; } } } @@ -66,29 +63,26 @@ DEFINE_HOOK(0x736F67, UnitClass_UpdateFiring_BurstNoDelay, 0x6) { if (pWeapon->Burst > 1) { - if (const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon)) + if (WeaponTypeExt::ExtMap.Find(pWeapon)->Burst_NoDelay) { - if (pWeaponExt->Burst_NoDelay) + if (pThis->Fire(pTarget, wpIdx)) { - if (pThis->Fire(pTarget, wpIdx)) - { - if (!pThis->CurrentBurstIndex) - return SkipVanillaFire; + if (!pThis->CurrentBurstIndex) + return SkipVanillaFire; - auto rof = pThis->RearmTimer.TimeLeft; - pThis->RearmTimer.Start(0); - - for (auto i = pThis->CurrentBurstIndex; i != pWeapon->Burst && pThis->GetFireError(pTarget, wpIdx, true) == FireError::OK && pThis->Fire(pTarget, wpIdx); ++i) - { - rof = pThis->RearmTimer.TimeLeft; - pThis->RearmTimer.Start(0); - } + auto rof = pThis->RearmTimer.TimeLeft; + pThis->RearmTimer.Start(0); - pThis->RearmTimer.Start(rof); + for (auto i = pThis->CurrentBurstIndex; i != pWeapon->Burst && pThis->GetFireError(pTarget, wpIdx, true) == FireError::OK && pThis->Fire(pTarget, wpIdx); ++i) + { + rof = pThis->RearmTimer.TimeLeft; + pThis->RearmTimer.Start(0); } - return SkipVanillaFire; + pThis->RearmTimer.Start(rof); } + + return SkipVanillaFire; } } } @@ -241,77 +235,45 @@ DEFINE_HOOK(0x70DE40, BuildingClass_sub_70DE40_GattlingRateDownDelay, 0xA) GET(BuildingClass* const, pThis, ECX); GET_STACK(int, rateDown, STACK_OFFSET(0x0, 0x4)); - do - { - auto newValue = pThis->GattlingValue; - - if (const auto pExt = TechnoExt::ExtMap.Find(pThis)) - { - const auto pTypeExt = pExt->TypeExtData; - - if (pTypeExt->RateDown_Reset) - { - if (!pThis->Target) - { - pExt->LastTargetID = 0xFFFFFFFF; - pThis->GattlingValue = 0; - pThis->CurrentGattlingStage = 0; + auto newValue = pThis->GattlingValue; + const auto pExt = TechnoExt::ExtMap.Find(pThis); + const auto pTypeExt = pExt->TypeExtData; - return Return; - } - else if (pExt->LastTargetID != pThis->Target->UniqueID) - { - pExt->LastTargetID = pThis->Target->UniqueID; - pThis->GattlingValue = 0; - pThis->CurrentGattlingStage = 0; - - return Return; - } - } - - if (pTypeExt->RateDown_Delay < 0) - return Return; - - ++pExt->AccumulatedGattlingValue; - auto remain = pExt->AccumulatedGattlingValue; - - if (!pExt->ShouldUpdateGattlingValue) - remain -= pTypeExt->RateDown_Delay; - - if (remain <= 0) - return Return; - - // Time's up - pExt->AccumulatedGattlingValue = 0; - pExt->ShouldUpdateGattlingValue = true; + if (pTypeExt->RateDown_Reset && (!pThis->Target || pExt->LastTargetID != pThis->Target->UniqueID)) + { + pExt->LastTargetID = pThis->Target ? pThis->Target->UniqueID : 0xFFFFFFFF; + pThis->GattlingValue = 0; + pThis->CurrentGattlingStage = 0; + return Return; + } - if (pThis->Ammo <= pTypeExt->RateDown_Ammo) - rateDown = pTypeExt->RateDown_Cover; + if (pTypeExt->RateDown_Delay < 0) + return Return; - if (!rateDown) - break; + ++pExt->AccumulatedGattlingValue; + auto remain = pExt->AccumulatedGattlingValue; - newValue -= (rateDown * remain); - } - else - { - if (!rateDown) - break; + if (!pExt->ShouldUpdateGattlingValue) + remain -= pTypeExt->RateDown_Delay; - newValue -= rateDown; - } + if (remain <= 0) + return Return; - if (newValue <= 0) - break; + // Time's up + pExt->AccumulatedGattlingValue = 0; + pExt->ShouldUpdateGattlingValue = true; - pThis->GattlingValue = newValue; + if (pThis->Ammo <= pTypeExt->RateDown_Ammo) + rateDown = pTypeExt->RateDown_Cover; + if (!rateDown) + { + pThis->GattlingValue = 0; return Return; } - while (false); - - pThis->GattlingValue = 0; + newValue -= (rateDown * remain); + pThis->GattlingValue = (newValue <= 0) ? 0 : newValue; return Return; } @@ -321,20 +283,11 @@ DEFINE_HOOK(0x70DE70, TechnoClass_sub_70DE70_GattlingRateDownReset, 0x5) if (const auto pExt = TechnoExt::ExtMap.Find(pThis)) { - if (pExt->TypeExtData->RateDown_Reset) + if (pExt->TypeExtData->RateDown_Reset && (!pThis->Target || pExt->LastTargetID != pThis->Target->UniqueID)) { - if (!pThis->Target) - { - pExt->LastTargetID = 0xFFFFFFFF; - pThis->GattlingValue = 0; - pThis->CurrentGattlingStage = 0; - } - else if (pExt->LastTargetID != pThis->Target->UniqueID) - { - pExt->LastTargetID = pThis->Target->UniqueID; - pThis->GattlingValue = 0; - pThis->CurrentGattlingStage = 0; - } + pExt->LastTargetID = pThis->Target ? pThis->Target->UniqueID : 0xFFFFFFFF; + pThis->GattlingValue = 0; + pThis->CurrentGattlingStage = 0; } pExt->AccumulatedGattlingValue = 0; @@ -351,84 +304,50 @@ DEFINE_HOOK(0x70E01E, TechnoClass_sub_70E000_GattlingRateDownDelay, 0x6) GET(TechnoClass* const, pThis, ESI); GET_STACK(int, rateMult, STACK_OFFSET(0x10, 0x4)); - do - { - auto newValue = pThis->GattlingValue; - - if (const auto pExt = TechnoExt::ExtMap.Find(pThis)) - { - const auto pTypeExt = pExt->TypeExtData; - - if (pTypeExt->RateDown_Reset) - { - if (!pThis->Target) - { - pExt->LastTargetID = 0xFFFFFFFF; - pThis->GattlingValue = 0; - pThis->CurrentGattlingStage = 0; - - return SkipGameCode; - } - else if (pExt->LastTargetID != pThis->Target->UniqueID) - { - pExt->LastTargetID = pThis->Target->UniqueID; - pThis->GattlingValue = 0; - pThis->CurrentGattlingStage = 0; - - return SkipGameCode; - } - } - - if (pTypeExt->RateDown_Delay < 0) - return SkipGameCode; + auto newValue = pThis->GattlingValue; + const auto pExt = TechnoExt::ExtMap.Find(pThis); + const auto pTypeExt = pExt->TypeExtData; - pExt->AccumulatedGattlingValue += rateMult; - auto remain = pExt->AccumulatedGattlingValue; - - if (!pExt->ShouldUpdateGattlingValue) - remain -= pTypeExt->RateDown_Delay; - - if (remain <= 0 && rateMult) - return SkipGameCode; - - // Time's up - pExt->AccumulatedGattlingValue = 0; - pExt->ShouldUpdateGattlingValue = true; + if (pTypeExt->RateDown_Reset && (!pThis->Target || pExt->LastTargetID != pThis->Target->UniqueID)) + { + pExt->LastTargetID = pThis->Target ? pThis->Target->UniqueID : 0xFFFFFFFF; + pThis->GattlingValue = 0; + pThis->CurrentGattlingStage = 0; + return SkipGameCode; + } - if (!rateMult) - break; + if (pTypeExt->RateDown_Delay < 0) + return SkipGameCode; - const auto rateDown = (pThis->Ammo <= pTypeExt->RateDown_Ammo) ? pTypeExt->RateDown_Cover.Get() : pTypeExt->OwnerObject()->RateDown; + pExt->AccumulatedGattlingValue += rateMult; + auto remain = pExt->AccumulatedGattlingValue; - if (!rateDown) - break; + if (!pExt->ShouldUpdateGattlingValue) + remain -= pTypeExt->RateDown_Delay; - newValue -= (rateDown * remain); - } - else - { - if (!rateMult) - break; - - const auto rateDown = pThis->GetTechnoType()->RateDown; - - if (!rateDown) - break; + if (remain <= 0 && rateMult) + return SkipGameCode; - newValue -= (rateDown * rateMult); - } + // Time's up + pExt->AccumulatedGattlingValue = 0; + pExt->ShouldUpdateGattlingValue = true; - if (newValue <= 0) - break; + if (!rateMult) + { + pThis->GattlingValue = 0; + return SkipGameCode; + } - pThis->GattlingValue = newValue; + const auto rateDown = (pThis->Ammo <= pTypeExt->RateDown_Ammo) ? pTypeExt->RateDown_Cover.Get() : pTypeExt->OwnerObject()->RateDown; + if (!rateDown) + { + pThis->GattlingValue = 0; return SkipGameCode; } - while (false); - - pThis->GattlingValue = 0; + newValue -= (rateDown * remain); + pThis->GattlingValue = (newValue <= 0) ? 0 : newValue; return SkipGameCode; } @@ -643,6 +562,7 @@ bool __fastcall CanEnterNow(UnitClass* pTransport, FootClass* pPassenger) const auto linkCell = pLink->GetCoords(); const auto tranCell = pTransport->GetCoords(); + // When the most important passenger is close, need to prevent overlap if (abs(linkCell.X - tranCell.X) <= 384 && abs(linkCell.Y - tranCell.Y) <= 384) return (predictSize <= (maxSize - pLink->GetTechnoType()->Size)); } @@ -654,6 +574,7 @@ bool __fastcall CanEnterNow(UnitClass* pTransport, FootClass* pPassenger) if (needCalculate && remain < static_cast(pLink->GetTechnoType()->Size)) { + // Avoid passenger moving forward, resulting in overlap with transport and create invisible barrier pLink->SendToFirstLink(RadioCommand::NotifyUnlink); pLink->EnterIdleMode(false, true); } @@ -794,6 +715,7 @@ DEFINE_HOOK(0x73DC9C, UnitClass_Mission_Unload_NoQueueUpToUnloadBreak, 0xA) if (RulesExt::Global()->NoQueueUpToUnload) { + // Play the sound when interrupted for some reason GET(UnitClass* const, pThis, ESI); PlayUnitLeaveTransportSound(pThis); } @@ -811,6 +733,7 @@ DEFINE_HOOK(0x73DC1E, UnitClass_Mission_Unload_NoQueueUpToUnloadLoop, 0xA) { if (pThis->Passengers.NumPassengers <= pThis->NonPassengerCount) { + // If unloading is required within one frame, the sound will only be played when the last passenger leaves PlayUnitLeaveTransportSound(pThis); pThis->MissionStatus = 4; return UnloadReturn;