Strategic AI changes:

- Removed Omerta from the list of "unimportant" sectors (Estoni and San Mona still "unimportant")
- Allowed queen to attack Omerta before day 2 at 7:45AM and Drassen before day 3 at 6:30AM
- The reinforcements are not reassigned anymore when the sector where they were going to is captured by player
- Omerta garrison is not reassigned anymore when queen fortifies cities
- Enabled investigation of lost city sector by the enemy 
*Limit for the investigation of the sector depends on difficulty level (4, 8, 12 and unlimited on INSANE)

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@861 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
lalien
2007-04-27 21:30:59 +00:00
parent d8ed7117f0
commit 60b6b85801
6 changed files with 176 additions and 129 deletions
+4
View File
@@ -574,6 +574,10 @@ void LoadGameExternalOptions()
gGameExternalOptions.gfHardAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","EXPERT_QUEEN_AGGRESSIVE",FALSE);
gGameExternalOptions.gfInsaneAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","INSANE_QUEEN_AGGRESSIVE",TRUE);
gGameExternalOptions.gfInvestigateSector = iniReader.ReadBoolean("JA2 Gameplay Settings","ENEMY_INVESTIGATE_SECTOR",FALSE);
gGameExternalOptions.gfReassignPendingReinforcements = iniReader.ReadBoolean("JA2 Gameplay Settings","REASSIGN_PENDING_REINFORCEMENTS",TRUE);
// WANNE: Drop Items
gGameExternalOptions.ubEnemiesItemDrop = iniReader.ReadInteger("JA2 Gameplay Settings","ENEMIES_ITEM_DROP", 0);
+3
View File
@@ -341,6 +341,9 @@ typedef struct
BOOLEAN gfHardAggressiveQueen;
BOOLEAN gfInsaneAggressiveQueen;
BOOLEAN gfInvestigateSector;
BOOLEAN gfReassignPendingReinforcements;
// WANNE
INT32 ubEnemiesItemDrop;
+1 -1
View File
@@ -23,7 +23,7 @@ wchar_t zVersionLabel[256] = { L"Beta v. 0.98" };
#else
//RELEASE BUILD VERSION
wchar_t zVersionLabel[256] = { L"Release v1.13.857" };
wchar_t zVersionLabel[256] = { L"Release v1.13.861" };
#endif
+1 -1
View File
@@ -546,7 +546,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libexpatMT.lib winmm.lib smackw32.lib mss32.lib fmodvc.lib"
OutputFile="D:\games\Jagged Alliance 2 v1.13\JA2 v1.13.844_EN.exe"
OutputFile="D:\games\Jagged Alliance 2 v1.13\JA2 v1.13.861_EN.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories=".\..\..\Standard Gaming Platform\"
+164 -127
View File
@@ -647,19 +647,24 @@ void RequestAttackOnSector( UINT8 ubSectorID, UINT16 usDefencePoints )
BOOLEAN AdjacentSectorIsImportantAndUndefended( UINT8 ubSectorID )
{
SECTORINFO *pSector;
switch( ubSectorID )
{
case SEC_A9: case SEC_A10: //Omerta
//case SEC_A9: case SEC_A10: //Omerta
case SEC_C5: case SEC_C6: case SEC_D5: //San Mona
case SEC_I6: //Estoni
//These sectors aren't important.
return FALSE;
case SEC_I6: //Estoni
//These sectors aren't important. //Lalien: changed this, need to externalize
return FALSE;
}
pSector = &SectorInfo[ ubSectorID ];
if( pSector->ubNumTroops || pSector->ubNumElites || pSector->ubNumAdmins )
{
return FALSE;
}
if( pSector->ubTraversability[ 4 ] == TOWN )
{
if( !PlayerSectorDefended( ubSectorID ) )
@@ -1609,19 +1614,22 @@ BOOLEAN EnemyPermittedToAttackSector( GROUP **pGroup, UINT8 ubSectorID )
if( CheckFact( 273, FALSE ) )
return FALSE;
break;
case SEC_A9:
case SEC_A10:
//Omerta -- not until Day 2 at 7:45AM.
if( GetWorldTotalMin() < 3345 )
return FALSE;
break;
case SEC_B13:
case SEC_C13:
case SEC_D13:
//Drassen -- not until Day 3 at 6:30AM.
if( GetWorldTotalMin() < 4710 )
return FALSE;
break;
//Lalien: deactivated
//case SEC_A9:
//case SEC_A10:
// //Omerta -- not until Day 2 at 7:45AM.
// if( GetWorldTotalMin() < 3345 )
// return FALSE;
// break;
//case SEC_B13:
//case SEC_C13:
//case SEC_D13:
// //Drassen -- not until Day 3 at 6:30AM.
// if( GetWorldTotalMin() < 4710 )
// return FALSE;
// break;
case SEC_C5:
case SEC_C6:
case SEC_D5:
@@ -4455,38 +4463,41 @@ void ClearStrategicLog()
void InvestigateSector( UINT8 ubSectorID )
{
/*
INT32 i;
SECTORINFO *pSector;
INT16 sSectorX, sSectorY;
UINT8 ubAdmins[4], ubTroops[4], ubElites[4], ubNumToSend, ubTotal;
//@@@ Disabled! Also commented out the posting of the event
return;
sSectorX = (INT16)SECTORX( ubSectorID );
sSectorY = (INT16)SECTORY( ubSectorID );
if( guiCurrentScreen != GAME_SCREEN )
{ //If we aren't in tactical, then don't do this. It is strictly added flavour and would be irritating if
//you got the prebattle interface in mapscreen while compressing time (right after clearing it...)
return;
}
if( sSectorX != gWorldSectorX || sSectorY != gWorldSectorY || gbWorldSectorZ )
{ //The sector isn't loaded, so don't bother...
return;
}
//Now, we will investigate this sector if there are forces in adjacent towns. For each
//sector that applies, we will add 1-2 soldiers.
ubTotal = 0;
for( i = 0; i < 4; i++ )
//Lalien: enabled
if ( gGameExternalOptions.gfInvestigateSector == TRUE )
{
ubAdmins[i] = ubTroops[i] = ubElites[i] = 0;
switch( i )
INT32 i;
SECTORINFO *pSector;
INT16 sSectorX, sSectorY;
UINT8 ubAdmins[4], ubTroops[4], ubElites[4], ubNumToSend, ubTotal;
//Lalien: enabled again
//@@@ Disabled! Also commented out the posting of the event
//return;
sSectorX = (INT16)SECTORX( ubSectorID );
sSectorY = (INT16)SECTORY( ubSectorID );
if( guiCurrentScreen != GAME_SCREEN )
{ //If we aren't in tactical, then don't do this. It is strictly added flavour and would be irritating if
//you got the prebattle interface in mapscreen while compressing time (right after clearing it...)
return;
}
if( sSectorX != gWorldSectorX || sSectorY != gWorldSectorY || gbWorldSectorZ )
{ //The sector isn't loaded, so don't bother...
return;
}
//Now, we will investigate this sector if there are forces in adjacent towns. For each
//sector that applies, we will add 1-2 soldiers.
ubTotal = 0;
for( i = 0; i < 4; i++ )
{
ubAdmins[i] = ubTroops[i] = ubElites[i] = 0;
switch( i )
{
case 0: //NORTH
if( sSectorY == 1 )
continue;
@@ -4507,51 +4518,54 @@ void InvestigateSector( UINT8 ubSectorID )
continue;
pSector = &SectorInfo[ ubSectorID - 1 ];
break;
}
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites > 4 )
{
ubNumToSend = (UINT8)(Random( 2 ) + 1);
while( ubNumToSend )
}
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites > 4 )
{
if( pSector->ubNumAdmins )
ubNumToSend = (UINT8)(Random( 2 ) + 1);
while( ubNumToSend )
{
pSector->ubNumAdmins--;
ubNumToSend--;
ubAdmins[i]++;
ubTotal++;
}
else if( pSector->ubNumTroops )
{
pSector->ubNumTroops--;
ubNumToSend--;
ubTroops[i]++;
ubTotal++;
}
else if( pSector->ubNumElites )
{
pSector->ubNumTroops--;
ubNumToSend--;
ubTroops[i]++;
ubTotal++;
}
else
{
break; //???
if( pSector->ubNumAdmins )
{
pSector->ubNumAdmins--;
ubNumToSend--;
ubAdmins[i]++;
ubTotal++;
}
else if( pSector->ubNumTroops )
{
pSector->ubNumTroops--;
ubNumToSend--;
ubTroops[i]++;
ubTotal++;
}
else if( pSector->ubNumElites )
{
pSector->ubNumTroops--;
ubNumToSend--;
ubTroops[i]++;
ubTotal++;
}
else
{
break; //???
}
}
}
}
}
if( !ubTotal )
{ //Nobody is available to investigate
return;
}
//Now we have decided who to send, so send them.
for( i = 0; i < 4; i++ )
{
if( ubAdmins[i] + ubTroops[i] + ubElites[i] )
if( !ubTotal )
{ //Nobody is available to investigate
return;
}
//Now we have decided who to send, so send them.
for( i = 0; i < 4; i++ )
{
switch( i )
if( ubAdmins[i] + ubTroops[i] + ubElites[i] )
{
switch( i )
{
case 0: //NORTH
AddEnemiesToBattle( NULL, INSERTION_CODE_NORTH, ubAdmins[i], ubTroops[i], ubElites[i], TRUE );
break;
@@ -4564,14 +4578,15 @@ void InvestigateSector( UINT8 ubSectorID )
case 3: //WEST
AddEnemiesToBattle( NULL, INSERTION_CODE_WEST, ubAdmins[i], ubTroops[i], ubElites[i], TRUE );
break;
}
}
}
if( !gfQueenAIAwake )
{
gfFirstBattleMeanwhileScenePending = TRUE;
}
}
if( !gfQueenAIAwake )
{
gfFirstBattleMeanwhileScenePending = TRUE;
}
*/
}
void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
@@ -4582,11 +4597,12 @@ void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY,
{ //The queen doesn't care about anything happening under the ground.
return;
}
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
if( StrategicMap[ sSectorX + sSectorY * MAP_WORLD_X ].fEnemyControlled )
{ //If the sector doesn't belong to the player, then we shouldn't be calling this function!
{
//If the sector doesn't belong to the player, then we shouldn't be calling this function!
SAIReportError( L"StrategicHandleQueenLosingControlOfSector() was called for a sector that is internally considered to be enemy controlled." );
return;
}
@@ -4606,26 +4622,34 @@ void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY,
return;
}
else
{ //check to see if there are any pending reinforcements. If so, then cancel their orders and have them
//reassigned, so the player doesn't get pestered. This is a feature that *dumbs* down the AI, and is done
//for the sake of gameplay. We don't want the game to be tedious.
if( !pSector->uiTimeLastPlayerLiberated )
{
//Lalien
if ( gGameExternalOptions.gfReassignPendingReinforcements == TRUE )
{
pSector->uiTimeLastPlayerLiberated = GetWorldTotalSeconds();
}
else
{ //convert hours to seconds and subtract up to half of it randomly "seconds - (hours*3600 / 2)"
pSector->uiTimeLastPlayerLiberated = GetWorldTotalSeconds() - Random( gubHoursGracePeriod * 1800 );
}
if( gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID )
{
GROUP *pGroup;
pGroup = GetGroup( gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID );
if( pGroup )
//check to see if there are any pending reinforcements. If so, then cancel their orders and have them
//reassigned, so the player doesn't get pestered. This is a feature that *dumbs* down the AI, and is done
//for the sake of gameplay. We don't want the game to be tedious.
if( !pSector->uiTimeLastPlayerLiberated )
{
ReassignAIGroup( &pGroup );
pSector->uiTimeLastPlayerLiberated = GetWorldTotalSeconds();
}
else
{
//convert hours to seconds and subtract up to half of it randomly "seconds - (hours*3600 / 2)"
pSector->uiTimeLastPlayerLiberated = GetWorldTotalSeconds() - Random( gubHoursGracePeriod * 1800 );
}
if( gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID )
{
GROUP *pGroup;
pGroup = GetGroup( gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID );
if( pGroup )
{
ReassignAIGroup( &pGroup );
}
gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID = 0;
}
gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID = 0;
}
}
@@ -4709,18 +4733,27 @@ void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY,
return;
}
if( pSector->ubInvestigativeState >= ( 4 * gGameOptions.ubDifficultyLevel ) && gGameOptions.ubDifficultyLevel < DIF_LEVEL_INSANE ) //Madd: tweaked to increase attacks for experienced and expert to 8 and 12, and unlimited for insane
{ //This is the 4th time the player has conquered this sector. We won't pester the player with probing attacks here anymore.
//Madd: tweaked to increase attacks for experienced and expert to 8 and 12, and unlimited for insane
if( pSector->ubInvestigativeState >= ( 4 * gGameOptions.ubDifficultyLevel ) && gGameOptions.ubDifficultyLevel < DIF_LEVEL_INSANE )
{
//This is the 4th time the player has conquered this sector. We won't pester the player with probing attacks here anymore.
return;
}
if( sSectorX != gWorldSectorX || sSectorY != gWorldSectorY )
{ //The sector isn't loaded, so don't probe attack it. Otherwise, autoresolve would get them smoked!
return;
}
//@@@ disabled
//AddStrategicEventUsingSeconds( EVENT_INVESTIGATE_SECTOR, GetWorldTotalSeconds() + 45 * pSector->ubInvestigativeState + Random( 60 ), SECTOR( sSectorX, sSectorY ) );
//Lalien: enabled investigation of lost sector by enemy
if ( gGameExternalOptions.gfInvestigateSector == TRUE)
{
AddStrategicEventUsingSeconds( EVENT_INVESTIGATE_SECTOR, GetWorldTotalSeconds() + 45 * pSector->ubInvestigativeState + Random( 60 ), SECTOR( sSectorX, sSectorY ) );
}
}
void RequestHighPriorityStagingGroupReinforcements( GROUP *pGroup )
{
// GROUP *pClosestGroup;
@@ -4882,7 +4915,7 @@ void MassFortifyTowns()
{
INT32 i;
SECTORINFO *pSector;
GROUP *pGroup;
//GROUP *pGroup;
UINT8 ubNumTroops, ubDesiredTroops;
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
@@ -4892,29 +4925,33 @@ void MassFortifyTowns()
pSector = &SectorInfo[ gGarrisonGroup[ i ].ubSectorID ];
ubNumTroops = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
ubDesiredTroops = (UINT8)gArmyComp[ gGarrisonGroup[ i ].ubComposition ].bDesiredPopulation;
if( ubNumTroops < ubDesiredTroops )
{
if( !gGarrisonGroup[ i ].ubPendingGroupID &&
gGarrisonGroup[ i ].ubComposition != ROADBLOCK &&
EnemyPermittedToAttackSector( NULL, gGarrisonGroup[ i ].ubSectorID ) )
gGarrisonGroup[ i ].ubComposition != ROADBLOCK &&
EnemyPermittedToAttackSector( NULL, gGarrisonGroup[ i ].ubSectorID ) )
{
RequestHighPriorityGarrisonReinforcements( i, (UINT8)(ubDesiredTroops - ubNumTroops) );
}
}
}
//Lalien: removed, the queen should attack and stay in Omerta
//Convert the garrison sitting in Omerta (if alive), and reassign them
pSector = &SectorInfo[ SEC_A9 ];
if( pSector->ubNumTroops )
{
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A9, 0, pSector->ubNumTroops, 0 );
Assert( pGroup );
pSector->ubNumTroops = 0;
pGroup->pEnemyGroup->ubIntention = PATROL;
pGroup->ubMoveType = ONE_WAY;
ReassignAIGroup( &pGroup );
ValidateGroup( pGroup );
RecalculateSectorWeight( SEC_A9 );
}
//pSector = &SectorInfo[ SEC_A9 ];
//if( pSector->ubNumTroops )
//{
// pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A9, 0, pSector->ubNumTroops, 0 );
// Assert( pGroup );
// pSector->ubNumTroops = 0;
// pGroup->pEnemyGroup->ubIntention = PATROL;
// pGroup->ubMoveType = ONE_WAY;
// ReassignAIGroup( &pGroup );
// ValidateGroup( pGroup );
// RecalculateSectorWeight( SEC_A9 );
//}
}
void RenderAIViewerGarrisonInfo( INT32 x, INT32 y, SECTORINFO *pSector )
+3
View File
@@ -3522,6 +3522,9 @@
<File
RelativePath=".\XML_Army.cpp">
</File>
<File
RelativePath=".\XML_Roaming.cpp">
</File>
</Filter>
<Filter
Name="Header Files"