From f68f6131b979c7ef236dfaca1102e0a2ee1d555d Mon Sep 17 00:00:00 2001 From: Kriplo Date: Sat, 31 Aug 2013 10:22:25 +0000 Subject: [PATCH] Brief: //dnl ch64 - Fixing Tank bursting shells problem, and some other tank related bugs. Details: - There are several problem with Tank handling, main was forcing to use gun although already decide to use machinegun which lead to bursting shells. - Another one was related to machinegun usage as current autofire handling is not supported by TANK BURST animation which had limit to 6 rounds, so decision to fire anything different then 6 lead to complete wrong APs deduction. - Fix some invalid animation decision as current tank cannot raise gun or move or check for cover. - Fix problem with wrong return (INT8) although after introduction of 100AP system APs variables are INT16 which create bad APs calculation for tank. - Fix general problem with burst and autofire when soldier decide to when swap weapons. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6340 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Items.cpp | 2 +- Tactical/Points.cpp | 14 +++++++------- Tactical/Points.h | 2 +- Tactical/Soldier Ani.cpp | 7 +++++++ Tactical/Soldier Control.cpp | 10 +++++----- TacticalAI/AIMain.cpp | 12 ++++++++---- TacticalAI/Attacks.cpp | 36 +++++++++++++++++++++--------------- TacticalAI/DecideAction.cpp | 24 ++++++++++++++++-------- 8 files changed, 66 insertions(+), 41 deletions(-) diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index ac422874..83d44081 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -3157,7 +3157,7 @@ void SwapObjs(SOLDIERTYPE* pSoldier, int leftSlot, int rightSlot, BOOLEAN fPerma { SwapObjs(&pSoldier->inv[ leftSlot ], &pSoldier->inv[ rightSlot ]); - if (fPermanent) + if(fPermanent && !TANK(pSoldier))//dnl ch64 290813 for current tank don't go further as it lead to invalid animation { //old usItem for the left slot is now stored in the right slot, and vice versa HandleTacticalEffectsOfEquipmentChange(pSoldier, leftSlot, pSoldier->inv[ rightSlot ].usItem, pSoldier->inv[ leftSlot ].usItem); diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index d4d8d830..a6ebfeeb 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -1960,7 +1960,7 @@ void GetAPChargeForShootOrStabWRTGunRaises( SOLDIERTYPE *pSoldier, INT32 sGridNo ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); // Is it the same as he's facing? - if ( ubDirection != pSoldier->ubDirection ) + if ( ubDirection != pSoldier->ubDirection && !(ubDirection == pSoldier->pathing.bDesiredDirection && pSoldier->aiData.bLastAction == AI_ACTION_CHANGE_FACING) )//dnl ch64 310813 sometimes turning is in progress and APs already deducted { fAddingTurningCost = TRUE; } @@ -2285,7 +2285,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime, } } - if ( AM_A_ROBOT( pSoldier ) ) + if ( AM_A_ROBOT( pSoldier ) || TANK( pSoldier ) )//dnl ch64 300813 robots and tanks cannot do this { fAddingRaiseGunCost = FALSE; } @@ -2416,13 +2416,13 @@ INT16 MinPtsToMove(SOLDIERTYPE *pSoldier) { // look around all 8 directions and return lowest terrain cost UINT8 cnt; - INT16 sLowest=127; + INT16 sLowest=32767;//dnl ch64 290813 100AP made return of INT8 or 127 obsolete as other variables are INT16 INT16 sCost; INT32 sGridNo; if ( TANK( pSoldier ) ) { - return( (INT8)sLowest); + return(sLowest);//dnl ch64 290813 100AP made INT8 return obsolete } // WANNE - BMP: FIX: Valid directions are only from 0-7!! @@ -2438,7 +2438,7 @@ INT16 MinPtsToMove(SOLDIERTYPE *pSoldier) } } } - return( (INT8)sLowest); + return(sLowest);//dnl ch64 290813 100AP made INT8 return obsolete } INT8 PtsToMoveDirection(SOLDIERTYPE *pSoldier, INT8 bDirection ) @@ -3763,7 +3763,7 @@ INT16 GetAPsToJumpOver( SOLDIERTYPE *pSoldier ) // HEADROCK HAM 3.6: Calculate the actual AP cost to add this many Extra Aiming levels, taking into account // APBP Constants and extra game features. -INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAimTime ) +INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAimTime, UINT8 ubAddRaiseGunCost )//dnl ch64 310813 { INT16 sAPCost = 0; UINT16 usItemNum = pSoldier->inv[HANDPOS].usItem; @@ -3771,7 +3771,7 @@ INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAim Assert(pSoldier != NULL); Assert(&pSoldier->inv[HANDPOS] != NULL); - if (!( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_FIREREADY | ANIM_FIRE ))) + if (ubAddRaiseGunCost && !TANK(pSoldier) && !( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_FIREREADY | ANIM_FIRE )))//dnl ch64 310813 { // Weapon not ready, check aiming from hip, else add raise gun cost //if (!pSoldier->IsValidShotFromHip(bAimTime,sTargetGridNo)) diff --git a/Tactical/Points.h b/Tactical/Points.h index cac545a4..14580a3e 100644 --- a/Tactical/Points.h +++ b/Tactical/Points.h @@ -368,7 +368,7 @@ UINT16 GetAPsToReloadRobot( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pRobot ); INT16 GetAPsToReloadGunWithAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE * pGun, OBJECTTYPE * pAmmo, BOOLEAN usAllAPs = TRUE ); INT16 GetAPsToAutoReload( SOLDIERTYPE * pSoldier ); -INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAimTime ); +INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAimTime, UINT8 ubAddRaiseGunCost=TRUE );//dnl ch64 310813 INT8 CalcAimingLevelsAvailableWithAP( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAPsLeft ); // SANDRO - added these: diff --git a/Tactical/Soldier Ani.cpp b/Tactical/Soldier Ani.cpp index e84430e0..dfd06ece 100644 --- a/Tactical/Soldier Ani.cpp +++ b/Tactical/Soldier Ani.cpp @@ -389,6 +389,13 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) pSoldier->usAniCode = 3; else if(pSoldier->usAnimState == FIRE_BURST_LOW_STAND || pSoldier->usAnimState == LOW_BURST_ALTERNATIVE_STAND && pSoldier->usAniCode == 37) //we are firing down to something very close, last shot pSoldier->usAniCode = 14; + else if(pSoldier->usAnimState == TANK_BURST)//dnl ch64 280813 fix 6 round burst limitation + { + if(pSoldier->bDoBurst < pSoldier->bDoAutofire)//!!! this will be fine as long you not decide to equip tank with other weapons add limitted ammo, weapon jam, etc. + pSoldier->usAniCode = 4; + else + pSoldier->usAniCode = 34; + } } OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &pSoldier->inv[ pSoldier->ubAttackingHand ] ); diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 69dc1a36..337ebbbd 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -3656,7 +3656,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart { // ATE: Also check for the transition anims to not reset this // this should have used a flag but we're out of them.... - if ( usNewState != READY_ALTERNATIVE_STAND && usNewState != READY_RIFLE_STAND && usNewState != READY_RIFLE_PRONE && usNewState != READY_RIFLE_CROUCH && usNewState != ROBOT_SHOOT ) + if ( usNewState != READY_ALTERNATIVE_STAND && usNewState != READY_RIFLE_STAND && usNewState != READY_RIFLE_PRONE && usNewState != READY_RIFLE_CROUCH && usNewState != ROBOT_SHOOT && usNewState != TANK_SHOOT && usNewState != TANK_BURST )//dnl ch64 300813 { this->sLastTarget = NOWHERE; } @@ -18154,8 +18154,8 @@ BOOLEAN SOLDIERTYPE::IsValidShotFromHip( INT16 bAimTime, INT32 iTrgGridNo ) { return( FALSE ); } - // robots cannot do this - if ( AM_A_ROBOT( this ) ) + // robots and tanks cannot do this + if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813 { return( FALSE ); } @@ -18206,8 +18206,8 @@ BOOLEAN SOLDIERTYPE::IsValidPistolFastShot( INT16 bAimTime, INT32 iTrgGridNo ) { return( FALSE ); } - // robots cannot do this - if ( AM_A_ROBOT( this ) ) + // robots and tanks cannot do this + if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813 { return( FALSE ); } diff --git a/TacticalAI/AIMain.cpp b/TacticalAI/AIMain.cpp index 14649479..7352f331 100644 --- a/TacticalAI/AIMain.cpp +++ b/TacticalAI/AIMain.cpp @@ -1233,7 +1233,8 @@ void CancelAIAction(SOLDIERTYPE *pSoldier, UINT8 ubForce) #endif // re-enable cover checking, something is new or something strange happened - SkipCoverCheck = FALSE; + if(!TANK(pSoldier))//dnl ch64 290813 + SkipCoverCheck = FALSE; // turn off new situation flag to stop this from repeating all the time! if ( pSoldier->aiData.bNewSituation == IS_NEW_SITUATION ) @@ -1502,6 +1503,8 @@ void RefreshAI(SOLDIERTYPE *pSoldier) if (pSoldier->aiData.bAlertStatus == STATUS_YELLOW) SkipCoverCheck = FALSE; + if(TANK(pSoldier))//dnl ch64 290813 tanks don't have move animations + SkipCoverCheck = TRUE; // if he's in battle or knows opponents are here if (gfTurnBasedAI) @@ -1591,7 +1594,8 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier) // in most cases, merc will change location, or may cause damage to opponents, // so a new cover check will be necessary. Exceptions handled individually. - SkipCoverCheck = FALSE; + if(!TANK(pSoldier))//dnl ch64 290813 + SkipCoverCheck = FALSE; // reset this field, too pSoldier->aiData.bLastAttackHit = FALSE; @@ -1600,7 +1604,7 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier) UINT16 usHandItem = pSoldier->inv[HANDPOS].usItem; INT8 bSlot; - +#if 0//dnl ch64 260813 decision to use machinegun or cannon is done in DecideAction, this here will just lead into burst with cannon if decision was use machinegun if (TANK(pSoldier)) { // No cannon selected to fire @@ -1618,7 +1622,7 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier) } } } - +#endif UINT16 usSoldierIndex; // added by SANDRO #ifdef TESTAICONTROL diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp index dfbd05f5..f9d9c93c 100644 --- a/TacticalAI/Attacks.cpp +++ b/TacticalAI/Attacks.cpp @@ -164,7 +164,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns UINT8 ubChanceToReallyHit = 0; INT16 ubChanceToHit,ubChanceToHit2,ubBestAimTime,ubChanceToGetThrough,ubBestChanceToHit; SOLDIERTYPE *pOpponent; - INT16 ubBurstAPs; + //INT16 ubBurstAPs;//dnl ch64 270813 INT8 bScopeMode; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalcBestShot"); @@ -174,7 +174,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; pSoldier->bWeaponMode = WM_NORMAL; - ubBurstAPs = CalcAPsToBurst( pSoldier->CalcActionPoints( ), &(pSoldier->inv[HANDPOS]), pSoldier ); + //ubBurstAPs = CalcAPsToBurst( pSoldier->CalcActionPoints( ), &(pSoldier->inv[HANDPOS]), pSoldier );//dnl ch64 270813 InitAttackType(pBestShot); // set all structure fields to defaults @@ -357,7 +357,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo,0,FALSE); // calculate the maximum possible aiming time - +#if 0//dnl ch64 270813 maybe I'm wrong but don't see purpose of this if ( TANK( pSoldier ) ) { ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost; @@ -373,6 +373,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns } else +#endif { // HEADROCK HAM 3.6: Calculation must take into account APBP constants and other aiming modifications! INT8 bAPsLeft = pSoldier->bActionPoints - ubMinAPcost; @@ -389,11 +390,13 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns //NumMessage("ubAimTime = ",ubAimTime); //dnl ch59 180813 Find true best chance to hit depending of stance so AI would be more eager to attack ubChanceToHit = AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING); - if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit) - ubChanceToHit = ubChanceToHit2; - if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit) - ubChanceToHit = ubChanceToHit2; - + if(!TANK(pSoldier))//dnl ch64 270813 + { + if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit) + ubChanceToHit = ubChanceToHit2; + if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit) + ubChanceToHit = ubChanceToHit2; + } // ExtMen[pOpponent->ubID].haveStats = TRUE; //NumMessage("chance to Hit = ",ubChanceToHit); @@ -417,10 +420,13 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns ubAimTime = APBPConstants[AP_MIN_AIM_ATTACK]; //dnl ch59 180813 Find true best chance to hit depending of stance for autofire ubChanceToHit = AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING); - if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit) - ubChanceToHit = ubChanceToHit2; - if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit) - ubChanceToHit = ubChanceToHit2; + if(!TANK(pSoldier))//dnl ch64 270813 + { + if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit) + ubChanceToHit = ubChanceToHit2; + if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit) + ubChanceToHit = ubChanceToHit2; + } Assert( ubRawAPCost > 0); iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); iBestHitRate = iHitRate; @@ -1276,10 +1282,10 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) pBestThrow->ubOpponent = ubOpponentID[ubLoop]; pBestThrow->ubAimTime = ubMaxPossibleAimTime; pBestThrow->ubChanceToReallyHit = ubChanceToReallyHit; - pBestThrow->sTarget = sGridNo; + pBestThrow->sTarget = sGridNo; pBestThrow->iAttackValue = iAttackValue; - pBestThrow->ubAPCost = CalcTotalAPsToAttack(pSoldier, pBestThrow->sTarget, TRUE, pBestThrow->ubAimTime);//dnl ch63 240813 - pBestThrow->bTargetLevel = bOpponentLevel[ubLoop]; + pBestThrow->ubAPCost = ubMinAPcost + CalcAPCostForAiming(pSoldier, sGridNo, ubMaxPossibleAimTime, FALSE);//dnl ch64 310813 + pBestThrow->bTargetLevel = bOpponentLevel[ubLoop]; //sprintf(tempstr,"new best THROW AttackValue = %d at grid #%d",iAttackValue/100000,gridno); //PopMessage(tempstr); diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index db7154bb..7972daca 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -4766,7 +4766,7 @@ INT16 ubMinAPCost; } //////////////////////////////////////////////////////////////////////////////////// } - if (BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE))) + if (BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE)) && !(TANK(pSoldier) && ubBestAttackAction == AI_ACTION_FIRE_GUN && BestShot.ubChanceToReallyHit > 20 && Random(2)))//dnl ch64 290813 tank always had better chance to fire from cannon so this will increase probabilty to use machinegun too { ubBestAttackAction = AI_ACTION_TOSS_PROJECTILE; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw something"); @@ -5175,17 +5175,14 @@ INT16 ubMinAPCost; 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 + sActualAimTime && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire - && dTotalRecoil <= 10.0f ); + while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs + sActualAimTime && pSoldier->inv[ BestAttack.bWeaponIn ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire && dTotalRecoil <= 10.0f );//dnl ch64 260813 pSoldier->ubAttackingHand is wrong because decision is to use BestAttack.bWeaponIn } else { do { pSoldier->bDoAutofire++; ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire, pSoldier ); } - while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs && - pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire && - GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80); + while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs && pSoldier->inv[ BestAttack.bWeaponIn ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire && GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80);//dnl ch64 260813 pSoldier->ubAttackingHand is wrong because decision is to use BestAttack.bWeaponIn } pSoldier->bDoAutofire--; @@ -5251,7 +5248,7 @@ INT16 ubMinAPCost; pSoldier->bDoBurst = 1; INT16 ubHalfBurstAPs = CalcAPsToAutofire(pSoldier->CalcActionPoints(), &pSoldier->inv[BestAttack.bWeaponIn], 4, pSoldier); if(Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) - iChance += 25; + iChance = 35; if(pSoldier->bActionPoints > (2 * BestAttack.ubAPCost + ubHalfBurstAPs) && PreRandom(100) < iChance) { // Try short autofire to enhance chance of hitting @@ -5400,13 +5397,24 @@ INT16 ubMinAPCost; ////////////////////////////////////////////////////////////////////////// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"OTHERWISE, JUST GO AHEAD & ATTACK!"); - + //dnl ch64 270813 must be as below RearrangePocket with FOREVER will screw already decided BURST or AUTOFIRE + INT8 bDoBurst = pSoldier->bDoBurst; + UINT8 bDoAutofire = pSoldier->bDoAutofire; // swap weapon to hand if necessary if (BestAttack.bWeaponIn != HANDPOS) { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap weapon into hand"); RearrangePocket(pSoldier,HANDPOS,BestAttack.bWeaponIn,FOREVER); } + if(ubBestAttackAction == AI_ACTION_FIRE_GUN && bDoBurst == 1)//dnl ch64 270813 + { + pSoldier->bDoAutofire = bDoAutofire; + pSoldier->bDoBurst = bDoBurst; + if(bDoAutofire > 1) + pSoldier->bWeaponMode = WM_AUTOFIRE; + else + pSoldier->bWeaponMode = WM_BURST; + } if (fChangeStanceFirst) { // currently only for guns...