From f3ce1d5ff9d3374234c0eb11877cbc46302963f9 Mon Sep 17 00:00:00 2001 From: Asdow <20314541+Asdow@users.noreply.github.com> Date: Sat, 10 Jan 2026 16:37:14 +0200 Subject: [PATCH] Fix Tank suppression fire Code used wrong item to calculate recoil and burst APs causing the burst length loop to be stuck until the whole 2000 round mg magazine would be fired in one go. --- TacticalAI/DecideAction.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index df27421a..83becb94 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -8587,15 +8587,8 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier) (fExtraClip || pSoldier->inv[BestShot.bWeaponIn][0]->data.gun.ubGunShotsLeft > gGameExternalOptions.ubAISuppressionMinimumMagSize) ) { // then do it! - - // if necessary, swap the usItem from holster into the hand position DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "ArmedVehicleDecideActionRed: suppression fire possible!" ); - if ( BestShot.bWeaponIn != HANDPOS ) - { - RearrangePocket( pSoldier, HANDPOS, BestShot.bWeaponIn, FOREVER ); - } - pSoldier->aiData.usActionData = BestShot.sTarget; pSoldier->bTargetLevel = BestShot.bTargetLevel; pSoldier->aiData.bAimTime = 0; @@ -8603,33 +8596,42 @@ INT8 ArmedVehicleDecideActionRed( SOLDIERTYPE *pSoldier) pSoldier->bDoBurst = 1; INT16 ubBurstAPs = 0; + INT16 totalUsedAPs = 0; FLOAT dTotalRecoil = 0; + auto& weapon = pSoldier->inv[BestShot.bWeaponIn]; + const auto remainingAmmo = weapon[0]->data.gun.ubGunShotsLeft; if ( UsingNewCTHSystem( ) ) { do { pSoldier->bDoAutofire++; - dTotalRecoil += AICalcRecoilForShot( pSoldier, &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire ); - ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire, pSoldier ); - } while ( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs && pSoldier->inv[pSoldier->ubAttackingHand][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire - && dTotalRecoil <= 10.0f ); + dTotalRecoil += AICalcRecoilForShot( pSoldier, &weapon, pSoldier->bDoAutofire ); + ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &weapon, pSoldier->bDoAutofire, pSoldier ); + totalUsedAPs = BestShot.ubAPCost + ubBurstAPs; + } while ( pSoldier->bActionPoints >= totalUsedAPs && remainingAmmo >= pSoldier->bDoAutofire && dTotalRecoil <= 10.0f ); } else { do { pSoldier->bDoAutofire++; - ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire, pSoldier ); - } while ( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs && - pSoldier->inv[pSoldier->ubAttackingHand][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire && - GetAutoPenalty( &pSoldier->inv[pSoldier->ubAttackingHand], gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE )*pSoldier->bDoAutofire <= 80 ); + ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &weapon, pSoldier->bDoAutofire, pSoldier ); + totalUsedAPs = BestShot.ubAPCost + ubBurstAPs; + } while ( pSoldier->bActionPoints >= totalUsedAPs && remainingAmmo >= pSoldier->bDoAutofire && + GetAutoPenalty( &weapon, gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE )*pSoldier->bDoAutofire <= 80 ); } pSoldier->bDoAutofire--; // Make sure we decided to fire at least one shot! - ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire, pSoldier ); + ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints( ), &weapon, pSoldier->bDoAutofire, pSoldier ); + + // if necessary, swap the usItem from holster into the hand position + if ( BestShot.bWeaponIn != HANDPOS ) + { + RearrangePocket( pSoldier, HANDPOS, BestShot.bWeaponIn, FOREVER ); + } // minimum 5 bullets if ( pSoldier->bDoAutofire >= 5 && pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs )