diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index c0d392ec..e8537fc1 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -8644,16 +8644,20 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, return (iChance);*/ } -UINT32 AICalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos ) +UINT32 AICalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos, INT8 bTargetLevel, UINT16 usAnimState)//dnl ch59 180813 { + INT8 bTrueLevel;//dnl ch59 180813 if target is above ground CalcChanceToHitGun will return 0 because pSoldier->bTargetLevel contains some old values from previous target which was on ground level UINT16 usTrueState; UINT32 uiChance; // same as CCTHG but fakes the attacker always standing usTrueState = pSoldier->usAnimState; - pSoldier->usAnimState = STANDING; + bTrueLevel = pSoldier->bTargetLevel; + pSoldier->bTargetLevel = bTargetLevel; + pSoldier->usAnimState = usAnimState; uiChance = CalcChanceToHitGun( pSoldier, sGridNo, ubAimTime, ubAimPos ); pSoldier->usAnimState = usTrueState; + pSoldier->bTargetLevel = bTrueLevel; if(UsingNewCTHSystem() == true) { //////////////////////////////////////////////////////////////////////////////////// diff --git a/Tactical/Weapons.h b/Tactical/Weapons.h index b5782f8c..84dbfddc 100644 --- a/Tactical/Weapons.h +++ b/Tactical/Weapons.h @@ -465,7 +465,7 @@ extern BOOLEAN InRange( SOLDIERTYPE *pSoldier, INT32 sGridNo ); extern void ShotMiss( UINT8 ubAttackerID, INT32 iBullet ); extern UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos ); extern UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos ); -extern UINT32 AICalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos ); +extern UINT32 AICalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos, INT8 bTargetLevel, UINT16 usAnimState);//dnl ch59 180813 extern UINT32 CalcChanceToPunch(SOLDIERTYPE *pAttacker, SOLDIERTYPE * pDefender, INT16 ubAimTime); extern UINT32 CalcChanceToStab(SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAimTime); UINT32 CalcChanceToSteal(SOLDIERTYPE *pAttacker, SOLDIERTYPE * pDefender, INT16 ubAimTime); diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp index 1856f80c..4763634f 100644 --- a/TacticalAI/Attacks.cpp +++ b/TacticalAI/Attacks.cpp @@ -292,7 +292,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns if ( gGameExternalOptions.ubAllowAlternativeWeaponHolding ) { pSoldier->bScopeMode = USE_ALT_WEAPON_HOLD; - ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,0, AIM_SHOT_TORSO); // get CtH from alternative hold, without aiming + ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, 0, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);//dnl ch59 130813 get CtH from alternative hold, without aiming pSoldier->bScopeMode = USE_BEST_SCOPE; // CASE #1 - Enemy very close, or we have very good chance to hit from hip with no aiming if (( PythSpacesAway( pSoldier->sGridNo, pOpponent->sGridNo ) < 5 || ubChanceToHit > 80 ) && !WeaponReady(pSoldier) ) @@ -308,9 +308,9 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns else if ( !WeaponReady(pSoldier) ) // ... and we are not in ready weapon stance yet { pSoldier->bScopeMode = USE_ALT_WEAPON_HOLD; - ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO); + ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);//dnl ch59 130813 pSoldier->bScopeMode = USE_BEST_SCOPE; - ubChanceToHit2 = (INT16) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO); + ubChanceToHit2 = (INT16) AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);//dnl ch59 130813 if ( ubChanceToHit > ubChanceToHit2 && ubChanceToHit > 30 && (ubChanceToHit-ubChanceToHit2) >= 15 ) bScopeMode = USE_ALT_WEAPON_HOLD; } @@ -322,7 +322,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns // in case the best scope is not actually the "best" (at this distance), we will use the other one if ( bScopeMode == USE_BEST_SCOPE ) { - ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO); + ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);//dnl ch59 130813 std::map ObjList; GetScopeLists(&pSoldier->inv[HANDPOS], ObjList); do @@ -330,7 +330,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns pSoldier->bScopeMode++; if ( ObjList[pSoldier->bScopeMode] != NULL ) { - ubChanceToHit2 = (INT16) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO); + ubChanceToHit2 = (INT16) AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, AllowedAimingLevels( pSoldier, pOpponent->sGridNo ), AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);//dnl ch59 130813 if ( ubChanceToHit2 > ubChanceToHit ) { bScopeMode = pSoldier->bScopeMode; @@ -379,8 +379,13 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns //HandleMyMouseCursor(KEYBOARDALSO); //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; - ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO); // ExtMen[pOpponent->ubID].haveStats = TRUE; //NumMessage("chance to Hit = ",ubChanceToHit); @@ -402,10 +407,14 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns else { ubAimTime = APBPConstants[AP_MIN_AIM_ATTACK]; - ubChanceToHit = (INT16) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO); + //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; Assert( ubRawAPCost > 0); iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); - iBestHitRate = iHitRate; ubBestAimTime = ubAimTime; ubBestChanceToHit = ubChanceToHit; @@ -1175,7 +1184,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) if ( EXPLOSIVE_GUN( usInHand ) ) { ubRawAPCost = MinAPsToShootOrStab( pSoldier, sGridNo,ubMaxPossibleAimTime,FALSE); - ubChanceToHit = (UINT8) AICalcChanceToHitGun(pSoldier, sGridNo, ubMaxPossibleAimTime, AIM_SHOT_TORSO ); + ubChanceToHit = (UINT8) AICalcChanceToHitGun(pSoldier, sGridNo, ubMaxPossibleAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);//dnl ch59 130813 } else { @@ -2884,4 +2893,4 @@ FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubS // HEADROCK HAM 4: TODO: Incorporate items that alter max counter-force. FLOAT AverageRecoil = __max(0, ((FLOAT)sqrt( (FLOAT)(bRecoilX * bRecoilX) + (FLOAT)(bRecoilY * bRecoilY) ) - (gGameCTHConstants.RECOIL_MAX_COUNTER_FORCE * 0.7f) ) ); return AverageRecoil; -} \ No newline at end of file +}