mirror of
https://github.com/1dot13/source.git
synced 2026-08-05 14:00:23 +02:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -341,6 +341,9 @@ typedef struct
|
||||
BOOLEAN gfHardAggressiveQueen;
|
||||
BOOLEAN gfInsaneAggressiveQueen;
|
||||
|
||||
BOOLEAN gfInvestigateSector;
|
||||
BOOLEAN gfReassignPendingReinforcements;
|
||||
|
||||
// WANNE
|
||||
INT32 ubEnemiesItemDrop;
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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 )
|
||||
|
||||
@@ -3522,6 +3522,9 @@
|
||||
<File
|
||||
RelativePath=".\XML_Army.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\XML_Roaming.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
|
||||
Reference in New Issue
Block a user