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
+45 -2
View File
@@ -24,6 +24,7 @@
#include "Soldier Create.h"
#include "SkillCheck.h" // added by SANDRO
#include "Vehicles.h" // added by silversurfer
#include "Game Clock.h" // added by sevenfm
#endif
#include "GameInitOptionsScreen.h"
@@ -76,8 +77,8 @@ UINT16 MovementMode[LAST_MOVEMENT_ACTION + 1][NUM_URGENCY_STATES] =
{WALKING, WALKING, WALKING}, // AI_ACTION_SCHEDULE_MOVE
{WALKING, WALKING, WALKING}, // AI_ACTION_WALK
{WALKING, RUNNING, RUNNING}, // withdraw
{WALKING, SWATTING, SWATTING}, // flank left
{WALKING, SWATTING, SWATTING}, // flank right
{RUNNING, RUNNING, SWATTING}, // flank left
{RUNNING, RUNNING, SWATTING}, // flank right
{RUNNING, RUNNING, RUNNING}, // AI_ACTION_MOVE_TO_CLIMB
};
@@ -3230,4 +3231,46 @@ UINT8 GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTe
}
return id;
}
// sevenfm: define normal vision limits for day/night
INT16 MaxNormalVisionDistance( void )
{
if( NightTime() )
{
return gGameExternalOptions.ubStraightSightRange * STRAIGHT_RATIO;
}
return gGameExternalOptions.ubStraightSightRange * 2 * STRAIGHT_RATIO;
}
// sevenfm: check friendly soldiers between me and noise gridno
// count only friends that are active and not stationary/onguard/sniper
UINT8 CountFriendsInDirection( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
{
SOLDIERTYPE * pFriend;
UINT8 ubFriendDir, ubMyDir;
UINT8 ubFriends = 0;
ubMyDir = atan8(CenterX(sTargetGridNo),CenterY(sTargetGridNo),CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo));
// Run through each friendly.
for ( UINT8 iCounter = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID ; iCounter <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID ; iCounter ++ )
{
pFriend = MercPtrs[ iCounter ];
ubFriendDir = atan8(CenterX(sTargetGridNo),CenterY(sTargetGridNo),CenterX(pFriend->sGridNo),CenterY(pFriend->sGridNo));
if (pFriend != pSoldier &&
pFriend->bActive &&
pFriend->stats.bLife >= OKLIFE &&
pFriend->stats.bLife >= pFriend->stats.bLifeMax/2 &&
pFriend->aiData.bOrders > ONGUARD &&
pFriend->aiData.bOrders != SNIPER &&
(ubFriendDir == ubMyDir || ubFriendDir == gOneCDirection[ubMyDir] || ubFriendDir == gOneCCDirection[ubMyDir]) &&
PythSpacesAway( sTargetGridNo, pFriend->sGridNo) < PythSpacesAway(sTargetGridNo, pSoldier->sGridNo) )
{
ubFriends++;
}
}
return ubFriends;
}