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
This commit is contained in:
Kriplo
2013-08-31 10:22:25 +00:00
parent 1bb3f5a56a
commit f68f6131b9
8 changed files with 66 additions and 41 deletions
+1 -1
View File
@@ -3157,7 +3157,7 @@ void SwapObjs(SOLDIERTYPE* pSoldier, int leftSlot, int rightSlot, BOOLEAN fPerma
{ {
SwapObjs(&pSoldier->inv[ leftSlot ], &pSoldier->inv[ rightSlot ]); 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 //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); HandleTacticalEffectsOfEquipmentChange(pSoldier, leftSlot, pSoldier->inv[ rightSlot ].usItem, pSoldier->inv[ leftSlot ].usItem);
+7 -7
View File
@@ -1960,7 +1960,7 @@ void GetAPChargeForShootOrStabWRTGunRaises( SOLDIERTYPE *pSoldier, INT32 sGridNo
ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier );
// Is it the same as he's facing? // 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; 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; fAddingRaiseGunCost = FALSE;
} }
@@ -2416,13 +2416,13 @@ INT16 MinPtsToMove(SOLDIERTYPE *pSoldier)
{ {
// look around all 8 directions and return lowest terrain cost // look around all 8 directions and return lowest terrain cost
UINT8 cnt; 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; INT16 sCost;
INT32 sGridNo; INT32 sGridNo;
if ( TANK( pSoldier ) ) 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!! // 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 ) 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 // 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. // 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; INT16 sAPCost = 0;
UINT16 usItemNum = pSoldier->inv[HANDPOS].usItem; UINT16 usItemNum = pSoldier->inv[HANDPOS].usItem;
@@ -3771,7 +3771,7 @@ INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAim
Assert(pSoldier != NULL); Assert(pSoldier != NULL);
Assert(&pSoldier->inv[HANDPOS] != 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 // Weapon not ready, check aiming from hip, else add raise gun cost
//if (!pSoldier->IsValidShotFromHip(bAimTime,sTargetGridNo)) //if (!pSoldier->IsValidShotFromHip(bAimTime,sTargetGridNo))
+1 -1
View File
@@ -368,7 +368,7 @@ UINT16 GetAPsToReloadRobot( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pRobot );
INT16 GetAPsToReloadGunWithAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE * pGun, OBJECTTYPE * pAmmo, BOOLEAN usAllAPs = TRUE ); INT16 GetAPsToReloadGunWithAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE * pGun, OBJECTTYPE * pAmmo, BOOLEAN usAllAPs = TRUE );
INT16 GetAPsToAutoReload( SOLDIERTYPE * pSoldier ); 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 ); INT8 CalcAimingLevelsAvailableWithAP( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAPsLeft );
// SANDRO - added these: // SANDRO - added these:
+7
View File
@@ -389,6 +389,13 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
pSoldier->usAniCode = 3; 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 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; 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 ] ); OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
+5 -5
View File
@@ -3656,7 +3656,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
{ {
// ATE: Also check for the transition anims to not reset this // ATE: Also check for the transition anims to not reset this
// this should have used a flag but we're out of them.... // 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; this->sLastTarget = NOWHERE;
} }
@@ -18154,8 +18154,8 @@ BOOLEAN SOLDIERTYPE::IsValidShotFromHip( INT16 bAimTime, INT32 iTrgGridNo )
{ {
return( FALSE ); return( FALSE );
} }
// robots cannot do this // robots and tanks cannot do this
if ( AM_A_ROBOT( this ) ) if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813
{ {
return( FALSE ); return( FALSE );
} }
@@ -18206,8 +18206,8 @@ BOOLEAN SOLDIERTYPE::IsValidPistolFastShot( INT16 bAimTime, INT32 iTrgGridNo )
{ {
return( FALSE ); return( FALSE );
} }
// robots cannot do this // robots and tanks cannot do this
if ( AM_A_ROBOT( this ) ) if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813
{ {
return( FALSE ); return( FALSE );
} }
+8 -4
View File
@@ -1233,7 +1233,8 @@ void CancelAIAction(SOLDIERTYPE *pSoldier, UINT8 ubForce)
#endif #endif
// re-enable cover checking, something is new or something strange happened // 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! // turn off new situation flag to stop this from repeating all the time!
if ( pSoldier->aiData.bNewSituation == IS_NEW_SITUATION ) if ( pSoldier->aiData.bNewSituation == IS_NEW_SITUATION )
@@ -1502,6 +1503,8 @@ void RefreshAI(SOLDIERTYPE *pSoldier)
if (pSoldier->aiData.bAlertStatus == STATUS_YELLOW) if (pSoldier->aiData.bAlertStatus == STATUS_YELLOW)
SkipCoverCheck = FALSE; 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 he's in battle or knows opponents are here
if (gfTurnBasedAI) if (gfTurnBasedAI)
@@ -1591,7 +1594,8 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
// in most cases, merc will change location, or may cause damage to opponents, // in most cases, merc will change location, or may cause damage to opponents,
// so a new cover check will be necessary. Exceptions handled individually. // 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 // reset this field, too
pSoldier->aiData.bLastAttackHit = FALSE; pSoldier->aiData.bLastAttackHit = FALSE;
@@ -1600,7 +1604,7 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
UINT16 usHandItem = pSoldier->inv[HANDPOS].usItem; UINT16 usHandItem = pSoldier->inv[HANDPOS].usItem;
INT8 bSlot; 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)) if (TANK(pSoldier))
{ {
// No cannon selected to fire // No cannon selected to fire
@@ -1618,7 +1622,7 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
} }
} }
} }
#endif
UINT16 usSoldierIndex; // added by SANDRO UINT16 usSoldierIndex; // added by SANDRO
#ifdef TESTAICONTROL #ifdef TESTAICONTROL
+21 -15
View File
@@ -164,7 +164,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
UINT8 ubChanceToReallyHit = 0; UINT8 ubChanceToReallyHit = 0;
INT16 ubChanceToHit,ubChanceToHit2,ubBestAimTime,ubChanceToGetThrough,ubBestChanceToHit; INT16 ubChanceToHit,ubChanceToHit2,ubBestAimTime,ubChanceToGetThrough,ubBestChanceToHit;
SOLDIERTYPE *pOpponent; SOLDIERTYPE *pOpponent;
INT16 ubBurstAPs; //INT16 ubBurstAPs;//dnl ch64 270813
INT8 bScopeMode; INT8 bScopeMode;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalcBestShot"); 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->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem;
pSoldier->bWeaponMode = WM_NORMAL; 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 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); ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo,0,FALSE);
// calculate the maximum possible aiming time // 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 ) ) if ( TANK( pSoldier ) )
{ {
ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost; ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost;
@@ -373,6 +373,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
} }
else else
#endif
{ {
// HEADROCK HAM 3.6: Calculation must take into account APBP constants and other aiming modifications! // HEADROCK HAM 3.6: Calculation must take into account APBP constants and other aiming modifications!
INT8 bAPsLeft = pSoldier->bActionPoints - ubMinAPcost; INT8 bAPsLeft = pSoldier->bActionPoints - ubMinAPcost;
@@ -389,11 +390,13 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
//NumMessage("ubAimTime = ",ubAimTime); //NumMessage("ubAimTime = ",ubAimTime);
//dnl ch59 180813 Find true best chance to hit depending of stance so AI would be more eager to attack //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); 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) if(!TANK(pSoldier))//dnl ch64 270813
ubChanceToHit = ubChanceToHit2; {
if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit) if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit)
ubChanceToHit = ubChanceToHit2; ubChanceToHit = ubChanceToHit2;
if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit)
ubChanceToHit = ubChanceToHit2;
}
// ExtMen[pOpponent->ubID].haveStats = TRUE; // ExtMen[pOpponent->ubID].haveStats = TRUE;
//NumMessage("chance to Hit = ",ubChanceToHit); //NumMessage("chance to Hit = ",ubChanceToHit);
@@ -417,10 +420,13 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
ubAimTime = APBPConstants[AP_MIN_AIM_ATTACK]; ubAimTime = APBPConstants[AP_MIN_AIM_ATTACK];
//dnl ch59 180813 Find true best chance to hit depending of stance for autofire //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); 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) if(!TANK(pSoldier))//dnl ch64 270813
ubChanceToHit = ubChanceToHit2; {
if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit) if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit)
ubChanceToHit = ubChanceToHit2; ubChanceToHit = ubChanceToHit2;
if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, PRONE)) > ubChanceToHit)
ubChanceToHit = ubChanceToHit2;
}
Assert( ubRawAPCost > 0); Assert( ubRawAPCost > 0);
iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime);
iBestHitRate = iHitRate; iBestHitRate = iHitRate;
@@ -1276,10 +1282,10 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
pBestThrow->ubOpponent = ubOpponentID[ubLoop]; pBestThrow->ubOpponent = ubOpponentID[ubLoop];
pBestThrow->ubAimTime = ubMaxPossibleAimTime; pBestThrow->ubAimTime = ubMaxPossibleAimTime;
pBestThrow->ubChanceToReallyHit = ubChanceToReallyHit; pBestThrow->ubChanceToReallyHit = ubChanceToReallyHit;
pBestThrow->sTarget = sGridNo; pBestThrow->sTarget = sGridNo;
pBestThrow->iAttackValue = iAttackValue; pBestThrow->iAttackValue = iAttackValue;
pBestThrow->ubAPCost = CalcTotalAPsToAttack(pSoldier, pBestThrow->sTarget, TRUE, pBestThrow->ubAimTime);//dnl ch63 240813 pBestThrow->ubAPCost = ubMinAPcost + CalcAPCostForAiming(pSoldier, sGridNo, ubMaxPossibleAimTime, FALSE);//dnl ch64 310813
pBestThrow->bTargetLevel = bOpponentLevel[ubLoop]; pBestThrow->bTargetLevel = bOpponentLevel[ubLoop];
//sprintf(tempstr,"new best THROW AttackValue = %d at grid #%d",iAttackValue/100000,gridno); //sprintf(tempstr,"new best THROW AttackValue = %d at grid #%d",iAttackValue/100000,gridno);
//PopMessage(tempstr); //PopMessage(tempstr);
+16 -8
View File
@@ -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; ubBestAttackAction = AI_ACTION_TOSS_PROJECTILE;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw something"); 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 ); dTotalRecoil += AICalcRecoilForShot( pSoldier, &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire, pSoldier ); 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 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
&& dTotalRecoil <= 10.0f );
} else { } else {
do do
{ {
pSoldier->bDoAutofire++; pSoldier->bDoAutofire++;
ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire, pSoldier ); ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire, pSoldier );
} }
while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs && 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->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80);
} }
pSoldier->bDoAutofire--; pSoldier->bDoAutofire--;
@@ -5251,7 +5248,7 @@ INT16 ubMinAPCost;
pSoldier->bDoBurst = 1; pSoldier->bDoBurst = 1;
INT16 ubHalfBurstAPs = CalcAPsToAutofire(pSoldier->CalcActionPoints(), &pSoldier->inv[BestAttack.bWeaponIn], 4, pSoldier); INT16 ubHalfBurstAPs = CalcAPsToAutofire(pSoldier->CalcActionPoints(), &pSoldier->inv[BestAttack.bWeaponIn], 4, pSoldier);
if(Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) if(Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto)
iChance += 25; iChance = 35;
if(pSoldier->bActionPoints > (2 * BestAttack.ubAPCost + ubHalfBurstAPs) && PreRandom(100) < iChance) if(pSoldier->bActionPoints > (2 * BestAttack.ubAPCost + ubHalfBurstAPs) && PreRandom(100) < iChance)
{ {
// Try short autofire to enhance chance of hitting // 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!"); 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 // swap weapon to hand if necessary
if (BestAttack.bWeaponIn != HANDPOS) if (BestAttack.bWeaponIn != HANDPOS)
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap weapon into hand"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap weapon into hand");
RearrangePocket(pSoldier,HANDPOS,BestAttack.bWeaponIn,FOREVER); 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) if (fChangeStanceFirst)
{ // currently only for guns... { // currently only for guns...