diff --git a/src/Ext/Techno/Hooks.Firing.cpp b/src/Ext/Techno/Hooks.Firing.cpp index 300ea0f465..e6baa92582 100644 --- a/src/Ext/Techno/Hooks.Firing.cpp +++ b/src/Ext/Techno/Hooks.Firing.cpp @@ -1,4 +1,4 @@ -#include "Body.h" +#include "Body.h" #include #include @@ -199,59 +199,68 @@ DEFINE_HOOK(0x6F3432, TechnoClass_WhatWeaponShouldIUse_Gattling, 0xA) auto const pTargetTechno = abstract_cast(pTarget); const int oddWeaponIndex = 2 * pThis->CurrentGattlingStage; const int evenWeaponIndex = oddWeaponIndex + 1; - int chosenWeaponIndex = oddWeaponIndex; const int eligibleWeaponIndex = TechnoExt::PickWeaponIndex(pThis, pTargetTechno, pTarget, oddWeaponIndex, evenWeaponIndex, true); if (eligibleWeaponIndex != -1) { - chosenWeaponIndex = eligibleWeaponIndex; + R->EAX(eligibleWeaponIndex); + return UseWeaponIndex; } - else if (pTargetTechno) + + int chosenWeaponIndex = oddWeaponIndex; + + if (pTargetTechno) { auto const pTargetExt = TechnoExt::ExtMap.Find(pTargetTechno); - auto const pWeaponOdd = pThis->GetWeapon(oddWeaponIndex)->WeaponType; auto const pWeaponEven = pThis->GetWeapon(evenWeaponIndex)->WeaponType; - bool skipRemainingChecks = false; + auto const pShield = pTargetExt->Shield.get(); + auto const armor = pTargetTechno->GetTechnoType()->Armor; + const bool inAir = pTargetTechno->IsInAir(); + const bool isUnderground = pTargetTechno->InWhichLayer() == Layer::Underground; - if (const auto pShield = pTargetExt->Shield.get()) - { - if (pShield->IsActive() && !pShield->CanBeTargeted(pWeaponOdd)) + auto isWeaponValid = [&](WeaponTypeClass* pWeapon) { - chosenWeaponIndex = evenWeaponIndex; - skipRemainingChecks = true; - } + if (inAir && !pWeapon->Projectile->AA) + return false; + if (isUnderground && !BulletTypeExt::ExtMap.Find(pWeapon->Projectile)->AU) + return false; + if (pShield && pShield->IsActive() && !pShield->CanBeTargeted(pWeapon)) + return false; + if (GeneralUtils::GetWarheadVersusArmor(pWeapon->Warhead, armor) == 0.0) + return false; + return true; + }; + + // check even weapon first + + if (!isWeaponValid(pWeaponEven)) + { + R->EAX(chosenWeaponIndex); + return UseWeaponIndex; } - if (!skipRemainingChecks) + // handle naval targeting + + if (!pTargetTechno->OnBridge && !inAir) { - if (GeneralUtils::GetWarheadVersusArmor(pWeaponOdd->Warhead, pTargetTechno->GetTechnoType()->Armor) == 0.0) - { - chosenWeaponIndex = evenWeaponIndex; - } - else if (pTargetTechno->InWhichLayer() == Layer::Underground) + auto const landType = pTargetTechno->GetCell()->LandType; + + if (landType == LandType::Water || landType == LandType::Beach) { - if (BulletTypeExt::ExtMap.Find(pWeaponEven->Projectile)->AU && !BulletTypeExt::ExtMap.Find(pWeaponOdd->Projectile)->AU) + if (pThis->SelectNavalTargeting(pTargetTechno) == 1) chosenWeaponIndex = evenWeaponIndex; - } - else - { - auto const landType = pTargetTechno->GetCell()->LandType; - const bool isOnWater = (landType == LandType::Water || landType == LandType::Beach) && !pTargetTechno->IsInAir(); - if (!pTargetTechno->OnBridge && isOnWater && pThis->SelectNavalTargeting(pTargetTechno) == 2) - { - chosenWeaponIndex = evenWeaponIndex; - } - else if (pTargetTechno->IsInAir() && !pWeaponOdd->Projectile->AA && pWeaponEven->Projectile->AA) - { - chosenWeaponIndex = evenWeaponIndex; - } - else if (pThis->GetTechnoType()->LandTargeting == LandTargetingType::Land_Secondary) - { - chosenWeaponIndex = evenWeaponIndex; - } + R->EAX(chosenWeaponIndex); + return UseWeaponIndex; } } + + // check odd weapon + + auto const pWeaponOdd = pThis->GetWeapon(oddWeaponIndex)->WeaponType; + + if (!isWeaponValid(pWeaponOdd) || pThis->GetTechnoType()->LandTargeting == LandTargetingType::Land_Secondary) + chosenWeaponIndex = evenWeaponIndex; } R->EAX(chosenWeaponIndex); diff --git a/src/Ext/Techno/Hooks.WeaponRange.cpp b/src/Ext/Techno/Hooks.WeaponRange.cpp index 8296c3ed75..c60dea0db5 100644 --- a/src/Ext/Techno/Hooks.WeaponRange.cpp +++ b/src/Ext/Techno/Hooks.WeaponRange.cpp @@ -196,7 +196,7 @@ DEFINE_HOOK(0x6FC3A1, TechnoClass_CanFire_InBunkerRangeCheck, 0x5) GET(TechnoClass*, pThis, EBP); GET(WeaponTypeClass*, pWeapon, EDI); - if (pThis->WhatAmI() == AbstractType::Unit && WeaponTypeExt::GetRangeWithModifiers(pWeapon, pThis) < 384.0) + if (pThis->WhatAmI() == AbstractType::Unit && WeaponTypeExt::GetRangeWithModifiers(pWeapon, pThis) < 384) return CannotFire; return ContinueChecks; diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index b3dbfc04b2..157ce79212 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -158,9 +158,6 @@ int TechnoTypeExt::ExtData::SelectMultiWeapon(TechnoClass* const pThis, Abstract if (const auto pTargetTechno = abstract_cast(pTarget)) { - if (pTargetTechno->Health <= 0 || !pTargetTechno->IsAlive) - return 0; - bool getNavalTargeting = false; auto checkSecondary = [&](int weaponIndex) -> bool @@ -217,9 +214,8 @@ int TechnoTypeExt::ExtData::SelectMultiWeapon(TechnoClass* const pThis, Abstract }; const LandType landType = pTargetTechno->GetCell()->LandType; - const bool targetOnWater = landType == LandType::Water || landType == LandType::Beach; - if (!pTargetTechno->OnBridge && targetOnWater) + if (!pTargetTechno->OnBridge && (landType == LandType::Water || landType == LandType::Beach) && !pTargetTechno->IsInAir()) { const int result = pThis->SelectNavalTargeting(pTargetTechno);