From 1adc9c542cf6658a58ae304f8ab583cde0ac63b2 Mon Sep 17 00:00:00 2001 From: Kriplo Date: Fri, 23 Aug 2013 16:27:36 +0000 Subject: [PATCH] Brief: //dnl ch58 - Fix several problems which lead into bad or no AI decisions, add optional decision of short autofire. Details: - Avoid use of last two locations per turn - Fix problems with improper APs calculations for burst and autofire which lead into AI to forcably cancel and end turn for those actions. - Add option for decide to use short autofire instead of one long to enchance chance to hit. - After taking cover change facing toward closest enemy to avoid going in status red and rather take proper black decisions. - Fix bad public noise processing after AI investigate closest disturbance and find nothing, also erase all same noise points in team members if one of them already investigated. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6310 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Weapons.cpp | 2 +- TacticalAI/AIUtils.cpp | 14 +++++++++++- TacticalAI/DecideAction.cpp | 42 +++++++++++++++++++++++++++--------- TacticalAI/FindLocations.cpp | 5 +++++ 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 29fdf03e..c0d392ec 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -7351,7 +7351,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, iChance = gGameExternalOptions.ubMinimumCTH; if ( gGameExternalOptions.ubMinimumCTH == 0 ) { - if ( PreRandom( gGameExternalOptions.usMinimumCTHDivisor ) == (gGameExternalOptions.usMinimumCTHDivisor - 1) ) + if ( PreRandom( gGameExternalOptions.usMinimumCTHDivisor ) == (gGameExternalOptions.usMinimumCTHDivisor - 1) && fCalculateCTHDuringGunfire == TRUE )//dnl ch58 271009 Any Random function must not be used during calculation, only allow when you actually FireGun because AI became confused and sometimes do nothing { iChance = 1; } diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp index 651bbf9d..e1803a05 100644 --- a/TacticalAI/AIUtils.cpp +++ b/TacticalAI/AIUtils.cpp @@ -1035,6 +1035,15 @@ INT32 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK, // if we are there (at the noise gridno) if (sGridNo == pSoldier->sGridNo) { + for(uiLoop=0; uiLoopbSide == pOpp->bSide && pSoldier->ubID != pOpp->ubID&& pSoldier->aiData.sNoiseGridno == pOpp->aiData.sNoiseGridno) + { + pOpp->aiData.sNoiseGridno = NOWHERE;// Erase for all from the same team as it not useful anymore, this will avoid others to check already tested location + pOpp->aiData.ubNoiseVolume = 0; + } + } pSoldier->aiData.sNoiseGridno = NOWHERE; // wipe it out, not useful anymore pSoldier->aiData.ubNoiseVolume = 0; } @@ -1092,7 +1101,10 @@ INT32 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK, else { // degrade our public noise a bit - *pusNoiseGridNo -= 2; + //dnl ch58 160813 + //*pusNoiseGridNo -= 2; + if(*pubNoiseVolume > 1) + (*pubNoiseVolume)--; } } diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index 522e666d..3a9f902b 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -54,7 +54,7 @@ UINT32 guiRedSeekTimeTotal = 0, guiRedHelpTimeTotal = 0, guiRedHideTimeTotal = 0 UINT32 guiRedSeekCounter = 0, guiRedHelpCounter = 0; guiRedHideCounter = 0; #endif -#define CENTER_OF_RING 11237 +#define CENTER_OF_RING 11237//dnl!!! #define MAX_FLANKS_RED 15 #define MAX_FLANKS_YELLOW 25 @@ -3993,7 +3993,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) { INT32 iCoverPercentBetter, iOffense, iDefense, iChance; - INT32 sClosestOpponent,sBestCover = NOWHERE; + INT32 sClosestOpponent = NOWHERE,sBestCover = NOWHERE;//dnl ch58 160813 INT32 sClosestDisturbance; INT16 ubMinAPCost; UINT8 ubCanMove; @@ -5118,13 +5118,16 @@ INT16 ubMinAPCost; if ( (INT32) PreRandom( 100 ) < iChance) { - BestAttack.ubAimTime = BURSTING; BestAttack.ubAPCost = BestAttack.ubAPCost + ubBurstAPs; // check for spread burst possibilities if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY) { CalcSpreadBurst( pSoldier, BestAttack.sTarget, BestAttack.bTargetLevel ); } + //dnl ch58 180813 After HAM 4 BURSTING is not in use any more, for burst bAimTime and bDoAutofire must be set to 0 + pSoldier->aiData.bAimTime = 0; + pSoldier->bDoBurst = 1; + pSoldier->bDoAutofire = 0; } } } @@ -5218,9 +5221,22 @@ INT16 ubMinAPCost; if ((INT32) PreRandom( 100 ) < iChance || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) { - pSoldier->aiData.bAimTime = BestAttack.ubAimTime ; + //dnl ch58 180813 After HAM 4 AUTOFIRING and sActualAimTime is not used in burst or autofire mode calculations and pSoldier->aiData.bAimTime must be 0 + pSoldier->aiData.bAimTime = 0; pSoldier->bDoBurst = 1; - BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire, pSoldier ) + sActualAimTime; + INT16 ubHalfBurstAPs = CalcAPsToAutofire(pSoldier->CalcActionPoints(), &pSoldier->inv[BestAttack.bWeaponIn], 4, pSoldier); + if(Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) + iChance += 25; + if(pSoldier->bActionPoints > (2 * BestAttack.ubAPCost + ubHalfBurstAPs) && PreRandom(100) < iChance) + { + // Try short autofire to enhance chance of hitting + pSoldier->bDoAutofire = 4; + BestAttack.ubAPCost += ubHalfBurstAPs; + } + else + { + BestAttack.ubAPCost += ubBurstAPs; + } } else { @@ -5430,15 +5446,16 @@ INT16 ubMinAPCost; if ( (INT32) PreRandom( 100 ) < iChance) { DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "DecideActionBlack: Doing GL burst"); - BestAttack.ubAimTime = BURSTING; BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToBurst( pSoldier->CalcActionPoints(), &(pSoldier->inv[HANDPOS]), pSoldier ); // check for spread burst possibilities if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY) { CalcSpreadBurst( pSoldier, BestAttack.sTarget, BestAttack.bTargetLevel ); } + //dnl ch58 200813 After HAM 4 BURSTING is not in use any more, for burst bAimTime and bDoAutofire must be set to 0 + pSoldier->aiData.bAimTime = 0; pSoldier->bDoBurst = 1; - + pSoldier->bDoAutofire = 0; } } } @@ -5590,7 +5607,11 @@ INT16 ubMinAPCost; #endif //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"AI %d taking cover, morale %d, from %d to %d", pSoldier->ubID, pSoldier->aiData.bAIMorale, pSoldier->sGridNo, sBestCover ); pSoldier->aiData.usActionData = sBestCover; - + if(!TileIsOutOfBounds(sClosestOpponent))//dnl ch58 160813 After taking cover change facing toward closest enemy, currently such turn not charge APs and seems because AI is still in moving animation from take cover action + { + pSoldier->aiData.bNextAction = AI_ACTION_CHANGE_FACING; + pSoldier->aiData.usNextActionData = atan8(CenterX(sBestCover),CenterY(sBestCover),CenterX(sClosestOpponent),CenterY(sClosestOpponent)); + } return(AI_ACTION_TAKE_COVER); } @@ -7905,15 +7926,16 @@ void DecideAlertStatus( SOLDIERTYPE *pSoldier ) if ( (INT32) PreRandom( 100 ) < iChance) { DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "DecideActionBlack: Doing GL burst"); - BestAttack.ubAimTime = BURSTING; BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToBurst( pSoldier->CalcActionPoints(), &(pSoldier->inv[HANDPOS]), pSoldier ); // check for spread burst possibilities if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY) { CalcSpreadBurst( pSoldier, BestAttack.sTarget, BestAttack.bTargetLevel ); } + //dnl ch58 200813 After HAM 4 BURSTING is not in use any more, for burst bAimTime and bDoAutofire must be set to 0 + pSoldier->aiData.bAimTime = 0; pSoldier->bDoBurst = 1; - + pSoldier->bDoAutofire = 0; } } } diff --git a/TacticalAI/FindLocations.cpp b/TacticalAI/FindLocations.cpp index 7651cb4e..84540747 100644 --- a/TacticalAI/FindLocations.cpp +++ b/TacticalAI/FindLocations.cpp @@ -1311,6 +1311,11 @@ INT32 FindSpotMaxDistFromOpponents(SOLDIERTYPE *pSoldier) // Turn off the "reachable" flag for his current location // so we don't consider it gpWorldLevelData[pSoldier->sGridNo].uiFlags &= ~(MAPELEMENT_REACHABLE); + //dnl ch58 170813 also don't use last two locations to avoid looping same decisions per turn + if(!TileIsOutOfBounds(pSoldier->sLastTwoLocations[0])) + gpWorldLevelData[pSoldier->sLastTwoLocations[0]].uiFlags &= ~(MAPELEMENT_REACHABLE); + else if(!TileIsOutOfBounds(pSoldier->sLastTwoLocations[1])) + gpWorldLevelData[pSoldier->sLastTwoLocations[1]].uiFlags &= ~(MAPELEMENT_REACHABLE); for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++) {