Moving Tanks Feature (by anv)

- feature: tanks can move around in tactical. Set with Tactical Gameplay Settings > ENEMY_TANKS_CAN_MOVE.
- feature: tanks can ignore chance to get through and destroy enemy cover even if it probably won't hit anyone behind it. Set with Tactical Gameplay Settings > ENEMY_TANKS_BLOW_OBSTACLES_UP.
- feature: tanks can use cannon even against single mercs and in perfect health. Set with Tactical Gameplay Settings > ENEMY_TANKS_DONT_SPARE_SHELLS.
- feature: tanks can noticed as soon as any part of it is visible. Set with Tactical Gameplay Settings > ENEMY_TANKS_ANY_PART_VISIBLE.
- feature: depending on game difficulty enemy patrols at game start can be randomly reinforced with tank. Set with Strategic Gameplay Settings > ARMY_USES_TANKS_IN_PATROLS.
- feature: depending on game difficulty enemy groups created during offensives can include tanks. Set with trategic Gameplay Settings > ARMY_USES_TANKS_IN_ATTACKS.
- feature: mercs in vehicles automatically rest their guns,
- fix: guns can be rested on vehicles,
- rewritten code to allow putting enemies inside vehicles,
- added missing descriptions for all vehicle options to INIEditorJA2Options.xml.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7277 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2014-06-18 18:10:07 +00:00
parent 33b3707381
commit 981c81b4b4
42 changed files with 971 additions and 372 deletions
+28 -20
View File
@@ -161,7 +161,7 @@ void ViewCreaturesCallback( GUI_BUTTON *btn, INT32 reason );
void ExtractAndUpdatePopulations();
void PrintEnemyPopTable();
void PrintEnemiesKilledTable();
UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites );
UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites, UINT8 ubTanks );
void BlitGroupIcon( UINT8 ubIconType, UINT8 ubIconColor, UINT32 uiX, UINT32 uiY, HVOBJECT hVObject );
void PrintDetailedEnemiesInSectorInfo( INT32 iScreenX, INT32 iScreenY, UINT8 ubSectorX, UINT8 ubSectorY );
@@ -188,6 +188,7 @@ UINT16 gusDkBlue;
INT16 gsAINumAdmins = -1;
INT16 gsAINumTroops = -1;
INT16 gsAINumElites = -1;
INT16 gsAINumTanks = -1;
INT16 gsAINumCreatures = -1;
BOOLEAN gfOverrideSector = FALSE;
@@ -488,11 +489,11 @@ void RenderStationaryGroups()
ubGroupSize = pSector->ubNumberOfCivsAtLevel[0] + pSector->ubNumberOfCivsAtLevel[1] + pSector->ubNumberOfCivsAtLevel[2];
}
else
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites )
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks )
{
// show enemies
ubIconColor = ChooseEnemyIconColor( pSector->ubNumAdmins, pSector->ubNumTroops, pSector->ubNumElites );
ubGroupSize = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
ubIconColor = ChooseEnemyIconColor( pSector->ubNumAdmins, pSector->ubNumTroops, pSector->ubNumElites, pSector->ubNumTanks );
ubGroupSize = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
if( pSector->ubGarrisonID != NO_GARRISON )
{
if( gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID )
@@ -536,7 +537,7 @@ void RenderMovingGroupsAndMercs()
GROUP *pGroup;
HVOBJECT hVObject;
INT32 x, y;
UINT8 ubNumTroops, ubNumAdmins, ubNumElites;
UINT8 ubNumTroops, ubNumAdmins, ubNumElites, ubNumTanks;
float ratio;
INT32 minX, maxX, minY, maxY;
UINT8 ubIconType;
@@ -591,12 +592,13 @@ void RenderMovingGroupsAndMercs()
ubNumAdmins = pGroup->pEnemyGroup->ubNumAdmins;//+ pGroup->pEnemyGroup->ubAdminsInBattle;
ubNumTroops = pGroup->pEnemyGroup->ubNumTroops;//+ pGroup->pEnemyGroup->ubTroopsInBattle;
ubNumElites = pGroup->pEnemyGroup->ubNumElites;// + pGroup->pEnemyGroup->ubElitesInBattle;
ubNumTanks = pGroup->pEnemyGroup->ubNumTanks;
// must have one of the three, already checked groupsize!
Assert( ubNumAdmins || ubNumTroops || ubNumElites );
Assert( ubNumAdmins || ubNumTroops || ubNumElites || ubNumTanks );
//determine icon color
ubIconColor = ChooseEnemyIconColor( ubNumAdmins, ubNumTroops, ubNumElites );
ubIconColor = ChooseEnemyIconColor( ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
// must have a valid intention
Assert( pGroup->pEnemyGroup->ubIntention < NUM_ENEMY_INTENTIONS );
@@ -721,7 +723,7 @@ void RenderInfoInSector()
{
SECTORINFO *pSector;
GROUP *pGroup;
UINT8 ubNumAdmins=0, ubNumTroops=0, ubNumElites=0, ubAdminsInBattle=0, ubTroopsInBattle=0, ubElitesInBattle=0, ubNumGroups=0;
UINT8 ubNumAdmins=0, ubNumTroops=0, ubNumElites=0, ubNumTanks=0, ubAdminsInBattle=0, ubTroopsInBattle=0, ubElitesInBattle=0, ubTanksInBattle=0, ubNumGroups=0;
pSector = &SectorInfo[ SECTOR( ubSectorX, ubSectorY ) ];
@@ -734,9 +736,11 @@ void RenderInfoInSector()
ubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
ubNumElites += pGroup->pEnemyGroup->ubNumElites;
ubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
ubTroopsInBattle += pGroup->pEnemyGroup->ubTroopsInBattle;
ubElitesInBattle += pGroup->pEnemyGroup->ubElitesInBattle;
ubAdminsInBattle += pGroup->pEnemyGroup->ubAdminsInBattle;
ubTanksInBattle += pGroup->pEnemyGroup->ubTanksInBattle;
ubNumGroups++;
}
pGroup = pGroup->next;
@@ -753,15 +757,17 @@ void RenderInfoInSector()
pSector->ubNumberOfCivsAtLevel[0], pSector->ubNumberOfCivsAtLevel[1], pSector->ubNumberOfCivsAtLevel[2] );
yp += 10;
SetFontForeground( FONT_ORANGE );
mprintf( 280, yp, L"Garrison: (%d:%d Admins, %d:%d Troops, %d:%d Elites)",
mprintf( 280, yp, L"Garrison: (%d:%d Admins, %d:%d Troops, %d:%d Elites, %d:%d Tanks)",
pSector->ubAdminsInBattle, pSector->ubNumAdmins,
pSector->ubTroopsInBattle, pSector->ubNumTroops,
pSector->ubElitesInBattle, pSector->ubNumElites );
pSector->ubElitesInBattle, pSector->ubNumElites,
pSector->ubTanksInBattle, pSector->ubNumTanks );
yp += 10;
mprintf( 280, yp, L"%d Groups: (%d:%d Admins, %d:%d Troops, %d:%d Elites)", ubNumGroups,
mprintf( 280, yp, L"%d Groups: (%d:%d Admins, %d:%d Troops, %d:%d Elites, %d:%d Tanks)", ubNumGroups,
ubAdminsInBattle, ubNumAdmins,
ubTroopsInBattle, ubNumTroops,
ubElitesInBattle, ubNumElites );
ubElitesInBattle, ubNumElites,
ubTanksInBattle, ubNumTanks );
yp += 10;
SetFontForeground( FONT_WHITE );
@@ -1266,7 +1272,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
gfRenderViewer = TRUE;
if( gsSelSectorY > 1 )
{
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-16, 0, 11, 5 );
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-16, 0, 11, 5, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 10;
@@ -1278,7 +1284,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
}
if( gsSelSectorY < 16 )
{
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+16, 0, 8, 8 );
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+16, 0, 8, 8, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 12;
@@ -1290,7 +1296,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
}
if( gsSelSectorX > 1 )
{
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-1, 0, 11, 5 );
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-1, 0, 11, 5, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 11;
@@ -1302,7 +1308,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
}
if( gsSelSectorX < 16 )
{
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, 0, 14, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, 0, 14, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 13;
@@ -1557,6 +1563,7 @@ void PrintEnemyPopTable()
usEnemyPopTable[ ENEMY_RANK_ADMIN ][ ENEMY_TYPE_GARRISON ] += pSector->ubNumAdmins;
usEnemyPopTable[ ENEMY_RANK_TROOP ][ ENEMY_TYPE_GARRISON ] += pSector->ubNumTroops;
usEnemyPopTable[ ENEMY_RANK_ELITE ][ ENEMY_TYPE_GARRISON ] += pSector->ubNumElites;
//usEnemyPopTable[ ENEMY_RANK_TANK ][ ENEMY_TYPE_GARRISON ] += pSector->ubNumTanks;
}
// count moving enemies
@@ -1583,6 +1590,7 @@ void PrintEnemyPopTable()
usEnemyPopTable[ ENEMY_RANK_ADMIN ][ ubEnemyType ] += pGroup->pEnemyGroup->ubNumAdmins;
usEnemyPopTable[ ENEMY_RANK_TROOP ][ ubEnemyType ] += pGroup->pEnemyGroup->ubNumTroops;
usEnemyPopTable[ ENEMY_RANK_ELITE ][ ubEnemyType ] += pGroup->pEnemyGroup->ubNumElites;
//usEnemyPopTable[ ENEMY_RANK_TANK ][ ubEnemyType ] += pGroup->pEnemyGroup->ubNumTanks;
}
pGroup = pGroup->next;
@@ -1823,7 +1831,7 @@ void PrintEnemiesKilledTable()
UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites )
UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites, UINT8 ubTanks )
{
UINT8 ubIconColor;
@@ -1834,7 +1842,7 @@ UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites )
// Orange Mixed, no elites (Admins + Troops)
// Burgundy Mixed, with elites (Elites + (Admins OR Troops))
Assert( ubAdmins || ubTroops || ubElites );
Assert( ubAdmins || ubTroops || ubElites ||ubTanks );
if ( ubElites )
{
@@ -1895,8 +1903,8 @@ void PrintDetailedEnemiesInSectorInfo( INT32 iScreenX, INT32 iScreenY, UINT8 ubS
// handle garrisoned enemies
if( pSector->ubGarrisonID != NO_GARRISON )
{
iDesired = gArmyComp[ gGarrisonGroup[ pSector->ubGarrisonID ].ubComposition ].bDesiredPopulation;
iSurplus = pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumElites - iDesired;
iDesired = gArmyComp[ gGarrisonGroup[ pSector->ubGarrisonID ].ubComposition ].bDesiredPopulation;
iSurplus = pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumElites + pSector->ubNumTanks - iDesired;
SetFontForeground( FONT_WHITE );
swprintf( wString, L"Garrison #%d: %d desired, ", pSector->ubGarrisonID, iDesired );
+2
View File
@@ -6839,6 +6839,7 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
pSectorInfo->ubNumTroops = min(255, pSectorInfo->ubNumTroops + prisonersregular);
pSectorInfo->ubNumElites = min(255, pSectorInfo->ubNumElites + prisonerselite + prisonersofficer);
pSectorInfo->ubNumAdmins = min(255, pSectorInfo->ubNumAdmins + prisonersadmin);
pSectorInfo->ubNumTanks = min(255, pSectorInfo->ubNumTanks );
// all prisoners are free, reduce count!
DeleteAllPrisoners(pSectorInfo);
@@ -6892,6 +6893,7 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
pSectorInfo->ubNumTroops = min( 512, pSectorInfo->ubNumTroops + escapedregulars );
pSectorInfo->ubNumElites = min( 512, pSectorInfo->ubNumElites + escapedelites + escapedofficers );
pSectorInfo->ubNumAdmins = min( 512, pSectorInfo->ubNumAdmins + escapedadmins );
pSectorInfo->ubNumTanks = min( 512, pSectorInfo->ubNumTanks );
// reduce prisoner count!
ChangeNumberOfPrisoners( pSectorInfo, -escapedofficers, -escapedelites, -escapedregulars, -escapedadmins, sMapX, sMapY );
+54 -9
View File
@@ -166,7 +166,7 @@ typedef struct AUTORESOLVE_STRUCT
UINT8 ubEnemyLeadership;
UINT8 ubPlayerLeadership;
UINT8 ubMercs, ubCivs, ubEnemies;
UINT8 ubAdmins, ubTroops, ubElites;
UINT8 ubAdmins, ubTroops, ubElites, ubTanks;
UINT8 ubYMCreatures, ubYFCreatures, ubAMCreatures, ubAFCreatures;
UINT8 ubAliveMercs, ubAliveCivs, ubAliveEnemies;
UINT8 ubMercCols, ubMercRows;
@@ -226,10 +226,11 @@ typedef struct AUTORESOLVE_STRUCT
#define CELL_ASSIGNED 0x00080000
#define CELL_EPC 0x00100000
#define CELL_ROBOT 0x00200000
#define CELL_TANK 0x00400000
//Combined flags
#define CELL_PLAYER ( CELL_MERC | CELL_MILITIA )
#define CELL_ENEMY ( CELL_ELITE | CELL_TROOP | CELL_ADMIN )
#define CELL_ENEMY ( CELL_ELITE | CELL_TROOP | CELL_ADMIN | CELL_TANK )
#define CELL_CREATURE ( CELL_AF_CREATURE | CELL_AM_CREATURE | CELL_YF_CREATURE | CELL_YM_CREATURE )
#define CELL_FEMALECREATURE ( CELL_AF_CREATURE | CELL_YF_CREATURE )
#define CELL_MALECREATURE ( CELL_AM_CREATURE | CELL_YM_CREATURE )
@@ -441,7 +442,7 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
// we must process the enemies killed right here & give out loyalty bonuses as if the battle had been fought & won
if( !gpAR )
{
GetNumberOfEnemiesInSector( ubSectorX, ubSectorY, &ubNumEnemies[ 0 ], &ubNumEnemies[ 1 ], &ubNumEnemies[ 2 ] );
GetNumberOfEnemiesInSector( ubSectorX, ubSectorY, &ubNumEnemies[ 0 ], &ubNumEnemies[ 1 ], &ubNumEnemies[ 2 ], &ubNumEnemies[ 3 ] );
for ( ubRankIndex = 0; ubRankIndex < NUM_ENEMY_RANKS; ubRankIndex++ )
{
@@ -461,6 +462,7 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
pSector->ubNumTroops = 0;
pSector->ubNumElites = 0;
pSector->ubNumAdmins = 0;
pSector->ubNumTanks = 0;
pSector->ubNumCreatures = 0;
pSector->bLastKnownEnemies = 0;
//Remove the mobile forces here, but only if battle is over.
@@ -749,9 +751,9 @@ void AssociateEnemiesWithStrategicGroups()
{
SECTORINFO *pSector;
GROUP *pGroup;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites;
UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites;
UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks;
UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites, ubISNumTanks;
UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup, ubNumTanksInGroup;
INT32 i;
UINT8 pSectors[4];
UINT8 ubDirAmount;
@@ -766,6 +768,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumAdmins = pSector->ubNumAdmins;
ubNumTroops = pSector->ubNumTroops;
ubNumElites = pSector->ubNumElites;
ubNumTanks = pSector->ubNumTanks;
//Now go through our enemies in the autoresolve array, and assign the ubGroupID to the soldier
//Stationary groups have a group ID of 0
@@ -789,13 +792,20 @@ void AssociateEnemiesWithStrategicGroups()
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
ubNumAdmins--;
}
else if( gpEnemies[ i ].uiFlags & CELL_TANK && ubNumTanks )
{
gpEnemies[ i ].pSoldier->ubGroupID = 0;
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
ubNumTanks--;
}
}
ubNumAdmins = gpAR->ubAdmins - pSector->ubNumAdmins;
ubNumTroops = gpAR->ubTroops - pSector->ubNumTroops;
ubNumElites = gpAR->ubElites - pSector->ubNumElites;
ubNumTanks = gpAR->ubTanks - pSector->ubNumTanks;
if( !ubNumElites && !ubNumTroops && !ubNumAdmins )
if( !ubNumElites && !ubNumTroops && !ubNumAdmins && !ubNumTanks )
{ //All troops accounted for.
return;
}
@@ -809,6 +819,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites;
ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops;
ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks;
for( i = 0; i < gpAR->ubEnemies; i++ )
{
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
@@ -834,6 +845,13 @@ void AssociateEnemiesWithStrategicGroups()
ubNumAdmins--;
ubNumAdminsInGroup--;
}
else if( ubNumTanks && ubNumTanksInGroup )
{
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
ubNumTanks--;
ubNumTanksInGroup--;
}
}
}
}
@@ -850,6 +868,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites;
ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops;
ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks;
for( i = 0; i < gpAR->ubEnemies; i++ )
{
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
@@ -875,6 +894,13 @@ void AssociateEnemiesWithStrategicGroups()
ubNumAdmins--;
ubNumAdminsInGroup--;
}
else if( ubNumTanks && ubNumTanksInGroup )
{
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
ubNumTanks--;
ubNumTanksInGroup--;
}
}
}
}
@@ -892,10 +918,11 @@ void AssociateEnemiesWithStrategicGroups()
ubISNumAdmins = pSector->ubNumAdmins;
ubISNumTroops = pSector->ubNumTroops;
ubISNumElites = pSector->ubNumElites;
ubISNumTanks = pSector->ubNumTanks;
for( i = 0; i < gpAR->ubEnemies; i++ )
{
if( ubISNumAdmins + ubISNumTroops + ubISNumElites <= gubReinforcementMinEnemyStaticGroupSize ) break;
if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break;
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
{
@@ -926,6 +953,15 @@ void AssociateEnemiesWithStrategicGroups()
ubISNumAdmins--;
ubNumAdmins--;
}
else if( gpEnemies[ i ].uiFlags & CELL_TANK && ubISNumTanks && ubNumTanks )
{
gpEnemies[ i ].pSoldier->ubGroupID = 0;
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
gpEnemies[ i ].pSoldier->sSectorX = SECTORX( pSectors[ ubCurrSI ] );
gpEnemies[ i ].pSoldier->sSectorY = SECTORY( pSectors[ ubCurrSI ] );
ubISNumTanks--;
ubNumTanks--;
}
}
}
}
@@ -2480,6 +2516,15 @@ void CreateAutoResolveInterface()
gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY;
swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[ STR_AR_ADMINISTRATOR_NAME ] );
}
for( i = 0; i < gpAR->ubTanks; i++, index++ )
{
gpEnemies[index].pSoldier = TacticalCreateEnemyTank();
gpEnemies[index].uiVObjectID = gpAR->iFaces;
gpEnemies[index].usIndex = ELITE_FACE;
gpEnemies[index].pSoldier->sSectorX = gpAR->ubSectorX;
gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY;
//swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[ STR_AR_ADMINISTRATOR_NAME ] );
}
AssociateEnemiesWithStrategicGroups();
}
else
@@ -3141,7 +3186,7 @@ void CalculateAutoResolveInfo()
{
// GetNumberOfEnemiesInSector( gpAR->ubSectorX, gpAR->ubSectorY,
GetNumberOfEnemiesInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY,
&gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites );
&gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites, &gpAR->ubTanks );
gpAR->ubEnemies = (UINT8)min( gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubElites, MAX_AR_TEAM_SIZE );
}
else
+6 -6
View File
@@ -337,25 +337,25 @@ void GeneratePatrolGroups()
GROUP *pGroup;
UINT8 ubNumTroops;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_C7, 0, ubNumTroops, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_C7, 0, ubNumTroops, 0, 0 );
pGroup->ubTransportationMask = CAR;
AddWaypointToPGroup( pGroup, 8, 3 ); //C8
AddWaypointToPGroup( pGroup, 7, 3 ); //C7
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_D9, 0, ubNumTroops, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_D9, 0, ubNumTroops, 0, 0 );
AddWaypointToPGroup( pGroup, 9, 5 ); //E9
AddWaypointToPGroup( pGroup, 9, 4 ); //D9
pGroup->ubTransportationMask = TRUCK;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_B9, 0, ubNumTroops, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_B9, 0, ubNumTroops, 0, 0 );
AddWaypointToPGroup( pGroup, 12, 2 ); //B12
AddWaypointToPGroup( pGroup, 9, 2 ); //B9
pGroup->ubTransportationMask = FOOT;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A14, 0, ubNumTroops, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A14, 0, ubNumTroops, 0, 0 );
pGroup->ubMoveType = ENDTOEND_FORWARDS;
AddWaypointToPGroup( pGroup, 13, 1 ); //A13
AddWaypointToPGroup( pGroup, 15, 1 ); //A15
@@ -366,13 +366,13 @@ void GeneratePatrolGroups()
pGroup->ubTransportationMask = TRACKED;
ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N6, 0, ubNumTroops, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N6, 0, ubNumTroops, 0, 0 );
AddWaypointToPGroup( pGroup, 9, 14 ); //N9
AddWaypointToPGroup( pGroup, 6, 14 ); //N6
pGroup->ubTransportationMask = CAR;
ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N10, 0, ubNumTroops, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N10, 0, ubNumTroops, 0, 0 );
AddWaypointToPGroup( pGroup, 10, 11 ); //K10
AddWaypointToPGroup( pGroup, 10, 14 ); //N10
pGroup->ubTransportationMask = CAR;
+8 -2
View File
@@ -500,7 +500,10 @@ typedef struct SECTORINFO
UINT32 uiTimeAIArtillerywasOrdered; // Flugente: updated every time an artillery strike is ordered from the militia
INT8 bPadding[ 29 ];
UINT8 ubNumTanks;
UINT8 ubTanksInBattle;
INT8 bPadding[ 27 ];
}SECTORINFO;
@@ -539,7 +542,10 @@ typedef struct UNDERGROUND_SECTORINFO
UINT8 uiNumberOfPrisonersOfWar[PRISONER_MAX];
INT8 bPadding[32];
UINT8 ubNumTanks;
UINT8 ubTanksInBattle;
INT8 bPadding[30];
//no padding left!
}UNDERGROUND_SECTORINFO;
+71 -50
View File
@@ -123,16 +123,16 @@ JA25_SECTOR_AI_MANAGER gJa25StrategicAi;
BOOLEAN AddEnemiesToInitialSectorH7();
UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites );
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pubNumTanks );
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
void InitJa25InitialEnemiesInSector();
void InitJa25UnderGroundSectors();
void InitNumberOfEnemiesInAboveGroundSectors( );
void InitNumberOfEnemiesInUnderGroundSectors( );
void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8 bBloodCatPlacements );
void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
void ResetJa25SectorProbabilities();
BOOLEAN InitJa25StrategicSectorAI( BOOLEAN fReset );
@@ -152,8 +152,8 @@ void FixEnemyCounterInSectorBug();
void AddEnemiesToFirstTunnelSector();
void AddEnemiesToSecondTunnelSector();
UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites );
UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites );
UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks );
UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks );
void RemoveAllEnemySoldierInitListLinks();
INT16 GetGridNoEnemyWillSeekWhenAttacking( INT8 bSaiSector );
void SetH11NumEnemiesInSector();
@@ -175,7 +175,7 @@ BOOLEAN Ja25BetaDateToInvalidateExe();
UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites )
UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pNumTanks )
{
SECTORINFO *pSector;
@@ -187,6 +187,7 @@ UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSec
*pNumAdmins = pSector->ubNumAdmins;
*pNumTroops = pSector->ubNumTroops;
*pNumElites = pSector->ubNumElites;
*pNumTanks = pSector->ubNumTanks;
}
else
{
@@ -198,6 +199,7 @@ UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSec
*pNumAdmins = pSector->ubNumAdmins;
*pNumTroops = pSector->ubNumTroops;
*pNumElites = pSector->ubNumElites;
*pNumTanks = pSector->ubNumTanks;
}
}
@@ -278,15 +280,17 @@ BOOLEAN AddEnemiesToInitialSectorH7()
UINT8 ubNumAdmins;
UINT8 ubNumTroops;
UINT8 ubNumElites;
UINT8 ubNumTanks;
UINT8 ubNumRemovedAdmins=0;
UINT8 ubNumRemovedTroops=0;
UINT8 ubNumRemovedElites=0;
UINT8 ubNumRemovedTanks=0;
ubSector = SECTOR( JA2_5_START_SECTOR_X, JA2_5_START_SECTOR_Y );
//Get the number of enemies in the guard post sector
GetNumberOfJA25EnemiesInSector( 8, MAP_ROW_H, 0, &ubNumAdmins, &ubNumTroops, &ubNumElites );
GetNumberOfJA25EnemiesInSector( 8, MAP_ROW_H, 0, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
//determine the #of enemies to travel to the initial heli sector
@@ -299,13 +303,16 @@ BOOLEAN AddEnemiesToInitialSectorH7()
if( ubNumElites > 1 )
ubNumRemovedElites = ubNumElites / 3 + + Random( 3 );
if( ubNumTanks > 1 )
ubNumRemovedTanks = ubNumTanks / 3 + + Random( 3 );
//deduct the # that are moving from the # in the guard post sector
// SetNumberJa25EnemiesInSurfaceSector( SEC_H8, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites) );
SetNumberJa25EnemiesInSector( 8, MAP_ROW_H, 0, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites) );
SetNumberJa25EnemiesInSector( 8, MAP_ROW_H, 0, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites), (UINT8)(ubNumTanks-ubNumRemovedTanks) );
uiWorldMin = GetWorldTotalMin();
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, ubNumRemovedAdmins, ubNumRemovedTroops, ubNumRemovedElites );
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, ubNumRemovedAdmins, ubNumRemovedTroops, ubNumRemovedElites, ubNumRemovedTanks );
if( pGroup == NULL )
{
@@ -396,24 +403,24 @@ void InitJa25UnderGroundSectors()
*/
}
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites )
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks )
{
//if its a ground level
if( bSectorZ == 0 )
{
SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//its an underground level
else
{
SetNumberJa25EnemiesInUnderGroundSector( sSectorX, sSectorY, bSectorZ, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInUnderGroundSector( sSectorX, sSectorY, bSectorZ, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
}
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites )
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks )
{
SECTORINFO *pSector;
@@ -421,6 +428,7 @@ void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UI
pSector->ubNumAdmins = ubNumAdmins;
pSector->ubNumTroops = ubNumTroops;
pSector->ubNumElites = ubNumElites;
pSector->ubNumTanks = ubNumTanks;
}
void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8 bBloodCatPlacements )
@@ -433,7 +441,7 @@ void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8
pSector->bBloodCatPlacements = bBloodCatPlacements;
}
void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites )
void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks )
{
UNDERGROUND_SECTORINFO *pSector=NULL;
@@ -444,6 +452,7 @@ void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, IN
pSector->ubNumAdmins = ubNumAdmins;
pSector->ubNumTroops = ubNumTroops;
pSector->ubNumElites = ubNumElites;
pSector->ubNumTanks = ubNumTanks;
}
void InitNumberOfEnemiesInAboveGroundSectors( )
@@ -451,6 +460,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks=0;
//H7
{
@@ -477,7 +487,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
ubNumElites = 0 + Random( 0 );
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_H7, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_H7, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
@@ -508,7 +518,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_H8, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_H8, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//Guard Post
@@ -538,7 +548,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_H9, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_H9, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
// SEC_H10:
@@ -567,7 +577,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_H10, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_H10, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//SEC_H11
@@ -600,7 +610,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_I9, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_I9, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//First part of town
@@ -630,7 +640,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_I10, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_I10, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//Second part of town
@@ -660,7 +670,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_I11, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_I11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//SEC_I12:
@@ -689,7 +699,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_I12, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_I12, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//Abandoned mine
@@ -719,7 +729,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_I13, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_I13, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
// SEC_J11:
@@ -748,7 +758,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_J11, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_J11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
// SEC_J12:
@@ -777,7 +787,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_J12, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_J12, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//Power Generator, Ground Level
@@ -807,7 +817,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_J13, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_J13, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
//Complex, Ground Level
@@ -837,7 +847,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_K15, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_K15, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
}
@@ -846,6 +856,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks;
//Mine Sector Level 1
switch( gGameOptions.ubDifficultyLevel )
@@ -866,7 +877,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 );
break;
}
SetNumberJa25EnemiesInSector( 13, 9, 1, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 13, 9, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
//Power Generator Level 1
@@ -888,7 +899,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 );
break;
}
SetNumberJa25EnemiesInSector( 13, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 13, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
//Tunnel First Part, Level 1
@@ -910,7 +921,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 );
break;
}
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
//Tunnel Second Part, Level 1
@@ -932,7 +943,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 );
break;
}
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
@@ -955,7 +966,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 6 + Random( 4 );
break;
}
SetNumberJa25EnemiesInSector( 15, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 15, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
//Complex, Level 2, K15
@@ -977,7 +988,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 10 + Random( 2 );
break;
}
SetNumberJa25EnemiesInSector( 15, 11, 2, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 15, 11, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
//Complex, Level 2, L15
@@ -999,7 +1010,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 14 + Random( 2 );
break;
}
SetNumberJa25EnemiesInSector( 15, 12, 2, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 15, 12, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
//Complex, Level 3, L15
@@ -1021,7 +1032,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 15 + Random( 0 );
break;
}
SetNumberJa25EnemiesInSector( 15, 12, 3, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 15, 12, 3, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
void InitJa25SaveStruct()
@@ -1270,7 +1281,7 @@ void HandleAddingEnemiesToTunnelMaps()
else if( AreAnyPlayerMercsStillInSector( 14, 10, 1 ) &&
!AreAnyPlayerMercsStillInSector( 14, 11, 1 ) )
{
ubNumEnemies = NumEnemiesToAttackFirstTunnelSector( NULL, NULL, NULL );
ubNumEnemies = NumEnemiesToAttackFirstTunnelSector( NULL, NULL, NULL, NULL );
//Add enemies to the first sector
HandleAddEnemiesToSectorPlayerIsntIn( JA25_J14_1, ubNumEnemies );
@@ -1284,7 +1295,7 @@ void HandleAddingEnemiesToTunnelMaps()
//else if the player is in the second sector
else if( AreAnyPlayerMercsStillInSector( 14, 11, 1 ) )
{
ubNumEnemies = NumEnemiesToAttackSecondTunnelSector( NULL, NULL, NULL );
ubNumEnemies = NumEnemiesToAttackSecondTunnelSector( NULL, NULL, NULL, NULL );
//Add enemies to the first sector
HandleAddEnemiesToSectorPlayerIsntIn( JA25_K14_1, ubNumEnemies );
@@ -1313,10 +1324,11 @@ void AddEnemiesToFirstTunnelSector()
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks=0;
NumEnemiesToAttackFirstTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites );
NumEnemiesToAttackFirstTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
void AddEnemiesToSecondTunnelSector()
@@ -1324,16 +1336,18 @@ void AddEnemiesToSecondTunnelSector()
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks=0;
NumEnemiesToAttackSecondTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites );
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites );
NumEnemiesToAttackSecondTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites )
UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks )
{
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks=0;
//if the player blew up the fan, add a ton of enemies to the sector
//1st Tunnel Sector
@@ -1365,14 +1379,18 @@ UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8
if( pElites )
*pElites = ubNumElites;
return( ubNumAdmins + ubNumTroops + ubNumElites );
if( pTanks )
*pTanks = ubNumTanks;
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks );
}
UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites )
UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks )
{
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks=0;
//if the player blew up the fan, add a ton of enemies to the sector
//1st Tunnel Sector
@@ -1402,8 +1420,10 @@ UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT
*pTroops = ubNumTroops;
if( pElites )
*pElites = ubNumElites;
if( pTanks )
*pTanks = ubNumTanks;
return( ubNumAdmins + ubNumTroops + ubNumElites );
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks );
}
@@ -2166,7 +2186,7 @@ BOOLEAN HandleAddEnemiesToSectorPlayerIsntIn( INT16 sSaiSector, UINT8 ubNumEnemi
gubEnemyEncounterCode = ENEMY_INVASION_CODE;
}
SetNumberJa25EnemiesInSector( sSectorX, sSectorY, bSectorZ, 0, ubNumEnemies, 0 );
SetNumberJa25EnemiesInSector( sSectorX, sSectorY, bSectorZ, 0, ubNumEnemies, 0, 0 );
SetThisSectorAsEnemyControlled( sSectorX, sSectorY, bSectorZ, FALSE );
@@ -2211,7 +2231,7 @@ if ( gGameUBOptions.pJA2UB == TRUE )
if( gJa25AiSectorStruct[ sSaiSector ].bSectorZ == 0 )
{
pGroup = CreateNewEnemyGroupDepartingFromSector( sSector, 0, ubNumEnemies, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( sSector, 0, ubNumEnemies, 0, 0 );
if( sGridNo != -1 )
{
@@ -2241,7 +2261,7 @@ if ( gGameUBOptions.pJA2UB == TRUE )
Ja25SAI_DetermineWhichLevelToAttackFrom( sSaiSector, &sSector, &bLevel );
//underground, we have to specify
pGroup = CreateNewEnemyGroupDepartingFromSectorUsingZLevel( sSector, bLevel, 0, ubNumEnemies, 0 );//was sSector
pGroup = CreateNewEnemyGroupDepartingFromSectorUsingZLevel( sSector, bLevel, 0, ubNumEnemies, 0, 0 );//was sSector
// pGroup->pEnemyGroup->ubTroopsInBattle = ubNumEnemies;
}
@@ -2802,6 +2822,7 @@ void SetH11NumEnemiesInSector()
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks=0;
// SEC_H11:
{
@@ -2829,7 +2850,7 @@ void SetH11NumEnemiesInSector()
break;
}
SetNumberJa25EnemiesInSurfaceSector( SEC_H11, ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SEC_H11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
}
}
+4 -4
View File
@@ -188,12 +188,12 @@ BOOLEAN ShouldEnemiesBeAddedToInitialSector();
void InitJa25StrategicAi();
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
void InitJa25SaveStruct();
void InitJa25StrategicAiBloodcats( );
extern void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
extern void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
BOOLEAN SaveJa25SaveInfoToSaveGame( HWFILE hFile );
BOOLEAN LoadJa25SaveInfoFromSavedGame( HWFILE hFile );
@@ -305,7 +305,7 @@ enum
extern BOOLEAN gfEnemyShouldImmediatelySeekThePlayer;
//extern INT32 giNumJA25Sectors;
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
void SetJa25SectorOwnedStatus( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, BOOLEAN fPlayerOwned );
INT8 GetTheFurthestSectorPlayerOwns();
void Ja25_UpdateTimeOfEndOfLastBattle( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
@@ -317,7 +317,7 @@ void JA25_HandleUpdateOfStrategicAi();
void SetEnemiesToFindThePlayerMercs();
void HandleSayingDontStayToLongWarningInSectorH8();
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
#ifdef JA2BETAVERSION
BOOLEAN InitJa25StrategicAiDecisions( BOOLEAN fLoadedGame );
+9 -2
View File
@@ -1996,6 +1996,7 @@ static int l_AddEnemyToUnderGroundSector(lua_State *L)
UINT8 ubNumAdmins = lua_tointeger(L,4);
UINT8 ubNumTroops = lua_tointeger(L,5);
UINT8 ubNumElites = lua_tointeger(L,6);
UINT8 ubNumTanks = lua_tointeger(L,7);
UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( sSectorX, sSectorY, bLevel );
@@ -2004,6 +2005,7 @@ static int l_AddEnemyToUnderGroundSector(lua_State *L)
pSector->ubNumAdmins = ubNumAdmins;
pSector->ubNumTroops = ubNumTroops;
pSector->ubNumElites = ubNumElites;
pSector->ubNumTanks = ubNumTanks;
}
}
@@ -2191,6 +2193,7 @@ int i;
UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0;
UINT8 ubNumElites=0;
UINT8 ubNumTanks=0;
INT16 sSectorX;
INT16 sSectorY;
@@ -2202,8 +2205,9 @@ INT16 sSectorY;
if (i == 3 ) ubNumAdmins = lua_tointeger(L,i);
if (i == 4 ) ubNumTroops = lua_tointeger(L,i);
if (i == 5 ) ubNumElites = lua_tointeger(L,i);
if (i == 6 ) ubNumTanks = lua_tointeger(L,i);
}
SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites );
SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks );
return 0;
}
@@ -4360,7 +4364,8 @@ UINT16 y = -1;
UINT16 z = -1;
UINT8 TROOPS_ILOSC = 0;
UINT8 ELITA_ILOSC = 0;
UINT CREATURE_ILOSC = 0;
UINT8 CREATURE_ILOSC = 0;
UINT8 TANKS_ILOSC = 0;
if ( ( x >= 1 || x <= 16 ) && ( y >= 1 || y <= 16 ) )
{
@@ -4370,12 +4375,14 @@ UINT CREATURE_ILOSC = 0;
TROOPS_ILOSC = lh_getIntegerFromTable(L, "Troops");
ELITA_ILOSC = lh_getIntegerFromTable(L, "Elite");
CREATURE_ILOSC = lh_getIntegerFromTable(L, "Creature");
TANKS_ILOSC = lh_getIntegerFromTable(L, "Tanks");
//z = lh_getIntegerFromTable(L, "SectorZ");
SectorInfo[ (UINT8)SECTOR( x, y ) ].ubNumTroops = TROOPS_ILOSC;
SectorInfo[ (UINT8)SECTOR( x, y ) ].ubNumElites = ELITA_ILOSC;
SectorInfo[ (UINT8)SECTOR( x, y ) ].ubNumCreatures = CREATURE_ILOSC;
SectorInfo[ (UINT8)SECTOR( x, y ) ].ubNumTanks = TANKS_ILOSC;
}
return 0;
+10 -10
View File
@@ -2689,39 +2689,39 @@ void MobileMilitiaDeserters(INT16 sMapX, INT16 sMapY, BOOLEAN fDeleteEquip, BOOL
///////////////////////
// check enemy presence to decide if mobiles are threatened and some will desert.
// Note: cant use NumEnemiesInFiveSectors() as it does not work for omerta or when reinforcements are deactivated, also it uses generateDirectionInfo(), which is used for militia movement.
UINT8 eAdmins = 0, eTroops = 0, eElites = 0;
UINT8 eAdmins = 0, eTroops = 0, eElites = 0, eTanks = 0;
//enemies in current sector
GetNumberOfEnemiesInSector( sMapX, sMapY, &eAdmins, &eTroops, &eElites );
GetNumberOfEnemiesInSector( sMapX, sMapY, &eAdmins, &eTroops, &eElites, &eTanks );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) )
enemiesNear = TRUE;
if ( ( sMapX > MINIMUM_VALID_X_COORDINATE ) && !enemiesNear )
{
//left side
GetNumberOfEnemiesInSector( sMapX - 1, sMapY, &eAdmins, &eTroops, &eElites );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) )
GetNumberOfEnemiesInSector( sMapX - 1, sMapY, &eAdmins, &eTroops, &eElites, &eTanks );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE;
}
if ( ( sMapX < MAXIMUM_VALID_X_COORDINATE ) && !enemiesNear)
{
//right side
GetNumberOfEnemiesInSector( sMapX + 1, sMapY, &eAdmins, &eTroops, &eElites );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) )
GetNumberOfEnemiesInSector( sMapX + 1, sMapY, &eAdmins, &eTroops, &eElites, &eTanks );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE;
}
if ( ( sMapY > MINIMUM_VALID_Y_COORDINATE ) && !enemiesNear )
{
//top side
GetNumberOfEnemiesInSector( sMapX, sMapY - 1, &eAdmins, &eTroops, &eElites );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) )
GetNumberOfEnemiesInSector( sMapX, sMapY - 1, &eAdmins, &eTroops, &eElites, &eTanks );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE;
}
if ( ( sMapY < MAXIMUM_VALID_Y_COORDINATE ) && !enemiesNear)
{
//bottom side
GetNumberOfEnemiesInSector( sMapX, sMapY + 1, &eAdmins, &eTroops, &eElites );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) )
GetNumberOfEnemiesInSector( sMapX, sMapY + 1, &eAdmins, &eTroops, &eElites, &eTanks );
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE;
}
+6 -3
View File
@@ -221,12 +221,13 @@ void ValidateAndCorrectInBattleCounters( GROUP *pLocGroup )
{
if( pGroup->ubSectorX == pLocGroup->ubSectorX && pGroup->ubSectorY == pLocGroup->ubSectorY )
{
if( pGroup->pEnemyGroup->ubAdminsInBattle || pGroup->pEnemyGroup->ubTroopsInBattle || pGroup->pEnemyGroup->ubElitesInBattle )
if( pGroup->pEnemyGroup->ubAdminsInBattle || pGroup->pEnemyGroup->ubTroopsInBattle || pGroup->pEnemyGroup->ubElitesInBattle || pGroup->pEnemyGroup->ubTanksInBattle )
{
ubInvalidGroups++;
pGroup->pEnemyGroup->ubAdminsInBattle = 0;
pGroup->pEnemyGroup->ubTroopsInBattle = 0;
pGroup->pEnemyGroup->ubElitesInBattle = 0;
pGroup->pEnemyGroup->ubTanksInBattle = 0;
}
}
}
@@ -244,17 +245,19 @@ void ValidateAndCorrectInBattleCounters( GROUP *pLocGroup )
L"If you can provide information on how a previous battle was resolved here or nearby patrol "
L"(auto resolve, tactical battle, cheat keys, or retreat),"
L"please forward that info (no data files necessary) as well as the following code (very important): "
L"G(%02d:%c%d_b%d) A(%02d:%02d) T(%02d:%02d) E(%02d:%02d) C(%02d:%02d)",
L"G(%02d:%c%d_b%d) A(%02d:%02d) T(%02d:%02d) E(%02d:%02d) C(%02d:%02d) Ta(%02d:%02d)",
ubInvalidGroups, pLocGroup->ubSectorY + 'A' - 1, pLocGroup->ubSectorX, pLocGroup->ubSectorZ,
pSector->ubNumAdmins, pSector->ubAdminsInBattle,
pSector->ubNumTroops, pSector->ubTroopsInBattle,
pSector->ubNumElites, pSector->ubElitesInBattle,
pSector->ubNumCreatures, pSector->ubCreaturesInBattle );
pSector->ubNumCreatures, pSector->ubCreaturesInBattle,
pSector->ubNumTanks, pSector->ubTanksInBattle );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0;
pSector->ubCreaturesInBattle = 0;
pSector->ubTanksInBattle = 0;
}
}
#endif
+162 -50
View File
@@ -161,7 +161,7 @@ UINT8 NumHostilesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
pSector = FindUnderGroundSector( sSectorX, sSectorY, (UINT8)sSectorZ );
if( pSector )
{
ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures);
ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures + pSector->ubNumTanks);
}
}
else
@@ -171,7 +171,7 @@ UINT8 NumHostilesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
//Count stationary hostiles
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures);
ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures + pSector->ubNumTanks);
//Count mobile enemies
pGroup = gpGroupList;
@@ -205,7 +205,7 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
pSector = FindUnderGroundSector( sSectorX, sSectorY, (UINT8)sSectorZ );
if( pSector )
{
ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
}
}
else
@@ -215,7 +215,7 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
//Count stationary enemies
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
//Count mobile enemies
pGroup = gpGroupList;
@@ -254,7 +254,7 @@ UINT8 NumEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubNumTroops = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
ubNumTroops = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
if (is_networked)
ubNumTroops += numenemyLAN((UINT8)sSectorX,(UINT8)sSectorY ); //hayden
@@ -295,7 +295,7 @@ UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
return( 0 );
}
return (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
return (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
}
UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
@@ -322,13 +322,13 @@ UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
if( pSector->ubGarrisonID == ROADBLOCK )
{ //consider these troops as mobile troops even though they are in a garrison
ubNumTroops += (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
ubNumTroops += (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
}
return ubNumTroops;
}
void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites )
void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks )
{
GROUP *pGroup;
SECTORINFO *pSector;
@@ -338,7 +338,7 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
//Now count the number of mobile groups in the sector.
*pubNumTroops = *pubNumElites = *pubNumAdmins = 0;
*pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumTanks = 0;
pGroup = gpGroupList;
while( pGroup )
{
@@ -347,6 +347,7 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
*pubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
*pubNumElites += pGroup->pEnemyGroup->ubNumElites;
*pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
*pubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
}
pGroup = pGroup->next;
}
@@ -357,11 +358,12 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
*pubNumAdmins += pSector->ubNumAdmins;
*pubNumTroops += pSector->ubNumTroops;
*pubNumElites += pSector->ubNumElites;
*pubNumTanks += pSector->ubNumTanks;
}
}
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites )
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks )
{
GROUP *pGroup;
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
@@ -370,7 +372,7 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
//Now count the number of mobile groups in the sector.
*pubNumTroops = *pubNumElites = *pubNumAdmins = 0;
*pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumTanks = 0;
pGroup = gpGroupList;
while( pGroup )
{
@@ -379,13 +381,14 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
*pubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
*pubNumElites += pGroup->pEnemyGroup->ubNumElites;
*pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
*pubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
}
pGroup = pGroup->next;
}
}
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites )
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks )
{
SECTORINFO *pSector;
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
@@ -398,19 +401,21 @@ void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8
*pubNumAdmins = pSector->ubNumAdmins;
*pubNumTroops = pSector->ubNumTroops;
*pubNumElites = pSector->ubNumElites;
*pubNumTanks = pSector->ubNumTanks;
}
void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites )
void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks )
{
UINT8 ubNumAdmins, ubNumTroops, ubNumElites;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks;
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites );
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks );
GetNumberOfMobileEnemiesInSector( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites );
GetNumberOfMobileEnemiesInSector( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
*pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites;
*pubNumTanks += ubNumTanks;
}
void EndTacticalBattleForEnemy()
@@ -426,6 +431,7 @@ void EndTacticalBattleForEnemy()
pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0;
}
else if( !gbWorldSectorZ )
{
@@ -435,6 +441,7 @@ void EndTacticalBattleForEnemy()
pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0;
pSector->ubNumCreatures = 0;
pSector->ubCreaturesInBattle = 0;
}
@@ -453,6 +460,7 @@ void EndTacticalBattleForEnemy()
pGroup->pEnemyGroup->ubTroopsInBattle = 0;
pGroup->pEnemyGroup->ubElitesInBattle = 0;
pGroup->pEnemyGroup->ubAdminsInBattle = 0;
pGroup->pEnemyGroup->ubTanksInBattle = 0;
}
pGroup = pGroup->next;
}
@@ -502,8 +510,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
SECTORINFO *pSector;
GROUP *pGroup;
SOLDIERTYPE *pSoldier;
unsigned ubNumAdmins, ubNumTroops, ubNumElites;
unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops;
unsigned ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks;
unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops, ubTotalTanks;
unsigned totalCountOfStationaryEnemies = 0;
unsigned totalCountOfMobileEnemies = 0;
int sNumSlots;
@@ -557,7 +565,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
pGroup->ubSectorY == gpBattleGroup->ubSectorY &&
!pGroup->pEnemyGroup->ubAdminsInBattle &&
!pGroup->pEnemyGroup->ubTroopsInBattle &&
!pGroup->pEnemyGroup->ubElitesInBattle )
!pGroup->pEnemyGroup->ubElitesInBattle &&
!pGroup->pEnemyGroup->ubTanksInBattle)
{
HandleArrivalOfReinforcements( pGroup );
}
@@ -592,11 +601,12 @@ BOOLEAN PrepareEnemyForSectorBattle()
// OJW - 20090403 - override max ai in co-op
if (is_networked && is_server && gMaxEnemiesEnabled == 1)
{
float totalEnemies = (float)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
float totalEnemies = (float)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
ubTotalAdmins = (unsigned int)(((float)pSector->ubNumAdmins / totalEnemies) * mapMaximumNumberOfEnemies);
ubTotalTroops = (unsigned int)(((float)pSector->ubNumTroops / totalEnemies) * mapMaximumNumberOfEnemies);
ubTotalElites = (unsigned int)(((float)pSector->ubNumElites / totalEnemies) * mapMaximumNumberOfEnemies);
totalEnemies = (float)(ubTotalAdmins + ubTotalTroops + ubTotalElites);
ubTotalTanks = (unsigned int)(((float)pSector->ubNumTanks / totalEnemies) * mapMaximumNumberOfEnemies);
totalEnemies = (float)(ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks);
// take care of any rounding losses
while (totalEnemies < mapMaximumNumberOfEnemies)
@@ -609,9 +619,11 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSector->ubNumAdmins = ubTotalAdmins;
pSector->ubNumTroops = ubTotalTroops;
pSector->ubNumElites = ubTotalElites;
pSector->ubNumTanks = ubTotalTanks;
pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0;
}
else
{
@@ -636,19 +648,22 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSector->ubNumAdmins = ubTotalAdmins;
pSector->ubNumTroops = ubTotalTroops;
pSector->ubNumElites = ubTotalElites;
pSector->ubNumTanks = ubTotalTanks;
pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0;
}
else
{
ubTotalAdmins = pSector->ubNumAdmins - pSector->ubAdminsInBattle;
ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle;
ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle;
ubTotalTanks = pSector->ubNumTanks - pSector->ubTanksInBattle;
}
}
totalCountOfStationaryEnemies = ubTotalAdmins + ubTotalTroops + ubTotalElites;
totalCountOfStationaryEnemies = ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks;
if( totalCountOfStationaryEnemies > mapMaximumNumberOfEnemies )
{
@@ -662,19 +677,21 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubTotalAdmins = min( mapMaximumNumberOfEnemies, ubTotalAdmins );
ubTotalTroops = min( mapMaximumNumberOfEnemies-ubTotalAdmins, ubTotalTroops );
ubTotalElites = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops, ubTotalElites );
ubTotalTanks = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops-ubTotalElites, ubTotalTanks );
}
pSector->ubAdminsInBattle += ubTotalAdmins;
pSector->ubTroopsInBattle += ubTotalTroops;
pSector->ubElitesInBattle += ubTotalElites;
pSector->ubTanksInBattle += ubTotalTanks;
#ifdef JA2TESTVERSION
if( gfOverrideSector )
{
//if there are no troops in the current groups, then we're done.
if( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites )
if( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalTanks )
return FALSE;
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites );
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks );
ValidateEnemiesHaveWeapons();
return TRUE;
}
@@ -701,7 +718,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
//Subtract the total number of stationary enemies from the available slots, as stationary forces take
//precendence in combat. The mobile forces that could also be in the same sector are considered later if
//all the slots fill up.
sNumSlots -= ubTotalAdmins + ubTotalTroops + ubTotalElites;
sNumSlots -= ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks;
//Now, process all of the groups and search for both enemy and player groups in the sector.
//For enemy groups, we fill up the slots until we have none left or all of the groups have been
@@ -756,6 +773,20 @@ BOOLEAN PrepareEnemyForSectorBattle()
pGroup->pEnemyGroup->ubElitesInBattle += ubNumElites;
ubTotalElites += ubNumElites;
}
if( sNumSlots > 0 )
{ //Add tanks
AssertGE(pGroup->pEnemyGroup->ubNumTanks, pGroup->pEnemyGroup->ubTanksInBattle);
ubNumTanks = pGroup->pEnemyGroup->ubNumTanks - pGroup->pEnemyGroup->ubTanksInBattle;
sNumSlots -= ubNumTanks;
if( sNumSlots < 0 )
{ //adjust the value to zero
ubNumTanks += sNumSlots;
sNumSlots = 0;
gfPendingEnemies = TRUE;
}
pGroup->pEnemyGroup->ubTanksInBattle += ubNumTanks;
ubTotalTanks += ubNumTanks;
}
//NOTE:
//no provisions for profile troop leader or retreat groups yet.
}
@@ -777,12 +808,12 @@ BOOLEAN PrepareEnemyForSectorBattle()
}
//if there are no troops in the current groups, then we're done.
if( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites )
if( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalTanks )
{
return FALSE;
}
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites );
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks );
//Now, we have to go through all of the enemies in the new map, and assign their respective groups if
//in a mobile group, but only for the ones that were assigned from the
@@ -797,7 +828,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubNumAdmins = pGroup->pEnemyGroup->ubAdminsInBattle;
ubNumTroops = pGroup->pEnemyGroup->ubTroopsInBattle;
ubNumElites = pGroup->pEnemyGroup->ubElitesInBattle;
unsigned num = ubNumAdmins + ubNumTroops + ubNumElites;
ubNumTanks = pGroup->pEnemyGroup->ubTanksInBattle;
unsigned num = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks;
unsigned firstSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
unsigned lastSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
@@ -863,12 +895,22 @@ BOOLEAN PrepareEnemyForSectorBattle()
}
}
break;
case SOLDIER_CLASS_TANK:
if( ubNumTanks )
{
num--;
sNumSlots--;
ubNumTanks--;
pSoldier->ubGroupID = pGroup->ubGroupID;
}
break;
}
}
AssertEQ( ubNumElites , 0);
AssertEQ( ubNumTroops , 0);
AssertEQ( ubNumAdmins , 0);
AssertEQ( ubNumTanks , 0);
AssertEQ( num , 0);
}
pGroup = pGroup->next;
@@ -882,7 +924,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
BOOLEAN PrepareEnemyForUndergroundBattle()
{
UNDERGROUND_SECTORINFO *pUnderground;
unsigned ubTotalAdmins, ubTotalTroops, ubTotalElites;
unsigned ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks;
pUnderground = gpUndergroundSectorInfoHead;
while( pUnderground )
@@ -896,13 +938,15 @@ BOOLEAN PrepareEnemyForUndergroundBattle()
ubTotalAdmins = (UINT8)(pUnderground->ubNumAdmins - pUnderground->ubAdminsInBattle);
ubTotalTroops = (UINT8)(pUnderground->ubNumTroops - pUnderground->ubTroopsInBattle);
ubTotalElites = (UINT8)(pUnderground->ubNumElites - pUnderground->ubElitesInBattle);
ubTotalTanks = (UINT8)(pUnderground->ubNumTanks - pUnderground->ubTanksInBattle);
pUnderground->ubAdminsInBattle += ubTotalAdmins;
pUnderground->ubTroopsInBattle += ubTotalTroops;
pUnderground->ubElitesInBattle += ubTotalElites;
AddSoldierInitListEnemyDefenceSoldiers( pUnderground->ubNumAdmins, pUnderground->ubNumTroops, pUnderground->ubNumElites );
pUnderground->ubTanksInBattle += ubTotalTanks;
AddSoldierInitListEnemyDefenceSoldiers( pUnderground->ubNumAdmins, pUnderground->ubNumTroops, pUnderground->ubNumElites, pUnderground->ubNumTanks );
ValidateEnemiesHaveWeapons();
}
return ( ( BOOLEAN) ( pUnderground->ubNumAdmins + pUnderground->ubNumTroops + pUnderground->ubNumElites > 0 ) );
return ( ( BOOLEAN) ( pUnderground->ubNumAdmins + pUnderground->ubNumTroops + pUnderground->ubNumElites + pUnderground->ubNumTanks > 0 ) );
}
pUnderground = pUnderground->next;
}
@@ -990,6 +1034,34 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
}
}
break;
case TANK_CAR:
if( !pSoldier->bSectorZ )
{
pSector = &SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ];
if( pSector->ubNumTanks )
{
pSector->ubNumTanks--;
}
if( pSector->ubTanksInBattle )
{
pSector->ubTanksInBattle--;
}
}
else
{
UNDERGROUND_SECTORINFO *pUnderground;
pUnderground = FindUnderGroundSector( (UINT8)pSoldier->sSectorX, (UINT8)pSoldier->sSectorY, (UINT8)pSoldier->bSectorZ );
Assert( pUnderground );
if( pUnderground->ubNumTanks)
{
pUnderground->ubNumTanks--;
}
if( pUnderground->ubTanksInBattle )
{
pUnderground->ubTanksInBattle--;
}
}
break;
}
if( pSoldier->aiData.bNeutral || pSoldier->bTeam != ENEMY_TEAM && pSoldier->bTeam != CREATURE_TEAM )
@@ -1130,7 +1202,7 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
// }
#ifdef JA2BETAVERSION
ubTotalEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
ubTotalEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
#endif
switch( pSoldier->ubSoldierClass )
@@ -1243,7 +1315,7 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
{ //basement level (UNDERGROUND_SECTORINFO)
UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
#ifdef JA2BETAVERSION
UINT32 ubTotalEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
UINT32 ubTotalEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
#endif
if( pSector )
{
@@ -1387,7 +1459,7 @@ void AddPossiblePendingEnemiesToBattle()
#endif
UINT8 ubSlots, ubNumAvailable;
UINT8 ubNumElites, ubNumTroops, ubNumAdmins;
UINT8 ubNumElites, ubNumTroops, ubNumAdmins, ubNumTanks;
UINT8 ubNumGroupsInSector;
UINT8 ubGroupIndex;
GROUP *pGroup;
@@ -1473,11 +1545,11 @@ void AddPossiblePendingEnemiesToBattle()
//return;
}
if( pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins )
if( pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks )
{
ubNumElites = ubNumTroops = ubNumAdmins = 0;
ubNumElites = ubNumTroops = ubNumAdmins = ubNumTanks = 0;
ubNumAvailable = pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins - pSector->ubElitesInBattle - pSector->ubTroopsInBattle - pSector->ubAdminsInBattle;
ubNumAvailable = pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks - pSector->ubElitesInBattle - pSector->ubTroopsInBattle - pSector->ubAdminsInBattle - pSector->ubTanksInBattle;
while( ubNumAvailable && ubSlots )
{
// So they just magically appear out of nowhere from the edge?
@@ -1504,6 +1576,13 @@ void AddPossiblePendingEnemiesToBattle()
ubSlots--;
ubNumAdmins++;
}
else if( pSector->ubTanksInBattle < pSector->ubNumTanks )
{ //Add a tank
pSector->ubTanksInBattle++;
ubNumAvailable--;
ubSlots--;
ubNumTanks++;
}
else
{
AssertMsg( 0, "AddPossiblePendingEnemiesToBattle(): Logic Error -- by Kris" );
@@ -1511,7 +1590,7 @@ void AddPossiblePendingEnemiesToBattle()
}
if( ubNumAdmins || ubNumTroops || ubNumElites )
if( ubNumAdmins || ubNumTroops || ubNumElites || ubNumTanks )
{ //This group has contributed forces, then add them now, because different
//groups appear on different sides of the map.
UINT8 ubStrategicInsertionCode = ubPredefinedInsertionCode;
@@ -1552,7 +1631,7 @@ void AddPossiblePendingEnemiesToBattle()
if( ubStrategicInsertionCode < INSERTION_CODE_NORTH ||ubStrategicInsertionCode > INSERTION_CODE_WEST )
ubStrategicInsertionCode = INSERTION_CODE_NORTH + Random( 4 );
AddEnemiesToBattle( 0, ubStrategicInsertionCode, ubNumAdmins, ubNumTroops, ubNumElites, FALSE );
AddEnemiesToBattle( 0, ubStrategicInsertionCode, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, FALSE );
gfPendingEnemies = TRUE;
}
}
@@ -1582,7 +1661,7 @@ void AddPossiblePendingEnemiesToBattle()
pGroup = pGroupInSectorList[ ubGroupIndex];
// Flugente fix: check for underflow...
UINT8 currentgroupsize = pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle;
UINT8 currentgroupsize = pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle + pGroup->pEnemyGroup->ubTanksInBattle;
if ( currentgroupsize > pGroup->ubGroupSize )
ubNumAvailable = 0;
else
@@ -1643,19 +1722,25 @@ void AddPossiblePendingEnemiesToBattle()
{ //Add an elite troop
pGroup->pEnemyGroup->ubElitesInBattle++;
ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 1, FALSE );
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 1, 0, FALSE );
}
else if( pGroup->pEnemyGroup->ubTroopsInBattle < pGroup->pEnemyGroup->ubNumTroops )
{ //Add a regular troop.
pGroup->pEnemyGroup->ubTroopsInBattle++;
ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, FALSE );
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, FALSE );
}
else if( pGroup->pEnemyGroup->ubAdminsInBattle < pGroup->pEnemyGroup->ubNumAdmins )
{ //Add an admin troop
pGroup->pEnemyGroup->ubAdminsInBattle++;
ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 1, 0, 0, FALSE );
AddEnemiesToBattle( pGroup, ubInsertionCode, 1, 0, 0, 0, FALSE );
}
else if( pGroup->pEnemyGroup->ubTanksInBattle < pGroup->pEnemyGroup->ubNumTanks )
{ //Add a tank
pGroup->pEnemyGroup->ubTanksInBattle++;
ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 1, FALSE );
}
else
{
@@ -1664,7 +1749,7 @@ void AddPossiblePendingEnemiesToBattle()
pGroup->pEnemyGroup->ubTroopsInBattle++;
ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, FALSE );
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, FALSE );
}
}
@@ -1733,7 +1818,7 @@ void NotifyPlayersOfNewEnemies()
}
}
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, BOOLEAN fMagicallyAppeared )
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, BOOLEAN fMagicallyAppeared )
{
SOLDIERTYPE *pSoldier;
MAPEDGEPOINTINFO MapEdgepointInfo;
@@ -1768,6 +1853,8 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
pSector->ubTroopsInBattle += ubNumTroops;
pSector->ubNumElites += ubNumElites;
pSector->ubElitesInBattle += ubNumElites;
pSector->ubNumTanks += ubNumTanks;
pSector->ubTanksInBattle += ubNumTanks;
}
else
{
@@ -1780,13 +1867,15 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
pSector->ubTroopsInBattle += ubNumTroops;
pSector->ubNumElites += ubNumElites;
pSector->ubElitesInBattle += ubNumElites;
pSector->ubNumTanks += ubNumTanks;
pSector->ubTanksInBattle += ubNumTanks;
}
}
//Because the enemies magically appeared, have one of our soldiers say something...
NotifyPlayersOfNewEnemies();
}
ubTotalSoldiers = ubNumAdmins + ubNumTroops + ubNumElites;
ubTotalSoldiers = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks;
#ifdef JA2UB
if( gsGridNoForMapEdgePointInfo != -1 )
@@ -1814,10 +1903,10 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
}
else
{
ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, (UINT8)(ubNumAdmins+ubNumElites+ubNumTroops) );
ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, (UINT8)(ubNumAdmins+ubNumElites+ubNumTroops+ubNumTanks) );
}
#else
ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, (UINT8)(ubNumAdmins+ubNumElites+ubNumTroops) );
ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, (UINT8)(ubNumAdmins+ubNumElites+ubNumTroops+ubNumTanks) );
#endif
@@ -1893,6 +1982,29 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
}
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 );
}
else if( ubNumTanks && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks) && ubNumberOfVehicles < 9 )
{
ubNumTanks--;
ubTotalSoldiers--;
Assert(pSoldier = TacticalCreateEnemyTank());
if( pGroup )
{
pSoldier->ubGroupID = pGroup->ubGroupID;
}
pSoldier->ubInsertionDirection = bDesiredDirection;
//Setup the position
if( ubCurrSlot < MapEdgepointInfo.ubNumPoints )
{ //using an edgepoint
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = MapEdgepointInfo.sGridNo[ ubCurrSlot++ ];
}
else
{ //no edgepoints left, so put him at the entrypoint.
pSoldier->ubStrategicInsertionCode = ubStrategicInsertionCode;
}
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 );
}
// HEADROCK HAM 3.2: enemy reinforcements arrive with 0 APs.
if (gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 1 || gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 2)
{
@@ -2454,7 +2566,7 @@ BOOLEAN CheckPendingEnemies()
{
if( gbWorldSectorZ ) return FALSE;
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
if( (pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins) > ( pSector->ubElitesInBattle + pSector->ubTroopsInBattle + pSector->ubAdminsInBattle) )
if( (pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks) > ( pSector->ubElitesInBattle + pSector->ubTroopsInBattle + pSector->ubAdminsInBattle + pSector->ubTanksInBattle) )
return TRUE;
for (GROUP *pGroup = gpGroupList; pGroup; pGroup = pGroup->next)
{
@@ -2462,7 +2574,7 @@ BOOLEAN CheckPendingEnemies()
&& !pGroup->fVehicle
&& pGroup->ubSectorX == gWorldSectorX
&& pGroup->ubSectorY == gWorldSectorY
&& pGroup->ubGroupSize > pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle)
&& pGroup->ubGroupSize > pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle + pGroup->pEnemyGroup->ubTanksInBattle)
return TRUE;
}
return FALSE;
+5 -5
View File
@@ -22,10 +22,10 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
UINT8 NumEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks );
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks );
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks );
void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks );
//Called when entering a sector so the campaign AI can automatically insert the
//correct number of troops of each type based on the current number in the sector
@@ -33,7 +33,7 @@ void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAd
BOOLEAN PrepareEnemyForSectorBattle();
BOOLEAN PrepareEnemyForUndergroundBattle();
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, BOOLEAN fMagicallyAppeared );
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, BOOLEAN fMagicallyAppeared );
void AddPossiblePendingEnemiesToBattle();
void EndTacticalBattleForEnemy();
+26 -13
View File
@@ -31,19 +31,20 @@
UINT8 gubReinforcementMinEnemyStaticGroupSize = 12;
UINT32 guiMilitiaReinforceTurn = 0, guiMilitiaArrived = 0;//dnl ch68 090913
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites )
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks )
{
UINT8 ubNumAdmins, ubNumTroops, ubNumElites;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks;
UINT16 pusMoveDir[4][3];
UINT8 ubDirNumber, ubIndex;
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites );
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks );
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites );
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
*pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites;
*pubNumTanks += ubNumTanks;
if( !gGameExternalOptions.gfAllowReinforcements )
return;
@@ -55,9 +56,9 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
{
GetNumberOfStationaryEnemiesInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites );
GetNumberOfStationaryEnemiesInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
while( ubNumElites + ubNumTroops + ubNumAdmins > gubReinforcementMinEnemyStaticGroupSize)
while( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks > gubReinforcementMinEnemyStaticGroupSize)
{
if( ubNumElites )
{
@@ -72,23 +73,29 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
*pubNumAdmins += 1;
ubNumAdmins--;
}
else if( ubNumTanks )
{
*pubNumTanks += 1;
ubNumTanks--;
}
}
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites );
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
*pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites;
*pubNumTanks += ubNumTanks;
}
}
UINT8 NumEnemiesInFiveSectors( INT16 sMapX, INT16 sMapY )
{
UINT8 ubNumAdmins, ubNumTroops, ubNumElites;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks;
GetNumberOfEnemiesInFiveSectors( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites );
GetNumberOfEnemiesInFiveSectors( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
return ubNumAdmins + ubNumTroops + ubNumElites;
return ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks;
}
BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY )
@@ -279,19 +286,25 @@ UINT8 DoReinforcementAsPendingEnemy( INT16 sMapX, INT16 sMapY )
(pThisSector->ubNumElites)++;
(pSector->ubNumElites)--;
(pThisSector->ubElitesInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 1, FALSE );
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 1, 0, FALSE );
}else if( pSector->ubNumTroops )
{
(pThisSector->ubNumTroops)++;
(pSector->ubNumTroops)--;
(pThisSector->ubTroopsInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 1, 0, FALSE );
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 1, 0, 0, FALSE );
}else if( pSector->ubNumAdmins )
{
(pThisSector->ubNumAdmins)++;
(pSector->ubNumAdmins)--;
(pThisSector->ubAdminsInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 1, 0, 0, FALSE );
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 1, 0, 0, 0, FALSE );
}else if( pSector->ubNumTanks )
{
(pThisSector->ubNumTanks)++;
(pSector->ubNumTanks)--;
(pThisSector->ubTanksInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 0, 1, FALSE );
}
return (UINT8)pusMoveDir[ ubIndex ][ 2 ];
+1 -1
View File
@@ -6,7 +6,7 @@
//For Autoresolve (mostly)
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites );
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks );
BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY );
UINT8 GetAdjacentSectors( UINT8 pSectors[4], INT16 sSectorX, INT16 sSectorY );
UINT8 CountAllMilitiaInFiveSectors(INT16 sMapX, INT16 sMapY);
+221 -92
View File
@@ -462,7 +462,7 @@ void SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup );
void ClearPreviousAIGroupAssignment( GROUP *pGroup );
void CalcNumTroopsBasedOnComposition( UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 ubTotal, INT32 iCompositionID );
void CalcNumTroopsBasedOnComposition( UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 ubTotal, INT32 iCompositionID );
void ConvertGroupTroopsToComposition( GROUP *pGroup, INT32 iCompositionID );
void RemoveSoldiersFromGarrisonBasedOnComposition( INT32 iGarrisonID, UINT8 ubSize );
@@ -556,7 +556,7 @@ INT32 GarrisonReinforcementsRequested( INT32 iGarrisonID, UINT8 *pubExtraReinfor
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
pSector = &SectorInfo[ gGarrisonGroup[ iGarrisonID ].ubSectorID ];
iExistingForces = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
iExistingForces = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
iReinforcementsRequested = gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bDesiredPopulation - iExistingForces;
//Record how many of the reinforcements are additionally provided due to being denied in the past. This will grow
@@ -592,7 +592,7 @@ INT32 ReinforcementsAvailable( INT32 iGarrisonID )
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
pSector = &SectorInfo[ gGarrisonGroup[ iGarrisonID ].ubSectorID ];
iReinforcementsAvailable = pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins;
iReinforcementsAvailable = pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins + pSector->ubNumTanks;
iReinforcementsAvailable -= gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bDesiredPopulation;
switch( gGarrisonGroup[ iGarrisonID ].ubComposition )
@@ -673,7 +673,7 @@ BOOLEAN AdjacentSectorIsImportantAndUndefended( UINT8 ubSectorID )
pSector = &SectorInfo[ ubSectorID ];
if( pSector->ubNumTroops || pSector->ubNumElites || pSector->ubNumAdmins )
if( pSector->ubNumTroops || pSector->ubNumElites || pSector->ubNumAdmins || pSector->ubNumTanks )
{
return FALSE;
}
@@ -815,7 +815,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic2");
}
}
#ifdef JA2BETAVERSION
if( pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites != pGroup->ubGroupSize ||
if( pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumTanks != pGroup->ubGroupSize ||
pGroup->ubGroupSize > iMaxEnemyGroupSize )
{
SAIReportError( L"Strategic AI: Internal error (bad group populations). Please send PRIOR save file and Strategic Decisions.txt." );
@@ -1120,6 +1120,7 @@ void InitStrategicAI()
SECTORINFO *pSector = NULL;
GROUP *pGroup;
UINT8 ubNumTroops;
UINT8 ubNumTanks;
INT32 iPercentElitesBonus;
INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3");
@@ -1432,9 +1433,9 @@ void InitStrategicAI()
}
// fill up deficit with admins if total enemies less than min enemy group size
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites < gubMinEnemyGroupSize )
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks < gubMinEnemyGroupSize )
{
pSector->ubNumAdmins = gubMinEnemyGroupSize - pSector->ubNumTroops - pSector->ubNumElites;
pSector->ubNumAdmins = gubMinEnemyGroupSize - pSector->ubNumTroops - pSector->ubNumElites - pSector->ubNumTanks;
}
//Calculate weight (range is -20 to +20 before multiplier).
@@ -1472,11 +1473,22 @@ void InitStrategicAI()
{ //Add this patrol group now.
ubNumTroops = (UINT8)(gPatrolGroup[ i ].bSize + Random( 3 ) - 1);
ubNumTroops = (UINT8)max( gubMinEnemyGroupSize, min( iMaxEnemyGroupSize, ubNumTroops ) );
ubNumTanks = 0;
if( ubNumTroops && gGameExternalOptions.fArmyUsesTanksInPatrols )
{
if( Random( 10 ) < gGameOptions.ubDifficultyLevel && i != 3 && i != 4)
{
ubNumTroops--;
ubNumTanks++;
}
}
//ubNumTroops = (UINT8)max( gubMinEnemyGroupSize, min( MAX_STRATEGIC_TEAM_SIZE, gPatrolGroup[ i ].bSize + Random( 3 ) - 1 ) );
//Note on adding patrol groups...
//The patrol group can't actually start on the first waypoint, so we set it to the second way
//point for initialization, and then add the waypoints from 0 up
pGroup = CreateNewEnemyGroupDepartingFromSector( gPatrolGroup[ i ].ubSectorID[ 1 ], 0, ubNumTroops, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( gPatrolGroup[ i ].ubSectorID[ 1 ], 0, ubNumTroops, 0, ubNumTanks );
Assert( pGroup );
if( i == 3 || i == 4 )
@@ -1788,7 +1800,8 @@ BOOLEAN HandlePlayerGroupNoticedByPatrolGroup( GROUP *pPlayerGroup, GROUP *pEnem
ubSectorID = (BOOLEAN)SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY );
usOffensePoints = pEnemyGroup->pEnemyGroup->ubNumAdmins * 2 +
pEnemyGroup->pEnemyGroup->ubNumTroops * 4 +
pEnemyGroup->pEnemyGroup->ubNumElites * 6;
pEnemyGroup->pEnemyGroup->ubNumElites * 6 +
pEnemyGroup->pEnemyGroup->ubNumTanks * 20;
if( PlayerForceTooStrong( ubSectorID, usOffensePoints, &usDefencePoints ) )
{
RequestAttackOnSector( ubSectorID, usDefencePoints );
@@ -1838,7 +1851,8 @@ void HandlePlayerGroupNoticedByGarrison( GROUP *pPlayerGroup, UINT8 ubSectorID )
}
usOffensePoints = pSector->ubNumAdmins * 2 +
pSector->ubNumTroops * 4 +
pSector->ubNumElites * 6;
pSector->ubNumElites * 6 +
pSector->ubNumTanks * 20;
if( PlayerForceTooStrong( ubSectorID, usOffensePoints, &usDefencePoints ) )
{
RequestAttackOnSector( ubSectorID, usDefencePoints );
@@ -1850,7 +1864,7 @@ void HandlePlayerGroupNoticedByGarrison( GROUP *pPlayerGroup, UINT8 ubSectorID )
if( pSector->ubGarrisonID != NO_GARRISON )
{
//Decide whether or not they will attack them with some of the troops.
ubEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
ubEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
iReinforcementsApproved = (ubEnemies - gArmyComp[ gGarrisonGroup[ pSector->ubGarrisonID ].ubComposition ].bDesiredPopulation );
else
@@ -1858,7 +1872,7 @@ void HandlePlayerGroupNoticedByGarrison( GROUP *pPlayerGroup, UINT8 ubSectorID )
if( iReinforcementsApproved*2 > pPlayerGroup->ubGroupSize*3 && iReinforcementsApproved > gubMinEnemyGroupSize )
{ //Then enemy's available outnumber the player by at least 3:2, so attack them.
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSectorID, 0, (UINT8)iReinforcementsApproved, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSectorID, 0, (UINT8)iReinforcementsApproved, 0, 0 );
ConvertGroupTroopsToComposition( pGroup, gGarrisonGroup[ pSector->ubGarrisonID ].ubComposition );
@@ -1866,12 +1880,12 @@ void HandlePlayerGroupNoticedByGarrison( GROUP *pPlayerGroup, UINT8 ubSectorID )
RemoveSoldiersFromGarrisonBasedOnComposition( pSector->ubGarrisonID, pGroup->ubGroupSize );
if( pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins > iMaxEnemyGroupSize )
if( pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins + pSector->ubNumTanks > iMaxEnemyGroupSize )
{
#ifdef JA2BETAVERSION
LogStrategicEvent( "ERROR: Sector %c%d now has %d enemies (max %d).",
gGarrisonGroup[ pSector->ubGarrisonID ].ubSectorID / 16 + 'A' , gGarrisonGroup[ pSector->ubGarrisonID ].ubSectorID % 16,
pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins, iMaxEnemyGroupSize );
pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins + pSector->ubNumTanks, iMaxEnemyGroupSize );
#endif
}
@@ -1893,7 +1907,8 @@ BOOLEAN HandleMilitiaNoticedByPatrolGroup( UINT8 ubSectorID, GROUP *pEnemyGroup
UINT8 ubSectorY = (UINT8)(ubSectorID / 16) + 1;
usOffensePoints = pEnemyGroup->pEnemyGroup->ubNumAdmins * 2 +
pEnemyGroup->pEnemyGroup->ubNumTroops * 4 +
pEnemyGroup->pEnemyGroup->ubNumElites * 6;
pEnemyGroup->pEnemyGroup->ubNumElites * 6 +
pEnemyGroup->pEnemyGroup->ubNumTanks * 20;
if( PlayerForceTooStrong( ubSectorID, usOffensePoints, &usDefencePoints ) )
{
RequestAttackOnSector( ubSectorID, usDefencePoints );
@@ -2043,11 +2058,11 @@ void HandleEmptySectorNoticedByGarrison( UINT8 ubGarrisonSectorID, UINT8 ubEmpty
//An opportunity has arisen, where the enemy has noticed an important sector that is undefended.
pSector = &SectorInfo[ ubGarrisonSectorID ];
ubAvailableTroops = pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins;
ubAvailableTroops = pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins + pSector->ubNumTanks;
if( ubAvailableTroops >= gubMinEnemyGroupSize * 2 )
{ //split group into two groups, and move one of the groups to the next sector.
pGroup = CreateNewEnemyGroupDepartingFromSector( ubGarrisonSectorID, 0, (UINT8)(ubAvailableTroops / 2), 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( ubGarrisonSectorID, 0, (UINT8)(ubAvailableTroops / 2), 0, 0 );
ConvertGroupTroopsToComposition( pGroup, gGarrisonGroup[ ubDstGarrisonID ].ubComposition );
RemoveSoldiersFromGarrisonBasedOnComposition( ubSrcGarrisonID, pGroup->ubGroupSize );
gGarrisonGroup[ ubDstGarrisonID ].ubPendingGroupID = pGroup->ubGroupID;
@@ -2145,11 +2160,12 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
pSector->ubNumAdmins = (UINT8)(pSector->ubNumAdmins + pGroup->pEnemyGroup->ubNumAdmins);
pSector->ubNumTroops = (UINT8)(pSector->ubNumTroops + pGroup->pEnemyGroup->ubNumTroops);
pSector->ubNumElites = (UINT8)(pSector->ubNumElites + pGroup->pEnemyGroup->ubNumElites);
pSector->ubNumTanks = (UINT8)(pSector->ubNumTanks + pGroup->pEnemyGroup->ubNumTanks);
#ifdef JA2BETAVERSION
LogStrategicEvent( "%d reinforcements have arrived to garrison sector %c%d",
pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTroops +
pGroup->pEnemyGroup->ubNumElites, pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX );
pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumTanks, pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX );
#endif
if( IsThisSectorASAMSector( pGroup->ubSectorX, pGroup->ubSectorY, 0 ) )
{
@@ -2218,10 +2234,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
pPatrolGroup->pEnemyGroup->ubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
pPatrolGroup->pEnemyGroup->ubNumElites += pGroup->pEnemyGroup->ubNumElites;
pPatrolGroup->pEnemyGroup->ubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
pPatrolGroup->ubGroupSize += (UINT8)(pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins );
pPatrolGroup->pEnemyGroup->ubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
pPatrolGroup->ubGroupSize += (UINT8)(pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks);
#ifdef JA2BETAVERSION
LogStrategicEvent( "%d reinforcements have joined patrol group at sector %c%d (new size: %d)",
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins,
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks,
pPatrolGroup->ubSectorY + 'A' - 1, pPatrolGroup->ubSectorX, pPatrolGroup->ubGroupSize );
#endif
if( pPatrolGroup->ubGroupSize > iMaxEnemyGroupSize )
@@ -2255,11 +2272,17 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
pGroup->pEnemyGroup->ubNumElites--;
pPatrolGroup->pEnemyGroup->ubNumElites--;
}
else if( pGroup->pEnemyGroup->ubNumTanks )
{
pGroup->pEnemyGroup->ubNumTanks--;
pPatrolGroup->pEnemyGroup->ubNumTanks--;
}
}
pPatrolGroup->ubGroupSize = iMaxEnemyGroupSize;
Assert( pPatrolGroup->pEnemyGroup->ubNumAdmins +
pPatrolGroup->pEnemyGroup->ubNumTroops +
pPatrolGroup->pEnemyGroup->ubNumElites == iMaxEnemyGroupSize );
pPatrolGroup->pEnemyGroup->ubNumElites +
pPatrolGroup->pEnemyGroup->ubNumTanks == iMaxEnemyGroupSize );
}
RemovePGroup( pGroup );
RecalculatePatrolWeight( i );
@@ -2285,7 +2308,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
#ifdef JA2BETAVERSION
LogStrategicEvent( "%d soldiers have arrived to patrol area near sector %c%d",
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins,
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks,
pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX );
#endif
RecalculatePatrolWeight( i );
@@ -2451,7 +2474,7 @@ BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup )
return FALSE;
}
pSector = &SectorInfo[ SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY-1 ) ];
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
if( ubNumEnemies && pSector->ubGarrisonID != NO_GARRISON && AttemptToNoticeAdjacentGroupSucceeds() )
{
HandlePlayerGroupNoticedByGarrison( pPlayerGroup, (UINT8)SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY-1 ) );
@@ -2483,7 +2506,7 @@ BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup )
return FALSE;
}
pSector = &SectorInfo[ SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY+1 ) ];
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
if( ubNumEnemies && pSector->ubGarrisonID != NO_GARRISON && AttemptToNoticeAdjacentGroupSucceeds() )
{
HandlePlayerGroupNoticedByGarrison( pPlayerGroup, (UINT8)SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY+1 ) );
@@ -2499,7 +2522,7 @@ BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup )
return FALSE;
}
pSector = &SectorInfo[ SECTOR( pPlayerGroup->ubSectorX-1, pPlayerGroup->ubSectorY ) ];
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
if( ubNumEnemies && pSector->ubGarrisonID != NO_GARRISON && AttemptToNoticeAdjacentGroupSucceeds() )
{
HandlePlayerGroupNoticedByGarrison( pPlayerGroup, (UINT8)SECTOR( pPlayerGroup->ubSectorX-1, pPlayerGroup->ubSectorY ) );
@@ -2563,7 +2586,7 @@ void CheckEnemyControlledSector( UINT8 ubSectorID )
}
}
}
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites )
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks )
{
//The sector is still controlled, so look around to see if there are any players nearby.
@@ -2718,7 +2741,7 @@ void RecalculateGarrisonWeight( INT32 iGarrisonID )
pSector = &SectorInfo[ gGarrisonGroup[ iGarrisonID ].ubSectorID ];
iDesiredPop = gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bDesiredPopulation;
iCurrentPop = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
iCurrentPop = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
iPriority = gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bPriority;
//First, remove the previous weight from the applicable field.
@@ -2954,7 +2977,7 @@ void SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoints
#ifdef JA2BETAVERSION
LogStrategicEvent( "%d troops have been reassigned from %c%d to garrison sector %c%d",
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins,
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks,
pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX,
ubDstSectorY + 'A' - 1, ubDstSectorX );
#endif
@@ -3013,7 +3036,7 @@ void SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoints
}
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, (UINT8)iReinforcementsApproved, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, (UINT8)iReinforcementsApproved, 0, 0 );
ConvertGroupTroopsToComposition( pGroup, gGarrisonGroup[ iDstGarrisonID ].ubComposition );
pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY );
//Madd: unlimited reinforcements?
@@ -3023,7 +3046,7 @@ void SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoints
pGroup->ubMoveType = ONE_WAY;
gGarrisonGroup[ iDstGarrisonID ].ubPendingGroupID = pGroup->ubGroupID;
ubGroupSize = (UINT8)(pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins);
ubGroupSize = (UINT8)(pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks);
if( ubNumExtraReinforcements )
{
@@ -3099,13 +3122,13 @@ void SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoints
}
}
pGroup = CreateNewEnemyGroupDepartingFromSector( gGarrisonGroup[ iSrcGarrisonID ].ubSectorID, 0, (UINT8)iReinforcementsApproved, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( gGarrisonGroup[ iSrcGarrisonID ].ubSectorID, 0, (UINT8)iReinforcementsApproved, 0, 0 );
ConvertGroupTroopsToComposition( pGroup, gGarrisonGroup[ iDstGarrisonID ].ubComposition );
RemoveSoldiersFromGarrisonBasedOnComposition( iSrcGarrisonID, pGroup->ubGroupSize );
pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY );
pGroup->ubMoveType = ONE_WAY;
gGarrisonGroup[ iDstGarrisonID ].ubPendingGroupID = pGroup->ubGroupID;
ubGroupSize = (UINT8)( pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins );
ubGroupSize = (UINT8)( pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks );
if( ubNumExtraReinforcements )
{
@@ -3167,7 +3190,7 @@ void SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup )
#ifdef JA2BETAVERSION
LogStrategicEvent( "%d troops have been reassigned from %c%d to reinforce patrol group covering sector %c%d",
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins,
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks,
pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX,
ubDstSectorY + 'A' - 1, ubDstSectorX );
#endif
@@ -3181,7 +3204,7 @@ void SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup )
if( iRandom < giReinforcementPool )
{ //use the pool and send the requested amount from SECTOR P3 (queen's palace)
iReinforcementsApproved = min( iReinforcementsRequested, giReinforcementPool );
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, (UINT8)iReinforcementsApproved, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, (UINT8)iReinforcementsApproved, 0, 0 );
pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY );
//Madd: unlimited reinforcements?
@@ -3192,7 +3215,7 @@ void SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup )
#ifdef JA2BETAVERSION
LogStrategicEvent( "%d troops have been sent from palace to patrol area near sector %c%d",
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins,
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks,
ubDstSectorY + 'A' - 1, ubDstSectorX );
#endif
@@ -3219,7 +3242,7 @@ void SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup )
iReinforcementsAvailable = ReinforcementsAvailable( iSrcGarrisonID );
//Send the lowest of the two: number requested or number available
iReinforcementsApproved = min( iReinforcementsRequested, iReinforcementsAvailable );
pGroup = CreateNewEnemyGroupDepartingFromSector( gGarrisonGroup[ iSrcGarrisonID ].ubSectorID, 0, (UINT8)iReinforcementsApproved, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( gGarrisonGroup[ iSrcGarrisonID ].ubSectorID, 0, (UINT8)iReinforcementsApproved, 0, 0 );
pGroup->ubOriginalSector = (UINT8)SECTOR( ubDstSectorX, ubDstSectorY );
gPatrolGroup[ iPatrolID ].ubPendingGroupID = pGroup->ubGroupID;
@@ -3227,7 +3250,7 @@ void SendReinforcementsForPatrol( INT32 iPatrolID, GROUP **pOptionalGroup )
#ifdef JA2BETAVERSION
LogStrategicEvent( "%d troops have been sent from garrison sector %c%d to patrol area near sector %c%d",
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins,
pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks,
ubSrcSectorY + 'A' - 1, ubSrcSectorX,
ubDstSectorY + 'A' - 1, ubDstSectorX );
#endif
@@ -4284,6 +4307,10 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
UINT8 stagesector0, stagesector1, stagesector2, stagesector3;
UINT8 assaultsector0, assaultsector1, assaultsector2, assaultsector3;
unsigned ubNumSoldiers;
UINT8 ubNumTanks = 0;
UINT32 grouptroops[4] = {0,0,0,0};
UINT32 groupelites[4] = {0,0,0,0};
UINT32 grouptanks[4] = {0,0,0,0};
switch( usActionCode )
{
@@ -4366,11 +4393,25 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, ubNumSoldiers, ubNumSoldiers - ubNumSoldiers / gGameOptions.ubDifficultyLevel );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, ubNumSoldiers, ubNumSoldiers - ubNumSoldiers / gGameOptions.ubDifficultyLevel );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, ubNumSoldiers, ubNumSoldiers - ubNumSoldiers / gGameOptions.ubDifficultyLevel );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, ubNumSoldiers, ubNumSoldiers - ubNumSoldiers / gGameOptions.ubDifficultyLevel );
// anv: replace one of soldiers with tank
for( UINT8 ubCounter = 0; ubCounter < 4; ubCounter++ )
{
grouptroops[ubCounter] = ubNumSoldiers;
grouptanks[ubCounter] = 0;
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
if( Random(10) < gGameOptions.ubDifficultyLevel )
{
grouptroops[ubCounter]--;
grouptanks[ubCounter]++;
}
}
}
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[0], grouptroops[0] - grouptroops[0] / gGameOptions.ubDifficultyLevel, grouptanks[0] );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[1], grouptroops[1] - grouptroops[1] / gGameOptions.ubDifficultyLevel, grouptanks[1] );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[2], grouptroops[2] - grouptroops[2] / gGameOptions.ubDifficultyLevel, grouptanks[2] );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[3], grouptroops[3] - grouptroops[3] / gGameOptions.ubDifficultyLevel, grouptanks[3] );
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID )
{
@@ -4416,13 +4457,27 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
}
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
UINT32 grouptroops = ubNumSoldiers;
UINT32 groupelites = 0;
if ( gGameOptions.ubDifficultyLevel > 0 )
groupelites = ubNumSoldiers - ubNumSoldiers / gGameOptions.ubDifficultyLevel;
UINT32 totalusedsoldiers = 4 * min(grouptroops + groupelites, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
// anv: replace one of soldiers with tank
for( UINT8 ubCounter = 0; ubCounter < 4; ubCounter++ )
{
grouptroops[ubCounter] = ubNumSoldiers;
grouptanks[ubCounter] = 0;
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
if( Random(10) < gGameOptions.ubDifficultyLevel )
{
grouptroops[ubCounter]--;
grouptanks[ubCounter]++;
}
}
groupelites[ubCounter] = 0;
if ( gGameOptions.ubDifficultyLevel > 0 )
groupelites[ubCounter] = grouptroops[ubCounter] - grouptroops[ubCounter] / gGameOptions.ubDifficultyLevel;
}
//UINT32 totalusedsoldiers = 4 * min(grouptroops + groupelites + ubNumTanks, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
UINT32 totalusedsoldiers = 4 * min(grouptroops[0] + groupelites[0] + grouptanks[0], (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
switch( usActionCode )
{
@@ -4542,10 +4597,10 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
break;
}
pGroup0 = CreateNewEnemyGroupDepartingFromSector( stagesector0, 0, grouptroops, groupelites );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( stagesector1, 0, grouptroops, groupelites );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( stagesector2, 0, grouptroops, groupelites );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( stagesector3, 0, grouptroops, groupelites );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( stagesector0, 0, grouptroops[0], groupelites[0], grouptanks[0] );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( stagesector1, 0, grouptroops[1], groupelites[1], grouptanks[1] );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( stagesector2, 0, grouptroops[2], groupelites[2], grouptanks[2] );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( stagesector3, 0, grouptroops[3], groupelites[3], grouptanks[3] );
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID )
{
@@ -4599,6 +4654,13 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
ubNumSoldiers--;
ubNumTanks++;
}
UINT32 grouptroops = ubNumSoldiers;
UINT32 groupelites = 0;
if ( gGameOptions.ubDifficultyLevel > 0 )
@@ -4614,12 +4676,12 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
if ( !(SectorInfo[ ubSourceSectorID ].ubNumTroops > 0) )
ubSourceSectorID = SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, grouptroops, groupelites );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, grouptroops, groupelites );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, grouptroops, groupelites );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, grouptroops, groupelites, ubNumTanks );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, grouptroops, groupelites, ubNumTanks );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, grouptroops, groupelites, ubNumTanks );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, 0 );
totalusedsoldiers += min(grouptroops + groupelites, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
totalusedsoldiers += min(grouptroops + groupelites + ubNumTanks, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID )
{
@@ -4671,12 +4733,12 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
assaultsector3 = SEC_H9;
}
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, 0 );
totalusedsoldiers += min(grouptroops + groupelites, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
totalusedsoldiers += min(grouptroops + groupelites + ubNumTanks, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID )
{
@@ -4711,12 +4773,12 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
if ( !(SectorInfo[ ubSourceSectorID ].ubNumTroops > 0) )
ubSourceSectorID = SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
totalusedsoldiers += min(grouptroops + groupelites, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
totalusedsoldiers += min(grouptroops + groupelites + ubNumTanks, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID )
{
@@ -4751,10 +4813,10 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
if ( !(SectorInfo[ ubSourceSectorID ].ubNumTroops > 0) )
ubSourceSectorID = SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
totalusedsoldiers += min(grouptroops + groupelites, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
@@ -4792,10 +4854,10 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
// If we were to use our usual staging points in Meduna, the Chitzena and Grumm attacks would very likely combine in Grumm Mine. 2 double attacks in the same sector are a 'bit' too much
if ( (SectorInfo[ ubSourceSectorID ].ubNumTroops > 0) )
{
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops, groupelites, ubNumTanks );
totalusedsoldiers += min(grouptroops + groupelites, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
@@ -4839,11 +4901,22 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
ubSectorID = (UINT8)STRATEGIC_INDEX_TO_SECTOR_INFO( sWorldSectorLocationOfFirstBattle );
pSector = &SectorInfo[ ubSectorID ];
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 4);
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, ubNumSoldiers, 0 );
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
if( Random( 10 ) < gGameOptions.ubDifficultyLevel )
{
ubNumSoldiers--;
ubNumTanks++;
}
}
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, ubNumSoldiers, 0, ubNumTanks );
//Madd: unlimited reinforcements?
if ( !gfUnlimitedTroops )
giReinforcementPool -= ubNumSoldiers;
giReinforcementPool -= ( ubNumSoldiers + ubNumTanks );
giReinforcementPool = max( giReinforcementPool, 0 );
@@ -4915,6 +4988,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
unsigned adminsThisSquad = 0;
unsigned troopsThisSquad = 0;
unsigned elitesThisSquad = 0;
unsigned tanksThisSquad = 0;
if (direness < 25) {
adminsThisSquad = soldiersThisSquad * (40 + Random(20)) / 100; // 40-60% of total
troopsThisSquad = soldiersThisSquad - adminsThisSquad; // The rest
@@ -4932,7 +5006,16 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
elitesThisSquad = soldiersThisSquad - troopsThisSquad - adminsThisSquad; // The rest
}
Assert(adminsThisSquad + troopsThisSquad + elitesThisSquad == soldiersThisSquad);
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, adminsThisSquad, soldiersThisSquad, elitesThisSquad );
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
if( Random( 10 * 100 ) < gGameOptions.ubDifficultyLevel * direness )
{
elitesThisSquad--;
tanksThisSquad++;
}
}
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, adminsThisSquad, soldiersThisSquad, elitesThisSquad, tanksThisSquad );
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID ) {
pGroup0->pEnemyGroup->ubIntention = STAGE;
if (groupCnt > 2) {
@@ -5001,7 +5084,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
unsigned elitesThisSquad = soldiersThisSquad - troopsThisSquad - adminsThisSquad; // The rest
Assert(adminsThisSquad + troopsThisSquad + elitesThisSquad == soldiersThisSquad);
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, adminsThisSquad, soldiersThisSquad, elitesThisSquad );
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, adminsThisSquad, soldiersThisSquad, elitesThisSquad, 0 );
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID ) {
pGroup0->pEnemyGroup->ubIntention = STAGE;
if (groupCnt > 2) {
@@ -5018,7 +5101,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
case NPC_ACTION_SEND_SOLDIERS_TO_OMERTA:
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 6); //6, 12, or 18 based on difficulty.
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, ubNumSoldiers, (UINT8)(ubNumSoldiers/7) ); //add 1 elite to normal, and 2 for hard
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, ubNumSoldiers, (UINT8)(ubNumSoldiers/7), 0 ); //add 1 elite to normal, and 2 for hard
ubNumSoldiers = (UINT8)(ubNumSoldiers + ubNumSoldiers / 7);
//Madd: unlimited reinforcements
@@ -5048,8 +5131,18 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
if ( !gfUnlimitedTroops )
giReinforcementPool -= ubNumSoldiers;
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
if( Random( 10 * 100 ) < gGameOptions.ubDifficultyLevel * HighestPlayerProgressPercentage() )
{
ubNumSoldiers--;
ubNumTanks++;
}
}
giReinforcementPool = max( giReinforcementPool, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, 0, ubNumSoldiers );
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, 0, ubNumSoldiers, ubNumTanks );
MoveSAIGroupToSector( &pGroup, ubSectorID, STAGE, REINFORCEMENTS );
// WANNE: This should fix the assertion in UC in the cutscene!
@@ -5313,16 +5406,16 @@ void InvestigateSector( UINT8 ubSectorID )
switch( i )
{
case 0: //NORTH
AddEnemiesToBattle( NULL, INSERTION_CODE_NORTH, ubAdmins[i], ubTroops[i], ubElites[i], TRUE );
AddEnemiesToBattle( NULL, INSERTION_CODE_NORTH, ubAdmins[i], ubTroops[i], ubElites[i], 0, TRUE );
break;
case 1: //EAST
AddEnemiesToBattle( NULL, INSERTION_CODE_EAST, ubAdmins[i], ubTroops[i], ubElites[i], TRUE );
AddEnemiesToBattle( NULL, INSERTION_CODE_EAST, ubAdmins[i], ubTroops[i], ubElites[i], 0, TRUE );
break;
case 2: //SOUTH
AddEnemiesToBattle( NULL, INSERTION_CODE_SOUTH, ubAdmins[i], ubTroops[i], ubElites[i], TRUE );
AddEnemiesToBattle( NULL, INSERTION_CODE_SOUTH, ubAdmins[i], ubTroops[i], ubElites[i], 0, TRUE );
break;
case 3: //WEST
AddEnemiesToBattle( NULL, INSERTION_CODE_WEST, ubAdmins[i], ubTroops[i], ubElites[i], TRUE );
AddEnemiesToBattle( NULL, INSERTION_CODE_WEST, ubAdmins[i], ubTroops[i], ubElites[i], 0, TRUE );
break;
}
}
@@ -5561,7 +5654,7 @@ void RequestHighPriorityGarrisonReinforcements( INT32 iGarrisonID, UINT8 ubSoldi
if( pGroup->ubGroupSize > ubSoldiersRequested && pGroup->ubGroupSize - ubSoldiersRequested >= gubMinEnemyGroupSize )
{ //Split the group, and send to location
GROUP *pNewGroup;
pNewGroup = CreateNewEnemyGroupDepartingFromSector( (UINT8)SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ), 0, 0, 0 );
pNewGroup = CreateNewEnemyGroupDepartingFromSector( (UINT8)SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ), 0, 0, 0, 0 );
//Transfer the troops from group to new group
if( pGroup->pEnemyGroup->ubNumTroops >= ubSoldiersRequested )
{ //All of them are troops, so do it in one shot.
@@ -5604,6 +5697,16 @@ void RequestHighPriorityGarrisonReinforcements( INT32 iGarrisonID, UINT8 ubSoldi
ValidateLargeGroup( pGroup );
ValidateLargeGroup( pNewGroup );
}
else if( pGroup->pEnemyGroup->ubNumTanks )
{
pGroup->pEnemyGroup->ubNumTanks--;
pGroup->ubGroupSize--;
pNewGroup->pEnemyGroup->ubNumTanks++;
pNewGroup->ubGroupSize++;
ubSoldiersRequested--;
ValidateLargeGroup( pGroup );
ValidateLargeGroup( pNewGroup );
}
else
{
AssertMsg( 0, "Strategic AI group transfer error. KM : 0" );
@@ -5632,7 +5735,7 @@ void RequestHighPriorityGarrisonReinforcements( INT32 iGarrisonID, UINT8 ubSoldi
}
else
{ //There are no groups that have enough troops. Send a new force from the palace instead.
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, ubSoldiersRequested, 0 );
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, ubSoldiersRequested, 0, 0 );
pGroup->ubMoveType = ONE_WAY;
pGroup->pEnemyGroup->ubIntention = REINFORCEMENTS;
gGarrisonGroup[ iGarrisonID ].ubPendingGroupID = pGroup->ubGroupID;
@@ -5669,7 +5772,7 @@ void MassFortifyTowns()
for( i = 0; i < giGarrisonArraySize; i++ )
{
pSector = &SectorInfo[ gGarrisonGroup[ i ].ubSectorID ];
ubNumTroops = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
ubNumTroops = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
ubDesiredTroops = (UINT8)gArmyComp[ gGarrisonGroup[ i ].ubComposition ].bDesiredPopulation;
if( ubNumTroops < ubDesiredTroops )
@@ -5708,7 +5811,7 @@ void RenderAIViewerGarrisonInfo( INT32 x, INT32 y, SECTORINFO *pSector )
{
INT32 iDesired, iSurplus;
iDesired = gArmyComp[ gGarrisonGroup[ pSector->ubGarrisonID ].ubComposition ].bDesiredPopulation;
iSurplus = pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumElites - iDesired;
iSurplus = pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumElites + pSector->ubNumTanks- iDesired;
SetFontForeground( FONT_WHITE );
if( iSurplus >= 0 )
{
@@ -5779,7 +5882,7 @@ BOOLEAN GarrisonCanProvideMinimumReinforcements( INT32 iGarrisonID )
pSector = &SectorInfo[ gGarrisonGroup[ iGarrisonID ].ubSectorID ];
iAvailable = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
iAvailable = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
iDesired = gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bDesiredPopulation;
if( iAvailable - iDesired >= gubMinEnemyGroupSize )
@@ -5811,7 +5914,7 @@ BOOLEAN GarrisonRequestingMinimumReinforcements( INT32 iGarrisonID )
}
pSector = &SectorInfo[ gGarrisonGroup[ iGarrisonID ].ubSectorID ];
iAvailable = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
iAvailable = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
iDesired = gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bDesiredPopulation;
if( iDesired - iAvailable >= gubMinEnemyGroupSize )
@@ -5857,8 +5960,8 @@ void EliminateSurplusTroopsForGarrison( GROUP *pGroup, SECTORINFO *pSector )
INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic8");
iTotal = pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins +
pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins;
iTotal = pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks +
pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins + pSector->ubNumTanks;
if( iTotal <= iMaxEnemyGroupSize )
{
return;
@@ -5944,6 +6047,32 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic8");
iTotal = 0;
}
}
else if( pGroup->pEnemyGroup->ubNumTanks )
{
if( pGroup->pEnemyGroup->ubNumTanks < iTotal )
{
iTotal -= pGroup->pEnemyGroup->ubNumTanks;
pGroup->pEnemyGroup->ubNumTanks = 0;
}
else
{
pGroup->pEnemyGroup->ubNumTanks -= (UINT8)iTotal;
iTotal = 0;
}
}
else if( pSector->ubNumTanks )
{
if( pSector->ubNumTanks < iTotal )
{
iTotal -= pSector->ubNumTanks;
pSector->ubNumTanks = 0;
}
else
{
pSector->ubNumTanks -= (UINT8)iTotal;
iTotal = 0;
}
}
}
}
+10 -5
View File
@@ -695,7 +695,7 @@ BOOLEAN AddWaypointStrategicIDToPGroup( GROUP *pGroup, UINT32 uiSectorID )
//Enemy grouping functions -- private use by the strategic AI.
//............................................................
GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites )
GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks )
{
GROUP *pNew;
AssertMsg( uiSector >= 0 && uiSector <= 255, String( "CreateNewEnemyGroup with out of range value of %d", uiSector ) );
@@ -706,7 +706,7 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
AssertMsg( pNew->pEnemyGroup, "MemAlloc failure during enemy group creation." );
memset( pNew->pEnemyGroup, 0, sizeof( ENEMYGROUP ) );
// Make sure group is not bigger than allowed!
while (ubNumAdmins + ubNumTroops + ubNumElites > gGameExternalOptions.iMaxEnemyGroupSize)
while (ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks > gGameExternalOptions.iMaxEnemyGroupSize)
{
if (ubNumTroops)
{
@@ -716,10 +716,14 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
{
ubNumAdmins--;
}
else
else if (ubNumElites)
{
ubNumElites--;
}
else if (ubNumTanks)
{
ubNumTanks--;
}
}
pNew->pWaypoints = NULL;
pNew->ubSectorX = (UINT8)SECTORX( uiSector );
@@ -733,7 +737,8 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
pNew->pEnemyGroup->ubNumAdmins = ubNumAdmins;
pNew->pEnemyGroup->ubNumTroops = ubNumTroops;
pNew->pEnemyGroup->ubNumElites = ubNumElites;
pNew->ubGroupSize = (UINT8)(ubNumAdmins + ubNumTroops + ubNumElites);
pNew->pEnemyGroup->ubNumTanks = ubNumTanks;
pNew->ubGroupSize = (UINT8)(ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks);
pNew->ubTransportationMask = FOOT;
pNew->fVehicle = FALSE;
pNew->ubCreatedSectorID = pNew->ubOriginalSector;
@@ -5554,7 +5559,7 @@ BOOLEAN ScoutIsPresentInSquad( INT16 ubSectorNumX, INT16 ubSectorNumY )
}
#ifdef JA2UB
GROUP* CreateNewEnemyGroupDepartingFromSectorUsingZLevel( UINT32 uiSector, UINT8 ubSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites )
GROUP* CreateNewEnemyGroupDepartingFromSectorUsingZLevel( UINT32 uiSector, UINT8 ubSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks )
{
GROUP *pNew;
AssertMsg( uiSector >= 0 && uiSector <= 255, String( "CreateNewEnemyGroup with out of range value of %d", uiSector ) );
+5 -4
View File
@@ -71,8 +71,9 @@ typedef struct ENEMYGROUP
UINT8 ubTroopsInBattle; //number of soldiers currently in battle.
UINT8 ubElitesInBattle; //number of elite soldiers currently in battle.
// WDS - New AI
UINT8 numTanks;
INT8 bPadding[19];
UINT8 ubNumTanks;
UINT8 ubTanksInBattle;
INT8 bPadding[18];
}ENEMYGROUP;
//NOTE: ALL FLAGS ARE CLEARED WHENEVER A GROUP ARRIVES IN A SECTOR, OR ITS WAYPOINTS ARE
@@ -180,9 +181,9 @@ BOOLEAN SetGroupPatrolParameters( UINT8 ubGroupID, UINT8 ubRestAtFL, UINT8 ubRes
//Enemy grouping functions -- private use by the strategic AI.
//............................................................
GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
#ifdef JA2UB
GROUP* CreateNewEnemyGroupDepartingFromSectorUsingZLevel( UINT32 uiSector, UINT8 ubSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
GROUP* CreateNewEnemyGroupDepartingFromSectorUsingZLevel( UINT32 uiSector, UINT8 ubSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
#endif
//ARRIVALCALLBACK -- None of these functions should be called directly.
+1
View File
@@ -86,6 +86,7 @@ enum
ENEMY_RANK_ADMIN,
ENEMY_RANK_TROOP,
ENEMY_RANK_ELITE,
//ENEMY_RANK_TANK,
NUM_ENEMY_RANKS
};
+2
View File
@@ -88,6 +88,7 @@ BOOLEAN LuaUnderground::InitializeSectorList()
sectorData.getValue("numAdmins", s->ubNumAdmins);
sectorData.getValue("numTroops", s->ubNumTroops);
sectorData.getValue("numElites", s->ubNumElites);
sectorData.getValue("numTanks", s->ubNumTanks);
sectorData.getValue("numBloodcats", s->ubNumBloodcats);
sectorData.getValue("numCreatures", s->ubNumCreatures);
@@ -104,6 +105,7 @@ BOOLEAN LuaUnderground::InitializeSectorList()
m_log << "\t\tAdmins: " << static_cast<int>(s->ubNumAdmins) << LF;
m_log << "\t\tTroops: " << static_cast<int>(s->ubNumTroops) << LF;
m_log << "\t\tElites: " << static_cast<int>(s->ubNumElites) << LF;
m_log << "\t\tTanks: " << static_cast<int>(s->ubNumTanks) << LF;
m_log << "\t- Creature population" << LF;
m_log << "\t\tBloodcats: " << static_cast<int>(s->ubNumBloodcats) << LF;
m_log << "\t\tCrepitus: " << static_cast<int>(s->ubNumCreatures) << LF;
+3
View File
@@ -391,6 +391,7 @@ void CrippledVersionFailureToLoadMapCheck();
extern INT16 gsAINumAdmins;
extern INT16 gsAINumTroops;
extern INT16 gsAINumElites;
extern INT16 gsAINumTanks;
extern INT16 gsAINumCreatures;
//The wrapper time for EnterSector
BOOLEAN fStartNewFile = TRUE;
@@ -2550,6 +2551,7 @@ void PrepareLoadedSector()
pSector->ubNumAdmins = (UINT8)( gsAINumAdmins > 0 ? gsAINumAdmins : 0 );
pSector->ubNumTroops = (UINT8)( gsAINumTroops > 0 ? gsAINumTroops : 0 );
pSector->ubNumElites = (UINT8)( gsAINumElites > 0 ? gsAINumElites : 0 );
pSector->ubNumTanks = (UINT8)( gsAINumTanks > 0 ? gsAINumTanks : 0 );
pSector->ubNumCreatures = (UINT8)( gsAINumCreatures > 0 ? gsAINumCreatures : 0 );
}
else if( !gbWorldSectorZ )
@@ -2559,6 +2561,7 @@ void PrepareLoadedSector()
pSector->ubNumAdmins = (UINT8)( gsAINumAdmins > 0 ? gsAINumAdmins : 0 );
pSector->ubNumTroops = (UINT8)( gsAINumTroops > 0 ? gsAINumTroops : 0 );
pSector->ubNumElites = (UINT8)( gsAINumElites > 0 ? gsAINumElites : 0 );
pSector->ubNumTanks = (UINT8)( gsAINumTanks > 0 ? gsAINumTanks : 0 );
pSector->ubNumCreatures = (UINT8)( gsAINumCreatures > 0 ? gsAINumCreatures : 0 );
}
}