mirror of
https://github.com/1dot13/source.git
synced 2026-09-16 14:47:17 +02:00
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
This commit is contained in:
@@ -7351,7 +7351,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
|
|||||||
iChance = gGameExternalOptions.ubMinimumCTH;
|
iChance = gGameExternalOptions.ubMinimumCTH;
|
||||||
if ( gGameExternalOptions.ubMinimumCTH == 0 )
|
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;
|
iChance = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-1
@@ -1035,6 +1035,15 @@ INT32 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK,
|
|||||||
// if we are there (at the noise gridno)
|
// if we are there (at the noise gridno)
|
||||||
if (sGridNo == pSoldier->sGridNo)
|
if (sGridNo == pSoldier->sGridNo)
|
||||||
{
|
{
|
||||||
|
for(uiLoop=0; uiLoop<guiNumMercSlots; uiLoop++)//dnl ch58 160813
|
||||||
|
{
|
||||||
|
pOpp = MercSlots[uiLoop];
|
||||||
|
if(pSoldier->bSide == 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.sNoiseGridno = NOWHERE; // wipe it out, not useful anymore
|
||||||
pSoldier->aiData.ubNoiseVolume = 0;
|
pSoldier->aiData.ubNoiseVolume = 0;
|
||||||
}
|
}
|
||||||
@@ -1092,7 +1101,10 @@ INT32 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// degrade our public noise a bit
|
// degrade our public noise a bit
|
||||||
*pusNoiseGridNo -= 2;
|
//dnl ch58 160813
|
||||||
|
//*pusNoiseGridNo -= 2;
|
||||||
|
if(*pubNoiseVolume > 1)
|
||||||
|
(*pubNoiseVolume)--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
-10
@@ -54,7 +54,7 @@ UINT32 guiRedSeekTimeTotal = 0, guiRedHelpTimeTotal = 0, guiRedHideTimeTotal = 0
|
|||||||
UINT32 guiRedSeekCounter = 0, guiRedHelpCounter = 0; guiRedHideCounter = 0;
|
UINT32 guiRedSeekCounter = 0, guiRedHelpCounter = 0; guiRedHideCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CENTER_OF_RING 11237
|
#define CENTER_OF_RING 11237//dnl!!!
|
||||||
|
|
||||||
#define MAX_FLANKS_RED 15
|
#define MAX_FLANKS_RED 15
|
||||||
#define MAX_FLANKS_YELLOW 25
|
#define MAX_FLANKS_YELLOW 25
|
||||||
@@ -3993,7 +3993,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
|||||||
INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
|
INT8 DecideActionBlack(SOLDIERTYPE *pSoldier)
|
||||||
{
|
{
|
||||||
INT32 iCoverPercentBetter, iOffense, iDefense, iChance;
|
INT32 iCoverPercentBetter, iOffense, iDefense, iChance;
|
||||||
INT32 sClosestOpponent,sBestCover = NOWHERE;
|
INT32 sClosestOpponent = NOWHERE,sBestCover = NOWHERE;//dnl ch58 160813
|
||||||
INT32 sClosestDisturbance;
|
INT32 sClosestDisturbance;
|
||||||
INT16 ubMinAPCost;
|
INT16 ubMinAPCost;
|
||||||
UINT8 ubCanMove;
|
UINT8 ubCanMove;
|
||||||
@@ -5118,13 +5118,16 @@ INT16 ubMinAPCost;
|
|||||||
|
|
||||||
if ( (INT32) PreRandom( 100 ) < iChance)
|
if ( (INT32) PreRandom( 100 ) < iChance)
|
||||||
{
|
{
|
||||||
BestAttack.ubAimTime = BURSTING;
|
|
||||||
BestAttack.ubAPCost = BestAttack.ubAPCost + ubBurstAPs;
|
BestAttack.ubAPCost = BestAttack.ubAPCost + ubBurstAPs;
|
||||||
// check for spread burst possibilities
|
// check for spread burst possibilities
|
||||||
if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY)
|
if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY)
|
||||||
{
|
{
|
||||||
CalcSpreadBurst( pSoldier, BestAttack.sTarget, BestAttack.bTargetLevel );
|
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)
|
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -5430,15 +5446,16 @@ INT16 ubMinAPCost;
|
|||||||
if ( (INT32) PreRandom( 100 ) < iChance)
|
if ( (INT32) PreRandom( 100 ) < iChance)
|
||||||
{
|
{
|
||||||
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "DecideActionBlack: Doing GL burst");
|
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "DecideActionBlack: Doing GL burst");
|
||||||
BestAttack.ubAimTime = BURSTING;
|
|
||||||
BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToBurst( pSoldier->CalcActionPoints(), &(pSoldier->inv[HANDPOS]), pSoldier );
|
BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToBurst( pSoldier->CalcActionPoints(), &(pSoldier->inv[HANDPOS]), pSoldier );
|
||||||
// check for spread burst possibilities
|
// check for spread burst possibilities
|
||||||
if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY)
|
if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY)
|
||||||
{
|
{
|
||||||
CalcSpreadBurst( pSoldier, BestAttack.sTarget, BestAttack.bTargetLevel );
|
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->bDoBurst = 1;
|
||||||
|
pSoldier->bDoAutofire = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5590,7 +5607,11 @@ INT16 ubMinAPCost;
|
|||||||
#endif
|
#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 );
|
//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;
|
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);
|
return(AI_ACTION_TAKE_COVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7905,15 +7926,16 @@ void DecideAlertStatus( SOLDIERTYPE *pSoldier )
|
|||||||
if ( (INT32) PreRandom( 100 ) < iChance)
|
if ( (INT32) PreRandom( 100 ) < iChance)
|
||||||
{
|
{
|
||||||
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "DecideActionBlack: Doing GL burst");
|
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "DecideActionBlack: Doing GL burst");
|
||||||
BestAttack.ubAimTime = BURSTING;
|
|
||||||
BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToBurst( pSoldier->CalcActionPoints(), &(pSoldier->inv[HANDPOS]), pSoldier );
|
BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToBurst( pSoldier->CalcActionPoints(), &(pSoldier->inv[HANDPOS]), pSoldier );
|
||||||
// check for spread burst possibilities
|
// check for spread burst possibilities
|
||||||
if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY)
|
if (pSoldier->aiData.bAttitude != ATTACKSLAYONLY)
|
||||||
{
|
{
|
||||||
CalcSpreadBurst( pSoldier, BestAttack.sTarget, BestAttack.bTargetLevel );
|
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->bDoBurst = 1;
|
||||||
|
pSoldier->bDoAutofire = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1311,6 +1311,11 @@ INT32 FindSpotMaxDistFromOpponents(SOLDIERTYPE *pSoldier)
|
|||||||
// Turn off the "reachable" flag for his current location
|
// Turn off the "reachable" flag for his current location
|
||||||
// so we don't consider it
|
// so we don't consider it
|
||||||
gpWorldLevelData[pSoldier->sGridNo].uiFlags &= ~(MAPELEMENT_REACHABLE);
|
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++)
|
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user