AI flanking improvement by Sevenfm:

Improved AI RED/YELLOW flanking:
 - better direction calculation (use direction arrays)
 - increased search range 4->8
 - removed incorrectly calculated AP limit (use CalcActionPoints instead)
 - additional direction for flank spot searching
 - prefer desired direction
 - penalize tiles with no cover from noise location
 - penalize tiles too far from noise location
 - don't go into deep water for flanking
 - skip water tiles (can flank over water tiles only if can cross them in one turn)
 - min/max flanking range depends on time of day and base sight range
 - skip buildings when searching for flank spot if not in building already, because soldiers often run into buildings and stop flanking
 - use RUNNING movement mode for flanking instead of default SWATTING
 - only CUNNINGSOLO and CUNNINGAID soldiers flank
 - don't start flanking when no friends between soldier and noise gridno (in 3 directions)
 - stop flanking when no friends between soldier and noise gridno (in 3 directions)
 - stop flanking and reset flank counter in BLACK state
 - avoid map edges when flanking
 - disable flanking for soldiers with limited roaming range (STATIONARY/ONGUARD/CLOSEPATROL/SNIPER)

 In general, AI flanking is much more effective now (it never fully worked previously, especially in turnbased).

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8003 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
silversurfer
2015-11-17 19:19:22 +00:00
parent 38e77c7295
commit 1e54f492ff
4 changed files with 179 additions and 93 deletions
+42 -14
View File
@@ -57,14 +57,15 @@ UINT32 guiRedSeekCounter = 0, guiRedHelpCounter = 0; guiRedHideCounter = 0;
#define CENTER_OF_RING 11237//dnl!!!
#define MAX_FLANKS_RED 15
// sevenfm: moved to ai.h
/*#define MAX_FLANKS_RED 15
#define MAX_FLANKS_YELLOW 25
#define MIN_FLANK_DIST_YELLOW 10 * STRAIGHT_RATIO
#define MAX_FLANK_DIST_YELLOW 50 * STRAIGHT_RATIO
#define MIN_FLANK_DIST_RED 10 * STRAIGHT_RATIO
#define MAX_FLANK_DIST_RED 40 * STRAIGHT_RATIO
#define MAX_FLANK_DIST_RED 40 * STRAIGHT_RATIO*/
#ifdef ENABLE_ZOMBIES
INT8 ZombieDecideActionGreen(SOLDIERTYPE *pSoldier);
@@ -1928,7 +1929,9 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
if ( origDir > currDir )
origDir -= NUM_WORLD_DIRECTIONS;
if ( (currDir - origDir) >= 4 )
// sevenfm: stop flanking if no friends between me and noise gridno
if ( (currDir - origDir) >= 4 ||
CountFriendsInDirection( pSoldier, tempGridNo ) == 0 )
{
pSoldier->numFlanks = MAX_FLANKS_YELLOW;
}
@@ -1946,7 +1949,9 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
if ( origDir < currDir )
origDir += NUM_WORLD_DIRECTIONS;
if ( (origDir - currDir) >= 4 )
// sevenfm: stop flanking if no friends between me and noise gridno
if ( (origDir - currDir) >= 4 ||
CountFriendsInDirection( pSoldier, tempGridNo ) == 0 )
{
pSoldier->numFlanks = MAX_FLANKS_YELLOW;
}
@@ -2090,7 +2095,14 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
}
}
if ( ( pSoldier->aiData.bAttitude == CUNNINGAID || pSoldier->aiData.bAttitude == CUNNINGSOLO || pSoldier->aiData.bAttitude == BRAVESOLO ) )
// possibly start YELLOW flanking
// sevenfm: only CUNNINGAID and CUNNINGSOLO should flank
// check that there are some friends between me and noise gridno
// STATIONARY/ONGUARD/CLOSEPATROL/SNIPER should not flank
if ( ( pSoldier->aiData.bAttitude == CUNNINGAID || pSoldier->aiData.bAttitude == CUNNINGSOLO ) &&
CountFriendsInDirection( pSoldier, sNoiseGridNo ) > 0 &&
pSoldier->aiData.bOrders > CLOSEPATROL &&
pSoldier->aiData.bOrders != SNIPER )
{
INT8 action = AI_ACTION_SEEK_NOISE;
INT16 dist = PythSpacesAway ( pSoldier->sGridNo, sNoiseGridNo );
@@ -3345,7 +3357,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
else
tempGridNo = sClosestDisturbance;
if ( pSoldier->numFlanks > 0 && pSoldier->numFlanks < MAX_FLANKS_RED && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE )
// continue flanking
// sevenfm: dont' flank when under fire
if ( pSoldier->numFlanks > 0 &&
pSoldier->numFlanks < MAX_FLANKS_RED &&
gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE &&
!pSoldier->aiData.bUnderFire )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: continue flanking");
INT16 currDir = GetDirectionFromGridNo ( tempGridNo, pSoldier );
@@ -3356,7 +3373,9 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if ( origDir > currDir )
origDir -= NUM_WORLD_DIRECTIONS;
if ( (currDir - origDir) >= 4 )
// sevenfm: stop flanking if no friend between me and noise gridno
if ( (currDir - origDir) >= 4 ||
CountFriendsInDirection( pSoldier, tempGridNo ) == 0 )
{
pSoldier->numFlanks = MAX_FLANKS_RED;
}
@@ -3375,7 +3394,9 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if ( origDir < currDir )
origDir += NUM_WORLD_DIRECTIONS;
if ( (origDir - currDir) >= 4 )
// sevenfm: stop flanking if no friend between me and noise gridno
if ( (origDir - currDir) >= 4 ||
CountFriendsInDirection( pSoldier, tempGridNo ) == 0 )
{
pSoldier->numFlanks = MAX_FLANKS_RED;
}
@@ -3592,8 +3613,15 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
// return( AI_ACTION_CLIMB_ROOF );
//}
if ( ( pSoldier->aiData.bAttitude == CUNNINGAID || pSoldier->aiData.bAttitude == CUNNINGSOLO || pSoldier->aiData.bAttitude == BRAVESOLO ) && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE )
// possibly start RED flanking
// sevenfm: only CUNNINGAID and CUNNINGSOLO should flank
// check that there are friends between me and noise gridno
// STATIONARY\ONGUARD\CLOSEPATROL\SNIPER should not flank
if ( ( pSoldier->aiData.bAttitude == CUNNINGAID || pSoldier->aiData.bAttitude == CUNNINGSOLO ) &&
gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE &&
CountFriendsInDirection( pSoldier, sClosestDisturbance ) > 0 &&
pSoldier->aiData.bOrders > CLOSEPATROL &&
pSoldier->aiData.bOrders != SNIPER )
{
INT8 action = AI_ACTION_SEEK_OPPONENT;
INT16 dist = PythSpacesAway ( pSoldier->sGridNo, sClosestDisturbance );
@@ -4363,10 +4391,10 @@ INT16 ubMinAPCost;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack");
// once we hit status black, reset flanking status
//pSoldier->numFlanks = 0;
// sevenfm: stop flanking when we see enemy
if( pSoldier->numFlanks < MAX_FLANKS_RED )
pSoldier->numFlanks = 0;
// if we have absolutely no action points, we can't do a thing under BLACK!
if (!pSoldier->bActionPoints)
{