Expanded feature: Militia Strategic Movement is turned on with ALLOW_MILITIA_STRATEGIC_COMMAND set to TRUE and allows plotting paths for the militia just like for merc squads.

GameDir >= r2204 is recommended.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7727 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2015-02-08 22:11:16 +00:00
parent c94ac421ae
commit c9bcf90966
47 changed files with 3156 additions and 1322 deletions
+4
View File
@@ -2059,6 +2059,10 @@ void LoadGameExternalOptions()
// Moa: If enabled militia will spread when following or set to FALSE to fill up the destination group to maximum. // Moa: If enabled militia will spread when following or set to FALSE to fill up the destination group to maximum.
gGameExternalOptions.gfAllowMilitiaSpreadWhenFollowing = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_MILITIA_SPREAD_WHEN_FOLLOWING", FALSE); gGameExternalOptions.gfAllowMilitiaSpreadWhenFollowing = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_MILITIA_SPREAD_WHEN_FOLLOWING", FALSE);
//################# Militia Strategic Movement Settings ##################
gGameExternalOptions.fMilitiaStrategicCommand = iniReader.ReadBoolean("Militia Strategic Movement Settings", "ALLOW_MILITIA_STRATEGIC_COMMAND", FALSE );
// SANDRO - added several bonuses for militia // SANDRO - added several bonuses for militia
//################# Militia Strength Settings ################## //################# Militia Strength Settings ##################
+3
View File
@@ -445,6 +445,9 @@ typedef struct
UINT8 gbMobileMilitiaMaxActiveMode; //Moa: Used to check if the maximum of mobile militia is reached (for training/deserting). THIS IS A MODE UINT8 gbMobileMilitiaMaxActiveMode; //Moa: Used to check if the maximum of mobile militia is reached (for training/deserting). THIS IS A MODE
FLOAT gfpMobileMilitiaMaxActiveModifier; //Moa: const multiplier for the mode used (precalculated with MOBILE_MILITIA_MAX_ACTIVE_MODIFIER * MAX_MILITIA_PER_SECTOR). FLOAT gfpMobileMilitiaMaxActiveModifier; //Moa: const multiplier for the mode used (precalculated with MOBILE_MILITIA_MAX_ACTIVE_MODIFIER * MAX_MILITIA_PER_SECTOR).
// Flugente: militia movement
BOOLEAN fMilitiaStrategicCommand;
BOOLEAN gfAllowReinforcements; BOOLEAN gfAllowReinforcements;
BOOLEAN gfAllowReinforcementsOnlyInCity; BOOLEAN gfAllowReinforcementsOnlyInCity;
+2 -1
View File
@@ -21,6 +21,7 @@ extern CHAR16 zTrackingNumber[16];
// Keeps track of the saved game version. Increment the saved game version whenever // Keeps track of the saved game version. Increment the saved game version whenever
// you will invalidate the saved game file // you will invalidate the saved game file
#define MILITIA_PATH_PLOTTING 162 // Flugente: the player can plot militia paths in strategic, similar to player or helicopter travel
#define STRATEGIC_TEAM_GROUPS 161 // Flugente: a change to the GROUP-structure allows any team to have strategic movement groups #define STRATEGIC_TEAM_GROUPS 161 // Flugente: a change to the GROUP-structure allows any team to have strategic movement groups
#define PMC_WEBSITE 160 // Flugente: a new PMC allows us to hire trained militia #define PMC_WEBSITE 160 // Flugente: a new PMC allows us to hire trained militia
#define DISEASE_SYSTEM 159 // Flugente: mercs can get diseases #define DISEASE_SYSTEM 159 // Flugente: mercs can get diseases
@@ -80,7 +81,7 @@ extern CHAR16 zTrackingNumber[16];
#define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes #define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes
#define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system #define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system
#define SAVE_GAME_VERSION STRATEGIC_TEAM_GROUPS #define SAVE_GAME_VERSION MILITIA_PATH_PLOTTING
//#define RUSSIANGOLD //#define RUSSIANGOLD
#ifdef __cplusplus #ifdef __cplusplus
+56 -62
View File
@@ -3992,11 +3992,21 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing vehicle info"); ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing vehicle info");
goto FAILED_TO_SAVE; goto FAILED_TO_SAVE;
} }
#ifdef JA2BETAVERSION
SaveGameFilePosition( FileGetPos( hFile ), "Vehicle Information" );
#endif
#ifdef JA2BETAVERSION
SaveGameFilePosition( FileGetPos( hFile ), "Vehicle Information" );
#endif
// Flugente: militia movement
if ( !SaveMilitiaMovementInformationToSaveGameFile( hFile ) )
{
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing militia movement" );
goto FAILED_TO_SAVE;
}
#ifdef JA2BETAVERSION
SaveGameFilePosition( FileGetPos( hFile ), "Militia Movement" );
#endif
if( !SaveBulletStructureToSaveGameFile( hFile ) ) if( !SaveBulletStructureToSaveGameFile( hFile ) )
{ {
@@ -4019,9 +4029,6 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
#endif #endif
if( !SaveAirRaidInfoToSaveGameFile( hFile ) ) if( !SaveAirRaidInfoToSaveGameFile( hFile ) )
{ {
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing air raid info"); ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing air raid info");
@@ -5268,16 +5275,11 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
} }
uiRelEndPerc += 1; uiRelEndPerc += 1;
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Vehicle Information..." ); SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Vehicle Information..." );
RenderProgressBar( 0, 100 ); RenderProgressBar( 0, 100 );
uiRelStartPerc = uiRelEndPerc; uiRelStartPerc = uiRelEndPerc;
if( guiCurrentSaveGameVersion >= 22 ) if( guiCurrentSaveGameVersion >= 22 )
{ {
if( !LoadVehicleInformationFromSavedGameFile( hFile, guiCurrentSaveGameVersion ) ) if( !LoadVehicleInformationFromSavedGameFile( hFile, guiCurrentSaveGameVersion ) )
@@ -5286,20 +5288,33 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
FileClose( hFile ); FileClose( hFile );
return(FALSE); return(FALSE);
} }
#ifdef JA2BETAVERSION
LoadGameFilePosition( FileGetPos( hFile ), "Vehicle Information" ); #ifdef JA2BETAVERSION
#endif LoadGameFilePosition( FileGetPos( hFile ), "Vehicle Information" );
#endif
} }
uiRelEndPerc += 1;
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Militia Movement..." );
RenderProgressBar( 0, 100 );
uiRelStartPerc = uiRelEndPerc;
if ( !LoadMilitiaMovementInformationFromSavedGameFile( hFile, guiCurrentSaveGameVersion ) )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "LoadMilitiaMovementInformationFromSavedGameFile failed" ) );
FileClose( hFile );
return(FALSE);
}
#ifdef JA2BETAVERSION
LoadGameFilePosition( FileGetPos( hFile ), "Militia Movement" );
#endif
uiRelEndPerc += 1; uiRelEndPerc += 1;
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Bullet Information..." ); SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Bullet Information..." );
RenderProgressBar( 0, 100 ); RenderProgressBar( 0, 100 );
uiRelStartPerc = uiRelEndPerc; uiRelStartPerc = uiRelEndPerc;
if( guiCurrentSaveGameVersion >= 24 ) if( guiCurrentSaveGameVersion >= 24 )
{ {
if( !LoadBulletStructureFromSavedGameFile( hFile ) ) if( !LoadBulletStructureFromSavedGameFile( hFile ) )
@@ -6520,9 +6535,8 @@ BOOLEAN SaveSoldierStructure( HWFILE hFile )
UINT8 ubZero = 0; UINT8 ubZero = 0;
//Loop through all the soldier structs to save //Loop through all the soldier structs to save
for( cnt=0; cnt< TOTAL_SOLDIERS; cnt++) for( cnt=0; cnt< TOTAL_SOLDIERS; ++cnt)
{ {
//if the soldier isnt active, dont add them to the saved game file. //if the soldier isnt active, dont add them to the saved game file.
if( !Menptr[ cnt ].bActive ) if( !Menptr[ cnt ].bActive )
{ {
@@ -6533,7 +6547,6 @@ BOOLEAN SaveSoldierStructure( HWFILE hFile )
return(FALSE); return(FALSE);
} }
} }
else else
{ {
// Save the byte specifing to load the soldiers // Save the byte specifing to load the soldiers
@@ -6587,6 +6600,7 @@ BOOLEAN SaveSoldierStructure( HWFILE hFile )
} }
} }
} }
return( TRUE ); return( TRUE );
} }
@@ -6662,7 +6676,6 @@ BOOLEAN LoadSoldierStructure( HWFILE hFile )
if( !LoadMercPathToSoldierStruct( hFile, ubId ) ) if( !LoadMercPathToSoldierStruct( hFile, ubId ) )
return( FALSE ); return( FALSE );
// //
//do we have a KEY_ON_RING *pKeyRing; //do we have a KEY_ON_RING *pKeyRing;
// //
@@ -6694,7 +6707,6 @@ BOOLEAN LoadSoldierStructure( HWFILE hFile )
return(FALSE); return(FALSE);
} }
} }
} }
else else
{ {
@@ -6870,12 +6882,12 @@ BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile )
UINT8 *pData; UINT8 *pData;
UINT32 uiNumBytesRead; UINT32 uiNumBytesRead;
if(FileExists(pSrcFileName)) if(FileExists(pSrcFileName))
{ {
//open the file //open the file
hSrcFile = FileOpen( pSrcFileName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); hSrcFile = FileOpen( pSrcFileName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
} }
if( !hSrcFile ) if( !hSrcFile )
{ {
// Write the the size of the file to the saved game file // Write the the size of the file to the saved game file
@@ -6888,10 +6900,9 @@ BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile )
return( TRUE ); return( TRUE );
} }
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
guiNumberOfMapTempFiles++; //Increment counter: To determine where the temp files are crashing ++guiNumberOfMapTempFiles; //Increment counter: To determine where the temp files are crashing
#endif #endif
//Get the file size of the source data file //Get the file size of the source data file
uiFileSize = FileGetSize( hSrcFile ); uiFileSize = FileGetSize( hSrcFile );
@@ -6905,8 +6916,6 @@ BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile )
return(FALSE); return(FALSE);
} }
//Allocate a buffer to read the data into //Allocate a buffer to read the data into
pData = (UINT8 *) MemAlloc( uiFileSize ); pData = (UINT8 *) MemAlloc( uiFileSize );
if( pData == NULL ) if( pData == NULL )
@@ -6923,8 +6932,6 @@ BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile )
return(FALSE); return(FALSE);
} }
// Write the buffer to the saved game file // Write the buffer to the saved game file
FileWrite( hFile, pData, uiFileSize, &uiNumBytesWritten ); FileWrite( hFile, pData, uiFileSize, &uiNumBytesWritten );
if( uiNumBytesWritten != uiFileSize ) if( uiNumBytesWritten != uiFileSize )
@@ -6941,10 +6948,10 @@ BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile )
//Clsoe the source data file //Clsoe the source data file
FileClose( hSrcFile ); FileClose( hSrcFile );
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
//Write out the name of the temp file so we can track whcih ones get loaded, and saved //Write out the name of the temp file so we can track whcih ones get loaded, and saved
WriteTempFileNameToFile( pSrcFileName, uiFileSize, hFile ); WriteTempFileNameToFile( pSrcFileName, uiFileSize, hFile );
#endif #endif
return( TRUE ); return( TRUE );
} }
@@ -6958,8 +6965,6 @@ BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile )
UINT8 *pData; UINT8 *pData;
UINT32 uiNumBytesRead; UINT32 uiNumBytesRead;
//If the source file exists, delete it //If the source file exists, delete it
if( FileExists( pSrcFileName ) ) if( FileExists( pSrcFileName ) )
{ {
@@ -6970,9 +6975,9 @@ BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile )
} }
} }
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
guiNumberOfMapTempFiles++; //Increment counter: To determine where the temp files are crashing ++guiNumberOfMapTempFiles; //Increment counter: To determine where the temp files are crashing
#endif #endif
//open the destination file to write to //open the destination file to write to
hSrcFile = FileOpen( pSrcFileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); hSrcFile = FileOpen( pSrcFileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
@@ -6982,7 +6987,6 @@ BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile )
return( FALSE ); return( FALSE );
} }
// Read the size of the data // Read the size of the data
FileRead( hFile, &uiFileSize, sizeof( UINT32 ), &uiNumBytesRead ); FileRead( hFile, &uiFileSize, sizeof( UINT32 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( UINT32 ) ) if( uiNumBytesRead != sizeof( UINT32 ) )
@@ -6992,7 +6996,6 @@ BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile )
return(FALSE); return(FALSE);
} }
//if there is nothing in the file, return; //if there is nothing in the file, return;
if( uiFileSize == 0 ) if( uiFileSize == 0 )
{ {
@@ -7022,8 +7025,6 @@ BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile )
return(FALSE); return(FALSE);
} }
// Write the buffer to the new file // Write the buffer to the new file
FileWrite( hSrcFile, pData, uiFileSize, &uiNumBytesWritten ); FileWrite( hSrcFile, pData, uiFileSize, &uiNumBytesWritten );
if( uiNumBytesWritten != uiFileSize ) if( uiNumBytesWritten != uiFileSize )
@@ -7042,9 +7043,9 @@ BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile )
//Close the source data file //Close the source data file
FileClose( hSrcFile ); FileClose( hSrcFile );
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
WriteTempFileNameToFile( pSrcFileName, uiFileSize, hFile ); WriteTempFileNameToFile( pSrcFileName, uiFileSize, hFile );
#endif #endif
return( TRUE ); return( TRUE );
} }
@@ -7079,10 +7080,9 @@ BOOLEAN SaveEmailToSavedGame( HWFILE hFile )
return(FALSE); return(FALSE);
} }
//loop trhough all the emails, add each one individually //loop trhough all the emails, add each one individually
pEmail = pEmailList; pEmail = pEmailList;
for( cnt=0; cnt<uiNumOfEmails; cnt++) for( cnt=0; cnt<uiNumOfEmails; ++cnt)
{ {
//Get the strng length of the subject //Get the strng length of the subject
uiStringLength = ( wcslen( pEmail->pSubject ) + 1 ) * 2; uiStringLength = ( wcslen( pEmail->pSubject ) + 1 ) * 2;
@@ -7101,7 +7101,6 @@ BOOLEAN SaveEmailToSavedGame( HWFILE hFile )
return(FALSE); return(FALSE);
} }
//Get the current emails data and asign it to the 'Saved email' struct //Get the current emails data and asign it to the 'Saved email' struct
SavedEmail.usOffset = pEmail->usOffset; SavedEmail.usOffset = pEmail->usOffset;
SavedEmail.usLength = pEmail->usLength; SavedEmail.usLength = pEmail->usLength;
@@ -7891,15 +7890,13 @@ BOOLEAN SaveMercPathFromSoldierStruct( HWFILE hFile, UINT8 ubID )
PathStPtr pTempPath = Menptr[ ubID ].pMercPath; PathStPtr pTempPath = Menptr[ ubID ].pMercPath;
UINT32 uiNumBytesWritten=0; UINT32 uiNumBytesWritten=0;
//loop through to get all the nodes //loop through to get all the nodes
while( pTempPath ) while( pTempPath )
{ {
uiNumOfNodes++; ++uiNumOfNodes;
pTempPath = pTempPath->pNext; pTempPath = pTempPath->pNext;
} }
//Save the number of the nodes //Save the number of the nodes
FileWrite( hFile, &uiNumOfNodes, sizeof( UINT32 ), &uiNumBytesWritten ); FileWrite( hFile, &uiNumOfNodes, sizeof( UINT32 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( UINT32 ) ) if( uiNumBytesWritten != sizeof( UINT32 ) )
@@ -7910,8 +7907,7 @@ BOOLEAN SaveMercPathFromSoldierStruct( HWFILE hFile, UINT8 ubID )
//loop through all the nodes and add them //loop through all the nodes and add them
pTempPath = Menptr[ ubID ].pMercPath; pTempPath = Menptr[ ubID ].pMercPath;
//loop through nodes and save all the nodes
//loop through nodes and save all the nodes
while( pTempPath ) while( pTempPath )
{ {
//Save the number of the nodes //Save the number of the nodes
@@ -7924,8 +7920,6 @@ BOOLEAN SaveMercPathFromSoldierStruct( HWFILE hFile, UINT8 ubID )
pTempPath = pTempPath->pNext; pTempPath = pTempPath->pNext;
} }
return( TRUE ); return( TRUE );
} }
@@ -7939,8 +7933,6 @@ BOOLEAN LoadMercPathToSoldierStruct( HWFILE hFile, UINT8 ubID )
UINT32 uiNumBytesRead=0; UINT32 uiNumBytesRead=0;
UINT32 cnt; UINT32 cnt;
//The list SHOULD be empty at this point //The list SHOULD be empty at this point
/* /*
//if there is nodes, loop through and delete them //if there is nodes, loop through and delete them
@@ -7968,7 +7960,7 @@ BOOLEAN LoadMercPathToSoldierStruct( HWFILE hFile, UINT8 ubID )
} }
//load all the nodes //load all the nodes
for( cnt=0; cnt<uiNumOfNodes; cnt++ ) for( cnt=0; cnt<uiNumOfNodes; ++cnt )
{ {
//Allocate memory for the new node //Allocate memory for the new node
pTemp = (PathStPtr) MemAlloc( sizeof( PathSt ) ); pTemp = (PathStPtr) MemAlloc( sizeof( PathSt ) );
@@ -7978,8 +7970,8 @@ BOOLEAN LoadMercPathToSoldierStruct( HWFILE hFile, UINT8 ubID )
ClearStrategicPathList( pTempPath, -1 ); ClearStrategicPathList( pTempPath, -1 );
return( FALSE ); return( FALSE );
} }
memset( pTemp, 0 , sizeof( PathSt ) );
memset( pTemp, 0 , sizeof( PathSt ) );
//Load the node //Load the node
FileRead( hFile, pTemp, sizeof( PathSt ), &uiNumBytesRead ); FileRead( hFile, pTemp, sizeof( PathSt ), &uiNumBytesRead );
@@ -9367,10 +9359,12 @@ void UnPauseAfterSaveGame( void )
void ValidateStrategicGroups() void ValidateStrategicGroups()
{ {
SECTORINFO *pSector; // Flugente:this function doesn't do anything, no need to loop here
INT32 i; return;
for( i = SEC_A1; i < SEC_P16; i++ ) SECTORINFO *pSector;
for ( INT32 i = SEC_A1; i < SEC_P16; ++i )
{ {
pSector = &SectorInfo[ i ]; pSector = &SectorInfo[ i ];
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks > gGameExternalOptions.iMaxEnemyGroupSize ) if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks > gGameExternalOptions.iMaxEnemyGroupSize )
+21 -19
View File
@@ -37,6 +37,7 @@
#include "Auto Resolve.h" #include "Auto Resolve.h"
#include "Strategic Status.h" #include "Strategic Status.h"
#include "wordwrap.h" #include "wordwrap.h"
#include "Town Militia.h" // added by Flugente
#endif #endif
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
@@ -452,27 +453,29 @@ void RenderStationaryGroups()
{ {
HVOBJECT hVObject; HVOBJECT hVObject;
SECTORINFO *pSector; SECTORINFO *pSector;
INT32 x, y, xp, yp; INT32 xp, yp;
CHAR16 str[20]; CHAR16 str[20];
INT32 iSector = 0; INT32 iSector = 0;
UINT8 ubIconColor = 0; UINT8 ubIconColor = 0;
UINT8 ubGroupSize = 0; UINT8 ubGroupSize = 0;
SetFont( FONT10ARIAL ); SetFont( FONT10ARIAL );
SetFontShadow( FONT_NEARBLACK ); SetFontShadow( FONT_NEARBLACK );
GetVideoObject( &hVObject, guiMapIconsID ); GetVideoObject( &hVObject, guiMapIconsID );
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */ Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
//Render groups that are stationary... //Render groups that are stationary...
for( y = 0; y < 16; y++ ) for ( INT32 y = 0; y < 16; ++y )
{ {
yp = VIEWER_TOP + VIEWER_CELLH * y + 1; yp = VIEWER_TOP + VIEWER_CELLH * y + 1;
for( x = 0; x < 16; x++ ) for ( INT32 x = 0; x < 16; ++x )
{ {
SetFontForeground( FONT_YELLOW ); SetFontForeground( FONT_YELLOW );
xp = VIEWER_LEFT + VIEWER_CELLW * x + 1; xp = VIEWER_LEFT + VIEWER_CELLW * x + 1;
iSector = SECTOR(x, y);
pSector = &SectorInfo[ iSector ]; pSector = &SectorInfo[ iSector ];
if( pSector->uiFlags & SF_MINING_SITE ) if( pSector->uiFlags & SF_MINING_SITE )
@@ -481,19 +484,20 @@ void RenderStationaryGroups()
if( pSector->uiFlags & SF_SAM_SITE ) if( pSector->uiFlags & SF_SAM_SITE )
BltVideoObject( FRAME_BUFFER, hVObject, SAM_ICON, xp + 20, yp + 4, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObject( FRAME_BUFFER, hVObject, SAM_ICON, xp + 20, yp + 4, VO_BLT_SRCTRANSPARENCY, NULL );
UINT8 nummilitia = NumNonPlayerTeamMembersInSector( x, y, MILITIA_TEAM );
if( pSector->ubNumberOfCivsAtLevel[0] + pSector->ubNumberOfCivsAtLevel[1] + pSector->ubNumberOfCivsAtLevel[2] ) if ( nummilitia )
{ {
// show militia // show militia
ubIconColor = ICON_COLOR_BLUE; ubIconColor = ICON_COLOR_BLUE;
ubGroupSize = pSector->ubNumberOfCivsAtLevel[0] + pSector->ubNumberOfCivsAtLevel[1] + pSector->ubNumberOfCivsAtLevel[2]; ubGroupSize = nummilitia;
} }
else else if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks )
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks )
{ {
// show enemies // show enemies
ubIconColor = ChooseEnemyIconColor( pSector->ubNumAdmins, pSector->ubNumTroops, pSector->ubNumElites, pSector->ubNumTanks ); ubIconColor = ChooseEnemyIconColor( pSector->ubNumAdmins, pSector->ubNumTroops, pSector->ubNumElites, pSector->ubNumTanks );
ubGroupSize = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks; ubGroupSize = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks;
if( pSector->ubGarrisonID != NO_GARRISON ) if( pSector->ubGarrisonID != NO_GARRISON )
{ {
if( gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID ) if( gGarrisonGroup[ pSector->ubGarrisonID ].ubPendingGroupID )
@@ -527,7 +531,7 @@ void RenderStationaryGroups()
mprintf( xp + 2, yp + 2, str ); mprintf( xp + 2, yp + 2, str );
} }
iSector++; ++iSector;
} }
} }
} }
@@ -754,7 +758,7 @@ void RenderInfoInSector()
yp += 10; yp += 10;
SetFontForeground( FONT_LTBLUE ); SetFontForeground( FONT_LTBLUE );
mprintf( 280, yp, L"Militia: (%d Green, %d Regular, %d Elite)", mprintf( 280, yp, L"Militia: (%d Green, %d Regular, %d Elite)",
pSector->ubNumberOfCivsAtLevel[0], pSector->ubNumberOfCivsAtLevel[1], pSector->ubNumberOfCivsAtLevel[2] ); MilitiaInSectorOfRank( ubSectorX, ubSectorY, GREEN_MILITIA ), MilitiaInSectorOfRank( ubSectorX, ubSectorY, REGULAR_MILITIA ), MilitiaInSectorOfRank( ubSectorX, ubSectorY, ELITE_MILITIA ) );
yp += 10; yp += 10;
SetFontForeground( FONT_ORANGE ); SetFontForeground( FONT_ORANGE );
mprintf( 280, yp, L"Garrison: (%d:%d Admins, %d:%d Troops, %d:%d Elites, %d:%d Tanks)", mprintf( 280, yp, L"Garrison: (%d:%d Admins, %d:%d Troops, %d:%d Elites, %d:%d Tanks)",
@@ -967,19 +971,17 @@ void HandleViewerInput()
pSector = NULL; pSector = NULL;
if( gsSelSectorX && gsSelSectorY ) if( gsSelSectorX && gsSelSectorY )
{ {
pSector = &SectorInfo[ SECTOR( gsSelSectorX, gsSelSectorY ) ]; StrategicAddMilitiaToSector( gsSelSectorX, gsSelSectorY, GREEN_MILITIA, 15 );
pSector->ubNumberOfCivsAtLevel[0] = 15; StrategicAddMilitiaToSector( gsSelSectorX, gsSelSectorY, REGULAR_MILITIA, 4 );
pSector->ubNumberOfCivsAtLevel[1] = 4; StrategicAddMilitiaToSector( gsSelSectorX, gsSelSectorY, ELITE_MILITIA, 1 );
pSector->ubNumberOfCivsAtLevel[2] = 1;
gfRenderMap = TRUE; gfRenderMap = TRUE;
EliminateAllEnemies( (UINT8)gsSelSectorX, (UINT8)gsSelSectorY ); EliminateAllEnemies( (UINT8)gsSelSectorX, (UINT8)gsSelSectorY );
} }
else if( gsHiSectorX && gsHiSectorY ) else if( gsHiSectorX && gsHiSectorY )
{ {
pSector = &SectorInfo[ SECTOR( gsHiSectorX, gsHiSectorY ) ]; StrategicAddMilitiaToSector( gsHiSectorX, gsHiSectorY, GREEN_MILITIA, 15 );
pSector->ubNumberOfCivsAtLevel[0] = 15; StrategicAddMilitiaToSector( gsHiSectorX, gsHiSectorY, REGULAR_MILITIA, 4 );
pSector->ubNumberOfCivsAtLevel[1] = 4; StrategicAddMilitiaToSector( gsHiSectorX, gsHiSectorY, ELITE_MILITIA, 1 );
pSector->ubNumberOfCivsAtLevel[2] = 1;
gfRenderMap = TRUE; gfRenderMap = TRUE;
EliminateAllEnemies( (UINT8)gsHiSectorX, (UINT8)gsHiSectorY ); EliminateAllEnemies( (UINT8)gsHiSectorX, (UINT8)gsHiSectorY );
} }
+8 -7
View File
@@ -3026,7 +3026,6 @@ UINT32 CalculateSnitchGuardValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts )
UINT32 CalculateAllGuardsValueInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) UINT32 CalculateAllGuardsValueInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
{ {
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
UINT32 prisonguardvalue = 0; UINT32 prisonguardvalue = 0;
// count any mercs found here, and sum up their guard values // count any mercs found here, and sum up their guard values
@@ -3036,7 +3035,7 @@ UINT32 CalculateAllGuardsValueInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
UINT32 lastid = gTacticalStatus.Team[ OUR_TEAM ].bLastID; UINT32 lastid = gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier) for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier)
{ {
if( pSoldier->bActive && ( pSoldier->sSectorX == sMapX ) && ( pSoldier->sSectorY == sMapY ) && ( pSoldier->bSectorZ == bZ) && pSoldier->flags.fMercAsleep == FALSE ) if( pSoldier->bActive && ( pSoldier->sSectorX == sMapX ) && ( pSoldier->sSectorY == sMapY ) && ( pSoldier->bSectorZ == bZ) && !pSoldier->flags.fMercAsleep )
{ {
UINT16 tmp; UINT16 tmp;
prisonguardvalue += CalculatePrisonGuardValue(pSoldier, &tmp ); prisonguardvalue += CalculatePrisonGuardValue(pSoldier, &tmp );
@@ -3044,14 +3043,13 @@ UINT32 CalculateAllGuardsValueInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
} }
// add militia strength // add militia strength
prisonguardvalue += 100 * pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + 150 * pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + 200 * pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; prisonguardvalue += 100 * MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA ) + 150 * MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA ) + 200 * MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA );
return( prisonguardvalue ); return( prisonguardvalue );
} }
UINT32 CalculateAllSnitchesGuardValueInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) UINT32 CalculateAllSnitchesGuardValueInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
{ {
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
UINT32 prisonguardvalue = 0; UINT32 prisonguardvalue = 0;
// count any mercs found here, and sum up their guard values // count any mercs found here, and sum up their guard values
@@ -3069,14 +3067,13 @@ UINT32 CalculateAllSnitchesGuardValueInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ
} }
// add militia strength // add militia strength
prisonguardvalue += 100 * pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + 150 * pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + 200 * pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; prisonguardvalue += 100 * MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA ) + 150 * MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA ) + 200 * MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA );
return( prisonguardvalue ); return( prisonguardvalue );
} }
UINT32 CalculateAllGuardsNumberInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) UINT32 CalculateAllGuardsNumberInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
{ {
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
UINT8 numprisonguards = 0; UINT8 numprisonguards = 0;
// count any mercs found here // count any mercs found here
@@ -3095,7 +3092,7 @@ UINT32 CalculateAllGuardsNumberInPrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
} }
// add militia strength // add militia strength
numprisonguards += pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; numprisonguards += NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM );
return( numprisonguards ); return( numprisonguards );
} }
@@ -18075,6 +18072,10 @@ BOOLEAN BasicCanCharacterTrainMobileMilitia( SOLDIERTYPE *pSoldier )
return ( FALSE ); return ( FALSE );
} }
// Flugente: not allowed if we can move militia in strategic, as this then becomes pointless
if ( gGameExternalOptions.fMilitiaStrategicCommand )
return FALSE;
// Is character dead or unconscious? // Is character dead or unconscious?
if( pSoldier->stats.bLife < OKLIFE ) if( pSoldier->stats.bLife < OKLIFE )
{ {
+46 -23
View File
@@ -608,7 +608,7 @@ void EnterAutoResolveMode( UINT8 ubSectorX, UINT8 ubSectorY )
CreateDestroyMapInvButton(); CreateDestroyMapInvButton();
RenderButtons(); RenderButtons();
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve1"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve1");
// WDS - make number of mercenaries, etc. be configurable // WDS - make number of mercenaries, etc. be configurable
//Allocate memory for all the globals while we are in this mode. //Allocate memory for all the globals while we are in this mode.
gpAR = (AUTORESOLVE_STRUCT*)MemAlloc( sizeof( AUTORESOLVE_STRUCT ) ); gpAR = (AUTORESOLVE_STRUCT*)MemAlloc( sizeof( AUTORESOLVE_STRUCT ) );
@@ -784,7 +784,7 @@ void AssociateEnemiesWithStrategicGroups()
//Now go through our enemies in the autoresolve array, and assign the ubGroupID to the soldier //Now go through our enemies in the autoresolve array, and assign the ubGroupID to the soldier
//Stationary groups have a group ID of 0 //Stationary groups have a group ID of 0
for( i = 0; i < gpAR->ubEnemies; i++ ) for( i = 0; i < gpAR->ubEnemies; ++i )
{ {
if( gpEnemies[ i ].uiFlags & CELL_ELITE && ubNumElites ) if( gpEnemies[ i ].uiFlags & CELL_ELITE && ubNumElites )
{ {
@@ -826,7 +826,7 @@ void AssociateEnemiesWithStrategicGroups()
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->ubSectorX == gpAR->ubSectorX && pGroup->ubSectorY == gpAR->ubSectorY ) if ( pGroup->usGroupTeam == ENEMY_TEAM && pGroup->ubSectorX == gpAR->ubSectorX && pGroup->ubSectorY == gpAR->ubSectorY )
{ {
ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites; ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites;
ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops; ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops;
@@ -876,7 +876,7 @@ void AssociateEnemiesWithStrategicGroups()
while( pGroup ) while( pGroup )
{ {
// Don't process road block. It'll be processed as static // Don't process road block. It'll be processed as static
if ( pGroup->ubGroupID && pGroup->usGroupTeam != OUR_TEAM && IsGroupInARightSectorToReinforce( pGroup, gpAR->ubSectorX, gpAR->ubSectorY ) ) if ( pGroup->ubGroupID && pGroup->usGroupTeam == ENEMY_TEAM && IsGroupInARightSectorToReinforce( pGroup, gpAR->ubSectorX, gpAR->ubSectorY ) )
{ {
ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites; ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites;
ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops; ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops;
@@ -920,11 +920,10 @@ void AssociateEnemiesWithStrategicGroups()
pGroup = pGroup->next; pGroup = pGroup->next;
} }
// Set GroupID = 0 for the rest
// Set GroupID = 0 for the rest
ubDirAmount = GetAdjacentSectors( pSectors, gpAR->ubSectorX, gpAR->ubSectorY ); ubDirAmount = GetAdjacentSectors( pSectors, gpAR->ubSectorX, gpAR->ubSectorY );
for( ubCurrSI = 0; ubCurrSI < ubDirAmount; ubCurrSI++ ) for( ubCurrSI = 0; ubCurrSI < ubDirAmount; ++ubCurrSI )
{ {
pSector = &SectorInfo[ pSectors[ ubCurrSI ] ]; pSector = &SectorInfo[ pSectors[ ubCurrSI ] ];
@@ -933,7 +932,7 @@ void AssociateEnemiesWithStrategicGroups()
ubISNumElites = pSector->ubNumElites; ubISNumElites = pSector->ubNumElites;
ubISNumTanks = pSector->ubNumTanks; ubISNumTanks = pSector->ubNumTanks;
for( i = 0; i < gpAR->ubEnemies; i++ ) for( i = 0; i < gpAR->ubEnemies; ++i )
{ {
if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break; if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break;
@@ -978,7 +977,6 @@ void AssociateEnemiesWithStrategicGroups()
} }
} }
} }
} }
@@ -2790,11 +2788,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
gbGreenToRegPromotions = 0; gbGreenToRegPromotions = 0;
gbRegToElitePromotions = 0; gbRegToElitePromotions = 0;
gbMilitiaPromotions = 0; gbMilitiaPromotions = 0;
for( i = 0; i < MAX_AR_TEAM_SIZE; i++ ) for( i = 0; i < MAX_AR_TEAM_SIZE; ++i )
{ {
if( gpCivs[ i ].pSoldier ) if( gpCivs[ i ].pSoldier )
{ {
ubCurrentRank = MAX_AR_TEAM_SIZE; ubCurrentRank = GREEN_MILITIA;
switch( gpCivs[ i ].pSoldier->ubSoldierClass ) switch( gpCivs[ i ].pSoldier->ubSoldierClass )
{ {
case SOLDIER_CLASS_GREEN_MILITIA: ubCurrentRank = GREEN_MILITIA; break; case SOLDIER_CLASS_GREEN_MILITIA: ubCurrentRank = GREEN_MILITIA; break;
@@ -2829,18 +2827,24 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
{ {
if( ubPromotions == 2 ) if( ubPromotions == 2 )
{ {
gbGreenToElitePromotions++; ++gbGreenToElitePromotions;
gbMilitiaPromotions++; ++gbMilitiaPromotions;
ubCurrentRank = ELITE_MILITIA;
} }
else if( gpCivs[ i ].pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA ) else if( gpCivs[ i ].pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA )
{ {
gbGreenToRegPromotions++; ++gbGreenToRegPromotions;
gbMilitiaPromotions++; ++gbMilitiaPromotions;
ubCurrentRank = REGULAR_MILITIA;
} }
else if( gpCivs[ i ].pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA ) else if( gpCivs[ i ].pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA )
{ {
gbRegToElitePromotions++; ++gbRegToElitePromotions;
gbMilitiaPromotions++; ++gbMilitiaPromotions;
ubCurrentRank = ELITE_MILITIA;
} }
} }
} }
@@ -2850,8 +2854,27 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
} }
} }
// Flugente: after we fought, move any militia in groups into the sector garrison - the player will likely want to rethink orders for the survivors
// Flugente: in case militia died we have to lower the group sizes
// loop over all militia groups that are in this sector and alter their size. If a group has size 0 delete it. If any militia are left place them into this sector
{
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == MILITIA_TEAM && pGroup->ubSectorX == gpAR->ubSectorX && pGroup->ubSectorY == gpAR->ubSectorY )
{
GROUP* pDeleteGroup = pGroup;
pGroup = pGroup->next;
DissolveMilitiaGroup( pDeleteGroup->ubGroupID );
}
else
pGroup = pGroup->next;
}
}
//Record and process all enemy deaths //Record and process all enemy deaths
for( i = 0; i < MAX_AR_TEAM_SIZE; i++ ) for( i = 0; i < MAX_AR_TEAM_SIZE; ++i )
{ {
if( gpEnemies[ i ].pSoldier ) if( gpEnemies[ i ].pSoldier )
{ {
@@ -2877,7 +2900,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
} }
} }
//Physically delete the soldiers now. //Physically delete the soldiers now.
for( i = 0; i < MAX_AR_TEAM_SIZE; i++ ) for( i = 0; i < MAX_AR_TEAM_SIZE; ++i )
{ {
if( gpEnemies[ i ].pSoldier ) if( gpEnemies[ i ].pSoldier )
{ {
@@ -2886,14 +2909,15 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
} }
} }
for( i = 0; i < NUM_AR_BUTTONS; i++ ) for( i = 0; i < NUM_AR_BUTTONS; ++i )
{ {
UnloadButtonImage( gpAR->iButtonImage[ i ] ); UnloadButtonImage( gpAR->iButtonImage[ i ] );
RemoveButton( gpAR->iButton[ i ] ); RemoveButton( gpAR->iButton[ i ] );
} }
if( fDeleteForGood )
{ //Warp the game time accordingly
if( fDeleteForGood )
{
//Warp the game time accordingly
WarpGameTime( gpAR->uiTotalElapsedBattleTimeInMilliseconds/1000, WARPTIME_NO_PROCESSING_OF_EVENTS ); WarpGameTime( gpAR->uiTotalElapsedBattleTimeInMilliseconds/1000, WARPTIME_NO_PROCESSING_OF_EVENTS );
//Deallocate all of the global memory. //Deallocate all of the global memory.
@@ -2909,7 +2933,6 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
MemFree( gpEnemies ); MemFree( gpEnemies );
gpEnemies = NULL; gpEnemies = NULL;
} }
//KM : Aug 09, 1999 Patch fix -- Would break future dialog while time compressing //KM : Aug 09, 1999 Patch fix -- Would break future dialog while time compressing
+1 -2
View File
@@ -2702,8 +2702,7 @@ BOOLEAN LuaInternalQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN
{ {
LuaFunction(_LS.L, "InternalEndQuest" ).Param<int>(ubQuest).Param<int>(sSectorX).Param<int>(sSectorY).Param<bool>(fUpdateHistory).Call(4); LuaFunction(_LS.L, "InternalEndQuest" ).Param<int>(ubQuest).Param<int>(sSectorX).Param<int>(sSectorY).Param<bool>(fUpdateHistory).Call(4);
} }
else if ( Init == 1 )
if ( Init == 1 )
{ {
LuaFunction(_LS.L, "InternalStartQuest" ).Param<int>(ubQuest).Param<int>(sSectorX).Param<int>(sSectorY).Param<bool>(fUpdateHistory).Call(4); LuaFunction(_LS.L, "InternalStartQuest" ).Param<int>(ubQuest).Param<int>(sSectorX).Param<int>(sSectorY).Param<bool>(fUpdateHistory).Call(4);
} }
+20 -32
View File
@@ -32,6 +32,7 @@
// HEADROCK HAM 5: Required for inventory filter popup // HEADROCK HAM 5: Required for inventory filter popup
#include "popup_callback.h" #include "popup_callback.h"
#include "popup_class.h" #include "popup_class.h"
#include "Queen Command.h" // added by Flugente
#endif #endif
#include "connect.h" #include "connect.h"
@@ -167,12 +168,9 @@ void DeleteMapBorderGraphics( void )
// procedure will delete graphics loaded for map border // procedure will delete graphics loaded for map border
DeleteVideoObjectFromIndex( guiMapBorder ); DeleteVideoObjectFromIndex( guiMapBorder );
return;
} }
void RenderMapBorder( void ) void RenderMapBorder( void )
{ {
// renders the actual border to the guiSAVEBUFFER // renders the actual border to the guiSAVEBUFFER
@@ -201,7 +199,7 @@ void RenderMapBorder( void )
// get and blt border // get and blt border
GetVideoObject(&hHandle, guiMapBorder ); GetVideoObject(&hHandle, guiMapBorder );
// HEADROCK HAM 4: Load different map border depending on whether we want to display the mobile militia button or not. // HEADROCK HAM 4: Load different map border depending on whether we want to display the mobile militia button or not.
if (gGameExternalOptions.gfAllowMilitiaGroups) if ( gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand )
{ {
BltVideoObject( guiSAVEBUFFER , hHandle, 1, xResOffset + MAP_BORDER_X, yResOffset + MAP_BORDER_Y, VO_BLT_SRCTRANSPARENCY,NULL ); BltVideoObject( guiSAVEBUFFER , hHandle, 1, xResOffset + MAP_BORDER_X, yResOffset + MAP_BORDER_Y, VO_BLT_SRCTRANSPARENCY,NULL );
} }
@@ -214,8 +212,6 @@ void RenderMapBorder( void )
// show the level marker // show the level marker
DisplayCurrentLevelMarker( ); DisplayCurrentLevelMarker( );
return;
} }
@@ -229,7 +225,7 @@ void RenderMapBorderEtaPopUp( void )
return; return;
} }
if( fPlotForHelicopter == TRUE ) if( fPlotForHelicopter )
{ {
DisplayDistancesForHelicopter( ); DisplayDistancesForHelicopter( );
return; return;
@@ -250,8 +246,6 @@ void RenderMapBorderEtaPopUp( void )
BltVideoObject( FRAME_BUFFER , hHandle, 2, xVal, yVal, VO_BLT_SRCTRANSPARENCY,NULL ); BltVideoObject( FRAME_BUFFER , hHandle, 2, xVal, yVal, VO_BLT_SRCTRANSPARENCY,NULL );
InvalidateRegion( xVal, yVal, xVal + 100 , yVal + 19); InvalidateRegion( xVal, yVal, xVal + 100 , yVal + 19);
return;
} }
BOOLEAN CreateButtonsForMapBorder( void ) BOOLEAN CreateButtonsForMapBorder( void )
@@ -302,7 +296,7 @@ BOOLEAN CreateButtonsForMapBorder( void )
// WANNE: Only display the buton when mobile militia is allowed! // WANNE: Only display the buton when mobile militia is allowed!
// HEADROCK HAM 4: Mobile Restrictions Button // HEADROCK HAM 4: Mobile Restrictions Button
if (gGameExternalOptions.gfAllowMilitiaGroups) if ( gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand )
{ {
giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,20,-1,21,-1 ); giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,20,-1,21,-1 );
giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ], MAP_BORDER_MOBILE_BTN_X, MAP_BORDER_MOBILE_BTN_Y, giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ], MAP_BORDER_MOBILE_BTN_X, MAP_BORDER_MOBILE_BTN_Y,
@@ -318,7 +312,7 @@ BOOLEAN CreateButtonsForMapBorder( void )
SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_ITEM_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_ITEM_BTN ] ); SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_ITEM_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_ITEM_BTN ] );
SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_MILITIA_BTN ] ); SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_MILITIA_BTN ] );
if (gGameExternalOptions.gfAllowMilitiaGroups) if ( gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand )
SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_MOBILE_BTN ] ); // HEADROCK HAM 4: Mobile Militia button SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_MOBILE_BTN ] ); // HEADROCK HAM 4: Mobile Militia button
SetButtonCursor(giMapBorderButtons[ MAP_BORDER_TOWN_BTN ], MSYS_NO_CURSOR ); SetButtonCursor(giMapBorderButtons[ MAP_BORDER_TOWN_BTN ], MSYS_NO_CURSOR );
@@ -328,7 +322,7 @@ BOOLEAN CreateButtonsForMapBorder( void )
SetButtonCursor(giMapBorderButtons[ MAP_BORDER_ITEM_BTN ], MSYS_NO_CURSOR ); SetButtonCursor(giMapBorderButtons[ MAP_BORDER_ITEM_BTN ], MSYS_NO_CURSOR );
SetButtonCursor(giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ], MSYS_NO_CURSOR ); SetButtonCursor(giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ], MSYS_NO_CURSOR );
if (gGameExternalOptions.gfAllowMilitiaGroups) if ( gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand )
SetButtonCursor(giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ], MSYS_NO_CURSOR ); // HEADROCK HAM 4: Mobile Militia button SetButtonCursor(giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ], MSYS_NO_CURSOR ); // HEADROCK HAM 4: Mobile Militia button
// Flugente: disease // Flugente: disease
@@ -438,7 +432,7 @@ void DeleteMapBorderButtons( void )
RemoveButton( giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ]); RemoveButton( giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ]);
// WANNE: Only remove if we added the button // WANNE: Only remove if we added the button
if (gGameExternalOptions.gfAllowMilitiaGroups) if ( gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand )
RemoveButton( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ]); // HEADROCK HAM 4 RemoveButton( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ]); // HEADROCK HAM 4
if ( giMapBorderButtons[MAP_BORDER_DISEASE_BTN] != -1 ) if ( giMapBorderButtons[MAP_BORDER_DISEASE_BTN] != -1 )
@@ -454,7 +448,7 @@ void DeleteMapBorderButtons( void )
UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_MILITIA_BTN ] ); UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_MILITIA_BTN ] );
// WANNE: Only unload if we added the button // WANNE: Only unload if we added the button
if (gGameExternalOptions.gfAllowMilitiaGroups) if ( gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand )
UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ] ); // HEADROCK HAM 4 UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ] ); // HEADROCK HAM 4
if ( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] != -1 ) if ( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] != -1 )
@@ -771,7 +765,7 @@ void ToggleAirspaceMode( void )
fShowAircraftFlag = FALSE; fShowAircraftFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN );
if( fPlotForHelicopter == TRUE ) if( fPlotForHelicopter )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -1121,7 +1115,7 @@ void TurnOnItemFilterMode( void )
MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN );
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -1189,7 +1183,7 @@ void TurnOnDiseaseFilterMode( void )
MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN );
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -1257,7 +1251,7 @@ void TurnOnMobileFilterMode( void )
MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); MapBorderButtonOff( MAP_BORDER_DISEASE_BTN );
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -1375,15 +1369,12 @@ void InitializeMapBorderButtonStates( void )
BOOLEAN DoesPlayerHaveAnyMilitia( void ) BOOLEAN DoesPlayerHaveAnyMilitia( void )
{ {
INT16 sX, sY;
// run through list of towns that might have militia..if any return TRUE..else return FALSE // run through list of towns that might have militia..if any return TRUE..else return FALSE
for( sX = 1; sX < MAP_WORLD_X - 1; sX++ ) for ( INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{ {
for( sY = 1; sY < MAP_WORLD_Y - 1; sY++ ) for ( INT16 sY = 1; sY < MAP_WORLD_Y - 1; ++sY )
{ {
if( ( SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] if ( NumNonPlayerTeamMembersInSector( sX, sY, MILITIA_TEAM ) > 0 )
+ SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] ) > 0 )
{ {
// found at least one // found at least one
return( TRUE ); return( TRUE );
@@ -1398,25 +1389,22 @@ BOOLEAN DoesPlayerHaveAnyMilitia( void )
// HEADROCK HAM 4: Check for Mobile Militia // HEADROCK HAM 4: Check for Mobile Militia
UINT8 DoesPlayerHaveAnyMobileMilitia( void ) UINT8 DoesPlayerHaveAnyMobileMilitia( void )
{ {
INT16 sX, sY; if ( !gGameExternalOptions.gfAllowMilitiaGroups || gGameExternalOptions.fMilitiaStrategicCommand )
if (!gGameExternalOptions.gfAllowMilitiaGroups)
{ {
// Mobile Militia not allowed at all. // Mobile Militia not allowed at all.
return (0); return (0);
} }
// run through list of towns that might have militia..if any return TRUE..else return FALSE // run through list of towns that might have militia..if any return TRUE..else return FALSE
for( sX = 1; sX < MAP_WORLD_X - 1; sX++ ) for ( INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{ {
for( sY = 1; sY < MAP_WORLD_Y - 1; sY++ ) for ( INT16 sY = 1; sY < MAP_WORLD_Y - 1; ++sY )
{ {
// Look only in sectors where Militia Training is not allowed at all. If any militia are found there, // Look only in sectors where Militia Training is not allowed at all. If any militia are found there,
// it means that they had to MOVE there, hence mobile militia. // it means that they had to MOVE there, hence mobile militia.
if (!MilitiaTrainingAllowedInSector( sX, sY, 0 )) if (!MilitiaTrainingAllowedInSector( sX, sY, 0 ))
{ {
if( ( SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] if ( NumNonPlayerTeamMembersInSector( sX, sY, MILITIA_TEAM ) > 0 )
+ SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] ) > 0 )
{ {
// found at least one // found at least one
return( 2 ); return( 2 );
@@ -1535,7 +1523,7 @@ void InitMapBorderButtonCoordinates()
MAP_LEVEL_MARKER_DELTA = 8; MAP_LEVEL_MARKER_DELTA = 8;
MAP_LEVEL_MARKER_WIDTH = 55; MAP_LEVEL_MARKER_WIDTH = 55;
if (gGameExternalOptions.gfAllowMilitiaGroups) if ( gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand )
{ {
// Mobile button appears next to Militia button. // Mobile button appears next to Militia button.
MAP_BORDER_MOBILE_BTN_X = xResOffset + MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X - 2 * xResOffset) / 2) + 16; MAP_BORDER_MOBILE_BTN_X = xResOffset + MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X - 2 * xResOffset) / 2) + 16;
+2 -3
View File
@@ -1339,7 +1339,7 @@ BOOLEAN AllowedToTimeCompress( void )
} }
// moving / confirming movement // moving / confirming movement
if( ( bSelectedDestChar != -1 ) || fPlotForHelicopter || gfInConfirmMapMoveMode || fShowMapScreenMovementList ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia || gfInConfirmMapMoveMode || fShowMapScreenMovementList )
{ {
return( FALSE ); return( FALSE );
} }
@@ -1680,7 +1680,7 @@ BOOLEAN CommonTimeCompressionChecks( void )
return( TRUE ); return( TRUE );
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
// abort plotting movement // abort plotting movement
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
@@ -1700,7 +1700,6 @@ BOOLEAN AnyUsableRealMercenariesOnTeam( void )
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
INT32 iCounter = 0, iNumberOnTeam = 0; INT32 iCounter = 0, iNumberOnTeam = 0;
// this is for speed, this runs once/frame // this is for speed, this runs once/frame
iNumberOnTeam = gTacticalStatus.Team[ OUR_TEAM ].bLastID; iNumberOnTeam = gTacticalStatus.Team[ OUR_TEAM ].bLastID;
File diff suppressed because it is too large Load Diff
+22 -4
View File
@@ -87,6 +87,12 @@ void PlotPathForHelicopter( INT16 sX, INT16 sY );
// the temp path, where the helicopter could go // the temp path, where the helicopter could go
void PlotATemporaryPathForHelicopter( INT16 sX, INT16 sY ); void PlotATemporaryPathForHelicopter( INT16 sX, INT16 sY );
// plot path for helicopter
void PlotPathForMilitia( INT16 sX, INT16 sY );
// the temp path, where the helicopter could go
void PlotATemporaryPathForMilitia( INT16 sX, INT16 sY );
// trace a route for a passed path...doesn't require dest char - most more general // trace a route for a passed path...doesn't require dest char - most more general
BOOLEAN TracePathRoute( BOOLEAN fCheckFlag, BOOLEAN fForceUpDate, PathStPtr pPath ); BOOLEAN TracePathRoute( BOOLEAN fCheckFlag, BOOLEAN fForceUpDate, PathStPtr pPath );
@@ -108,6 +114,8 @@ void DisplaySoldierPath( SOLDIERTYPE *pCharacter );
void DisplaySoldierTempPath( SOLDIERTYPE *pCharacter ); void DisplaySoldierTempPath( SOLDIERTYPE *pCharacter );
void DisplayHelicopterPath( void ); void DisplayHelicopterPath( void );
void DisplayHelicopterTempPath( void ); void DisplayHelicopterTempPath( void );
void DisplayMilitiaPath( void );
void DisplayMilitiaTempPath( void );
// clear path after this sector // clear path after this sector
@@ -118,12 +126,18 @@ void CancelPathForCharacter( SOLDIERTYPE *pCharacter );
void CancelPathForVehicle( VEHICLETYPE *pVehicle, BOOLEAN fAlreadyReversed ); void CancelPathForVehicle( VEHICLETYPE *pVehicle, BOOLEAN fAlreadyReversed );
void CancelPathForGroup( GROUP *pGroup ); void CancelPathForGroup( GROUP *pGroup );
void CancelPathForMilitiaGroup( UINT8 uGroupId );
// check if we have waited long enought object update temp path // check if we have waited long enought object update temp path
void DisplayThePotentialPathForHelicopter(INT16 sMapX, INT16 sMapY ); void DisplayThePotentialPathForHelicopter(INT16 sMapX, INT16 sMapY );
void DisplayThePotentialPathForMilitia( INT16 sMapX, INT16 sMapY );
// clear out helicopter list after this sector // clear out helicopter list after this sector
UINT32 ClearPathAfterThisSectorForHelicopter( INT16 sX, INT16 sY ); UINT32 ClearPathAfterThisSectorForHelicopter( INT16 sX, INT16 sY );
UINT32 ClearPathAfterThisSectorForMilitia( INT16 sX, INT16 sY );
// check to see if sector is highlightable // check to see if sector is highlightable
BOOLEAN IsTheCursorAllowedToHighLightThisSector( INT16 sSectorX, INT16 sSectorY ); BOOLEAN IsTheCursorAllowedToHighLightThisSector( INT16 sSectorX, INT16 sSectorY );
@@ -150,6 +164,8 @@ void ShowMilitiaInMotion( INT16 sX, INT16 sY); // added by Flugente
// last sector in helicopter's path // last sector in helicopter's path
INT16 GetLastSectorOfHelicoptersPath( void ); INT16 GetLastSectorOfHelicoptersPath( void );
INT16 GetLastSectorOfMilitiaPath( void );
// display info about helicopter path // display info about helicopter path
void DisplayDistancesForHelicopter( void ); void DisplayDistancesForHelicopter( void );
@@ -169,10 +185,6 @@ void RemoveMilitiaPopUpBox( void );
// check if anyone left behind, if not, move selected cursor along with movement group // check if anyone left behind, if not, move selected cursor along with movement group
//void CheckIfAnyoneLeftInSector( INT16 sX, INT16 sY, INT16 sNewX, INT16 sNewY, INT8 bZ ); //void CheckIfAnyoneLeftInSector( INT16 sX, INT16 sY, INT16 sNewX, INT16 sNewY, INT8 bZ );
// grab the total number of militia in sector
INT32 GetNumberOfMilitiaInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
// create destroy // create destroy
void CreateDestroyMilitiaPopUPRegions( void ); void CreateDestroyMilitiaPopUPRegions( void );
@@ -332,6 +344,8 @@ extern SGPRect MapScreenRect;
// draw temp path // draw temp path
extern BOOLEAN fDrawTempHeliPath; extern BOOLEAN fDrawTempHeliPath;
extern BOOLEAN fDrawTempMilitiaPath;
// selected destination char // selected destination char
extern INT8 bSelectedDestChar; extern INT8 bSelectedDestChar;
@@ -384,4 +398,8 @@ extern POINT pTownPoints[ MAX_TOWNS ];
extern void SetUpValidCampaignSectors( void ); extern void SetUpValidCampaignSectors( void );
#endif #endif
void CreateMilitiaGroupBox( );
void DestroyMilitiaGroupBox( );
void DisplayMilitiaGroupBox( );
#endif #endif
+7 -23
View File
@@ -1349,7 +1349,7 @@ void JumpToLevel( INT32 iLevel )
return; return;
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -2640,7 +2640,7 @@ void GoToNextCharacterInList( void )
return; return;
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if( ( bSelectedDestChar != -1 ) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -2655,7 +2655,7 @@ void GoToNextCharacterInList( void )
iCount = bSelectedInfoChar + 1; iCount = bSelectedInfoChar + 1;
} }
for( iCounter = 0; iCounter < giMAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ ) for( iCounter = 0; iCounter < giMAXIMUM_NUMBER_OF_PLAYER_SLOTS; ++iCounter )
{ {
if ( ( gCharactersList[ iCount ].fValid ) && ( iCount < giMAXIMUM_NUMBER_OF_PLAYER_SLOTS ) && ValidSelectableCharForNextOrPrev( iCount ) ) if ( ( gCharactersList[ iCount ].fValid ) && ( iCount < giMAXIMUM_NUMBER_OF_PLAYER_SLOTS ) && ValidSelectableCharForNextOrPrev( iCount ) )
{ {
@@ -2664,7 +2664,7 @@ void GoToNextCharacterInList( void )
} }
else else
{ {
iCount++; ++iCount;
if( iCount >= giMAXIMUM_NUMBER_OF_PLAYER_SLOTS ) if( iCount >= giMAXIMUM_NUMBER_OF_PLAYER_SLOTS )
{ {
@@ -2684,7 +2684,7 @@ void GoToFirstCharacterInList( void )
return; return;
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -2710,7 +2710,7 @@ void GoToLastCharacterInList( void )
return; return;
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -2736,7 +2736,7 @@ void GoToPrevCharacterInList( void )
return; return;
} }
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -4636,7 +4636,6 @@ void HandleSettingTheSelectedListOfMercs( void )
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
BOOLEAN fSelected; BOOLEAN fSelected;
// reset the selected character // reset the selected character
bSelectedDestChar = -1; bSelectedDestChar = -1;
@@ -6060,16 +6059,13 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
INT16 sSector = 0; INT16 sSector = 0;
BOOLEAN fProblemExists = FALSE; BOOLEAN fProblemExists = FALSE;
// valid soldier? // valid soldier?
Assert( pSoldier ); Assert( pSoldier );
Assert( pSoldier->bActive); Assert( pSoldier->bActive);
// NOTE: Check for the most permanent conditions first, and the most easily remedied ones last! // NOTE: Check for the most permanent conditions first, and the most easily remedied ones last!
// In case several cases apply, only the reason found first will be given, so make it a good one! // In case several cases apply, only the reason found first will be given, so make it a good one!
// still in transit? // still in transit?
if( IsCharacterInTransit( pSoldier ) == TRUE ) if( IsCharacterInTransit( pSoldier ) == TRUE )
{ {
@@ -6084,7 +6080,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
return( FALSE ); return( FALSE );
} }
// underground? (can't move strategically, must use tactical traversal ) // underground? (can't move strategically, must use tactical traversal )
if( pSoldier->bSectorZ != 0 ) if( pSoldier->bSectorZ != 0 )
{ {
@@ -6092,7 +6087,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
return( FALSE ); return( FALSE );
} }
// vehicle checks // vehicle checks
if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{ {
@@ -6136,7 +6130,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
} }
} }
// if merc is in a particular sector, not somewhere in between // if merc is in a particular sector, not somewhere in between
if ( pSoldier->flags.fBetweenSectors == FALSE ) if ( pSoldier->flags.fBetweenSectors == FALSE )
{ {
@@ -6178,7 +6171,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
} }
} }
// if in L12 museum, and the museum alarm went off, and Eldin still around? // if in L12 museum, and the museum alarm went off, and Eldin still around?
if ( ( pSoldier->sSectorX == 12 ) && ( pSoldier->sSectorY == MAP_ROW_L ) && ( pSoldier->bSectorZ == 0 ) && if ( ( pSoldier->sSectorX == 12 ) && ( pSoldier->sSectorY == MAP_ROW_L ) && ( pSoldier->bSectorZ == 0 ) &&
( !pSoldier->flags.fBetweenSectors ) && gMercProfiles[ ELDIN ].bMercStatus != MERC_IS_DEAD ) ( !pSoldier->flags.fBetweenSectors ) && gMercProfiles[ ELDIN ].bMercStatus != MERC_IS_DEAD )
@@ -6190,7 +6182,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
if ( InARoom( pSoldier->sGridNo, &usRoom ) && usRoom >= 22 && usRoom <= 41 ) if ( InARoom( pSoldier->sGridNo, &usRoom ) && usRoom >= 22 && usRoom <= 41 )
{ {
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( pSoldier2 = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier2++) for ( pSoldier2 = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier2++)
@@ -6207,7 +6198,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
} }
} }
// on assignment, other than just in a VEHICLE? // on assignment, other than just in a VEHICLE?
if( ( pSoldier->bAssignment >= ON_DUTY ) && ( pSoldier->bAssignment != VEHICLE ) ) if( ( pSoldier->bAssignment >= ON_DUTY ) && ( pSoldier->bAssignment != VEHICLE ) )
{ {
@@ -6225,7 +6215,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
return( FALSE ); return( FALSE );
} }
// a robot? // a robot?
if ( AM_A_ROBOT( pSoldier ) ) if ( AM_A_ROBOT( pSoldier ) )
{ {
@@ -6259,7 +6248,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
} }
} }
// assume there's no problem // assume there's no problem
fProblemExists = FALSE; fProblemExists = FALSE;
@@ -6285,7 +6273,6 @@ BOOLEAN CanCharacterMoveInStrategic( SOLDIERTYPE *pSoldier, INT8 *pbErrorNumber
return( FALSE ); return( FALSE );
} }
// passed all checks - this character may move strategically! // passed all checks - this character may move strategically!
return( TRUE ); return( TRUE );
} }
@@ -6298,7 +6285,6 @@ BOOLEAN CanEntireMovementGroupMercIsInMove( SOLDIERTYPE *pSoldier, INT8 *pbError
UINT8 ubGroup = 0; UINT8 ubGroup = 0;
UINT8 ubCurrentGroup = 0; UINT8 ubCurrentGroup = 0;
// first check the requested character himself // first check the requested character himself
if( CanCharacterMoveInStrategic( pSoldier, pbErrorNumber ) == FALSE ) if( CanCharacterMoveInStrategic( pSoldier, pbErrorNumber ) == FALSE )
{ {
@@ -6306,7 +6292,6 @@ BOOLEAN CanEntireMovementGroupMercIsInMove( SOLDIERTYPE *pSoldier, INT8 *pbError
return( FALSE ); return( FALSE );
} }
// now check anybody who would be travelling with him // now check anybody who would be travelling with him
// does character have group? // does character have group?
@@ -6376,7 +6361,6 @@ BOOLEAN CanEntireMovementGroupMercIsInMove( SOLDIERTYPE *pSoldier, INT8 *pbError
} }
} }
// everybody can move... Yey! :-) // everybody can move... Yey! :-)
return( TRUE ); return( TRUE );
} }
+358 -112
View File
@@ -125,34 +125,29 @@ BOOLEAN PlayerMercsInSector_MSE( UINT8 ubSectorX, UINT8 ubSectorY, BOOLEAN fDont
return ubNumMercs; return ubNumMercs;
} }
// get any enemy group id in the sector (if no group, will return 0 ) // get any enemy group id in the sector (if no group, will return 0 )
UINT8 GetEnemyGroupIdInSector( INT16 sMapX, INT16 sMapY ) UINT8 GetEnemyGroupIdInSector( INT16 sMapX, INT16 sMapY, UINT8 usTeam )
{ {
UINT8 ubRes = 0; UINT8 ubRes = 0;
GROUP *curr; GROUP *curr = gpGroupList;
curr = gpGroupList;
while( curr ) while( curr )
{ {
if ( curr->ubSectorX == sMapX && curr->ubSectorY == sMapY && curr->usGroupTeam != OUR_TEAM ) if ( curr->ubSectorX == sMapX && curr->ubSectorY == sMapY && curr->usGroupTeam == usTeam )
{
if( !curr->ubGroupID ) if( !curr->ubGroupID )
return curr->ubGroupID; return curr->ubGroupID;
else else
ubRes = curr->ubGroupID; ubRes = curr->ubGroupID;
}
curr = curr->next; curr = curr->next;
} }
return ubRes; return ubRes;
} }
// Count all militia in the sector
UINT8 CountMilitia(SECTORINFO *pSectorInfo)
{
return pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]+
pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]+
pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA];
}
// Creates militia at destination sector. The type and amount of militia depends on current sector's miltia type and amount // Creates militia at destination sector. The type and amount of militia depends on current sector's miltia type and amount
// HEADROCK HAM 3.4: Added Leadership argument. // HEADROCK HAM 3.4: Added Leadership argument.
void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, UINT8 ubBestLeadership ) void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, UINT8 ubBestLeadership )
@@ -169,8 +164,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
SECTORINFO *pTargetSector = &( SectorInfo[ SECTOR( sTMapX, sTMapY ) ] ); SECTORINFO *pTargetSector = &( SectorInfo[ SECTOR( sTMapX, sTMapY ) ] );
//HEADROCK HAM B2.7: Track the number of militia at the source. //HEADROCK HAM B2.7: Track the number of militia at the source.
UINT16 usTotalMilitiaAtSource = pSourceSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + pSourceSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + pSourceSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; UINT16 usTotalMilitiaAtTarget = NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM );
UINT16 usTotalMilitiaAtTarget = pTargetSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + pTargetSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + pTargetSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
// Desired number of Greens, Regulars and Elites to create. // Desired number of Greens, Regulars and Elites to create.
UINT8 ubTargetGreen, ubTargetRegular, ubTargetElite; UINT8 ubTargetGreen, ubTargetRegular, ubTargetElite;
// Upgrade points for replacing militia with better ones. // Upgrade points for replacing militia with better ones.
@@ -353,7 +347,6 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
ubMilitiaToTrain = 0; ubMilitiaToTrain = 0;
} }
} }
// Full militia group? See if you can upgrade some. // Full militia group? See if you can upgrade some.
else else
{ {
@@ -437,10 +430,9 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
if( ubActualyAdded > 0 ) if( ubActualyAdded > 0 )
RecordNumMilitiaTrainedForMercs( sMapX, sMapY, 0, ubActualyAdded, TRUE ); RecordNumMilitiaTrainedForMercs( sMapX, sMapY, 0, ubActualyAdded, TRUE );
// This reduces the group back to "maximum" size. It starts by eliminating extra greens, then regulars, then elites. // This reduces the group back to "maximum" size. It starts by eliminating extra greens, then regulars, then elites.
// That produces a group of max size, with only the best troops remaining. // That produces a group of max size, with only the best troops remaining.
while( CountMilitia(pTargetSector) > gGameExternalOptions.iMaxMilitiaPerSector ) while ( NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ) > gGameExternalOptions.iMaxMilitiaPerSector )
{ {
if(pTargetSector->ubNumberOfCivsAtLevel[GREEN_MILITIA]) if(pTargetSector->ubNumberOfCivsAtLevel[GREEN_MILITIA])
{ {
@@ -541,14 +533,14 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
// Both sectors not threatened. // Both sectors not threatened.
// Alter spreadout chance based on number of troops in Source and destination sectors. // Alter spreadout chance based on number of troops in Source and destination sectors.
if ( CountMilitia(pSectorInfo) >= gGameExternalOptions.iMaxMilitiaPerSector && if ( NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM ) >= gGameExternalOptions.iMaxMilitiaPerSector &&
CountMilitia(pTSectorInfo) == 0 ) NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ) == 0 )
{ {
// Source group is full, target sector is empty. The source group gets 30% chance to // Source group is full, target sector is empty. The source group gets 30% chance to
// spread out to that empty sector. // spread out to that empty sector.
ubChanceToSpreadOut = 30; ubChanceToSpreadOut = 30;
} }
else if ( CountMilitia(pSectorInfo) && CountMilitia(pTSectorInfo) ) else if ( NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM ) && NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ) )
{ {
// Source and destination groups both exist. 50% chance to spread out evenly between them. // Source and destination groups both exist. 50% chance to spread out evenly between them.
ubChanceToSpreadOut = 50; ubChanceToSpreadOut = 50;
@@ -566,7 +558,6 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
ubChanceToSpreadOut = 0; ubChanceToSpreadOut = 0;
} }
if (!gGameExternalOptions.gfAllowMilitiaSpread ) if (!gGameExternalOptions.gfAllowMilitiaSpread )
{ {
// Spreading is not allowed by user. Let them fill up the target sector. // Spreading is not allowed by user. Let them fill up the target sector.
@@ -584,7 +575,7 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
// Should we spread out into the target sector, or move en-masse? // Should we spread out into the target sector, or move en-masse?
if (PreRandom(100) < ubChanceToSpreadOut) if (PreRandom(100) < ubChanceToSpreadOut)
{ {
if ( CountMilitia(pSectorInfo) && CountMilitia(pTSectorInfo) ) if ( NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM ) && NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ) )
{ {
// Source and Target sectors both have groups in them. Source group will attempt to spread out, // Source and Target sectors both have groups in them. Source group will attempt to spread out,
// averaging the size and composition of both groups. // averaging the size and composition of both groups.
@@ -675,8 +666,8 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
{ {
// Source team moves En-Masse to target sector. // Source team moves En-Masse to target sector.
bNewDestGroupSize = __min((CountMilitia(pTSectorInfo) + CountMilitia(pSectorInfo)), (UINT8)gGameExternalOptions.iMaxMilitiaPerSector); bNewDestGroupSize = __min( (NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ) + NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM )), (UINT8)gGameExternalOptions.iMaxMilitiaPerSector );
bNewSourceGroupSize = __max(0,(CountMilitia(pTSectorInfo) + CountMilitia(pSectorInfo)) - gGameExternalOptions.iMaxMilitiaPerSector); bNewSourceGroupSize = __max( 0, (NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ) + NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM )) - gGameExternalOptions.iMaxMilitiaPerSector );
// If there are still going to be two teams after the transfer // If there are still going to be two teams after the transfer
if ( bNewSourceGroupSize > 0 ) if ( bNewSourceGroupSize > 0 )
@@ -778,7 +769,7 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
} }
} }
while( !fAlternativeMax && CountMilitia(pTSectorInfo) > gGameExternalOptions.iMaxMilitiaPerSector ) while ( !fAlternativeMax && NumNonPlayerTeamMembersInSector( sTMapX, sTMapY, MILITIA_TEAM ) > gGameExternalOptions.iMaxMilitiaPerSector )
{ {
if(pTSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]) if(pTSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA])
{ {
@@ -805,27 +796,27 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
BOOLEAN MoveOneBestMilitiaMan(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY) BOOLEAN MoveOneBestMilitiaMan(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY)
{ {
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); if ( MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA ) )
// SECTORINFO *pTSectorInfo = &( SectorInfo[ SECTOR( sTMapX, sTMapY ) ] );
if( pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] )
{ {
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, 1 ); StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, 1 );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, 1 ); StrategicRemoveMilitiaFromSector( sMapX, sMapY, ELITE_MILITIA, 1 );
return TRUE; return TRUE;
} }
if( pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] )
if ( MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA ) )
{ {
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, 1 ); StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, 1 );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, 1 ); StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, 1 );
return TRUE; return TRUE;
} }
if( pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] )
if ( MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA ) )
{ {
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, 1 ); StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, 1 );
StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, 1 ); StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, 1 );
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
@@ -1242,8 +1233,8 @@ BOOLEAN CheckStandardConditionsForDirection( INT16 sSMapX, INT16 sSMapY, INT16 s
{ {
// Flags to store INI option settings. // Flags to store INI option settings.
BOOLEAN fAllowReinforceCities = ( gGameExternalOptions.fAllowMobileReinforceCities && gGameExternalOptions.gfmusttrainroaming && gGameExternalOptions.gfAllowMilitiaGroups ); BOOLEAN fAllowReinforceCities = (gGameExternalOptions.fAllowMobileReinforceCities && gGameExternalOptions.gfmusttrainroaming && gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand );
BOOLEAN fAllowReinforceSAM = ( gGameExternalOptions.fAllowMobileReinforceSAM && gGameExternalOptions.gfmusttrainroaming && gGameExternalOptions.gfAllowMilitiaGroups ); BOOLEAN fAllowReinforceSAM = (gGameExternalOptions.fAllowMobileReinforceSAM && gGameExternalOptions.gfmusttrainroaming && gGameExternalOptions.gfAllowMilitiaGroups && !gGameExternalOptions.fMilitiaStrategicCommand );
// Town->Town, Town->SAM, SAM->Town and SAM->SAM are disallowed for peaceful movement. // Town->Town, Town->SAM, SAM->Town and SAM->SAM are disallowed for peaceful movement.
if ( fSourceIsMajorTown || fSourceIsSamSite ) if ( fSourceIsMajorTown || fSourceIsSamSite )
@@ -1255,7 +1246,7 @@ BOOLEAN CheckStandardConditionsForDirection( INT16 sSMapX, INT16 sSMapY, INT16 s
{ {
if ( !NumNonPlayerTeamMembersInSector( sMapX, sMapY, ENEMY_TEAM ) && // Is the sector under our control at the moment? if ( !NumNonPlayerTeamMembersInSector( sMapX, sMapY, ENEMY_TEAM ) && // Is the sector under our control at the moment?
pTargetSector->fSurfaceWasEverPlayerControlled && // Has it ever been under control? pTargetSector->fSurfaceWasEverPlayerControlled && // Has it ever been under control?
CountMilitia(pTargetSector) < gGameExternalOptions.iMaxMilitiaPerSector ) // Is there room here for more militia? NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM ) < gGameExternalOptions.iMaxMilitiaPerSector ) // Is there room here for more militia?
{ {
if (fTargetIsSamSite && fAllowReinforceSAM) if (fTargetIsSamSite && fAllowReinforceSAM)
{ {
@@ -1523,7 +1514,7 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
// If we don't want roaming militia // If we don't want roaming militia
// We shouldn't be here. // We shouldn't be here.
if( !gGameExternalOptions.gfAllowMilitiaGroups ) if ( !gGameExternalOptions.gfAllowMilitiaGroups || gGameExternalOptions.fMilitiaStrategicCommand )
return; return;
if( sMapX == 1 && sMapY == 1 ) if( sMapX == 1 && sMapY == 1 )
@@ -1535,7 +1526,7 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
if( CheckInBlockMoveList( sMapX, sMapY ) ) if( CheckInBlockMoveList( sMapX, sMapY ) )
return; return;
uiMilitiaCount = CountMilitia(pSectorInfo); uiMilitiaCount = NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM );
if( !uiMilitiaCount ) if( !uiMilitiaCount )
return; return;
@@ -1644,7 +1635,7 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
if ( NumNonPlayerTeamMembersInSector( targetX, targetY, ENEMY_TEAM ) ) if ( NumNonPlayerTeamMembersInSector( targetX, targetY, ENEMY_TEAM ) )
{ {
extern GROUP *gpBattleGroup; extern GROUP *gpBattleGroup;
gpBattleGroup = GetGroup( GetEnemyGroupIdInSector( targetX, targetY ) ); gpBattleGroup = GetGroup( GetEnemyGroupIdInSector( targetX, targetY, ENEMY_TEAM ) );
/* GROUP* pEnemyGroup = GetGroup( GetEnemyGroupIdInSector( targetX, targetY ) ); /* GROUP* pEnemyGroup = GetGroup( GetEnemyGroupIdInSector( targetX, targetY ) );
if(pEnemyGroup && pEnemyGroup->ubGroupID) if(pEnemyGroup && pEnemyGroup->ubGroupID)
@@ -1703,7 +1694,7 @@ void CreateMilitiaSquads(INT16 sMapX, INT16 sMapY )
UINT8 ubBestLeadership = FindBestMilitiaTrainingLeadershipInSector ( sMapX, sMapY, 0, MOBILE_MILITIA ); UINT8 ubBestLeadership = FindBestMilitiaTrainingLeadershipInSector ( sMapX, sMapY, 0, MOBILE_MILITIA );
// If we're not allowing roaming groups, then we're not creating them either. // If we're not allowing roaming groups, then we're not creating them either.
if( !gGameExternalOptions.gfAllowMilitiaGroups ) if ( !gGameExternalOptions.gfAllowMilitiaGroups || gGameExternalOptions.fMilitiaStrategicCommand )
return; return;
// Reset block move list. Does this cause issues with training in A1? Probably not. // Reset block move list. Does this cause issues with training in A1? Probably not.
@@ -1857,7 +1848,7 @@ void DoMilitiaHelpFromAdjacentSectors( INT16 sMapX, INT16 sMapY )
guiDirNumber = uiDirNumber + 1; guiDirNumber = uiDirNumber + 1;
x = 0; x = 0;
while( CountMilitia(pSectorInfo ) < gGameExternalOptions.iMaxMilitiaPerSector && while ( NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM ) < gGameExternalOptions.iMaxMilitiaPerSector &&
( fMoreTroopsLeft[0] || fMoreTroopsLeft[1] || fMoreTroopsLeft[2] || fMoreTroopsLeft[3] || fFirstLoop ) ) ( fMoreTroopsLeft[0] || fMoreTroopsLeft[1] || fMoreTroopsLeft[2] || fMoreTroopsLeft[3] || fFirstLoop ) )
{ {
fMoreTroopsLeft[ x ] = MoveOneBestMilitiaMan( SECTORX( pMoveDir[ x ][0] ), SECTORY( pMoveDir[ x ][0] ), sMapX, sMapY ); fMoreTroopsLeft[ x ] = MoveOneBestMilitiaMan( SECTORX( pMoveDir[ x ][0] ), SECTORY( pMoveDir[ x ][0] ), sMapX, sMapY );
@@ -1946,25 +1937,33 @@ BOOLEAN CallMilitiaReinforcements( INT16 sTargetMapX, INT16 sTargetMapY, INT16 s
ZeroMemory( gpAttackDirs, sizeof( gpAttackDirs ) ); ZeroMemory( gpAttackDirs, sizeof( gpAttackDirs ) );
gpAttackDirs[ guiDirNumber ][0] = uiNumGreen = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]; gpAttackDirs[guiDirNumber][0] = uiNumGreen = MilitiaInSectorOfRank( sTargetMapX, sTargetMapY, GREEN_MILITIA );
gpAttackDirs[ guiDirNumber ][1] = uiNumReg = pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]; gpAttackDirs[guiDirNumber][1] = uiNumReg = MilitiaInSectorOfRank( sTargetMapX, sTargetMapY, REGULAR_MILITIA );
gpAttackDirs[ guiDirNumber ][2] = uiNumElite = pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA]; gpAttackDirs[guiDirNumber][2] = uiNumElite = MilitiaInSectorOfRank( sTargetMapX, sTargetMapY, ELITE_MILITIA );
gpAttackDirs[ guiDirNumber ][3] = INSERTION_CODE_CENTER; gpAttackDirs[guiDirNumber][3] = INSERTION_CODE_CENTER;
guiDirNumber = insertioncode + 1; guiDirNumber = insertioncode + 1;
// we can't move more than we are told, and can't add more than would fit into the sector
UINT16 possibletomove = min( sNumber, gGameExternalOptions.iMaxMilitiaPerSector - NumNonPlayerTeamMembersInSector( sTargetMapX, sTargetMapY, MILITIA_TEAM ) );
UINT16 sMilitiaMoved = 0; UINT16 sMilitiaMoved = 0;
while ( sMilitiaMoved < sNumber && CountMilitia(pSectorInfo ) < gGameExternalOptions.iMaxMilitiaPerSector && MoveOneBestMilitiaMan( sSrcMapX, sSrcMapY, sTargetMapX, sTargetMapY ) ) while ( sMilitiaMoved < possibletomove && MoveOneBestMilitiaMan( sSrcMapX, sSrcMapY, sTargetMapX, sTargetMapY ) )
{ {
++sMilitiaMoved; ++sMilitiaMoved;
gpAttackDirs[ guiDirNumber ][0] += pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA] - uiNumGreen; UINT8 militia_green = MilitiaInSectorOfRank( sTargetMapX, sTargetMapY, GREEN_MILITIA );
gpAttackDirs[ guiDirNumber ][1] += pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA] - uiNumReg; UINT8 militia_troop = MilitiaInSectorOfRank( sTargetMapX, sTargetMapY, REGULAR_MILITIA );
gpAttackDirs[ guiDirNumber ][2] += pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA] - uiNumElite; UINT8 militia_elite = MilitiaInSectorOfRank( sTargetMapX, sTargetMapY, ELITE_MILITIA );
gpAttackDirs[ guiDirNumber ][3] = insertioncode;
uiNumGreen = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]; gpAttackDirs[guiDirNumber][0] += militia_green - uiNumGreen;
uiNumReg = pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]; gpAttackDirs[guiDirNumber][1] += militia_troop - uiNumReg;
uiNumElite = pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA]; gpAttackDirs[guiDirNumber][2] += militia_elite - uiNumElite;
gpAttackDirs[guiDirNumber][3] = insertioncode;
uiNumGreen = militia_green;
uiNumReg = militia_troop;
uiNumElite = militia_elite;
} }
guiDirNumber = 5; guiDirNumber = 5;
@@ -1972,7 +1971,7 @@ BOOLEAN CallMilitiaReinforcements( INT16 sTargetMapX, INT16 sTargetMapY, INT16 s
if ( !sMilitiaMoved ) if ( !sMilitiaMoved )
return FALSE; return FALSE;
// we need to se this falg. If it wasn't set prior to this, we remove it again afterwards, otherwise all militia will join us if we are in combat // we need to use this flag. If it wasn't set prior to this, we remove it again afterwards, otherwise all militia will join us if we are in combat
BOOLEAN wantreinforcements = (gTacticalStatus.uiFlags & WANT_MILITIA_REINFORCEMENTS); BOOLEAN wantreinforcements = (gTacticalStatus.uiFlags & WANT_MILITIA_REINFORCEMENTS);
gTacticalStatus.uiFlags |= WANT_MILITIA_REINFORCEMENTS; gTacticalStatus.uiFlags |= WANT_MILITIA_REINFORCEMENTS;
@@ -1996,6 +1995,88 @@ BOOLEAN CallMilitiaReinforcements( INT16 sTargetMapX, INT16 sTargetMapY, INT16 s
return TRUE; return TRUE;
} }
BOOLEAN MilitiaGroupEntersCurrentSector( UINT8 usGroupId, INT16 sMapX, INT16 sMapY )
{
GROUP* pGroup = GetGroup( usGroupId );
if ( !pGroup || pGroup->usGroupTeam != MILITIA_TEAM )
return FALSE;
INT16 sSrcMapX = pGroup->ubPrevX;
INT16 sSrcMapY = pGroup->ubPrevY;
UINT8 insertioncode = INSERTION_CODE_CENTER;
UINT8 movetype = THROUGH_STRATEGIC_MOVE;
// determine from which direction militia should enter (and exit if this isn't possible)
if ( sMapX == sSrcMapX + 1 && sMapY == sSrcMapY )
{
insertioncode = INSERTION_CODE_WEST;
movetype = EAST_STRATEGIC_MOVE;
}
else if ( sMapX == sSrcMapX - 1 && sMapY == sSrcMapY )
{
insertioncode = INSERTION_CODE_EAST;
movetype = WEST_STRATEGIC_MOVE;
}
else if ( sMapX == sSrcMapX && sMapY == sSrcMapY + 1 )
{
insertioncode = INSERTION_CODE_NORTH;
movetype = SOUTH_STRATEGIC_MOVE;
}
else if ( sMapX == sSrcMapX && sMapY == sSrcMapY - 1 )
{
insertioncode = INSERTION_CODE_SOUTH;
movetype = NORTH_STRATEGIC_MOVE;
}
else
{
// no proper direction here... get out
return FALSE;
}
// test wether travel from src to target is possible ( we cannot open the src map information, we'll rely on the xml data instead
if ( SectorInfo[SECTOR( sSrcMapX, sSrcMapY )].ubTraversability[movetype] == GROUNDBARRIER || SectorInfo[SECTOR( sSrcMapX, sSrcMapY )].ubTraversability[movetype] == EDGEOFWORLD )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Militia cannot traverse to this sector due to the terrain." );
return FALSE;
}
ZeroMemory( gpAttackDirs, sizeof(gpAttackDirs) );
guiDirNumber = insertioncode + 1;
gpAttackDirs[guiDirNumber][0] = pGroup->pEnemyGroup->ubNumAdmins;
gpAttackDirs[guiDirNumber][1] = pGroup->pEnemyGroup->ubNumTroops;
gpAttackDirs[guiDirNumber][2] = pGroup->pEnemyGroup->ubNumElites;
gpAttackDirs[guiDirNumber][3] = insertioncode;
guiDirNumber = 5;
// we need to use this flag. If it wasn't set prior to this, we remove it again afterwards, otherwise all militia will join us if we are in combat
BOOLEAN wantreinforcements = (gTacticalStatus.uiFlags & WANT_MILITIA_REINFORCEMENTS);
gTacticalStatus.uiFlags |= WANT_MILITIA_REINFORCEMENTS;
if ( is_networked )
{
if ( gfStrategicMilitiaChangesMade )
{
RemoveMilitiaFromTactical( );
if ( is_server && gMilitiaEnabled == 1 )
PrepareMilitiaForTactical( FALSE );
}
}
else
PrepareMilitiaForTactical( FALSE );
if ( !wantreinforcements )
gTacticalStatus.uiFlags &= ~WANT_MILITIA_REINFORCEMENTS;
gfStrategicMilitiaChangesMade = FALSE;
return TRUE;
}
void MSCallBack( UINT8 ubResult ) void MSCallBack( UINT8 ubResult )
{ {
if( ubResult == MSG_BOX_RETURN_YES ) if( ubResult == MSG_BOX_RETURN_YES )
@@ -2152,15 +2233,13 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
// Check north // Check north
if( sMapY > MINIMUM_VALID_Y_COORDINATE ) if( sMapY > MINIMUM_VALID_Y_COORDINATE )
{ {
pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY - 1 ) ] );
// Are militia allowed to travel in that direction from the current sector, for training purposes? // Are militia allowed to travel in that direction from the current sector, for training purposes?
if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX, sMapY - 1, TRUE, FALSE ) ) if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX, sMapY - 1, TRUE, FALSE ) )
{ {
// Count free slots. Each slot is worth 3 points. // Count free slots. Each slot is worth 3 points.
usMilitiaCapacity = 3 * (ubMaxMilitia - CountMilitia( pSectorInfo )); usMilitiaCapacity = 3 * (ubMaxMilitia - NumNonPlayerTeamMembersInSector( sMapX, sMapY - 1, MILITIA_TEAM ));
// Count militia that can be upgraded. Regular = 1 point, Green = 2 points. // Count militia that can be upgraded. Regular = 1 point, Green = 2 points.
usUpgradeCapacity = MilitiaUpgradeSlotsCheck( pSectorInfo ); usUpgradeCapacity = MilitiaUpgradeSlotsCheck( sMapX, sMapY - 1 );
// Found at least one slot here? // Found at least one slot here?
if (usUpgradeCapacity || usMilitiaCapacity) if (usUpgradeCapacity || usMilitiaCapacity)
@@ -2170,9 +2249,9 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity; pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity;
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_NORTH; pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_NORTH;
#ifdef DEBUG_SHOW_RATINGS #ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]); if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif #endif
++(*uiDirNumber); ++(*uiDirNumber);
} }
@@ -2182,15 +2261,13 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
// Check west // Check west
if( sMapX > MINIMUM_VALID_X_COORDINATE ) if( sMapX > MINIMUM_VALID_X_COORDINATE )
{ {
pSectorInfo = &( SectorInfo[ SECTOR( sMapX - 1, sMapY ) ] );
// Are militia allowed to travel in that direction from the current sector, for training purposes? // Are militia allowed to travel in that direction from the current sector, for training purposes?
if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX - 1, sMapY, TRUE, FALSE ) ) if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX - 1, sMapY, TRUE, FALSE ) )
{ {
// Count free slots. Each slot is worth 3 points. // Count free slots. Each slot is worth 3 points.
usMilitiaCapacity = 3 * (ubMaxMilitia - CountMilitia( pSectorInfo )); usMilitiaCapacity = 3 * (ubMaxMilitia - NumNonPlayerTeamMembersInSector( sMapX - 1, sMapY, MILITIA_TEAM ));
// Count militia that can be upgraded. Regular = 1 point, Green = 2 points. // Count militia that can be upgraded. Regular = 1 point, Green = 2 points.
usUpgradeCapacity = MilitiaUpgradeSlotsCheck( pSectorInfo ); usUpgradeCapacity = MilitiaUpgradeSlotsCheck( sMapX - 1, sMapY );
// Found at least one slot here? // Found at least one slot here?
if (usUpgradeCapacity || usMilitiaCapacity) if (usUpgradeCapacity || usMilitiaCapacity)
@@ -2200,9 +2277,9 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity; pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity;
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_WEST; pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_WEST;
#ifdef DEBUG_SHOW_RATINGS #ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]); if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif #endif
++(*uiDirNumber); ++(*uiDirNumber);
} }
@@ -2212,15 +2289,13 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
// Check south // Check south
if( sMapY < MAXIMUM_VALID_Y_COORDINATE ) if( sMapY < MAXIMUM_VALID_Y_COORDINATE )
{ {
pSectorInfo = &( SectorInfo[ SECTOR( sMapX , sMapY + 1 ) ] );
// Are militia allowed to travel in that direction from the current sector, for training purposes? // Are militia allowed to travel in that direction from the current sector, for training purposes?
if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX, sMapY + 1, TRUE, FALSE ) ) if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX, sMapY + 1, TRUE, FALSE ) )
{ {
// Count free slots. Each slot is worth 3 points. // Count free slots. Each slot is worth 3 points.
usMilitiaCapacity = 3 * (ubMaxMilitia - CountMilitia( pSectorInfo )); usMilitiaCapacity = 3 * (ubMaxMilitia - NumNonPlayerTeamMembersInSector( sMapX, sMapY + 1, MILITIA_TEAM ));
// Count militia that can be upgraded. Regular = 1 point, Green = 2 points. // Count militia that can be upgraded. Regular = 1 point, Green = 2 points.
usUpgradeCapacity = MilitiaUpgradeSlotsCheck( pSectorInfo ); usUpgradeCapacity = MilitiaUpgradeSlotsCheck( sMapX, sMapY + 1 );
// Found at least one slot here? // Found at least one slot here?
if (usUpgradeCapacity || usMilitiaCapacity) if (usUpgradeCapacity || usMilitiaCapacity)
@@ -2230,9 +2305,9 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity; pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity;
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_SOUTH; pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_SOUTH;
#ifdef DEBUG_SHOW_RATINGS #ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]); if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif #endif
++(*uiDirNumber); ++(*uiDirNumber);
} }
@@ -2242,15 +2317,13 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
// Check east // Check east
if( sMapX < MAXIMUM_VALID_X_COORDINATE ) if( sMapX < MAXIMUM_VALID_X_COORDINATE )
{ {
pSectorInfo = &( SectorInfo[ SECTOR( sMapX + 1 , sMapY ) ] );
// Are militia allowed to travel in that direction from the current sector, for training purposes? // Are militia allowed to travel in that direction from the current sector, for training purposes?
if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX +1 , sMapY, TRUE, FALSE ) ) if ( CheckStandardConditionsForDirection( sMapX, sMapY, sMapX +1 , sMapY, TRUE, FALSE ) )
{ {
// Count free slots. Each slot is worth 3 points. // Count free slots. Each slot is worth 3 points.
usMilitiaCapacity = 3 * (ubMaxMilitia - CountMilitia( pSectorInfo )); usMilitiaCapacity = 3 * (ubMaxMilitia - NumNonPlayerTeamMembersInSector( sMapX + 1, sMapY, MILITIA_TEAM ) );
// Count militia that can be upgraded. Regular = 1 point, Green = 2 points. // Count militia that can be upgraded. Regular = 1 point, Green = 2 points.
usUpgradeCapacity = MilitiaUpgradeSlotsCheck( pSectorInfo ); usUpgradeCapacity = MilitiaUpgradeSlotsCheck( sMapX + 1, sMapY );
// Found at least one slot here? // Found at least one slot here?
if (usUpgradeCapacity || usMilitiaCapacity) if (usUpgradeCapacity || usMilitiaCapacity)
@@ -2260,9 +2333,9 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity; pMoveDir[ *uiDirNumber ][1] = usMilitiaCapacity + usUpgradeCapacity;
pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_EAST; pMoveDir[ *uiDirNumber ][2] = INSERTION_CODE_EAST;
#ifdef DEBUG_SHOW_RATINGS #ifdef DEBUG_SHOW_RATINGS
if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]); if( DEBUG_RATINGS_CONDITION )ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Priority of north direction - %ld", pMoveDir[ *uiDirNumber ][1]);
#endif #endif
++(*uiDirNumber); ++(*uiDirNumber);
} }
@@ -2325,13 +2398,13 @@ BOOLEAN IsSectorRoamingAllowed( UINT32 uiSector )
// HEADROCK HAM 3.6: Function returns the number of "upgrade slots" available at target sector. Basically, every GREEN // HEADROCK HAM 3.6: Function returns the number of "upgrade slots" available at target sector. Basically, every GREEN
// Militia at the target sector counts as 2 upgrade slots, while every regular counts as 1. // Militia at the target sector counts as 2 upgrade slots, while every regular counts as 1.
UINT16 MilitiaUpgradeSlotsCheck( SECTORINFO * pSectorInfo ) UINT16 MilitiaUpgradeSlotsCheck( INT16 sMapX, INT16 sMapY )
{ {
// Result variables // Result variables
UINT16 usNumUpgradeSlots = 0; UINT16 usNumUpgradeSlots = 0;
// Target sector full of elites? // Target sector full of elites?
if (pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA] >= gGameExternalOptions.iMaxMilitiaPerSector) if ( MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA ) >= gGameExternalOptions.iMaxMilitiaPerSector )
{ {
// Militia cannot be placed or moved here at all. // Militia cannot be placed or moved here at all.
return 0; return 0;
@@ -2342,21 +2415,21 @@ UINT16 MilitiaUpgradeSlotsCheck( SECTORINFO * pSectorInfo )
(GetWorldDay( ) < gGameExternalOptions.guiTrainVeteranMilitiaDelay)) // Not yet allowed. (GetWorldDay( ) < gGameExternalOptions.guiTrainVeteranMilitiaDelay)) // Not yet allowed.
{ {
// If sector full of Regulars and Elites? // If sector full of Regulars and Elites?
if (pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]+pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA] >= gGameExternalOptions.iMaxMilitiaPerSector) // Target sector full of regular+elite militia if ( MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA ) + MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA ) >= gGameExternalOptions.iMaxMilitiaPerSector ) // Target sector full of regular+elite militia
{ {
// Can't upgrade Regulars to Elites, so the sector is already full. // Can't upgrade Regulars to Elites, so the sector is already full.
return 0; return 0;
} }
// Each Green we can convert to Regular counts as 2 slots. // Each Green we can convert to Regular counts as 2 slots.
usNumUpgradeSlots = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA] * 2; usNumUpgradeSlots = MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA ) * 2;
return (usNumUpgradeSlots); return (usNumUpgradeSlots);
} }
// Allowed to train Green->Regular, and Regular->Elite // Allowed to train Green->Regular, and Regular->Elite
usNumUpgradeSlots = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA] * 2; usNumUpgradeSlots = MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA ) * 2;
usNumUpgradeSlots += pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]; usNumUpgradeSlots += MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA );
return (usNumUpgradeSlots); return (usNumUpgradeSlots);
} }
@@ -2482,26 +2555,20 @@ UINT8 GetMobileMilitiaQuota( BOOLEAN printMessage )
{ {
// we have found a town (no sam site) // we have found a town (no sam site)
if ( StrategicMap[ iStrategicMapID ].fEnemyControlled == FALSE ) if ( !StrategicMap[ iStrategicMapID ].fEnemyControlled )
iTownSectorsUnderPlayerControl++; // remember player currently controls that town sector ++iTownSectorsUnderPlayerControl; // remember player currently controls that town sector
if ( pSectorInfo->fSurfaceWasEverPlayerControlled == TRUE ) if ( pSectorInfo->fSurfaceWasEverPlayerControlled )
iTownSectorsLiberatedAtLeastOnce++; // remember player had allready liberated that town sector once ++iTownSectorsLiberatedAtLeastOnce; // remember player had allready liberated that town sector once
if ( MilitiaTrainingAllowedInTown( iCurrT_ID ) == FALSE ) // considered as mobile only if in that town training is taboo (Tixa, Omerta..) if ( MilitiaTrainingAllowedInTown( iCurrT_ID ) == FALSE ) // considered as mobile only if in that town training is taboo (Tixa, Omerta..)
iActiveMobiles += CountMilitia( pSectorInfo ); iActiveMobiles += NumNonPlayerTeamMembersInSector( SECTORX( iSectorInfoID ), SECTORY( iSectorInfoID ), MILITIA_TEAM );
//for ( UINT8 militiaLevel = 0; militiaLevel < MAX_MILITIA_LEVELS; militiaLevel++ )
// iActiveMobiles += pSectorInfo->ubNumberOfCivsAtLevel[ militiaLevel ]; // remember number of roaming militia in that town sector (green, regular, elite, ..)
} }
//else if ( StrategicMap[ iStrategicMapID ].bSAMCondition > 0 ) //faster then below, but not safe //else if ( StrategicMap[ iStrategicMapID ].bSAMCondition > 0 ) //faster then below, but not safe
else if ( MilitiaTrainingAllowedInSector( SECTORX(iSectorInfoID), SECTORY(iSectorInfoID), 0 ) == FALSE ) else if ( MilitiaTrainingAllowedInSector( SECTORX(iSectorInfoID), SECTORY(iSectorInfoID), 0 ) == FALSE )
{ {
// we are in wilderness // we are in wilderness
iActiveMobiles += NumNonPlayerTeamMembersInSector( SECTORX( iSectorInfoID ), SECTORY( iSectorInfoID ), MILITIA_TEAM );
//for ( UINT8 militiaLevel = 0; militiaLevel < MAX_MILITIA_LEVELS; militiaLevel++ )
// iActiveMobiles += pSectorInfo->ubNumberOfCivsAtLevel[ militiaLevel ]; // remember number of roaming militia in that sector (green, regular, elite, ..)
iActiveMobiles += CountMilitia( pSectorInfo );
} }
} }
@@ -2698,39 +2765,33 @@ void MobileMilitiaDeserters(INT16 sMapX, INT16 sMapY, BOOLEAN fDeleteEquip, BOOL
/////////////////////// ///////////////////////
// check enemy presence to decide if mobiles are threatened and some will desert. // 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. // 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, eTanks = 0;
//enemies in current sector //enemies in current sector
GetNumberOfEnemiesInSector( sMapX, sMapY, &eAdmins, &eTroops, &eElites, &eTanks ); if ( NumNonPlayerTeamMembersInSector( sMapX, sMapY, ENEMY_TEAM ) )
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) )
enemiesNear = TRUE; enemiesNear = TRUE;
if ( ( sMapX > MINIMUM_VALID_X_COORDINATE ) && !enemiesNear ) if ( ( sMapX > MINIMUM_VALID_X_COORDINATE ) && !enemiesNear )
{ {
//left side //left side
GetNumberOfEnemiesInSector( sMapX - 1, sMapY, &eAdmins, &eTroops, &eElites, &eTanks ); if ( NumNonPlayerTeamMembersInSector( sMapX - 1, sMapY, ENEMY_TEAM ) )
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE; enemiesNear = TRUE;
} }
if ( ( sMapX < MAXIMUM_VALID_X_COORDINATE ) && !enemiesNear) if ( ( sMapX < MAXIMUM_VALID_X_COORDINATE ) && !enemiesNear)
{ {
//right side //right side
GetNumberOfEnemiesInSector( sMapX + 1, sMapY, &eAdmins, &eTroops, &eElites, &eTanks ); if ( NumNonPlayerTeamMembersInSector( sMapX + 1, sMapY, ENEMY_TEAM ) )
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE; enemiesNear = TRUE;
} }
if ( ( sMapY > MINIMUM_VALID_Y_COORDINATE ) && !enemiesNear ) if ( ( sMapY > MINIMUM_VALID_Y_COORDINATE ) && !enemiesNear )
{ {
//top side //top side
GetNumberOfEnemiesInSector( sMapX, sMapY - 1, &eAdmins, &eTroops, &eElites, &eTanks ); if ( NumNonPlayerTeamMembersInSector( sMapX, sMapY - 1, ENEMY_TEAM ) )
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE; enemiesNear = TRUE;
} }
if ( ( sMapY < MAXIMUM_VALID_Y_COORDINATE ) && !enemiesNear) if ( ( sMapY < MAXIMUM_VALID_Y_COORDINATE ) && !enemiesNear)
{ {
//bottom side //bottom side
GetNumberOfEnemiesInSector( sMapX, sMapY + 1, &eAdmins, &eTroops, &eElites, &eTanks ); if ( NumNonPlayerTeamMembersInSector( sMapX, sMapY + 1, ENEMY_TEAM ) )
if ( (eAdmins > 0) || (eTroops > 0) ||(eElites > 0) || (eTanks > 0) )
enemiesNear = TRUE; enemiesNear = TRUE;
} }
@@ -2742,8 +2803,8 @@ void MobileMilitiaDeserters(INT16 sMapX, INT16 sMapY, BOOLEAN fDeleteEquip, BOOL
if (quota > 100) //more active then allowed if (quota > 100) //more active then allowed
{ {
UINT8 militiaGreen = SectorInfo[ SECTOR( sMapX, sMapY) ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ]; UINT8 militiaGreen = MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA );
UINT8 militiaRegular = SectorInfo[ SECTOR( sMapX, sMapY) ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]; UINT8 militiaRegular = MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA );
desertersGreen = (quota - 100) * militiaGreen / 100; desertersGreen = (quota - 100) * militiaGreen / 100;
desertersGreen = Random( min( militiaGreen, desertersGreen ) );//cant remove more then actually exist in that group desertersGreen = Random( min( militiaGreen, desertersGreen ) );//cant remove more then actually exist in that group
@@ -2799,3 +2860,188 @@ void MobileMilitiaDeserters(INT16 sMapX, INT16 sMapY, BOOLEAN fDeleteEquip, BOOL
ResetMilitia(); ResetMilitia();
} }
} }
#include "mapscreen.h"
#include "Strategic Pathing.h"
#include "GameVersion.h"
// Flugente: militia movement
BOOLEAN SaveMilitiaMovementInformationToSaveGameFile( HWFILE hFile )
{
UINT32 uiNumBytesWritten = 0;
UINT8 number = MILITIA_PATROLS_MAX;
//Save the number of elements
FileWrite( hFile, &number, sizeof(UINT8), &uiNumBytesWritten );
if ( uiNumBytesWritten != sizeof(UINT8) )
{
return(FALSE);
}
for ( UINT8 cnt = 0; cnt < MILITIA_PATROLS_MAX; ++cnt )
{
UINT32 uiNumOfNodes = 0;
PathStPtr pTempPath = gMilitiaPath[cnt].path;
uiNumBytesWritten = 0;
//loop through to get all the nodes
while ( pTempPath )
{
++uiNumOfNodes;
pTempPath = pTempPath->pNext;
}
//Save the number of the nodes
FileWrite( hFile, &uiNumOfNodes, sizeof(UINT32), &uiNumBytesWritten );
if ( uiNumBytesWritten != sizeof(UINT32) )
{
return(FALSE);
}
//loop through all the nodes and add them
pTempPath = gMilitiaPath[cnt].path;
//loop through nodes and save all the nodes
while ( pTempPath )
{
//Save the number of the nodes
FileWrite( hFile, pTempPath, sizeof(PathSt), &uiNumBytesWritten );
if ( uiNumBytesWritten != sizeof(PathSt) )
{
return(FALSE);
}
pTempPath = pTempPath->pNext;
}
//Save the group id
FileWrite( hFile, &gMilitiaPath[cnt].sGroupid, sizeof(INT16), &uiNumBytesWritten );
if ( uiNumBytesWritten != sizeof(INT16) )
{
return(FALSE);
}
}
return(TRUE);
}
BOOLEAN LoadMilitiaMovementInformationFromSavedGameFile( HWFILE hFile, UINT32 uiSavedGameVersion )
{
UINT32 uiNumBytesRead;
UINT32 uiTotalNodeCount = 0;
UINT8 cnt;
UINT32 uiNodeCount = 0;
PathSt *pPath = NULL;
UINT8 ubPassengerCnt = 0;
PathSt *pTempPath;
UINT8 numpaths = 0;
DeleteAllMilitiaPaths( );
// if this is an older savegame, nothing to read
if ( uiSavedGameVersion < MILITIA_PATH_PLOTTING )
return TRUE;
//Load the number of elements
FileRead( hFile, &numpaths, sizeof(UINT8), &uiNumBytesRead );
if ( uiNumBytesRead != sizeof(UINT8) )
{
return(FALSE);
}
if ( numpaths != MILITIA_PATROLS_MAX )
return(FALSE);
for ( UINT32 cnt = 0; cnt < MILITIA_PATROLS_MAX; ++cnt )
{
UINT32 uiNumOfNodes = 0;
PathStPtr pTempPath = NULL;
PathStPtr pTemp = NULL;
UINT32 uiNumBytesRead = 0;
INT16 groupid = 0;
//Load the number of the nodes
FileRead( hFile, &uiNumOfNodes, sizeof(UINT32), &uiNumBytesRead );
if ( uiNumBytesRead != sizeof(UINT32) )
{
return(FALSE);
}
//load all the nodes
for ( UINT32 cnt2 = 0; cnt2 < uiNumOfNodes; ++cnt2 )
{
//Allocate memory for the new node
pTemp = (PathStPtr)MemAlloc( sizeof(PathSt) );
if ( pTemp == NULL )
{
pTempPath = MoveToBeginningOfPathList( pTempPath );
ClearStrategicPathList( pTempPath, -1 );
return(FALSE);
}
memset( pTemp, 0, sizeof(PathSt) );
//Load the node
FileRead( hFile, pTemp, sizeof(PathSt), &uiNumBytesRead );
if ( uiNumBytesRead != sizeof(PathSt) )
{
MemFree( pTemp );
pTempPath = MoveToBeginningOfPathList( pTempPath );
ClearStrategicPathList( pTempPath, -1 );
return(FALSE);
}
//Put the node into the list
if ( cnt2 == 0 )
{
pTempPath = pTemp;
pTemp->pPrev = NULL;
}
else
{
pTempPath->pNext = pTemp;
pTemp->pPrev = pTempPath;
pTempPath = pTempPath->pNext;
}
pTemp->pNext = NULL;
}
//move to beginning of list
pTempPath = MoveToBeginningOfPathList( pTempPath );
gMilitiaPath[cnt].path = pTempPath;
if ( gMilitiaPath[cnt].path )
gMilitiaPath[cnt].path->pPrev = NULL;
//Load the number of the nodes
FileRead( hFile, &groupid, sizeof(INT16), &uiNumBytesRead );
if ( uiNumBytesRead != sizeof(INT16) )
{
return(FALSE);
}
gMilitiaPath[cnt].sGroupid = groupid;
}
return(TRUE);
}
// delete a militia group and transfer its militia to the sector they are in
void DissolveMilitiaGroup( UINT8 uGroupId )
{
GROUP* pGroup = GetGroup( uGroupId );
if ( pGroup && pGroup->usGroupTeam == MILITIA_TEAM )
{
StrategicAddMilitiaToSector( pGroup->ubSectorX, pGroup->ubSectorY, GREEN_MILITIA, pGroup->pEnemyGroup->ubNumAdmins );
StrategicAddMilitiaToSector( pGroup->ubSectorX, pGroup->ubSectorY, REGULAR_MILITIA, pGroup->pEnemyGroup->ubNumTroops );
StrategicAddMilitiaToSector( pGroup->ubSectorX, pGroup->ubSectorY, ELITE_MILITIA, pGroup->pEnemyGroup->ubNumElites );
RemovePGroup( pGroup );
}
}
+10 -3
View File
@@ -56,12 +56,10 @@ BOOLEAN IsSectorRoamingAllowed( UINT32 uiSector );
// HEADROCK HAM 3.6: New upgrade check returns the amount of militia that can be upgraded at target sector, in // HEADROCK HAM 3.6: New upgrade check returns the amount of militia that can be upgraded at target sector, in
// "upgrade points" // "upgrade points"
UINT16 MilitiaUpgradeSlotsCheck( SECTORINFO * pSectorInfo ); UINT16 MilitiaUpgradeSlotsCheck( INT16 sMapX, INT16 sMapY );
// HEADROCK HAM 3.6: This needs to be accessible. // HEADROCK HAM 3.6: This needs to be accessible.
void AddToBlockMoveList(INT16 sMapX, INT16 sMapY); void AddToBlockMoveList(INT16 sMapX, INT16 sMapY);
// And this:
UINT8 CountMilitia(SECTORINFO *pSectorInfo);
// HEADROCK HAM 4: Returns whether sector is allowed for militia roaming, taking into account player-set restrictions. // HEADROCK HAM 4: Returns whether sector is allowed for militia roaming, taking into account player-set restrictions.
UINT8 ManualMobileMovementAllowed( UINT8 ubSector ); UINT8 ManualMobileMovementAllowed( UINT8 ubSector );
@@ -73,4 +71,13 @@ void InitManualMobileRestrictions();
extern void MobileMilitiaDeserters( INT16 sMapX, INT16 sMapY, BOOLEAN fDeleteEquip, BOOLEAN fPrintMessage ); extern void MobileMilitiaDeserters( INT16 sMapX, INT16 sMapY, BOOLEAN fDeleteEquip, BOOLEAN fPrintMessage );
extern UINT8 GetMobileMilitiaQuota( BOOLEAN printMessage ); extern UINT8 GetMobileMilitiaQuota( BOOLEAN printMessage );
// Flugente: militia movement
BOOLEAN SaveMilitiaMovementInformationToSaveGameFile( HWFILE hFile );
BOOLEAN LoadMilitiaMovementInformationFromSavedGameFile( HWFILE hFile, UINT32 uiSavedGameVersion );
// delete a militia group and transfer its militia to the sector they are in
void DissolveMilitiaGroup( UINT8 uGroupId );
BOOLEAN MilitiaGroupEntersCurrentSector( UINT8 usGroupId, INT16 sMapX, INT16 sMapY );
#endif #endif
+39 -32
View File
@@ -225,7 +225,7 @@ void ValidateAndCorrectInBattleCounters( GROUP *pLocGroup )
{ {
if( pGroup->pEnemyGroup->ubAdminsInBattle || pGroup->pEnemyGroup->ubTroopsInBattle || pGroup->pEnemyGroup->ubElitesInBattle || pGroup->pEnemyGroup->ubTanksInBattle ) if( pGroup->pEnemyGroup->ubAdminsInBattle || pGroup->pEnemyGroup->ubTroopsInBattle || pGroup->pEnemyGroup->ubElitesInBattle || pGroup->pEnemyGroup->ubTanksInBattle )
{ {
ubInvalidGroups++; ++ubInvalidGroups;
pGroup->pEnemyGroup->ubAdminsInBattle = 0; pGroup->pEnemyGroup->ubAdminsInBattle = 0;
pGroup->pEnemyGroup->ubTroopsInBattle = 0; pGroup->pEnemyGroup->ubTroopsInBattle = 0;
pGroup->pEnemyGroup->ubElitesInBattle = 0; pGroup->pEnemyGroup->ubElitesInBattle = 0;
@@ -279,7 +279,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
BOOLEAN fScoutPresent = FALSE; // Added by SANDRO BOOLEAN fScoutPresent = FALSE; // Added by SANDRO
// ARM: Feb01/98 - Cancel out of mapscreen movement plotting if PBI subscreen is coming up // ARM: Feb01/98 - Cancel out of mapscreen movement plotting if PBI subscreen is coming up
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia )
{ {
AbortMovementPlottingMode( ); AbortMovementPlottingMode( );
} }
@@ -305,18 +305,18 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
gfBlitBattleSectorLocator = TRUE; gfBlitBattleSectorLocator = TRUE;
gfBlinkHeader = FALSE; gfBlinkHeader = FALSE;
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( pBattleGroup ) if( pBattleGroup )
{ {
ValidateAndCorrectInBattleCounters( pBattleGroup ); ValidateAndCorrectInBattleCounters( pBattleGroup );
} }
#endif #endif
// InitializeTacticalStatusAtBattleStart(); // InitializeTacticalStatusAtBattleStart();
// CJC, Oct 5 98: this is all we should need from InitializeTacticalStatusAtBattleStart() // CJC, Oct 5 98: this is all we should need from InitializeTacticalStatusAtBattleStart()
if( gubEnemyEncounterCode != BLOODCAT_AMBUSH_CODE && gubEnemyEncounterCode != ENTERING_BLOODCAT_LAIR_CODE ) if( gubEnemyEncounterCode != BLOODCAT_AMBUSH_CODE && gubEnemyEncounterCode != ENTERING_BLOODCAT_LAIR_CODE )
{ {
if ( CheckFact( FACT_FIRST_BATTLE_FOUGHT, 0 ) == FALSE ) if ( !CheckFact( FACT_FIRST_BATTLE_FOUGHT, 0 ) )
{ {
SetFactTrue( FACT_FIRST_BATTLE_BEING_FOUGHT ); SetFactTrue( FACT_FIRST_BATTLE_BEING_FOUGHT );
} }
@@ -324,17 +324,17 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
//If we are currently in the AI Viewer development utility, then remove it first. It automatically //If we are currently in the AI Viewer development utility, then remove it first. It automatically
//returns to the mapscreen upon removal, which is where we want to go. //returns to the mapscreen upon removal, which is where we want to go.
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( guiCurrentScreen == AIVIEWER_SCREEN ) if( guiCurrentScreen == AIVIEWER_SCREEN )
{ {
gfExitViewer = TRUE; gfExitViewer = TRUE;
gpBattleGroup = pBattleGroup; gpBattleGroup = pBattleGroup;
gfEnteringMapScreen = TRUE; gfEnteringMapScreen = TRUE;
gfEnteringMapScreenToEnterPreBattleInterface = TRUE; gfEnteringMapScreenToEnterPreBattleInterface = TRUE;
gfUsePersistantPBI = TRUE; gfUsePersistantPBI = TRUE;
return; return;
} }
#endif #endif
// ATE: Added check for fPersistantPBI = TRUE if pBattleGroup == NULL // ATE: Added check for fPersistantPBI = TRUE if pBattleGroup == NULL
// Searched code and saw that this condition only happens for creatures // Searched code and saw that this condition only happens for creatures
@@ -386,19 +386,23 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
pSector = &SectorInfo[ SECTOR( gubPBSectorX, gubPBSectorY ) ]; pSector = &SectorInfo[ SECTOR( gubPBSectorX, gubPBSectorY ) ];
if( !gfPersistantPBI ) if( !gfPersistantPBI )
{ //calculate the non-persistant situation {
//calculate the non-persistant situation
gfBlinkHeader = TRUE; gfBlinkHeader = TRUE;
if( HostileCiviliansPresent() ) if( HostileCiviliansPresent() )
{ //There are hostile civilians, so no autoresolve allowed. {
//There are hostile civilians, so no autoresolve allowed.
gubExplicitEnemyEncounterCode = HOSTILE_CIVILIANS_CODE; gubExplicitEnemyEncounterCode = HOSTILE_CIVILIANS_CODE;
} }
else if( HostileBloodcatsPresent() ) else if( HostileBloodcatsPresent() )
{ //There are bloodcats in the sector, so no autoresolve allowed {
//There are bloodcats in the sector, so no autoresolve allowed
gubExplicitEnemyEncounterCode = HOSTILE_BLOODCATS_CODE; gubExplicitEnemyEncounterCode = HOSTILE_BLOODCATS_CODE;
} }
else if( gbWorldSectorZ > 0 ) else if( gbWorldSectorZ > 0 )
{ //We are underground, so no autoresolve allowed {
//We are underground, so no autoresolve allowed
if( pSector->ubCreaturesInBattle ) if( pSector->ubCreaturesInBattle )
{ {
gubExplicitEnemyEncounterCode = FIGHTING_CREATURES_CODE; gubExplicitEnemyEncounterCode = FIGHTING_CREATURES_CODE;
@@ -507,7 +511,6 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
// ARM: this must now be set before any calls utilizing the GetCurrentBattleSectorXYZ() function // ARM: this must now be set before any calls utilizing the GetCurrentBattleSectorXYZ() function
gfPreBattleInterfaceActive = TRUE; gfPreBattleInterfaceActive = TRUE;
CheckForRobotAndIfItsControlled(); CheckForRobotAndIfItsControlled();
// wake everyone up // wake everyone up
@@ -516,7 +519,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
//Count the number of players involved or not involved in this battle //Count the number of players involved or not involved in this battle
guiNumUninvolved = 0; guiNumUninvolved = 0;
guiNumInvolved = 0; guiNumInvolved = 0;
for( i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; i++ ) for( i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++i )
{ {
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) ) if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) )
{ {
@@ -524,7 +527,8 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
{ {
// involved // involved
if( !ubGroupID ) if( !ubGroupID )
{ //Record the first groupID. If there are more than one group in this battle, we {
//Record the first groupID. If there are more than one group in this battle, we
//can detect it by comparing the first value with future values. If we do, then //can detect it by comparing the first value with future values. If we do, then
//we set a flag which determines whether to use the singular help text or plural version //we set a flag which determines whether to use the singular help text or plural version
//for the retreat button. //for the retreat button.
@@ -546,7 +550,8 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
{ {
fUsePluralVersion = TRUE; fUsePluralVersion = TRUE;
} }
guiNumInvolved ++;
++guiNumInvolved;
// SANDRO - added check if we have a scout in group, needed later // SANDRO - added check if we have a scout in group, needed later
if( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( MercPtrs[ i ], SCOUTING_NT ) && gSkillTraitValues.fSCPreventsTheEnemyToAmbushMercs ) if( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( MercPtrs[ i ], SCOUTING_NT ) && gSkillTraitValues.fSCPreventsTheEnemyToAmbushMercs )
@@ -554,8 +559,9 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
fScoutPresent = TRUE; fScoutPresent = TRUE;
} }
} }
else { else
guiNumUninvolved++; {
++guiNumUninvolved;
} }
} }
} }
@@ -569,7 +575,8 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
if( gfPersistantPBI ) if( gfPersistantPBI )
{ {
if( !pBattleGroup ) if( !pBattleGroup )
{ //creature's attacking! {
//creature's attacking!
gubEnemyEncounterCode = CREATURE_ATTACK_CODE; gubEnemyEncounterCode = CREATURE_ATTACK_CODE;
} }
else if ( gpBattleGroup->usGroupTeam == OUR_TEAM ) else if ( gpBattleGroup->usGroupTeam == OUR_TEAM )
@@ -709,7 +716,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
// SANDRO - merc records - ambush experienced // SANDRO - merc records - ambush experienced
if( gubEnemyEncounterCode == ENEMY_AMBUSH_CODE || gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE || fAmbushPrevented ) if( gubEnemyEncounterCode == ENEMY_AMBUSH_CODE || gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE || fAmbushPrevented )
{ {
for( i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; i++ ) for( i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++i )
{ {
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) ) if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) )
{ {
+42 -32
View File
@@ -177,7 +177,7 @@ UINT8 NumHostilesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY ) if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->usGroupTeam != MILITIA_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{ {
ubNumHostiles += pGroup->ubGroupSize; ubNumHostiles += pGroup->ubGroupSize;
} }
@@ -221,7 +221,7 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY ) if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->usGroupTeam != MILITIA_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{ {
ubNumEnemies += pGroup->ubGroupSize; ubNumEnemies += pGroup->ubGroupSize;
} }
@@ -281,7 +281,7 @@ UINT8 NumNonPlayerTeamMembersInSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubT
return ubNumTroops; return ubNumTroops;
} }
UINT16 NumEnemyTanksInSector( INT16 sSectorX, INT16 sSectorY ) UINT16 NumTanksInSector( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
@@ -303,7 +303,9 @@ UINT16 NumEnemyTanksInSector( INT16 sSectorX, INT16 sSectorY )
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE ); AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )]; pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )];
ubNum = (UINT16)(pSector->ubNumTanks);
if ( usTeam == ENEMY_TEAM )
ubNum = (UINT16)(pSector->ubNumTanks);
// TODO // TODO
//if ( is_networked ) //if ( is_networked )
@@ -312,7 +314,7 @@ UINT16 NumEnemyTanksInSector( INT16 sSectorX, INT16 sSectorY )
pGroup = gpGroupList; pGroup = gpGroupList;
while ( pGroup ) while ( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY ) if ( pGroup->usGroupTeam == usTeam && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{ {
ubNum += pGroup->pEnemyGroup->ubNumTanks; ubNum += pGroup->pEnemyGroup->ubNumTanks;
} }
@@ -363,7 +365,7 @@ UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY ) if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->usGroupTeam != MILITIA_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{ {
ubNumTroops += pGroup->ubGroupSize; ubNumTroops += pGroup->ubGroupSize;
} }
@@ -372,7 +374,8 @@ UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
if( pSector->ubGarrisonID == ROADBLOCK ) if( pSector->ubGarrisonID == ROADBLOCK )
{ //consider these troops as mobile troops even though they are in a garrison {
//consider these troops as mobile troops even though they are in a garrison
ubNumTroops += (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks); ubNumTroops += (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks);
} }
@@ -393,7 +396,7 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY ) if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->usGroupTeam != MILITIA_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{ {
*pubNumTroops += pGroup->pEnemyGroup->ubNumTroops; *pubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
*pubNumElites += pGroup->pEnemyGroup->ubNumElites; *pubNumElites += pGroup->pEnemyGroup->ubNumElites;
@@ -405,16 +408,16 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
if( pSector->ubGarrisonID == ROADBLOCK ) if( pSector->ubGarrisonID == ROADBLOCK )
{ //consider these troops as mobile troops even though they are in a garrison {
//consider these troops as mobile troops even though they are in a garrison
*pubNumAdmins += pSector->ubNumAdmins; *pubNumAdmins += pSector->ubNumAdmins;
*pubNumTroops += pSector->ubNumTroops; *pubNumTroops += pSector->ubNumTroops;
*pubNumElites += pSector->ubNumElites; *pubNumElites += pSector->ubNumElites;
*pubNumTanks += pSector->ubNumTanks; *pubNumTanks += pSector->ubNumTanks;
} }
} }
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks ) void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks )
{ {
GROUP *pGroup; GROUP *pGroup;
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
@@ -427,7 +430,7 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY ) if ( pGroup->usGroupTeam == usTeam && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{ {
*pubNumTroops += pGroup->pEnemyGroup->ubNumTroops; *pubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
*pubNumElites += pGroup->pEnemyGroup->ubNumElites; *pubNumElites += pGroup->pEnemyGroup->ubNumElites;
@@ -506,7 +509,7 @@ void EndTacticalBattleForEnemy()
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY ) if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY )
{ {
pGroup->pEnemyGroup->ubTroopsInBattle = 0; pGroup->pEnemyGroup->ubTroopsInBattle = 0;
pGroup->pEnemyGroup->ubElitesInBattle = 0; pGroup->pEnemyGroup->ubElitesInBattle = 0;
@@ -519,12 +522,12 @@ void EndTacticalBattleForEnemy()
//Check to see if any of our mercs have abandoned the militia during a battle. This is cause for a rather //Check to see if any of our mercs have abandoned the militia during a battle. This is cause for a rather
//severe loyalty blow. //severe loyalty blow.
for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; i++ ) for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; ++i )
{ {
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->bInSector && MercPtrs[ i ]->stats.bLife >= OKLIFE ) if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->bInSector && MercPtrs[ i ]->stats.bLife >= OKLIFE )
{ //found one live militia, so look for any enemies/creatures. { //found one live militia, so look for any enemies/creatures.
// NOTE: this is relying on ENEMY_TEAM being immediately followed by CREATURE_TEAM // NOTE: this is relying on ENEMY_TEAM being immediately followed by CREATURE_TEAM
for( i = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; i <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; i++ ) for( i = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; i <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; ++i )
{ {
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->bInSector && MercPtrs[ i ]->stats.bLife >= OKLIFE ) if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->bInSector && MercPtrs[ i ]->stats.bLife >= OKLIFE )
{ //confirmed at least one enemy here, so do the loyalty penalty. { //confirmed at least one enemy here, so do the loyalty penalty.
@@ -578,7 +581,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
return PrepareEnemyForUndergroundBattle(); return PrepareEnemyForUndergroundBattle();
// Add the invading group // Add the invading group
if ( gpBattleGroup && gpBattleGroup->usGroupTeam != OUR_TEAM ) if ( gpBattleGroup && gpBattleGroup->usGroupTeam == ENEMY_TEAM )
{ {
//The enemy has instigated the battle which means they are the ones entering the conflict. //The enemy has instigated the battle which means they are the ones entering the conflict.
//The player was actually in the sector first, and the enemy doesn't use reinforced placements //The player was actually in the sector first, and the enemy doesn't use reinforced placements
@@ -782,11 +785,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
//For enemy groups, we fill up the slots until we have none left or all of the groups have been //For enemy groups, we fill up the slots until we have none left or all of the groups have been
//processed. //processed.
for( pGroup = gpGroupList; for( pGroup = gpGroupList; pGroup; pGroup = pGroup->next)
pGroup;
pGroup = pGroup->next)
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle &&
pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ ) pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ )
{ //Process enemy group in sector. { //Process enemy group in sector.
if( sNumSlots > 0 ) if( sNumSlots > 0 )
@@ -1124,9 +1125,11 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
if( pSoldier->aiData.bNeutral || pSoldier->bTeam != ENEMY_TEAM && pSoldier->bTeam != CREATURE_TEAM ) if( pSoldier->aiData.bNeutral || pSoldier->bTeam != ENEMY_TEAM && pSoldier->bTeam != CREATURE_TEAM )
return; return;
//we are recording an enemy death //we are recording an enemy death
if( pSoldier->ubGroupID ) if( pSoldier->ubGroupID )
{ //The enemy was in a mobile group {
//The enemy was in a mobile group
GROUP *pGroup; GROUP *pGroup;
pGroup = GetGroup( pSoldier->ubGroupID ); pGroup = GetGroup( pSoldier->ubGroupID );
if( !pGroup ) if( !pGroup )
@@ -1138,15 +1141,26 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
#endif #endif
return; return;
} }
if ( pGroup->usGroupTeam == OUR_TEAM ) if ( pGroup->usGroupTeam == OUR_TEAM )
{ {
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
CHAR16 str[256]; CHAR16 str[256];
swprintf( str, L"Attempting to process player group thinking it's an enemy group in ProcessQueenCmdImplicationsOfDeath()", pSoldier->ubGroupID ); swprintf( str, L"Attempting to process player group thinking it's an enemy group in ProcessQueenCmdImplicationsOfDeath()", pSoldier->ubGroupID );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL ); DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
#endif #endif
return; return;
} }
else if ( pGroup->usGroupTeam == MILITIA_TEAM )
{
#ifdef JA2BETAVERSION
CHAR16 str[256];
swprintf( str, L"Attempting to process militia group thinking it's an enemy group in ProcessQueenCmdImplicationsOfDeath()", pSoldier->ubGroupID );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
#endif
return;
}
switch( pSoldier->ubSoldierClass ) switch( pSoldier->ubSoldierClass )
{ {
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
@@ -1702,13 +1716,13 @@ void AddPossiblePendingEnemiesToBattle()
// Figure out which groups are in the sector, so we can have reinforcements arrive at random // Figure out which groups are in the sector, so we can have reinforcements arrive at random
for (ubNumGroupsInSector = 0, pGroup = gpGroupList; pGroup; pGroup = pGroup->next) for (ubNumGroupsInSector = 0, pGroup = gpGroupList; pGroup; pGroup = pGroup->next)
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ ) if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ )
ubNumGroupsInSector++; ++ubNumGroupsInSector;
} }
pGroupInSectorList = (GROUP**) MemAlloc( ubNumGroupsInSector * sizeof( GROUP*)); pGroupInSectorList = (GROUP**) MemAlloc( ubNumGroupsInSector * sizeof( GROUP*));
for (ubNumGroupsInSector = 0, pGroup = gpGroupList; pGroup; pGroup = pGroup->next) for (ubNumGroupsInSector = 0, pGroup = gpGroupList; pGroup; pGroup = pGroup->next)
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ ) if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ )
{ {
pGroupInSectorList[ ubNumGroupsInSector++] = pGroup; pGroupInSectorList[ ubNumGroupsInSector++] = pGroup;
} }
@@ -2701,17 +2715,13 @@ void HandleEnemyStatusInCurrentMapBeforeLoadingNewMap()
BOOLEAN PlayerSectorDefended( UINT8 ubSectorID ) BOOLEAN PlayerSectorDefended( UINT8 ubSectorID )
{ {
SECTORINFO *pSector; if ( NumNonPlayerTeamMembersInSector( SECTORX( ubSectorID ), SECTORY( ubSectorID ), MILITIA_TEAM ) )
pSector = &SectorInfo[ ubSectorID ];
if( pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] +
pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] +
pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] )
{ {
//militia in sector //militia in sector
return TRUE; return TRUE;
} }
if ( FindMovementGroupInSector( (UINT8)SECTORX( ubSectorID ), (UINT8)SECTORY( ubSectorID ), OUR_TEAM ) || FindMovementGroupInSector( (UINT8)SECTORX( ubSectorID ), (UINT8)SECTORY( ubSectorID ), MILITIA_TEAM ) ) if ( FindMovementGroupInSector( SECTORX( ubSectorID ), SECTORY( ubSectorID ), OUR_TEAM ) )
{ {
// player/militia in sector // player/militia in sector
return TRUE; return TRUE;
+2 -2
View File
@@ -22,11 +22,11 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
// returns how many members of a team are in a sector - not intended for OUR_TEAM! // returns how many members of a team are in a sector - not intended for OUR_TEAM!
UINT8 NumNonPlayerTeamMembersInSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubTeam ); UINT8 NumNonPlayerTeamMembersInSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubTeam );
UINT16 NumEnemyTanksInSector( INT16 sSectorX, INT16 sSectorY ); UINT16 NumTanksInSector( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam );
UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY ); UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY ); UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks ); 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 GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks );
void GetNumberOfStationaryEnemiesInSector( 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 ); void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks );
+34 -33
View File
@@ -41,7 +41,7 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks ); GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks );
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
@@ -82,7 +82,7 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
} }
} }
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
@@ -115,9 +115,11 @@ BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 s
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE ); GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ ) for ( ubIndex = 0; ubIndex < ubDirNumber; ++ubIndex )
{
if( pGroup->ubSectorX == SECTORX( pusMoveDir[ ubIndex ][ 0 ] ) && pGroup->ubSectorY == SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) ) if( pGroup->ubSectorX == SECTORX( pusMoveDir[ ubIndex ][ 0 ] ) && pGroup->ubSectorY == SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) )
return TRUE; return TRUE;
}
return FALSE; return FALSE;
} }
@@ -130,7 +132,7 @@ UINT8 GetAdjacentSectors( UINT8 pSectors[4], INT16 sSectorX, INT16 sSectorY )
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE ); GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ ) for( ubIndex = 0; ubIndex < ubDirNumber; ++ubIndex )
pSectors[ ubCounter++ ] = (UINT8)pusMoveDir[ ubIndex ][ 0 ]; pSectors[ ubCounter++ ] = (UINT8)pusMoveDir[ ubIndex ][ 0 ];
return ubCounter; return ubCounter;
@@ -152,7 +154,6 @@ UINT8 CountAllMilitiaInFiveSectors(INT16 sMapX, INT16 sMapY)
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ ) for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
ubResult += NumNonPlayerTeamMembersInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), MILITIA_TEAM ); ubResult += NumNonPlayerTeamMembersInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), MILITIA_TEAM );
return ubResult; return ubResult;
} }
@@ -165,8 +166,9 @@ BOOLEAN ARMoveBestMilitiaManFromAdjacentSector(INT16 sMapX, INT16 sMapY)
if( !gGameExternalOptions.gfAllowReinforcements ) if( !gGameExternalOptions.gfAllowReinforcements )
return FALSE; return FALSE;
if ( NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM ) >= gGameExternalOptions.iMaxMilitiaPerSector || UINT8 militiainsector = NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM );
CountAllMilitiaInFiveSectors( sMapX, sMapY ) - NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM ) == 0 ) if ( militiainsector >= gGameExternalOptions.iMaxMilitiaPerSector ||
CountAllMilitiaInFiveSectors( sMapX, sMapY ) - militiainsector == 0 )
return FALSE; return FALSE;
GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE ); GenerateDirectionInfos( sMapX, sMapY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
@@ -241,7 +243,10 @@ UINT8 DoReinforcementAsPendingNonPlayer( INT16 sMapX, INT16 sMapY, UINT8 usTeam
{ {
ubIndex = Random(ubDirNumber); ubIndex = Random(ubDirNumber);
if ( usTeam == ENEMY_TEAM && NumNonPlayerTeamMembersInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), usTeam ) > gubReinforcementMinEnemyStaticGroupSize ) INT16 sOtherX = SECTORX( pusMoveDir[ubIndex][0] );
INT16 sOtherY = SECTORY( pusMoveDir[ubIndex][0] );
if ( usTeam == ENEMY_TEAM && NumNonPlayerTeamMembersInSector( sOtherX, sOtherY, usTeam ) > gubReinforcementMinEnemyStaticGroupSize )
{ {
pSector = &SectorInfo[ pusMoveDir[ ubIndex ][ 0 ] ]; pSector = &SectorInfo[ pusMoveDir[ ubIndex ][ 0 ] ];
@@ -277,26 +282,24 @@ UINT8 DoReinforcementAsPendingNonPlayer( INT16 sMapX, INT16 sMapY, UINT8 usTeam
return (UINT8)pusMoveDir[ ubIndex ][ 2 ]; return (UINT8)pusMoveDir[ ubIndex ][ 2 ];
} }
// no required min size on militia groups // no required min size on militia groups
else if ( usTeam == MILITIA_TEAM && NumNonPlayerTeamMembersInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), usTeam ) ) else if ( usTeam == MILITIA_TEAM && NumNonPlayerTeamMembersInSector( sOtherX, sOtherY, usTeam ) )
{ {
pSector = &SectorInfo[pusMoveDir[ubIndex][0]]; if ( MilitiaInSectorOfRank( sOtherX, sOtherY, ELITE_MILITIA ) )
if ( pSector->ubNumberOfCivsAtLevel[ELITE_MILITIA] )
{ {
(pThisSector->ubNumberOfCivsAtLevel[ELITE_MILITIA])++; StrategicAddMilitiaToSector( sMapX, sMapY, ELITE_MILITIA, 1 );
(pSector->ubNumberOfCivsAtLevel[ELITE_MILITIA])--; StrategicRemoveMilitiaFromSector( sOtherX, sOtherY, ELITE_MILITIA, 1 );
AddMilitiaToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 0, 0, 1, FALSE ); AddMilitiaToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 0, 0, 1, FALSE );
} }
else if ( pSector->ubNumberOfCivsAtLevel[REGULAR_MILITIA] ) else if ( MilitiaInSectorOfRank( sOtherX, sOtherY, REGULAR_MILITIA ) )
{ {
(pThisSector->ubNumberOfCivsAtLevel[REGULAR_MILITIA])++; StrategicAddMilitiaToSector( sMapX, sMapY, REGULAR_MILITIA, 1 );
(pSector->ubNumberOfCivsAtLevel[REGULAR_MILITIA])--; StrategicRemoveMilitiaFromSector( sOtherX, sOtherY, REGULAR_MILITIA, 1 );
AddMilitiaToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 0, 1, 0, FALSE ); AddMilitiaToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 0, 1, 0, FALSE );
} }
else if ( pSector->ubNumberOfCivsAtLevel[GREEN_MILITIA] ) else if ( MilitiaInSectorOfRank( sOtherX, sOtherY, GREEN_MILITIA ) )
{ {
(pThisSector->ubNumberOfCivsAtLevel[GREEN_MILITIA])++; StrategicAddMilitiaToSector( sMapX, sMapY, GREEN_MILITIA, 1 );
(pSector->ubNumberOfCivsAtLevel[GREEN_MILITIA])--; StrategicRemoveMilitiaFromSector( sOtherX, sOtherY, GREEN_MILITIA, 1 );
AddMilitiaToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 1, 0, 0, FALSE ); AddMilitiaToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 1, 0, 0, FALSE );
} }
@@ -317,7 +320,6 @@ UINT8 DoReinforcementAsPendingMilitia( INT16 sMapX, INT16 sMapY, UINT8 *pubRank
{ {
UINT16 pusMoveDir[4][3]; UINT16 pusMoveDir[4][3];
UINT8 ubDirNumber = 0, ubIndex; UINT8 ubDirNumber = 0, ubIndex;
SECTORINFO *pSector;//*pThisSector,
if( !gGameExternalOptions.gfAllowReinforcements ) if( !gGameExternalOptions.gfAllowReinforcements )
return 255; return 255;
@@ -338,19 +340,19 @@ UINT8 DoReinforcementAsPendingMilitia( INT16 sMapX, INT16 sMapY, UINT8 *pubRank
ubIndex = Random(ubDirNumber); ubIndex = Random(ubDirNumber);
if ( NumNonPlayerTeamMembersInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), MILITIA_TEAM ) ) if ( NumNonPlayerTeamMembersInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), MILITIA_TEAM ) )
{ {
pSector = &SectorInfo[ pusMoveDir[ ubIndex ][ 0 ] ]; if ( MilitiaInSectorOfRank( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ELITE_MILITIA ) )
if( pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] )
{ {
StrategicAddMilitiaToSector( sMapX, sMapY,ELITE_MILITIA, 1 ); StrategicAddMilitiaToSector( sMapX, sMapY,ELITE_MILITIA, 1 );
StrategicRemoveMilitiaFromSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ),ELITE_MILITIA, 1 ); StrategicRemoveMilitiaFromSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ),ELITE_MILITIA, 1 );
*pubRank = ELITE_MILITIA; *pubRank = ELITE_MILITIA;
}else if( pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] ) }
else if ( MilitiaInSectorOfRank( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), REGULAR_MILITIA ) )
{ {
StrategicAddMilitiaToSector( sMapX, sMapY,REGULAR_MILITIA, 1 ); StrategicAddMilitiaToSector( sMapX, sMapY,REGULAR_MILITIA, 1 );
StrategicRemoveMilitiaFromSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ),REGULAR_MILITIA, 1 ); StrategicRemoveMilitiaFromSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ),REGULAR_MILITIA, 1 );
*pubRank = REGULAR_MILITIA; *pubRank = REGULAR_MILITIA;
}else if( pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] ) }
else if ( MilitiaInSectorOfRank( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), GREEN_MILITIA ) )
{ {
StrategicAddMilitiaToSector( sMapX, sMapY,GREEN_MILITIA, 1 ); StrategicAddMilitiaToSector( sMapX, sMapY,GREEN_MILITIA, 1 );
StrategicRemoveMilitiaFromSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ),GREEN_MILITIA, 1 ); StrategicRemoveMilitiaFromSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ),GREEN_MILITIA, 1 );
@@ -391,6 +393,7 @@ void AddPossiblePendingMilitiaToBattle()
|| (NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, ENEMY_TEAM ) == 0) || (NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, ENEMY_TEAM ) == 0)
) )
return; return;
//gGameExternalOptions.guiMaxMilitiaSquadSize - CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY ); //gGameExternalOptions.guiMaxMilitiaSquadSize - CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY );
ubSlots = NumFreeSlots( MILITIA_TEAM ); ubSlots = NumFreeSlots( MILITIA_TEAM );
if(gGameExternalOptions.sMinDelayMilitiaReinforcements)//dnl ch68 090913 if(gGameExternalOptions.sMinDelayMilitiaReinforcements)//dnl ch68 090913
@@ -455,25 +458,23 @@ void AddPossiblePendingMilitiaToBattle()
{ {
ubNumElites = ubNumRegulars = ubNumGreens = 0; ubNumElites = ubNumRegulars = ubNumGreens = 0;
// while( ubSlots )
switch( ubPredefinedRank ) switch( ubPredefinedRank )
{ {
case ELITE_MILITIA: case ELITE_MILITIA:
ubSlots--;
ubNumElites++; ubNumElites++;
break; break;
case REGULAR_MILITIA: case REGULAR_MILITIA:
ubSlots--;
ubNumRegulars++; ubNumRegulars++;
break; break;
case GREEN_MILITIA: case GREEN_MILITIA:
ubSlots--;
ubNumGreens++; ubNumGreens++;
break; break;
default: default:
ubSlots--; break;
} }
--ubSlots;
if( ubNumGreens || ubNumRegulars || ubNumElites ) if( ubNumGreens || ubNumRegulars || ubNumElites )
AddSoldierInitListMilitiaOnEdge( ubPredefinedInsertionCode, ubNumGreens, ubNumRegulars, ubNumElites ); AddSoldierInitListMilitiaOnEdge( ubPredefinedInsertionCode, ubNumGreens, ubNumRegulars, ubNumElites );
} }
@@ -482,7 +483,8 @@ void AddPossiblePendingMilitiaToBattle()
ubPredefinedRank = 255; ubPredefinedRank = 255;
if( ubSlots ) if( ubSlots )
{ //After going through the process, we have finished with some free slots and no more enemies to add. {
//After going through the process, we have finished with some free slots and no more enemies to add.
//So, we can turn off the flag, as this check is no longer needed. //So, we can turn off the flag, as this check is no longer needed.
ubPredefinedInsertionCode = DoReinforcementAsPendingMilitia( gWorldSectorX, gWorldSectorY, &ubPredefinedRank ); ubPredefinedInsertionCode = DoReinforcementAsPendingMilitia( gWorldSectorX, gWorldSectorY, &ubPredefinedRank );
@@ -500,4 +502,3 @@ void AddPossiblePendingMilitiaToBattle()
gfPendingNonPlayerTeam[MILITIA_TEAM] = FALSE; gfPendingNonPlayerTeam[MILITIA_TEAM] = FALSE;
} }
} }
+42 -38
View File
@@ -648,9 +648,9 @@ BOOLEAN PlayerForceTooStrong( UINT8 ubSectorID, UINT16 usOffensePoints, UINT16 *
// SANDRO - EVALUATE THE STRENGTH OF MILITIA BASED ON INI SETTING // SANDRO - EVALUATE THE STRENGTH OF MILITIA BASED ON INI SETTING
*pusDefencePoints = PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 5; *pusDefencePoints = PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 5;
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] * 1 * (100 + gGameExternalOptions.sGreenMilitiaAutoresolveStrength )/100); *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, GREEN_MILITIA ) * 1 * (100 + gGameExternalOptions.sGreenMilitiaAutoresolveStrength) / 100);
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] * 2 * (100 + gGameExternalOptions.sRegularMilitiaAutoresolveStrength)/100); *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, REGULAR_MILITIA ) * 2 * (100 + gGameExternalOptions.sRegularMilitiaAutoresolveStrength) / 100);
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] * 3 * (100 + gGameExternalOptions.sVeteranMilitiaAutoresolveStrength)/100); *pusDefencePoints += (MilitiaInSectorOfRank( ubSectorX, ubSectorY, ELITE_MILITIA ) * 3 * (100 + gGameExternalOptions.sVeteranMilitiaAutoresolveStrength) / 100);
if( *pusDefencePoints > usOffensePoints ) if( *pusDefencePoints > usOffensePoints )
{ {
@@ -661,11 +661,9 @@ BOOLEAN PlayerForceTooStrong( UINT8 ubSectorID, UINT16 usOffensePoints, UINT16 *
void RequestAttackOnSector( UINT8 ubSectorID, UINT16 usDefencePoints ) void RequestAttackOnSector( UINT8 ubSectorID, UINT16 usDefencePoints )
{ {
INT32 i; Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */ for ( INT32 i = 0; i < giGarrisonArraySize; ++i )
for( i = 0; i < giGarrisonArraySize; i++ )
{ {
if( gGarrisonGroup[ i ].ubSectorID == ubSectorID && !gGarrisonGroup[ i ].ubPendingGroupID ) if( gGarrisonGroup[ i ].ubSectorID == ubSectorID && !gGarrisonGroup[ i ].ubPendingGroupID )
{ {
@@ -824,7 +822,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic2");
} }
if( !pGroup->ubNextX || !pGroup->ubNextY ) if( !pGroup->ubNextX || !pGroup->ubNextY )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->pEnemyGroup->ubIntention != STAGING if ( pGroup->usGroupTeam == ENEMY_TEAM && pGroup->pEnemyGroup->ubIntention != STAGING
&& pGroup->pEnemyGroup->ubIntention != REINFORCEMENTS ) && pGroup->pEnemyGroup->ubIntention != REINFORCEMENTS )
{ {
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
@@ -2147,33 +2145,30 @@ BOOLEAN ReinforcementsApproved( INT32 iGarrisonID, UINT16 *pusDefencePoints )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
UINT16 usOffensePoints; UINT16 usOffensePoints;
UINT16 usDefencePoints;
UINT8 ubSectorX, ubSectorY; UINT8 ubSectorX, ubSectorY;
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */ Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
pSector = &SectorInfo[ gGarrisonGroup[ iGarrisonID ].ubSectorID ]; pSector = &SectorInfo[ gGarrisonGroup[ iGarrisonID ].ubSectorID ];
ubSectorX = (UINT8)SECTORX( gGarrisonGroup[ iGarrisonID ].ubSectorID ); ubSectorX = (UINT8)SECTORX( gGarrisonGroup[ iGarrisonID ].ubSectorID );
ubSectorY = (UINT8)SECTORY( gGarrisonGroup[ iGarrisonID ].ubSectorID ); ubSectorY = (UINT8)SECTORY( gGarrisonGroup[ iGarrisonID ].ubSectorID );
// SANDRO - EVALUATE THE MILITIA STRENGTH REGARDING THE GAME SETTINGS // SANDRO - EVALUATE THE MILITIA STRENGTH REGARDING THE GAME SETTINGS
*pusDefencePoints = PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 5; usOffensePoints = gArmyComp[gGarrisonGroup[iGarrisonID].ubComposition].bAdminPercentage * 2 +
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] * 1 * (100 + gGameExternalOptions.sGreenMilitiaAutoresolveStrength )/100); gArmyComp[gGarrisonGroup[iGarrisonID].ubComposition].bTroopPercentage * 3 +
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] * 2 * (100 + gGameExternalOptions.sRegularMilitiaAutoresolveStrength)/100); gArmyComp[gGarrisonGroup[iGarrisonID].ubComposition].bElitePercentage * 4 +
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] * 3 * (100 + gGameExternalOptions.sVeteranMilitiaAutoresolveStrength)/100); gubGarrisonReinforcementsDenied[iGarrisonID];
usOffensePoints = usOffensePoints * gArmyComp[gGarrisonGroup[iGarrisonID].ubComposition].bDesiredPopulation / 100;
usOffensePoints = gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bAdminPercentage * 2 + if ( PlayerForceTooStrong( gGarrisonGroup[iGarrisonID].ubSectorID, usOffensePoints, &usDefencePoints ) )
gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bTroopPercentage * 3 +
gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bElitePercentage * 4 +
gubGarrisonReinforcementsDenied[ iGarrisonID ];
usOffensePoints = usOffensePoints * gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bDesiredPopulation / 100;
if( usOffensePoints > *pusDefencePoints )
{ {
return TRUE; return TRUE;
} }
//Before returning false, determine if reinforcements have been denied repeatedly. If so, then //Before returning false, determine if reinforcements have been denied repeatedly. If so, then
//we might send an augmented force to take it back. //we might send an augmented force to take it back.
if( gubGarrisonReinforcementsDenied[ iGarrisonID ] + usOffensePoints > *pusDefencePoints ) if ( gubGarrisonReinforcementsDenied[iGarrisonID] + usOffensePoints > usDefencePoints )
{ {
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
LogStrategicEvent( "Sector %c%d will now recieve an %d extra troops due to multiple denials for reinforcements in the past for strong player presence.", LogStrategicEvent( "Sector %c%d will now recieve an %d extra troops due to multiple denials for reinforcements in the past for strong player presence.",
@@ -2209,16 +2204,22 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5");
return FALSE; return FALSE;
} }
Assert( pGroup->usGroupTeam != OUR_TEAM ); Assert( pGroup->usGroupTeam != OUR_TEAM );
// for now, nothing to do for militia groups
if ( pGroup->usGroupTeam == MILITIA_TEAM )
return FALSE;
if( pGroup->pEnemyGroup->ubIntention == PURSUIT ) if( pGroup->pEnemyGroup->ubIntention == PURSUIT )
{ //Lost the player group that he was going to attack. Return to original position. {
//Lost the player group that he was going to attack. Return to original position.
SetThisSectorAsEnemyControlled( pGroup->ubSectorX, pGroup->ubSectorY, 0, TRUE ); SetThisSectorAsEnemyControlled( pGroup->ubSectorX, pGroup->ubSectorY, 0, TRUE );
ReassignAIGroup( &pGroup ); ReassignAIGroup( &pGroup );
return TRUE; return TRUE;
} }
else if( pGroup->pEnemyGroup->ubIntention == REINFORCEMENTS ) else if( pGroup->pEnemyGroup->ubIntention == REINFORCEMENTS )
{ {
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */ Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
//The group has arrived at the location where he is supposed to reinforce. //The group has arrived at the location where he is supposed to reinforce.
//Step 1 -- Check for matching garrison location //Step 1 -- Check for matching garrison location
for( i = 0; i < giGarrisonArraySize; i++ ) for( i = 0; i < giGarrisonArraySize; i++ )
{ {
@@ -3851,8 +3852,9 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->ubGroupSize >= 16 ) if ( pGroup->usGroupTeam == ENEMY_TEAM && pGroup->ubGroupSize >= 16 )
{ //accident in patrol groups being too large {
//accident in patrol groups being too large
UINT8 ubGetRidOfXTroops = pGroup->ubGroupSize - 10; UINT8 ubGetRidOfXTroops = pGroup->ubGroupSize - 10;
if( gbWorldSectorZ || pGroup->ubSectorX != gWorldSectorX || pGroup->ubSectorY != gWorldSectorY ) if( gbWorldSectorZ || pGroup->ubSectorX != gWorldSectorX || pGroup->ubSectorY != gWorldSectorY )
{ //don't modify groups in the currently loaded sector. { //don't modify groups in the currently loaded sector.
@@ -3866,6 +3868,7 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
pGroup = pGroup->next; pGroup = pGroup->next;
} }
} }
if( ubSAIVersion < 13 ) if( ubSAIVersion < 13 )
{ {
for( i = 0; i < 255; i++ ) for( i = 0; i < 255; i++ )
@@ -4037,7 +4040,7 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
if( ubSAIVersion < 26 ) if( ubSAIVersion < 26 )
{ {
INT32 i; INT32 i;
for( i = 0; i < 255; i++ ) for( i = 0; i < 255; ++i )
{ {
if( SectorInfo[ i ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + if( SectorInfo[ i ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] +
SectorInfo[ i ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + SectorInfo[ i ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] +
@@ -6141,7 +6144,7 @@ void EliminateSurplusTroopsForGarrison( GROUP *pGroup, SECTORINFO *pSector )
INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize; INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic8"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic8");
iTotal = pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks + iTotal = pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites + pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTanks +
pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins + pSector->ubNumTanks; pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumAdmins + pSector->ubNumTanks;
if( iTotal <= iMaxEnemyGroupSize ) if( iTotal <= iMaxEnemyGroupSize )
{ {
@@ -6270,12 +6273,12 @@ void UpgradeAdminsToTroops()
GROUP *pGroup; GROUP *pGroup;
INT16 sPatrolIndex; INT16 sPatrolIndex;
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */ Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
// on normal, AI evaluates approximately every 10 hrs. There are about 130 administrators seeded on the map. // on normal, AI evaluates approximately every 10 hrs. There are about 130 administrators seeded on the map.
// Some of these will be killed by the player. // Some of these will be killed by the player.
// check all garrisons for administrators // check all garrisons for administrators
for( i = 0; i < giGarrisonArraySize; i++ ) for( i = 0; i < giGarrisonArraySize; ++i )
{ {
// skip sector if it's currently loaded, we'll never upgrade guys in those // skip sector if it's currently loaded, we'll never upgrade guys in those
if ( (gWorldSectorX != 0) && (gWorldSectorY != 0) && if ( (gWorldSectorX != 0) && (gWorldSectorY != 0) &&
@@ -6306,18 +6309,17 @@ void UpgradeAdminsToTroops()
pSector->ubNumTroops++; pSector->ubNumTroops++;
} }
ubAdminsToCheck--; --ubAdminsToCheck;
} }
} }
} }
} }
// check all moving enemy groups for administrators // check all moving enemy groups for administrators
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->ubGroupSize && pGroup->usGroupTeam != OUR_TEAM && !pGroup->fVehicle ) if ( pGroup->ubGroupSize && pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle )
{ {
Assert ( pGroup->pEnemyGroup ); Assert ( pGroup->pEnemyGroup );
@@ -6482,7 +6484,7 @@ void ReassignAIGroup( GROUP **pGroup )
//go through garrisons first and begin considering where the random value dictates. If that garrison doesn't require //go through garrisons first and begin considering where the random value dictates. If that garrison doesn't require
//reinforcements, it'll continue on considering all subsequent garrisons till the end of the array. If it fails at that //reinforcements, it'll continue on considering all subsequent garrisons till the end of the array. If it fails at that
//point, it'll restart the loop at zero, and consider all garrisons to the index that was first considered by the random value. //point, it'll restart the loop at zero, and consider all garrisons to the index that was first considered by the random value.
for( i = 0; i < giGarrisonArraySize; i++ ) for( i = 0; i < giGarrisonArraySize; ++i )
{ {
RecalculateGarrisonWeight( i ); RecalculateGarrisonWeight( i );
iWeight = gGarrisonGroup[ i ].bWeight; iWeight = gGarrisonGroup[ i ].bWeight;
@@ -6710,7 +6712,7 @@ void CalcNumTroopsBasedOnComposition( UINT8 *pubNumTroops, UINT8 *pubNumElites,
void ConvertGroupTroopsToComposition( GROUP *pGroup, INT32 iCompositionID ) void ConvertGroupTroopsToComposition( GROUP *pGroup, INT32 iCompositionID )
{ {
Assert( pGroup ); Assert( pGroup );
Assert( pGroup->usGroupTeam != OUR_TEAM ); Assert( pGroup->usGroupTeam == ENEMY_TEAM );
CalcNumTroopsBasedOnComposition( &pGroup->pEnemyGroup->ubNumTroops, &pGroup->pEnemyGroup->ubNumElites, pGroup->ubGroupSize, iCompositionID ); CalcNumTroopsBasedOnComposition( &pGroup->pEnemyGroup->ubNumTroops, &pGroup->pEnemyGroup->ubNumElites, pGroup->ubGroupSize, iCompositionID );
pGroup->pEnemyGroup->ubNumAdmins = 0; pGroup->pEnemyGroup->ubNumAdmins = 0;
pGroup->ubGroupSize = pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites; pGroup->ubGroupSize = pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites;
@@ -6815,10 +6817,12 @@ void MoveSAIGroupToSector( GROUP **pGroup, UINT8 ubSectorID, UINT32 uiMoveCode,
(*pGroup)->ubMoveType = ONE_WAY; (*pGroup)->ubMoveType = ONE_WAY;
if( (*pGroup)->ubSectorX == ubDstSectorX && (*pGroup)->ubSectorY == ubDstSectorY ) if( (*pGroup)->ubSectorX == ubDstSectorX && (*pGroup)->ubSectorY == ubDstSectorY )
{ //The destination sector is the current location. Instead of causing code logic problems, {
//The destination sector is the current location. Instead of causing code logic problems,
//simply process them as if they just arrived. //simply process them as if they just arrived.
if( EvaluateGroupSituation( *pGroup ) ) if( EvaluateGroupSituation( *pGroup ) )
{ //The group was deleted. {
//The group was deleted.
*pGroup = NULL; *pGroup = NULL;
return; return;
} }
@@ -6852,7 +6856,7 @@ UINT8 RedirectEnemyGroupsMovingThroughSector( UINT8 ubSectorX, UINT8 ubSectorY )
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
if ( pGroup->usGroupTeam != OUR_TEAM && pGroup->ubMoveType == ONE_WAY ) if ( pGroup->usGroupTeam == ENEMY_TEAM && pGroup->ubMoveType == ONE_WAY )
{ {
//check the waypoint list //check the waypoint list
if( GroupWillMoveThroughSector( pGroup, ubSectorX, ubSectorY ) ) if( GroupWillMoveThroughSector( pGroup, ubSectorX, ubSectorY ) )
+210 -28
View File
@@ -49,6 +49,7 @@
#include "Quests.h" #include "Quests.h"
#include "Interface.h" // added by Flugente for zBackground #include "Interface.h" // added by Flugente for zBackground
#include "Reinforcement.h" // added by Flugente for AddPossiblePendingMilitiaToBattle() #include "Reinforcement.h" // added by Flugente for AddPossiblePendingMilitiaToBattle()
#include "Militia Control.h" // added by Flugente for ResetMilitia()
#endif #endif
#include "MilitiaSquads.h" #include "MilitiaSquads.h"
@@ -778,6 +779,84 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
return NULL; return NULL;
} }
GROUP* CreateNewMilitiaGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites )
{
GROUP *pNew;
AssertMsg( uiSector >= 0 && uiSector <= 255, String( "CreateNewMilitiaGroupDepartingFromSector with out of range value of %d", uiSector ) );
pNew = (GROUP*)MemAlloc( sizeof(GROUP) );
AssertMsg( pNew, "MemAlloc failure during CreateNewEnemyGroup." );
memset( pNew, 0, sizeof(GROUP) );
pNew->pEnemyGroup = (ENEMYGROUP*)MemAlloc( sizeof(ENEMYGROUP) );
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 )
{
if ( ubNumTroops )
{
ubNumTroops--;
}
else if ( ubNumAdmins )
{
ubNumAdmins--;
}
else if ( ubNumElites )
{
ubNumElites--;
}
}
pNew->pWaypoints = NULL;
pNew->ubSectorX = (UINT8)SECTORX( uiSector );
pNew->ubSectorY = (UINT8)SECTORY( uiSector );
pNew->ubOriginalSector = (UINT8)uiSector;
pNew->usGroupTeam = MILITIA_TEAM;
pNew->ubMoveType = ONE_WAY; // we don't set up patrols...
pNew->ubNextWaypointID = 0;
pNew->ubFatigueLevel = 100;
pNew->ubRestAtFatigueLevel = 0;
pNew->pEnemyGroup->ubNumAdmins = ubNumAdmins;
pNew->pEnemyGroup->ubNumTroops = ubNumTroops;
pNew->pEnemyGroup->ubNumElites = ubNumElites;
pNew->ubGroupSize = (UINT8)(ubNumAdmins + ubNumTroops + ubNumElites);
pNew->ubTransportationMask = FOOT;
pNew->fVehicle = FALSE;
pNew->ubCreatedSectorID = pNew->ubOriginalSector;
pNew->ubSectorIDOfLastReassignment = 255;
#ifdef JA2BETAVERSION
{
/*CHAR16 str[512];
if ( PlayerMercsInSector( pNew->ubSectorX, pNew->ubSectorY, 0 ) || NumNonPlayerTeamMembersInSector( pNew->ubSectorX, pNew->ubSectorY, MILITIA_TEAM ) )
{
swprintf( str, L"Attempting to send enemy troops from player occupied location. "
L"Please ALT+TAB out of the game before doing anything else and send 'Strategic Decisions.txt' "
L"and this message. You'll likely need to revert to a previous save. If you can reproduce this "
L"with a save close to this event, that would really help me! -- KM:0" );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
}*/
/*
* Not valid
else if( pNew->ubGroupSize > 25 )
{
swprintf( str, L"Strategic AI warning: Creating an enemy group containing %d soldiers "
L"(%d admins, %d troops, %d elites) in sector %c%d. This message is a temporary test message "
L"to evaluate a potential problems with very large enemy groups.",
pNew->ubGroupSize, ubNumAdmins, ubNumTroops, ubNumElites,
pNew->ubSectorY + 'A' - 1, pNew->ubSectorX );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
}
*/
}
#endif
if ( AddGroupToList( pNew ) )
return pNew;
return NULL;
}
//INTERNAL LIST MANIPULATION FUNCTIONS //INTERNAL LIST MANIPULATION FUNCTIONS
//When adding any new group to the list, this is what must be done: //When adding any new group to the list, this is what must be done:
@@ -1150,7 +1229,8 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup )
} }
if( pGroup->uiFlags & GROUPFLAG_HIGH_POTENTIAL_FOR_AMBUSH && fBattlePending ) if( pGroup->uiFlags & GROUPFLAG_HIGH_POTENTIAL_FOR_AMBUSH && fBattlePending )
{ //This group has just arrived in a new sector from an adjacent sector that he retreated from {
//This group has just arrived in a new sector from an adjacent sector that he retreated from
//If this battle is an encounter type battle, then there is a 90% chance that the battle will //If this battle is an encounter type battle, then there is a 90% chance that the battle will
//become an ambush scenario. //become an ambush scenario.
gfHighPotentialForAmbush = TRUE; gfHighPotentialForAmbush = TRUE;
@@ -1172,26 +1252,37 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup )
} }
} }
} }
else else if ( pGroup->usGroupTeam == ENEMY_TEAM )
{ {
if ( NumNonPlayerTeamMembersInSector( pGroup->ubSectorX, pGroup->ubSectorY, MILITIA_TEAM ) ) if ( NumNonPlayerTeamMembersInSector( pGroup->ubSectorX, pGroup->ubSectorY, MILITIA_TEAM ) )
{ {
fMilitiaPresent = TRUE; fMilitiaPresent = TRUE;
fBattlePending = TRUE; fBattlePending = TRUE;
} }
if( fAliveMerc )
if ( fAliveMerc )
{ {
fBattlePending = TRUE; fBattlePending = TRUE;
} }
} }
else if ( pGroup->usGroupTeam == MILITIA_TEAM )
{
if ( NumNonPlayerTeamMembersInSector( pGroup->ubSectorX, pGroup->ubSectorY, ENEMY_TEAM ) )
{
fMilitiaPresent = TRUE;
fBattlePending = TRUE;
}
}
if( !fAliveMerc && !fMilitiaPresent ) if( !fAliveMerc && !fMilitiaPresent )
{ //empty vehicle, everyone dead, don't care. Enemies don't care. {
//empty vehicle, everyone dead, don't care. Enemies don't care.
return FALSE; return FALSE;
} }
if( fBattlePending ) if( fBattlePending )
{ //A battle is pending, but the players could be all unconcious or dead. {
//A battle is pending, but the players could be all unconcious or dead.
//Go through every group until we find at least one concious merc. The looping will determine //Go through every group until we find at least one concious merc. The looping will determine
//if there are any live mercs and/or concious ones. If there are no concious mercs, but alive ones, //if there are any live mercs and/or concious ones. If there are no concious mercs, but alive ones,
//then we will go straight to autoresolve, where the enemy will likely annihilate them or capture them. //then we will go straight to autoresolve, where the enemy will likely annihilate them or capture them.
@@ -1206,7 +1297,8 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup )
StopTimeCompression(); StopTimeCompression();
if( gubNumGroupsArrivedSimultaneously ) if( gubNumGroupsArrivedSimultaneously )
{ //Because this is a battle case, clear all the group flags {
//Because this is a battle case, clear all the group flags
curr = gpGroupList; curr = gpGroupList;
while( curr && gubNumGroupsArrivedSimultaneously ) while( curr && gubNumGroupsArrivedSimultaneously )
{ {
@@ -1228,14 +1320,16 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup )
} }
if( !fCombatAbleMerc ) if( !fCombatAbleMerc )
{ //Prepare for instant autoresolve. {
//Prepare for instant autoresolve.
gfDelayAutoResolveStart = TRUE; gfDelayAutoResolveStart = TRUE;
gfUsePersistantPBI = TRUE; gfUsePersistantPBI = TRUE;
if( fMilitiaPresent ) if( fMilitiaPresent )
{ {
NotifyPlayerOfInvasionByEnemyForces( pGroup->ubSectorX, pGroup->ubSectorY, 0, TriggerPrebattleInterface ); NotifyPlayerOfInvasionByEnemyForces( pGroup->ubSectorX, pGroup->ubSectorY, 0, TriggerPrebattleInterface );
if( GetTownIdForSector( pGroup->ubSectorX, pGroup->ubSectorY ) == BLANK_SECTOR) // trigger autoresolve if not in city, or this is a militia group
if ( pGroup->usGroupTeam == MILITIA_TEAM || GetTownIdForSector( pGroup->ubSectorX, pGroup->ubSectorY ) == BLANK_SECTOR )
{ {
// CHAR16 str[ 256 ]; // CHAR16 str[ 256 ];
// UINT16 uiSectorC = L'A' + pGroup->ubSectorY - 1; // UINT16 uiSectorC = L'A' + pGroup->ubSectorY - 1;
@@ -1254,10 +1348,10 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup )
} }
} }
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( guiCurrentScreen == AIVIEWER_SCREEN ) if( guiCurrentScreen == AIVIEWER_SCREEN )
gfExitViewer = TRUE; gfExitViewer = TRUE;
#endif #endif
if( pPlayerDialogGroup ) if( pPlayerDialogGroup )
{ {
@@ -1679,6 +1773,23 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
return; return;
} }
// Flugente: militia groups
if ( pGroup->usGroupTeam == MILITIA_TEAM )
{
// if the group would move from the current sector...
if ( gWorldSectorX == pGroup->ubSectorX && gWorldSectorY == pGroup->ubSectorY && !gbWorldSectorZ )
{
// if there is a fight going on in the sector where the group currently is, then we do not move them - erase the group instead
if ( gTacticalStatus.uiFlags & INCOMBAT )
{
// once militia have arrived, move them from the group to the sector
DissolveMilitiaGroup( pGroup->ubGroupID );
return;
}
}
}
if ( pGroup->usGroupTeam == OUR_TEAM ) if ( pGroup->usGroupTeam == OUR_TEAM )
{ {
//Set the fact we have visited the sector //Set the fact we have visited the sector
@@ -1765,7 +1876,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
pGroup->uiArrivalTime += Random(3) + 3; pGroup->uiArrivalTime += Random(3) + 3;
} }
if( !AddStrategicEvent( EVENT_GROUP_ARRIVAL, pGroup->uiArrivalTime, pGroup->ubGroupID ) ) if( !AddStrategicEvent( EVENT_GROUP_ARRIVAL, pGroup->uiArrivalTime, pGroup->ubGroupID ) )
AssertMsg( 0, "Failed to add movement event." ); AssertMsg( 0, "Failed to add movement event." );
@@ -2080,6 +2190,9 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
fCharacterInfoPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE;
} }
// in case we start a battle, we do not yet destroy militia groups
BOOLEAN fBattlePending = FALSE;
if ( !fGroupDestroyed ) if ( !fGroupDestroyed )
{ {
//Determine if a battle should start. //Determine if a battle should start.
@@ -2107,13 +2220,80 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
} }
} }
else else
{ //Handle cases for pre battle conditions {
//Handle cases for pre battle conditions
pGroup->uiFlags = 0; pGroup->uiFlags = 0;
if( gubNumAwareBattles ) if( gubNumAwareBattles )
{ //When the AI is looking for the players, and a battle is initiated, then {
//When the AI is looking for the players, and a battle is initiated, then
//decrement the value, otherwise the queen will continue searching to infinity. //decrement the value, otherwise the queen will continue searching to infinity.
gubNumAwareBattles--; --gubNumAwareBattles;
} }
fBattlePending = TRUE;
}
}
// Flugente: if a militia group has reached its final destination, add them to the current sector
if ( pGroup->usGroupTeam == MILITIA_TEAM )
{
// if they arrive in the sector we have currently loaded, let them join from the edge
// this will always remove them from the group - if you want them to continue moving, issue a new order
if ( pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && pGroup->ubSectorZ == gbWorldSectorZ )
{
MilitiaGroupEntersCurrentSector( pGroup->ubGroupID, pGroup->ubSectorX, pGroup->ubSectorY );
if ( !fBattlePending && GroupAtFinalDestination( pGroup ) )
{
// once militia have arrived, move them from the group to the sector
DissolveMilitiaGroup( pGroup->ubGroupID );
}
}
// if we have currently loaded the sector they are moving from, we have to remove them from tactical
else if ( pGroup->ubPrevX == gWorldSectorX && pGroup->ubPrevY == gWorldSectorY && pGroup->ubSectorZ == gbWorldSectorZ )
{
// first, let them (and all other militia) drop their gear
if ( gGameExternalOptions.fMilitiaUseSectorInventory )
TeamDropAll( MILITIA_TEAM );
// we now force a resetting of militia - they will be removed and recreated
// as the group's coordinates have alreay 'moved' to the next sector, the group militia will now be gone
gfStrategicMilitiaChangesMade = TRUE;
if ( gfStrategicMilitiaChangesMade )
ResetMilitia( );
// now restock the remaining militia
if ( gGameExternalOptions.fMilitiaUseSectorInventory )
TeamRestock( MILITIA_TEAM );
// move the gear along to the next sector
MoveMilitiaEquipment( pGroup->ubPrevX, pGroup->ubPrevY, pGroup->ubSectorX, pGroup->ubSectorY, pGroup->pEnemyGroup->ubNumElites, pGroup->pEnemyGroup->ubNumTroops, pGroup->pEnemyGroup->ubNumAdmins );
// if this is the last sector along the path, destroy the group after this and make the militia static
if ( !fBattlePending &&GroupAtFinalDestination( pGroup ) )
{
// once militia have arrived, move them from the group to the sector
DissolveMilitiaGroup( pGroup->ubGroupID );
}
// for safety, reset if necessary
ResetMilitia( );
}
else
{
// move the gear along to the next sector
MoveMilitiaEquipment( pGroup->ubPrevX, pGroup->ubPrevY, pGroup->ubSectorX, pGroup->ubSectorY, pGroup->pEnemyGroup->ubNumElites, pGroup->pEnemyGroup->ubNumTroops, pGroup->pEnemyGroup->ubNumAdmins );
// if this is the last sector along the path, destroy the group after this and make the militia static
if ( !fBattlePending && GroupAtFinalDestination( pGroup ) )
{
// once militia have arrived, move them from the group to the sector
DissolveMilitiaGroup( pGroup->ubGroupID );
}
// for safety, reset if necessary
ResetMilitia( );
} }
} }
@@ -2586,7 +2766,7 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup )
if ( !pGroup->ubSectorZ ) if ( !pGroup->ubSectorZ )
{ {
BOOLEAN fCalcRegularTime = TRUE; BOOLEAN fCalcRegularTime = TRUE;
if ( pGroup->usGroupTeam != OUR_TEAM ) if ( pGroup->usGroupTeam == ENEMY_TEAM )
{ {
//Determine if the enemy group is "sleeping". If so, then simply delay their arrival time by the amount of time //Determine if the enemy group is "sleeping". If so, then simply delay their arrival time by the amount of time
//they are going to be sleeping for. //they are going to be sleeping for.
@@ -2596,17 +2776,21 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup )
if ( Chance( 67 ) ) if ( Chance( 67 ) )
{ {
//2 in 3 chance of going to sleep. //2 in 3 chance of going to sleep.
pGroup->uiTraverseTime = GetSectorMvtTimeForGroup( ubSector, ubDirection, pGroup );
uiSleepMinutes = 360 + Random( 121 ); //6-8 hours sleep uiSleepMinutes = 360 + Random( 121 ); //6-8 hours sleep
fCalcRegularTime = FALSE;
} }
} }
} }
else if ( pGroup->usGroupTeam == MILITIA_TEAM )
if ( fCalcRegularTime )
{ {
pGroup->uiTraverseTime = GetSectorMvtTimeForGroup( ubSector, ubDirection, pGroup ); // As the player orders militia to move, a chance-based system is ill-advised - the player would simply cancel and reassign the order, leading to bypassing the mechanci in a tedious way
// so instead, we always add a penalty, but it will be lower
if ( GetWorldHour( ) >= 21 || GetWorldHour( ) <= 4 )
{
uiSleepMinutes = 280;
}
} }
pGroup->uiTraverseTime = GetSectorMvtTimeForGroup( ubSector, ubDirection, pGroup );
} }
else else
{ {
@@ -2713,8 +2897,7 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup )
void RemoveGroupWaypoints( UINT8 ubGroupID ) void RemoveGroupWaypoints( UINT8 ubGroupID )
{ {
GROUP *pGroup; GROUP* pGroup = GetGroup( ubGroupID );
pGroup = GetGroup( ubGroupID );
Assert( pGroup ); Assert( pGroup );
RemovePGroupWaypoints( pGroup ); RemovePGroupWaypoints( pGroup );
} }
@@ -4861,7 +5044,7 @@ void RandomizePatrolGroupLocation( GROUP *pGroup )
//return; //disabled for now //return; //disabled for now
Assert( pGroup->usGroupTeam != OUR_TEAM ); Assert( pGroup->usGroupTeam == ENEMY_TEAM );
Assert( pGroup->ubMoveType == ENDTOEND_FORWARDS ); Assert( pGroup->ubMoveType == ENDTOEND_FORWARDS );
Assert( pGroup->pEnemyGroup->ubIntention == PATROL ); Assert( pGroup->pEnemyGroup->ubIntention == PATROL );
@@ -4874,7 +5057,7 @@ void RandomizePatrolGroupLocation( GROUP *pGroup )
{ {
if( wp->next ) if( wp->next )
{ {
ubMaxWaypointID++; ++ubMaxWaypointID;
} }
wp = wp->next; wp = wp->next;
} }
@@ -4902,7 +5085,7 @@ void RandomizePatrolGroupLocation( GROUP *pGroup )
wp = pGroup->pWaypoints; wp = pGroup->pWaypoints;
while( wp && ubChosen ) while( wp && ubChosen )
{ {
ubChosen--; --ubChosen;
wp = wp->next; wp = wp->next;
} }
@@ -4922,7 +5105,6 @@ void RandomizePatrolGroupLocation( GROUP *pGroup )
//Immediately turn off the flag once finished. //Immediately turn off the flag once finished.
gfRandomizingPatrolGroup = FALSE; gfRandomizingPatrolGroup = FALSE;
} }
//Whenever a player group arrives in a sector, and if bloodcats exist in the sector, //Whenever a player group arrives in a sector, and if bloodcats exist in the sector,
+3
View File
@@ -182,6 +182,9 @@ BOOLEAN SetGroupPatrolParameters( UINT8 ubGroupID, UINT8 ubRestAtFL, UINT8 ubRes
//Enemy grouping functions -- private use by the strategic AI. //Enemy grouping functions -- private use by the strategic AI.
//............................................................ //............................................................
GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
GROUP* CreateNewMilitiaGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
#ifdef JA2UB #ifdef JA2UB
GROUP* CreateNewEnemyGroupDepartingFromSectorUsingZLevel( UINT32 uiSector, UINT8 ubSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); GROUP* CreateNewEnemyGroupDepartingFromSectorUsingZLevel( UINT32 uiSector, UINT8 ubSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
#endif #endif
+91 -86
View File
@@ -24,6 +24,7 @@
#include "Map Screen Interface.h" #include "Map Screen Interface.h"
#include "Game Event Hook.h" #include "Game Event Hook.h"
#include "Strategic AI.h" #include "Strategic AI.h"
#include "Queen Command.h" // added by Flugente
#endif #endif
@@ -210,7 +211,7 @@ INT32 FindStratPath(INT16 sStart, INT16 sDestination, INT16 sMvtGroupNumber, BOO
// for player groups only! // for player groups only!
pGroup = GetGroup( ( UINT8 )sMvtGroupNumber ); pGroup = GetGroup( ( UINT8 )sMvtGroupNumber );
if ( pGroup->usGroupTeam == OUR_TEAM ) if ( pGroup->usGroupTeam == OUR_TEAM || pGroup->usGroupTeam == MILITIA_TEAM )
{ {
// if player is holding down SHIFT key, find the shortest route instead of the quickest route! // if player is holding down SHIFT key, find the shortest route instead of the quickest route!
if ( _KeyDown( SHIFT ) ) if ( _KeyDown( SHIFT ) )
@@ -314,7 +315,7 @@ INT32 FindStratPath(INT16 sStart, INT16 sDestination, INT16 sMvtGroupNumber, BOO
{ {
continue; continue;
} }
if( GetNumberOfMilitiaInSector( sSectorX, sSectorY, 0 ) ) if ( NumNonPlayerTeamMembersInSector( sSectorX, sSectorY, MILITIA_TEAM ) )
{ {
continue; continue;
} }
@@ -478,78 +479,82 @@ INT32 FindStratPath(INT16 sStart, INT16 sDestination, INT16 sMvtGroupNumber, BOO
PathStPtr BuildAStrategicPath(PathStPtr pPath , INT16 iStartSectorNum, INT16 iEndSectorNum, INT16 sMvtGroupNumber, BOOLEAN fTacticalTraversal /*, BOOLEAN fTempPath */ ) PathStPtr BuildAStrategicPath(PathStPtr pPath , INT16 iStartSectorNum, INT16 iEndSectorNum, INT16 sMvtGroupNumber, BOOLEAN fTacticalTraversal /*, BOOLEAN fTempPath */ )
{ {
INT32 iCurrentSectorNum;
INT32 iDelta=0;
INT32 iPathLength;
INT32 iCount=0;
PathStPtr pNode=NULL;
PathStPtr pDeleteNode=NULL;
PathStPtr pHeadOfPathList = pPath;
INT32 iOldDelta = 0;
iCurrentSectorNum=iStartSectorNum;
INT32 iCurrentSectorNum; if(iEndSectorNum < MAP_WORLD_X-1)
INT32 iDelta=0; return NULL;
INT32 iPathLength;
INT32 iCount=0;
PathStPtr pNode=NULL;
PathStPtr pDeleteNode=NULL;
PathStPtr pHeadOfPathList = pPath;
INT32 iOldDelta = 0;
iCurrentSectorNum=iStartSectorNum;
if(iEndSectorNum < MAP_WORLD_X-1) if (pNode==NULL)
return NULL; {
// start new path list
pNode = (PathStPtr) MemAlloc(sizeof(PathSt));
/*
if ( _KeyDown( CTRL ))
pNode->fSpeed=SLOW_MVT;
else
*/
pNode->fSpeed=NORMAL_MVT;
pNode->uiSectorId=iStartSectorNum;
pNode->pNext=NULL;
pNode->pPrev=NULL;
pNode->uiEta = GetWorldTotalMin( );
pHeadOfPathList = pNode;
}
if (pNode==NULL) iPathLength=((INT32)FindStratPath(((INT16)iStartSectorNum),((INT16)iEndSectorNum), sMvtGroupNumber, fTacticalTraversal ));
{ while(iPathLength > iCount)
// start new path list {
pNode = (PathStPtr) MemAlloc(sizeof(PathSt)); switch(gusMapPathingData[iCount])
/* {
if ( _KeyDown( CTRL ))
pNode->fSpeed=SLOW_MVT;
else
*/
pNode->fSpeed=NORMAL_MVT;
pNode->uiSectorId=iStartSectorNum;
pNode->pNext=NULL;
pNode->pPrev=NULL;
pNode->uiEta = GetWorldTotalMin( );
pHeadOfPathList = pNode;
}
iPathLength=((INT32)FindStratPath(((INT16)iStartSectorNum),((INT16)iEndSectorNum), sMvtGroupNumber, fTacticalTraversal ));
while(iPathLength > iCount)
{
switch(gusMapPathingData[iCount])
{
case(NORTH): case(NORTH):
iDelta=NORTH_MOVE; iDelta=NORTH_MOVE;
break; break;
case(SOUTH): case(SOUTH):
iDelta=SOUTH_MOVE; iDelta=SOUTH_MOVE;
break; break;
case(EAST): case(EAST):
iDelta=EAST_MOVE; iDelta=EAST_MOVE;
break; break;
case(WEST): case(WEST):
iDelta=WEST_MOVE; iDelta=WEST_MOVE;
break; break;
} }
iCount++;
// create new node
iCurrentSectorNum+=iDelta;
if(!AddSectorToPathList(pHeadOfPathList, (UINT16)iCurrentSectorNum)) ++iCount;
{
pNode=pHeadOfPathList; // create new node
// intersected previous node, delete path to date iCurrentSectorNum+=iDelta;
if(!pNode)
return NULL; if(!AddSectorToPathList(pHeadOfPathList, (UINT16)iCurrentSectorNum))
while(pNode->pNext) {
pNode=pHeadOfPathList;
// intersected previous node, delete path to date
if(!pNode)
return NULL;
while(pNode->pNext)
pNode=pNode->pNext; pNode=pNode->pNext;
// start backing up // start backing up
while(pNode->uiSectorId!=(UINT32)iStartSectorNum) while(pNode->uiSectorId!=(UINT32)iStartSectorNum)
{ {
pDeleteNode=pNode; pDeleteNode=pNode;
pNode=pNode->pPrev; pNode=pNode->pPrev;
pNode->pNext=NULL; pNode->pNext=NULL;
MemFree(pDeleteNode); MemFree(pDeleteNode);
} }
return NULL;
}
return NULL;
}
// for strategic mvt events // for strategic mvt events
// we are at the new node, check if previous node was a change in deirection, ie change in delta..add waypoint // we are at the new node, check if previous node was a change in deirection, ie change in delta..add waypoint
@@ -568,16 +573,16 @@ PathStPtr BuildAStrategicPath(PathStPtr pPath , INT16 iStartSectorNum, INT16 iEn
} }
} }
*/ */
iOldDelta = iDelta; iOldDelta = iDelta;
pHeadOfPathList = pNode;
pHeadOfPathList = pNode; if(!pNode)
if(!pNode) return NULL;
return NULL;
while(pNode->pNext)
pNode=pNode->pNext;
} while(pNode->pNext)
pNode=pNode->pNext;
}
pNode=pHeadOfPathList; pNode=pHeadOfPathList;
@@ -591,7 +596,7 @@ PathStPtr BuildAStrategicPath(PathStPtr pPath , INT16 iStartSectorNum, INT16 iEn
MemFree(pNode); MemFree(pNode);
pHeadOfPathList = NULL; pHeadOfPathList = NULL;
pPath = pHeadOfPathList; pPath = pHeadOfPathList;
return FALSE; return FALSE;
} }
/* /*
@@ -604,8 +609,8 @@ PathStPtr BuildAStrategicPath(PathStPtr pPath , INT16 iStartSectorNum, INT16 iEn
*/ */
pPath=pHeadOfPathList; pPath=pHeadOfPathList;
return pPath;
return pPath;
} }
@@ -623,12 +628,12 @@ BOOLEAN AddSectorToPathList( PathStPtr pPath ,UINT16 uiSectorNum )
return FALSE; return FALSE;
if (pNode==NULL) if (pNode==NULL)
{ {
pNode = (PathStPtr) MemAlloc(sizeof(PathSt)); pNode = (PathStPtr) MemAlloc(sizeof(PathSt));
// Implement EtaCost Array as base EtaCosts of sectors // Implement EtaCost Array as base EtaCosts of sectors
// pNode->uiEtaCost=EtaCost[uiSectorNum]; // pNode->uiEtaCost=EtaCost[uiSectorNum];
pNode->uiSectorId=uiSectorNum; pNode->uiSectorId=uiSectorNum;
pNode->uiEta= GetWorldTotalMin( ); pNode->uiEta= GetWorldTotalMin( );
pNode->pNext=NULL; pNode->pNext=NULL;
pNode->pPrev=NULL; pNode->pPrev=NULL;
@@ -639,37 +644,37 @@ BOOLEAN AddSectorToPathList( PathStPtr pPath ,UINT16 uiSectorNum )
*/ */
pNode->fSpeed=NORMAL_MVT; pNode->fSpeed=NORMAL_MVT;
return TRUE; return TRUE;
} }
else else
{ {
//if (pNode->uiSectorId==uiSectorNum) //if (pNode->uiSectorId==uiSectorNum)
// return FALSE; // return FALSE;
while(pNode->pNext) while(pNode->pNext)
{ {
// if (pNode->uiSectorId==uiSectorNum) // if (pNode->uiSectorId==uiSectorNum)
// return FALSE; // return FALSE;
pNode=pNode->pNext; pNode=pNode->pNext;
}
} pTempNode = (PathStPtr) MemAlloc(sizeof(PathSt));
pTempNode->uiEta=0;
pTempNode = (PathStPtr) MemAlloc(sizeof(PathSt)); pNode->pNext=pTempNode;
pTempNode->uiEta=0; pTempNode->uiSectorId=uiSectorNum;
pNode->pNext=pTempNode; pTempNode->pPrev=pNode;
pTempNode->uiSectorId=uiSectorNum; pTempNode->pNext=NULL;
pTempNode->pPrev=pNode;
pTempNode->pNext=NULL;
/* /*
if ( _KeyDown( CTRL )) if ( _KeyDown( CTRL ))
pTempNode->fSpeed=SLOW_MVT; pTempNode->fSpeed=SLOW_MVT;
else else
*/ */
pTempNode->fSpeed=NORMAL_MVT; pTempNode->fSpeed=NORMAL_MVT;
pNode=pTempNode; pNode=pTempNode;
} }
pPath = pHeadOfList; pPath = pHeadOfList;
return TRUE; return TRUE;
} }
@@ -891,8 +896,8 @@ PathStPtr ClearStrategicPathList( PathStPtr pHeadOfPath, INT16 sMvtGroup )
if( ( sMvtGroup != -1 ) && ( sMvtGroup != 0 ) ) if( ( sMvtGroup != -1 ) && ( sMvtGroup != 0 ) )
{ {
// clear this groups mvt pathing // clear this groups mvt pathing
RemoveGroupWaypoints( ( UINT8 )sMvtGroup ); RemoveGroupWaypoints( ( UINT8 )sMvtGroup );
} }
return( pNode ); return( pNode );
+188 -89
View File
@@ -414,14 +414,44 @@ void StrategicPromoteMilitiaInSector(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRa
// damn well better have that many around to promote! // damn well better have that many around to promote!
//Assert(pSectorInfo->ubNumberOfCivsAtLevel[ ubCurrentRank ] >= ubHowMany); //Assert(pSectorInfo->ubNumberOfCivsAtLevel[ ubCurrentRank ] >= ubHowMany);
UINT8 stationary = MilitiaInSectorOfRankStationary( sMapX, sMapY, ubCurrentRank );
UINT8 ingroups = MilitiaInSectorOfRankInGroups( sMapX, sMapY, ubCurrentRank );
//KM : July 21, 1999 patch fix //KM : July 21, 1999 patch fix
if( pSectorInfo->ubNumberOfCivsAtLevel[ ubCurrentRank ] < ubHowMany ) if ( ubCurrentRank >= ELITE_MILITIA || stationary + ingroups < ubHowMany )
{ {
return; return;
} }
pSectorInfo->ubNumberOfCivsAtLevel[ ubCurrentRank ] -= ubHowMany; // determine how many static and - if necessary - group-based militia we have to remove
pSectorInfo->ubNumberOfCivsAtLevel[ ubCurrentRank + 1 ] += ubHowMany; UINT8 reducestatic = min( stationary, ubHowMany );
UINT8 reducegroups = min( ingroups, ubHowMany - reducestatic );
pSectorInfo->ubNumberOfCivsAtLevel[ubCurrentRank] -= reducestatic;
pSectorInfo->ubNumberOfCivsAtLevel[ubCurrentRank + 1] += reducestatic;
GROUP *pGroup = gpGroupList;
while ( pGroup && reducegroups )
{
if ( pGroup->usGroupTeam == MILITIA_TEAM && pGroup->ubSectorX == sMapX && pGroup->ubSectorY == sMapY )
{
if ( ubCurrentRank == GREEN_MILITIA )
{
UINT8 reduced = min( reducegroups, pGroup->pEnemyGroup->ubNumAdmins );
pGroup->pEnemyGroup->ubNumAdmins -= reduced;
pGroup->pEnemyGroup->ubNumTroops += reduced;
reducegroups -= reduced;
}
else if ( ubCurrentRank == REGULAR_MILITIA )
{
UINT8 reduced = min( reducegroups, pGroup->pEnemyGroup->ubNumTroops );
pGroup->pEnemyGroup->ubNumTroops -= reduced;
pGroup->pEnemyGroup->ubNumElites += reduced;
reducegroups -= reduced;
}
}
pGroup = pGroup->next;
}
if (ubHowMany && sMapX == gWorldSectorX && sMapY == gWorldSectorY ) if (ubHowMany && sMapX == gWorldSectorX && sMapY == gWorldSectorY )
{ {
@@ -441,13 +471,50 @@ void StrategicRemoveMilitiaFromSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UI
// damn well better have that many around to remove! // damn well better have that many around to remove!
//Assert(pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] >= ubHowMany); //Assert(pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] >= ubHowMany);
UINT8 stationary = MilitiaInSectorOfRankStationary( sMapX, sMapY, ubRank );
UINT8 ingroups = MilitiaInSectorOfRankInGroups( sMapX, sMapY, ubRank );
//KM : July 21, 1999 patch fix //KM : July 21, 1999 patch fix
if( pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] < ubHowMany ) if ( stationary + ingroups < ubHowMany )
{ {
return; return;
} }
pSectorInfo->ubNumberOfCivsAtLevel[ ubRank ] -= ubHowMany; // determine how many static and - if necessary - group-based militia we have to remove
UINT8 reducestatic = min( stationary, ubHowMany );
UINT8 reducegroups = min( ingroups, ubHowMany - reducestatic );
pSectorInfo->ubNumberOfCivsAtLevel[ubRank] -= reducestatic;
GROUP *pGroup = gpGroupList;
while ( pGroup && reducegroups )
{
if ( pGroup->usGroupTeam == MILITIA_TEAM && pGroup->ubSectorX == sMapX && pGroup->ubSectorY == sMapY )
{
if ( ubRank == GREEN_MILITIA )
{
UINT8 reduced = min( reducegroups, pGroup->pEnemyGroup->ubNumAdmins );
pGroup->pEnemyGroup->ubNumAdmins -= reduced;
pGroup->ubGroupSize -= reduced;
reducegroups -= reduced;
}
else if ( ubRank == REGULAR_MILITIA )
{
UINT8 reduced = min( reducegroups, pGroup->pEnemyGroup->ubNumTroops );
pGroup->pEnemyGroup->ubNumTroops -= reduced;
pGroup->ubGroupSize -= reduced;
reducegroups -= reduced;
}
else if ( ubRank == ELITE_MILITIA )
{
UINT8 reduced = min( reducegroups, pGroup->pEnemyGroup->ubNumElites );
pGroup->pEnemyGroup->ubNumElites -= reduced;
pGroup->ubGroupSize -= reduced;
reducegroups -= reduced;
}
}
pGroup = pGroup->next;
}
if (ubHowMany && sMapX == gWorldSectorX && sMapY == gWorldSectorY ) if (ubHowMany && sMapX == gWorldSectorX && sMapY == gWorldSectorY )
{ {
@@ -458,6 +525,18 @@ void StrategicRemoveMilitiaFromSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UI
fMapPanelDirty = TRUE; fMapPanelDirty = TRUE;
} }
void StrategicRemoveAllStaticMilitiaFromSector( INT16 sMapX, INT16 sMapY, UINT8 ubRank )
{
if ( ubRank < MAX_MILITIA_LEVELS )
SectorInfo[SECTOR( sMapX, sMapY )].ubNumberOfCivsAtLevel[ubRank] = 0;
if ( sMapX == gWorldSectorX && sMapY == gWorldSectorY )
gfStrategicMilitiaChangesMade = TRUE;
// update the screen display
fMapPanelDirty = TRUE;
}
// kill pts are (2 * kills) + assists // kill pts are (2 * kills) + assists
UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubRecentKillPts) UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubRecentKillPts)
@@ -488,21 +567,25 @@ UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank,
} }
// roll the bones, and see if he makes it // roll the bones, and see if he makes it
if (Random(100) < uiChanceToLevel) if ( Chance( uiChanceToLevel ) )
{ {
StrategicPromoteMilitiaInSector(sMapX, sMapY, ubCurrentRank, 1); StrategicPromoteMilitiaInSector(sMapX, sMapY, ubCurrentRank, 1);
if( ubCurrentRank == GREEN_MILITIA ) if( ubCurrentRank == GREEN_MILITIA )
{ //Attempt yet another level up if sufficient points {
//Attempt yet another level up if sufficient points
if( ubRecentKillPts > 2 ) if( ubRecentKillPts > 2 )
{ {
if( CheckOneMilitiaForPromotion( sMapX, sMapY, REGULAR_MILITIA, (UINT8)(ubRecentKillPts - 2) ) ) if( CheckOneMilitiaForPromotion( sMapX, sMapY, REGULAR_MILITIA, (UINT8)(ubRecentKillPts - 2) ) )
{ //success, this militia was promoted twice {
//success, this militia was promoted twice
return 2; return 2;
} }
} }
} }
return 1; return 1;
} }
return 0; return 0;
} }
@@ -510,39 +593,37 @@ UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank,
// call this if the player attacks his own militia // call this if the player attacks his own militia
void HandleMilitiaDefections(INT16 sMapX, INT16 sMapY) void HandleMilitiaDefections(INT16 sMapX, INT16 sMapY)
{ {
UINT8 ubRank;
UINT8 ubMilitiaCnt; UINT8 ubMilitiaCnt;
UINT8 ubCount;
UINT32 uiChanceToDefect; UINT32 uiChanceToDefect;
for( ubRank = 0; ubRank < MAX_MILITIA_LEVELS; ubRank++ ) for ( UINT8 ubRank = 0; ubRank < MAX_MILITIA_LEVELS; ++ubRank )
{ {
ubMilitiaCnt = MilitiaInSectorOfRank(sMapX, sMapY, ubRank); ubMilitiaCnt = MilitiaInSectorOfRank(sMapX, sMapY, ubRank);
// check each guy at each rank to see if he defects if ( ubMilitiaCnt )
for (ubCount = 0; ubCount < ubMilitiaCnt; ubCount++)
{ {
switch( ubRank ) switch ( ubRank )
{ {
case GREEN_MILITIA: case GREEN_MILITIA:
uiChanceToDefect = 50; uiChanceToDefect = 50;
break; break;
case REGULAR_MILITIA: case REGULAR_MILITIA:
uiChanceToDefect = 75; uiChanceToDefect = 75;
break; break;
case ELITE_MILITIA: case ELITE_MILITIA:
uiChanceToDefect = 90; uiChanceToDefect = 90;
break; break;
default:
Assert( 0 );
return;
} }
// roll the bones; should I stay or should I go now? (for you music fans out there) // check each guy at each rank to see if he defects
if (Random(100) < uiChanceToDefect) for ( UINT8 ubCount = 0; ubCount < ubMilitiaCnt; ++ubCount )
{ {
//B'bye! (for you SNL fans out there) // roll the bones; should I stay or should I go now? (for you music fans out there)
StrategicRemoveMilitiaFromSector(sMapX, sMapY, ubRank, 1); if ( Chance( uiChanceToDefect ) )
{
//B'bye! (for you SNL fans out there)
StrategicRemoveMilitiaFromSector(sMapX, sMapY, ubRank, 1);
}
} }
} }
} }
@@ -551,7 +632,36 @@ void HandleMilitiaDefections(INT16 sMapX, INT16 sMapY)
UINT8 MilitiaInSectorOfRank(INT16 sMapX, INT16 sMapY, UINT8 ubRank) UINT8 MilitiaInSectorOfRank(INT16 sMapX, INT16 sMapY, UINT8 ubRank)
{ {
unsigned count = SectorInfo[ SECTOR( sMapX, sMapY ) ].ubNumberOfCivsAtLevel[ ubRank ]; return MilitiaInSectorOfRankStationary( sMapX, sMapY, ubRank ) + MilitiaInSectorOfRankInGroups( sMapX, sMapY, ubRank );
}
UINT8 MilitiaInSectorOfRankStationary( INT16 sMapX, INT16 sMapY, UINT8 ubRank )
{
if ( ubRank < MAX_MILITIA_LEVELS )
return SectorInfo[SECTOR( sMapX, sMapY )].ubNumberOfCivsAtLevel[ubRank];
return 0;
}
UINT8 MilitiaInSectorOfRankInGroups( INT16 sMapX, INT16 sMapY, UINT8 ubRank )
{
UINT8 count = 0;
GROUP *pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == MILITIA_TEAM && pGroup->ubSectorX == sMapX && pGroup->ubSectorY == sMapY )
{
if ( ubRank == GREEN_MILITIA )
count += pGroup->pEnemyGroup->ubNumAdmins;
else if ( ubRank == REGULAR_MILITIA )
count += pGroup->pEnemyGroup->ubNumTroops;
else if ( ubRank == ELITE_MILITIA )
count += pGroup->pEnemyGroup->ubNumElites;
}
pGroup = pGroup->next;
}
return count; return count;
} }
@@ -1179,13 +1289,12 @@ BOOLEAN CanSomeoneNearbyScoutThisSector( INT16 sSectorX, INT16 sSectorY, BOOLEAN
INT16 sCounterA = 0, sCounterB = 0; INT16 sCounterA = 0, sCounterB = 0;
UINT8 ubScoutingRange = 1; UINT8 ubScoutingRange = 1;
// get the sector value // get the sector value
sSector = sSectorX + sSectorY * MAP_WORLD_X; sSector = sSectorX + sSectorY * MAP_WORLD_X;
for( sCounterA = sSectorX - ubScoutingRange; sCounterA <= sSectorX + ubScoutingRange; sCounterA++ ) for( sCounterA = sSectorX - ubScoutingRange; sCounterA <= sSectorX + ubScoutingRange; ++sCounterA )
{ {
for( sCounterB = sSectorY - ubScoutingRange; sCounterB <= sSectorY + ubScoutingRange; sCounterB++ ) for( sCounterB = sSectorY - ubScoutingRange; sCounterB <= sSectorY + ubScoutingRange; ++sCounterB )
{ {
// skip out of bounds sectors // skip out of bounds sectors
if ( ( sCounterA < 1 ) || ( sCounterA > 16 ) || ( sCounterB < 1 ) || ( sCounterB > 16 ) ) if ( ( sCounterA < 1 ) || ( sCounterA > 16 ) || ( sCounterB < 1 ) || ( sCounterB > 16 ) )
@@ -1213,15 +1322,7 @@ BOOLEAN CanSomeoneNearbyScoutThisSector( INT16 sSectorX, INT16 sSectorY, BOOLEAN
else else
{ {
// check if any sort of militia here // check if any sort of militia here
if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] ) if ( NumNonPlayerTeamMembersInSector( sCounterA, sCounterB, MILITIA_TEAM ) )
{
return( TRUE );
}
else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] )
{
return( TRUE );
}
else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] )
{ {
return( TRUE ); return( TRUE );
} }
@@ -1253,7 +1354,6 @@ BOOLEAN IsTownFullMilitia( INT8 bTownId, INT8 iMilitiaType )
// if sector is ours get number of militia here // if sector is ours get number of militia here
if( SectorOursAndPeaceful( sSectorX, sSectorY, 0 ) ) if( SectorOursAndPeaceful( sSectorX, sSectorY, 0 ) )
{ {
//Kaiden: Checking for Price Hikes. //Kaiden: Checking for Price Hikes.
if (iMilitiaType == GREEN_MILITIA) if (iMilitiaType == GREEN_MILITIA)
{ {
@@ -1262,7 +1362,7 @@ BOOLEAN IsTownFullMilitia( INT8 bTownId, INT8 iMilitiaType )
iNumberOfMilitia += MilitiaInSectorOfRank( sSectorX, sSectorY, ELITE_MILITIA ); iNumberOfMilitia += MilitiaInSectorOfRank( sSectorX, sSectorY, ELITE_MILITIA );
iMaxNumber += iMaxMilitiaPerSector; iMaxNumber += iMaxMilitiaPerSector;
if (MilitiaInSectorOfRank( sSectorX, sSectorY, GREEN_MILITIA ) > 0) if (MilitiaInSectorOfRank( sSectorX, sSectorY, GREEN_MILITIA ) > 0)
fIncreaseCost = TRUE; fIncreaseCost = TRUE;
} }
else if (iMilitiaType == REGULAR_MILITIA) else if (iMilitiaType == REGULAR_MILITIA)
@@ -1297,26 +1397,24 @@ BOOLEAN IsTownFullMilitia( INT8 bTownId, INT8 iMilitiaType )
} }
} }
iCounter++; ++iCounter;
} }
if (iMilitiaType == GREEN_MILITIA) if (iMilitiaType == GREEN_MILITIA)
{ {
if (( iNumberOfMilitia == iMaxNumber ) && (fIncreaseCost)) if (( iNumberOfMilitia == iMaxNumber ) && fIncreaseCost )
return( TRUE ); return( TRUE );
else else
return( FALSE ); return( FALSE );
}
else if (iMilitiaType == REGULAR_MILITIA)
{
if (( iNumberOfMilitia == iMaxNumber ) && (fIncreaseCost))
return( TRUE );
else
return( FALSE );
}
}
else if (iMilitiaType == REGULAR_MILITIA)
{
if (( iNumberOfMilitia == iMaxNumber ) && fIncreaseCost)
return( TRUE );
else
return( FALSE );
}
// now check the number of militia // now check the number of militia
if ( iMaxNumber > iNumberOfMilitia ) if ( iMaxNumber > iNumberOfMilitia )
@@ -2122,7 +2220,7 @@ void HandleMilitiaUpkeepPayment( void )
MILITIA_LIST_TYPE MilitiaList[256]; MILITIA_LIST_TYPE MilitiaList[256];
// Go through every sector and count how many militia we've got in total. // Go through every sector and count how many militia we've got in total.
for (UINT16 cnt = 0; cnt < 256; cnt++) for (UINT16 cnt = 0; cnt < 256; ++cnt)
{ {
SECTORINFO *pSectorInfo = &( SectorInfo[ cnt ] ); SECTORINFO *pSectorInfo = &( SectorInfo[ cnt ] );
UINT8 sMapX = SECTORX(cnt); UINT8 sMapX = SECTORX(cnt);
@@ -2134,18 +2232,18 @@ void HandleMilitiaUpkeepPayment( void )
if ((ubTownId != BLANK_SECTOR && MilitiaTrainingAllowedInTown(ubTownId)) || // Major Town if ((ubTownId != BLANK_SECTOR && MilitiaTrainingAllowedInTown(ubTownId)) || // Major Town
IsThisSectorASAMSector( sMapX, sMapY, 0 ) ) // SAM Site IsThisSectorASAMSector( sMapX, sMapY, 0 ) ) // SAM Site
{ {
MilitiaList[cnt].ubNumTownGreens = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]; MilitiaList[cnt].ubNumTownGreens = MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA );
MilitiaList[cnt].ubNumTownRegulars = pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]; MilitiaList[cnt].ubNumTownRegulars = MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA );
MilitiaList[cnt].ubNumTownElites = pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA]; MilitiaList[cnt].ubNumTownElites = MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA );
MilitiaList[cnt].ubNumMobileGreens = 0; MilitiaList[cnt].ubNumMobileGreens = 0;
MilitiaList[cnt].ubNumMobileRegulars = 0; MilitiaList[cnt].ubNumMobileRegulars = 0;
MilitiaList[cnt].ubNumMobileElites = 0; MilitiaList[cnt].ubNumMobileElites = 0;
} }
else else
{ {
MilitiaList[cnt].ubNumMobileGreens = pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]; MilitiaList[cnt].ubNumMobileGreens = MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA );
MilitiaList[cnt].ubNumMobileRegulars = pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]; MilitiaList[cnt].ubNumMobileRegulars = MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA );
MilitiaList[cnt].ubNumMobileElites = pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA]; MilitiaList[cnt].ubNumMobileElites = MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA );
MilitiaList[cnt].ubNumTownGreens = 0; MilitiaList[cnt].ubNumTownGreens = 0;
MilitiaList[cnt].ubNumTownRegulars = 0; MilitiaList[cnt].ubNumTownRegulars = 0;
MilitiaList[cnt].ubNumTownElites = 0; MilitiaList[cnt].ubNumTownElites = 0;
@@ -2169,53 +2267,54 @@ void HandleMilitiaUpkeepPayment( void )
uiMoneyUnpaid = 0; uiMoneyUnpaid = 0;
} }
SECTORINFO *pSectorInfo = &( SectorInfo[ MilitiaList[0].ubSectorId ] ); INT16 sX = SECTORX( MilitiaList[0].ubSectorId );
INT16 sY = SECTORY( MilitiaList[0].ubSectorId );
if (MilitiaList[0].ubNumMobileElites > 0) if (MilitiaList[0].ubNumMobileElites > 0)
{ {
// Remove one militia from sector // Remove one militia from sector
pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA]--; StrategicRemoveMilitiaFromSector( sX, sY, ELITE_MILITIA, 1 );
// Adjust list entry // Adjust list entry
MilitiaList[0].ubNumMobileElites--; MilitiaList[0].ubNumMobileElites--;
// Reduce debt appropriately // Reduce debt appropriately
uiMoneyUnpaid -= gGameExternalOptions.usDailyCostMobileElite; uiMoneyUnpaid -= gGameExternalOptions.usDailyCostMobileElite;
// Increase tally of militia removed // Increase tally of militia removed
uiNumMilitiaDisbanded++; ++uiNumMilitiaDisbanded;
} }
else if (MilitiaList[0].ubNumMobileRegulars > 0) else if (MilitiaList[0].ubNumMobileRegulars > 0)
{ {
pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]--; StrategicRemoveMilitiaFromSector( sX, sY, REGULAR_MILITIA, 1 );
MilitiaList[0].ubNumMobileRegulars--; MilitiaList[0].ubNumMobileRegulars--;
uiMoneyUnpaid -= gGameExternalOptions.usDailyCostMobileRegular; uiMoneyUnpaid -= gGameExternalOptions.usDailyCostMobileRegular;
uiNumMilitiaDisbanded++; ++uiNumMilitiaDisbanded;
} }
else if (MilitiaList[0].ubNumMobileGreens > 0) else if (MilitiaList[0].ubNumMobileGreens > 0)
{ {
pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]--; StrategicRemoveMilitiaFromSector( sX, sY, GREEN_MILITIA, 1 );
MilitiaList[0].ubNumMobileGreens--; MilitiaList[0].ubNumMobileGreens--;
uiMoneyUnpaid -= gGameExternalOptions.usDailyCostMobileGreen; uiMoneyUnpaid -= gGameExternalOptions.usDailyCostMobileGreen;
uiNumMilitiaDisbanded++; ++uiNumMilitiaDisbanded;
} }
else if (MilitiaList[0].ubNumTownElites > 0) else if (MilitiaList[0].ubNumTownElites > 0)
{ {
pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA]--; StrategicRemoveMilitiaFromSector( sX, sY, ELITE_MILITIA, 1 );
MilitiaList[0].ubNumTownElites--; MilitiaList[0].ubNumTownElites--;
uiMoneyUnpaid -= gGameExternalOptions.usDailyCostTownElite; uiMoneyUnpaid -= gGameExternalOptions.usDailyCostTownElite;
uiNumMilitiaDisbanded++; ++uiNumMilitiaDisbanded;
} }
else if (MilitiaList[0].ubNumTownRegulars > 0) else if (MilitiaList[0].ubNumTownRegulars > 0)
{ {
pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA]--; StrategicRemoveMilitiaFromSector( sX, sY, REGULAR_MILITIA, 1 );
MilitiaList[0].ubNumTownRegulars--; MilitiaList[0].ubNumTownRegulars--;
uiMoneyUnpaid -= gGameExternalOptions.usDailyCostTownRegular; uiMoneyUnpaid -= gGameExternalOptions.usDailyCostTownRegular;
uiNumMilitiaDisbanded++; ++uiNumMilitiaDisbanded;
} }
else if (MilitiaList[0].ubNumTownGreens > 0) else if (MilitiaList[0].ubNumTownGreens > 0)
{ {
pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA]--; StrategicRemoveMilitiaFromSector( sX, sY, GREEN_MILITIA, 1 );
MilitiaList[0].ubNumTownGreens--; MilitiaList[0].ubNumTownGreens--;
uiMoneyUnpaid -= gGameExternalOptions.usDailyCostTownGreen; uiMoneyUnpaid -= gGameExternalOptions.usDailyCostTownGreen;
uiNumMilitiaDisbanded++; ++uiNumMilitiaDisbanded;
} }
else else
{ {
@@ -2306,7 +2405,7 @@ UINT32 CalcMilitiaUpkeep( void )
{ {
UINT32 uiTotalPayment = 0; UINT32 uiTotalPayment = 0;
for (UINT16 cnt = 0; cnt < 256; cnt++) for (UINT16 cnt = 0; cnt < 256; ++cnt)
{ {
SECTORINFO *pSectorInfo = &( SectorInfo[ cnt ] ); SECTORINFO *pSectorInfo = &( SectorInfo[ cnt ] );
UINT8 sMapX = SECTORX(cnt); UINT8 sMapX = SECTORX(cnt);
@@ -2316,15 +2415,15 @@ UINT32 CalcMilitiaUpkeep( void )
if ((ubTownId != BLANK_SECTOR && MilitiaTrainingAllowedInTown(ubTownId)) || // Major Town if ((ubTownId != BLANK_SECTOR && MilitiaTrainingAllowedInTown(ubTownId)) || // Major Town
IsThisSectorASAMSector( sMapX, sMapY, 0 ) ) // SAM Site IsThisSectorASAMSector( sMapX, sMapY, 0 ) ) // SAM Site
{ {
uiTotalPayment += pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA] * gGameExternalOptions.usDailyCostTownGreen; uiTotalPayment += MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA ) * gGameExternalOptions.usDailyCostTownGreen;
uiTotalPayment += pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA] * gGameExternalOptions.usDailyCostTownRegular; uiTotalPayment += MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA ) * gGameExternalOptions.usDailyCostTownRegular;
uiTotalPayment += pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA] * gGameExternalOptions.usDailyCostTownElite; uiTotalPayment += MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA ) * gGameExternalOptions.usDailyCostTownElite;
} }
else else
{ {
uiTotalPayment += pSectorInfo->ubNumberOfCivsAtLevel[GREEN_MILITIA] * gGameExternalOptions.usDailyCostMobileGreen; uiTotalPayment += MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA ) * gGameExternalOptions.usDailyCostMobileGreen;
uiTotalPayment += pSectorInfo->ubNumberOfCivsAtLevel[REGULAR_MILITIA] * gGameExternalOptions.usDailyCostMobileRegular; uiTotalPayment += MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA ) * gGameExternalOptions.usDailyCostMobileRegular;
uiTotalPayment += pSectorInfo->ubNumberOfCivsAtLevel[ELITE_MILITIA] * gGameExternalOptions.usDailyCostMobileElite; uiTotalPayment += MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA ) * gGameExternalOptions.usDailyCostMobileElite;
} }
} }
+4
View File
@@ -34,6 +34,8 @@ void StrategicAddMilitiaToSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UINT8 u
void StrategicPromoteMilitiaInSector(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubHowMany); void StrategicPromoteMilitiaInSector(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubHowMany);
void StrategicRemoveMilitiaFromSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UINT8 ubHowMany); void StrategicRemoveMilitiaFromSector(INT16 sMapX, INT16 sMapY, UINT8 ubRank, UINT8 ubHowMany);
void StrategicRemoveAllStaticMilitiaFromSector( INT16 sMapX, INT16 sMapY, UINT8 ubRank );
// this will check for promotions and handle them for you // this will check for promotions and handle them for you
UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubRecentKillPts); UINT8 CheckOneMilitiaForPromotion(INT16 sMapX, INT16 sMapY, UINT8 ubCurrentRank, UINT8 ubRecentKillPts);
@@ -48,6 +50,8 @@ UINT8 FindBestMilitiaTrainingLeadershipInSector ( INT16 sMapX, INT16 sMapY, INT8
void HandleMilitiaDefections(INT16 sMapX, INT16 sMapY); void HandleMilitiaDefections(INT16 sMapX, INT16 sMapY);
UINT8 MilitiaInSectorOfRank(INT16 sMapX, INT16 sMapY, UINT8 ubRank); UINT8 MilitiaInSectorOfRank(INT16 sMapX, INT16 sMapY, UINT8 ubRank);
UINT8 MilitiaInSectorOfRankStationary( INT16 sMapX, INT16 sMapY, UINT8 ubRank );
UINT8 MilitiaInSectorOfRankInGroups( INT16 sMapX, INT16 sMapY, UINT8 ubRank );
// Returns TRUE if sector is under player control, has no enemies in it, and isn't currently in combat mode // Returns TRUE if sector is under player control, has no enemies in it, and isn't currently in combat mode
BOOLEAN SectorOursAndPeaceful( INT16 sMapX, INT16 sMapY, INT8 bMapZ ); BOOLEAN SectorOursAndPeaceful( INT16 sMapX, INT16 sMapY, INT8 bMapZ );
+735 -216
View File
File diff suppressed because it is too large Load Diff
+42
View File
@@ -119,4 +119,46 @@ enum
NUM_MANUAL_MOBILE_STATES, NUM_MANUAL_MOBILE_STATES,
}; };
// Flugente: militia movement
extern BOOLEAN fPlotForMilitia;
extern UINT32 gMilitiaPlotStartSector;
BOOLEAN RequestGiveMilitiaNewDestination( void );
void SetUpMilitiaForMovement();
INT32 GetGroundTravelTimeOfMilitia( );
typedef struct
{
INT16 sGroupid; // group ids are normally UINT8 - we use -1 to indicate that it hasn't been used
PathStPtr path; // the path of a militia group that travels
} MILITIA_PATH;
#define MILITIA_PATROLS_MAX 30
extern MILITIA_PATH gMilitiaPath[MILITIA_PATROLS_MAX];
// upon starting a game/loading from an old version, set up the data
void MilitiaPlotInit();
// when starting to plot, set up things
BOOLEAN MilitiaPlotStart();
// when finished plotting, set up other things
void MilitiaplotFinish();
// if this group is a militia travel group, return its slot, othewise return -1
INT16 GetMilitiaPathSlot(UINT8 uGroupId);
void DeleteAllMilitiaPaths();
// if a militia group is in this sector, return TRUE, group id will be stored in arId
BOOLEAN GetMilitiaGroupInSector( INT16 sMapX, INT16 sMapY, UINT8& arId );
BOOLEAN CanGiveStrategicMilitiaMoveOrder( INT16 sMapX, INT16 sMapY );
void ConvertMinTimeToDayHourMinString( UINT32 uiTimeInMin, STR16 sString );
void ConvertMinTimeToETADayHourMinString( UINT32 uiTimeInMin, STR16 sString );
#endif #endif
+3 -4
View File
@@ -19,7 +19,8 @@
#include "militiasquads.h" // added by Flugente #include "militiasquads.h" // added by Flugente
#include "Game Event Hook.h" // added by Flugente #include "Game Event Hook.h" // added by Flugente
#include "message.h" // added by Flugente #include "message.h" // added by Flugente
#include "Text.h" // added by Flugente #include "Text.h" // added by Flugente
#include "Queen Command.h" // added by Flugente
#endif #endif
#ifdef JA2UB #ifdef JA2UB
@@ -172,10 +173,8 @@ BOOLEAN SetMilitiaMovementOrder(INT16 sX, INT16 sY, INT8 sZ, UINT32 dir)
if ( sZ ) if ( sZ )
return FALSE; return FALSE;
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sX, sY ) ] );
// militia needs to be here... // militia needs to be here...
if ( !CountMilitia(pSectorInfo) ) if ( !NumNonPlayerTeamMembersInSector( sX, sY, MILITIA_TEAM ) )
return FALSE; return FALSE;
// in order to give movement orders, we need a merc to staff a military headquarter // in order to give movement orders, we need a merc to staff a military headquarter
+42 -81
View File
@@ -1857,24 +1857,6 @@ UINT8 GetTownSectorSize( INT8 bTownId )
return( ubSectorSize ); return( ubSectorSize );
} }
UINT8 GetMilitiaCountAtLevelAnywhereInTown( UINT8 ubTownValue, UINT8 ubLevelValue )
{
INT32 iCounter = 0;
UINT8 ubCount =0;
while( pTownNamesList[ iCounter ] != 0 )
{
if( StrategicMap[ pTownLocationsList[ iCounter ] ].bNameId == ubTownValue )
{
// match. Add the number of civs at this level
ubCount += SectorInfo[ STRATEGIC_INDEX_TO_SECTOR_INFO( pTownLocationsList[ iCounter ] ) ].ubNumberOfCivsAtLevel[ ubLevelValue ];
}
iCounter++;
}
return( ubCount );
}
// return number of sectors under player control for this town // return number of sectors under player control for this town
UINT8 GetTownSectorsUnderControl( INT8 bTownId ) UINT8 GetTownSectorsUnderControl( INT8 bTownId )
@@ -1882,14 +1864,13 @@ UINT8 GetTownSectorsUnderControl( INT8 bTownId )
INT8 ubSectorsControlled = 0; INT8 ubSectorsControlled = 0;
UINT16 usSector = 0; UINT16 usSector = 0;
for ( INT32 iCounterA = 0; iCounterA < (INT32)(MAP_WORLD_X - 1); iCounterA++ ) for ( INT32 iCounterA = 0; iCounterA < (INT32)(MAP_WORLD_X - 1); ++iCounterA )
{ {
for ( INT32 iCounterB = 0; iCounterB < (INT32)(MAP_WORLD_Y - 1); iCounterB++ ) for ( INT32 iCounterB = 0; iCounterB < (INT32)(MAP_WORLD_Y - 1); ++iCounterB )
{ {
usSector = (UINT16)CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB ); usSector = (UINT16)CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB );
if( ( StrategicMap[ usSector ].bNameId == bTownId ) && if( ( StrategicMap[ usSector ].bNameId == bTownId ) && !StrategicMap[ usSector ].fEnemyControlled &&
( StrategicMap[ usSector ].fEnemyControlled == FALSE ) &&
(NumNonPlayerTeamMembersInSector( (INT16)iCounterA, (INT16)iCounterB, ENEMY_TEAM ) == 0) ) (NumNonPlayerTeamMembersInSector( (INT16)iCounterA, (INT16)iCounterB, ENEMY_TEAM ) == 0) )
{ {
++ubSectorsControlled; ++ubSectorsControlled;
@@ -1902,14 +1883,13 @@ UINT8 GetTownSectorsUnderControl( INT8 bTownId )
void InitializeSAMSites( void ) void InitializeSAMSites( void )
{ {
UINT32 cnt;
// move the landing zone over to Omerta // move the landing zone over to Omerta
// HEADROCK HAM 3.5: Externalized coordinates // HEADROCK HAM 3.5: Externalized coordinates
gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX; gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY; gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
// all SAM sites start game in perfect working condition // all SAM sites start game in perfect working condition
for ( cnt = 0; cnt < NUMBER_OF_SAMS; cnt++ ) for ( UINT32 cnt = 0; cnt < NUMBER_OF_SAMS; ++cnt )
{ {
StrategicMap[ gpSamSectorX[cnt] + ( MAP_WORLD_X * gpSamSectorY[cnt] ) ].bSAMCondition = 100; StrategicMap[ gpSamSectorX[cnt] + ( MAP_WORLD_X * gpSamSectorY[cnt] ) ].bSAMCondition = 100;
}; };
@@ -1927,8 +1907,6 @@ void GetShortSectorString( INT16 sMapX,INT16 sMapY, STR16 sString )
{ {
// OK, build string id like J11 // OK, build string id like J11
swprintf( sString, L"%S%S",pVertStrings[ sMapY ], pHortStrings[ sMapX ] ); swprintf( sString, L"%S%S",pVertStrings[ sMapY ], pHortStrings[ sMapX ] );
return;
} }
@@ -2140,7 +2118,7 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
} }
} }
for (int i=0; i<TOTAL_SOLDIERS; i++) for (int i=0; i<TOTAL_SOLDIERS; ++i)
{ {
//CHRISL: We should only bother with this assertion if the soldier is alive. Dead soliders are moved to //CHRISL: We should only bother with this assertion if the soldier is alive. Dead soliders are moved to
// GridNo = NOWHERE, which causes this assertion to fail // GridNo = NOWHERE, which causes this assertion to fail
@@ -2780,7 +2758,7 @@ void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bN
// note it as stolen // note it as stolen
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++cnt,pSoldier++)
{ {
if ( pSoldier->bActive ) if ( pSoldier->bActive )
{ {
@@ -2791,7 +2769,7 @@ void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bN
} }
} }
if ( (gubQuest[ QUEST_KINGPIN_MONEY ] == QUESTINPROGRESS) && CheckFact( FACT_KINGPIN_CAN_SEND_ASSASSINS, 0 ) && (GetTownIdForSector( sNewSectorX, sNewSectorY ) != BLANK_SECTOR) && Random( 10 + GetNumberOfMilitiaInSector( sNewSectorX, sNewSectorY, bNewSectorZ ) ) < 3 ) if ( (gubQuest[QUEST_KINGPIN_MONEY] == QUESTINPROGRESS) && CheckFact( FACT_KINGPIN_CAN_SEND_ASSASSINS, 0 ) && (GetTownIdForSector( sNewSectorX, sNewSectorY ) != BLANK_SECTOR) && !bNewSectorZ && Random( 10 + NumNonPlayerTeamMembersInSector( sNewSectorX, sNewSectorY, MILITIA_TEAM ) ) < 3 )
{ {
DecideOnAssassin(); DecideOnAssassin();
} }
@@ -2999,7 +2977,6 @@ BOOLEAN EnterSector( INT16 sSectorX, INT16 sSectorY , INT8 bSectorZ )
SetSectorFlag( sSectorX, sSectorY, bSectorZ, SF_ALREADY_VISITED ); SetSectorFlag( sSectorX, sSectorY, bSectorZ, SF_ALREADY_VISITED );
} }
GetMapFileName( sSectorX, sSectorY, bSectorZ, bFilename, TRUE, TRUE ); GetMapFileName( sSectorX, sSectorY, bSectorZ, bFilename, TRUE, TRUE );
//Load the placeholder map if the real map doesn't exist. //Load the placeholder map if the real map doesn't exist.
@@ -3087,7 +3064,6 @@ BOOLEAN EnterSector( INT16 sSectorX, INT16 sSectorY , INT8 bSectorZ )
//Save to tempfile //Save to tempfile
SaveWorldItemsToTempItemFile( sSectorX, sSectorY, (INT8)bSectorZ, guiNumWorldItems, gWorldItems ); SaveWorldItemsToTempItemFile( sSectorX, sSectorY, (INT8)bSectorZ, guiNumWorldItems, gWorldItems );
return TRUE; //because the map was loaded. return TRUE; //because the map was loaded.
} }
@@ -3124,7 +3100,7 @@ void UpdateMercsInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
//if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) ) //if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{ {
for ( cnt = 0, pSoldier = MercPtrs[ cnt ]; cnt < MAX_NUM_SOLDIERS; cnt++, pSoldier++) for ( cnt = 0, pSoldier = MercPtrs[ cnt ]; cnt < MAX_NUM_SOLDIERS; ++cnt, ++pSoldier)
{ {
if ( gfRestoringEnemySoldiersFromTempFile && if ( gfRestoringEnemySoldiersFromTempFile &&
cnt >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID && cnt >= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID &&
@@ -3198,9 +3174,7 @@ void UpdateMercsInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
// Do action // Do action
HandleNPCDoAction( 0, NPC_ACTION_GRANT_EXPERIENCE_3, 0 ); HandleNPCDoAction( 0, NPC_ACTION_GRANT_EXPERIENCE_3, 0 );
} }
} }
} }
} }
@@ -3219,7 +3193,6 @@ void UpdateMercsInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
// Set to false // Set to false
fUsingEdgePointsForStrategicEntry = FALSE; fUsingEdgePointsForStrategicEntry = FALSE;
} }
} }
void UpdateMercInSector( SOLDIERTYPE *pSoldier, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) void UpdateMercInSector( SOLDIERTYPE *pSoldier, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
@@ -3809,7 +3782,6 @@ UINT8 SetInsertionDataFromAdjacentMoveDirection( SOLDIERTYPE *pSoldier, UINT8 ub
UINT8 ubDirection; UINT8 ubDirection;
EXITGRID ExitGrid; EXITGRID ExitGrid;
// Set insertion code // Set insertion code
switch( ubTacticalDirection ) switch( ubTacticalDirection )
{ {
@@ -3853,24 +3825,20 @@ UINT8 SetInsertionDataFromAdjacentMoveDirection( SOLDIERTYPE *pSoldier, UINT8 ub
} }
return( ubDirection ); return( ubDirection );
} }
UINT8 GetInsertionDataFromAdjacentMoveDirection( UINT8 ubTacticalDirection, INT32 sAdditionalData )//dnl ch56 151009 UINT8 GetInsertionDataFromAdjacentMoveDirection( UINT8 ubTacticalDirection, INT32 sAdditionalData )//dnl ch56 151009
{ {
UINT8 ubDirection; UINT8 ubDirection;
// Set insertion code // Set insertion code
switch( ubTacticalDirection ) switch( ubTacticalDirection )
{ {
// OK, we are using an exit grid - set insertion values... // OK, we are using an exit grid - set insertion values...
case 255: case 255:
ubDirection = 255; ubDirection = 255;
break; break;
case NORTH: case NORTH:
ubDirection = NORTH_STRATEGIC_MOVE; ubDirection = NORTH_STRATEGIC_MOVE;
break; break;
@@ -3893,24 +3861,20 @@ UINT8 GetInsertionDataFromAdjacentMoveDirection( UINT8 ubTacticalDirection, INT3
} }
return( ubDirection ); return( ubDirection );
} }
UINT8 GetStrategicInsertionDataFromAdjacentMoveDirection( UINT8 ubTacticalDirection, INT32 sAdditionalData )//dnl ch56 151009 UINT8 GetStrategicInsertionDataFromAdjacentMoveDirection( UINT8 ubTacticalDirection, INT32 sAdditionalData )//dnl ch56 151009
{ {
UINT8 ubDirection; UINT8 ubDirection;
// Set insertion code // Set insertion code
switch( ubTacticalDirection ) switch( ubTacticalDirection )
{ {
// OK, we are using an exit grid - set insertion values... // OK, we are using an exit grid - set insertion values...
case 255: case 255:
ubDirection = 255; ubDirection = 255;
break; break;
case NORTH: case NORTH:
ubDirection = INSERTION_CODE_SOUTH; ubDirection = INSERTION_CODE_SOUTH;
break; break;
@@ -3925,15 +3889,14 @@ UINT8 GetStrategicInsertionDataFromAdjacentMoveDirection( UINT8 ubTacticalDirect
break; break;
default: default:
// Wrong direction given! // Wrong direction given!
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Improper insertion direction %d given to SetInsertionDataFromAdjacentMoveDirection", ubTacticalDirection ) ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Improper insertion direction %d given to SetInsertionDataFromAdjacentMoveDirection", ubTacticalDirection ) );
ScreenMsg( FONT_RED, MSG_ERROR, L"Improper insertion direction %d given to GetStrategicInsertionDataFromAdjacentMoveDirection", ubTacticalDirection ); ScreenMsg( FONT_RED, MSG_ERROR, L"Improper insertion direction %d given to GetStrategicInsertionDataFromAdjacentMoveDirection", ubTacticalDirection );
#endif #endif
ubDirection = EAST_STRATEGIC_MOVE; ubDirection = EAST_STRATEGIC_MOVE;
} }
return( ubDirection ); return( ubDirection );
} }
@@ -4178,7 +4141,6 @@ BEGINNING_LOOP:
curr = curr->next; curr = curr->next;
} }
// OK, setup TacticalOverhead polling system that will notify us once everybody // OK, setup TacticalOverhead polling system that will notify us once everybody
// has made it to our destination. // has made it to our destination.
if ( ubTacticalDirection != 255 ) if ( ubTacticalDirection != 255 )
@@ -4202,7 +4164,6 @@ void HandleSoldierLeavingSectorByThemSelf( SOLDIERTYPE *pSoldier )
{ {
// soldier leaving thier squad behind, will rejoin later // soldier leaving thier squad behind, will rejoin later
// if soldier in a squad, set the fact they want to return here // if soldier in a squad, set the fact they want to return here
UINT8 ubGroupId;
if( pSoldier->bAssignment < ON_DUTY ) if( pSoldier->bAssignment < ON_DUTY )
{ {
@@ -4233,11 +4194,9 @@ void HandleSoldierLeavingSectorByThemSelf( SOLDIERTYPE *pSoldier )
if( pSoldier->ubGroupID == 0 ) if( pSoldier->ubGroupID == 0 )
{ {
// create independant group // create independant group
ubGroupId = CreateNewPlayerGroupDepartingFromSector( ( UINT8 )pSoldier->sSectorX, ( UINT8 )pSoldier->sSectorY ); UINT8 ubGroupId = CreateNewPlayerGroupDepartingFromSector( (UINT8)pSoldier->sSectorX, (UINT8)pSoldier->sSectorY );
AddPlayerToGroup( ubGroupId , pSoldier ); AddPlayerToGroup( ubGroupId , pSoldier );
} }
return;
} }
void AllMercsWalkedToExitGrid() void AllMercsWalkedToExitGrid()
@@ -4826,7 +4785,7 @@ BOOLEAN OKForSectorExit( INT8 bExitDirection, INT32 usAdditionalData, UINT32 *pu
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
// look for all mercs on the same team, // look for all mercs on the same team,
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++cnt, ++pSoldier)
{ {
// If we are controllable // If we are controllable
//if ( OK_CONTROLLABLE_MERC( pSoldier) && pSoldier->bAssignment == CurrentSquad( ) ) //if ( OK_CONTROLLABLE_MERC( pSoldier) && pSoldier->bAssignment == CurrentSquad( ) )
@@ -4990,12 +4949,10 @@ BOOLEAN OKForSectorExit( INT8 bExitDirection, INT32 usAdditionalData, UINT32 *pu
void SetupNewStrategicGame( ) void SetupNewStrategicGame( )
{ {
INT16 sSectorX, sSectorY;
// Set all sectors as enemy controlled // Set all sectors as enemy controlled
for ( sSectorX = 0; sSectorX < MAP_WORLD_X; sSectorX++ ) for ( INT16 sSectorX = 0; sSectorX < MAP_WORLD_X; ++sSectorX )
{ {
for ( sSectorY = 0; sSectorY < MAP_WORLD_Y; sSectorY++ ) for ( INT16 sSectorY = 0; sSectorY < MAP_WORLD_Y; ++sSectorY )
{ {
StrategicMap[ CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY ) ].fEnemyControlled = TRUE; StrategicMap[ CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY ) ].fEnemyControlled = TRUE;
} }
@@ -5042,7 +4999,6 @@ void SetupNewStrategicGame( )
AddEveryDayStrategicEvent( EVENT_ENRICO_MAIL, ENRICO_MAIL_TIME , 0 ); AddEveryDayStrategicEvent( EVENT_ENRICO_MAIL, ENRICO_MAIL_TIME , 0 );
#endif #endif
// if ( gGameOptions.fAirStrikes ) // if ( gGameOptions.fAirStrikes )
// { // {
// //Daily check for an air raid // //Daily check for an air raid
@@ -5056,9 +5012,6 @@ void SetupNewStrategicGame( )
//Clear any possible battle locator //Clear any possible battle locator
gfBlitBattleSectorLocator = FALSE; gfBlitBattleSectorLocator = FALSE;
StrategicTurnsNewGame( ); StrategicTurnsNewGame( );
} }
@@ -5066,9 +5019,6 @@ void SetupNewStrategicGame( )
// a -1 will be returned upon failure // a -1 will be returned upon failure
INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{ {
INT8 bCounter = 0;
INT16 sSectorValue = 0;
// check if valid sector // check if valid sector
if( bSectorZ != 0 ) if( bSectorZ != 0 )
{ {
@@ -5076,10 +5026,10 @@ INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
} }
// get the sector value // get the sector value
sSectorValue = SECTOR( sSectorX, sSectorY ); INT16 sSectorValue = SECTOR( sSectorX, sSectorY );
// run through list of sam sites // run through list of sam sites
for( bCounter = 0; bCounter < NUMBER_OF_SAMS; bCounter++ ) for ( INT8 bCounter = 0; bCounter < NUMBER_OF_SAMS; ++bCounter )
{ {
if( pSamList[ bCounter ] == sSectorValue ) if( pSamList[ bCounter ] == sSectorValue )
{ {
@@ -5087,7 +5037,6 @@ INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
} }
} }
return( -1 ); return( -1 );
} }
@@ -5131,14 +5080,14 @@ BOOLEAN CanGoToTacticalInSector( INT16 sX, INT16 sY, UINT8 ubZ )
INT32 GetNumberOfSAMSitesUnderPlayerControl( void ) INT32 GetNumberOfSAMSitesUnderPlayerControl( void )
{ {
INT32 iNumber = 0, iCounter = 0; INT32 iNumber = 0;
// if the sam site is under player control, up the number // if the sam site is under player control, up the number
for( iCounter = 0; iCounter < NUMBER_OF_SAMS; iCounter++ ) for ( INT32 iCounter = 0; iCounter < NUMBER_OF_SAMS; ++iCounter )
{ {
if( StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[ iCounter ] ) ].fEnemyControlled == FALSE ) if( StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( pSamList[ iCounter ] ) ].fEnemyControlled == FALSE )
{ {
iNumber++; ++iNumber;
} }
} }
@@ -5149,7 +5098,6 @@ INT32 SAMSitesUnderPlayerControl( INT16 sX, INT16 sY )
{ {
BOOLEAN fSamSiteUnderControl = FALSE; BOOLEAN fSamSiteUnderControl = FALSE;
// is this sector a SAM sector? // is this sector a SAM sector?
if( IsThisSectorASAMSector( sX, sY, 0 ) == TRUE ) if( IsThisSectorASAMSector( sX, sY, 0 ) == TRUE )
{ {
@@ -5167,15 +5115,13 @@ INT32 SAMSitesUnderPlayerControl( INT16 sX, INT16 sY )
void UpdateAirspaceControl( void ) void UpdateAirspaceControl( void )
{ {
INT32 iCounterA = 0, iCounterB = 0;
UINT8 ubControllingSAM; UINT8 ubControllingSAM;
StrategicMapElement *pSAMStrategicMap = NULL; StrategicMapElement *pSAMStrategicMap = NULL;
BOOLEAN fEnemyControlsAir; BOOLEAN fEnemyControlsAir;
for ( INT32 iCounterA = 1; iCounterA < (INT32)(MAP_WORLD_X - 1); ++iCounterA )
for( iCounterA = 1; iCounterA < ( INT32 )( MAP_WORLD_X - 1 ); iCounterA++ )
{ {
for( iCounterB = 1; iCounterB < ( INT32 )( MAP_WORLD_Y - 1 ); iCounterB++ ) for ( INT32 iCounterB = 1; iCounterB < (INT32)(MAP_WORLD_Y - 1); ++iCounterB )
{ {
// IMPORTANT: B and A are reverse here, since the table is stored transposed // IMPORTANT: B and A are reverse here, since the table is stored transposed
ubControllingSAM = ubSAMControlledSectors[ iCounterB ][ iCounterA ]; ubControllingSAM = ubSAMControlledSectors[ iCounterB ][ iCounterA ];
@@ -5211,7 +5157,6 @@ void UpdateAirspaceControl( void )
} }
} }
// check if currently selected arrival sector still has secure airspace // check if currently selected arrival sector still has secure airspace
// if it's not enemy air controlled // if it's not enemy air controlled
@@ -5232,9 +5177,9 @@ void UpdateAirspaceControl( void )
} }
else else
{ {
for (UINT8 ubSectorX = 1; ubSectorX <= 16; ubSectorX++) for (UINT8 ubSectorX = 1; ubSectorX <= 16; ++ubSectorX)
{ {
for (UINT8 ubSectorY = 1; ubSectorY <=16; ubSectorY++) for (UINT8 ubSectorY = 1; ubSectorY <=16; ++ubSectorY)
{ {
if ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( ubSectorX, ubSectorY ) ].fEnemyAirControlled == FALSE && !sBadSectorsList[ ubSectorX ][ ubSectorY ] ) if ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( ubSectorX, ubSectorY ) ].fEnemyAirControlled == FALSE && !sBadSectorsList[ ubSectorX ][ ubSectorY ] )
{ {
@@ -5265,7 +5210,6 @@ void UpdateAirspaceControl( void )
fTeamPanelDirty = TRUE; fTeamPanelDirty = TRUE;
} }
// ARM: airspace control now affects refueling site availability, so update that too with every change! // ARM: airspace control now affects refueling site availability, so update that too with every change!
UpdateRefuelSiteAvailability( ); UpdateRefuelSiteAvailability( );
} }
@@ -7574,3 +7518,20 @@ BOOLEAN MoveEnemyFromGridNoToRoofGridNo( UINT32 sSourceGridNo, UINT32 sDestGridN
return( FALSE ); return( FALSE );
} }
#endif #endif
// Flugente: militia movement: can we order militia reinforcements from( sSrcMapX, sSrcMapY ) to( sMapX, sMapY ) ?
BOOLEAN CanRequestMilitiaReinforcements( INT16 sMapX, INT16 sMapY, INT16 sSrcMapX, INT16 sSrcMapY )
{
if ( !gGameExternalOptions.gfAllowReinforcements )
return FALSE;
// we can request reinforcements only inside towns
if ( GetTownIdForSector( sMapX, sMapY ) != BLANK_SECTOR && GetTownIdForSector( sMapX, sMapY ) != GetTownIdForSector( sSrcMapX, sSrcMapY ) )
return FALSE;
// not possible of nobody is there
if ( !NumNonPlayerTeamMembersInSector( sSrcMapX, sSrcMapY, MILITIA_TEAM ) )
return FALSE;
return TRUE;
}
+3 -1
View File
@@ -150,7 +150,6 @@ void AllMercsHaveWalkedOffSector( );
void AdjustSoldierPathToGoOffEdge( SOLDIERTYPE *pSoldier, INT32 sEndGridNo, UINT8 ubTacticalDirection ); void AdjustSoldierPathToGoOffEdge( SOLDIERTYPE *pSoldier, INT32 sEndGridNo, UINT8 ubTacticalDirection );
void AllMercsWalkedToExitGrid(); void AllMercsWalkedToExitGrid();
UINT8 GetMilitiaCountAtLevelAnywhereInTown( UINT8 ubTownValue, UINT8 ubLevelValue );
void PrepareLoadedSector(); void PrepareLoadedSector();
@@ -213,4 +212,7 @@ void HandleSectorSpecificModificatioToMap( INT16 sMapX, INT16 sMapY, INT8 bMapZ,
void HandleEmailBeingSentWhenEnteringSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fLaptopJustGotFixed ); void HandleEmailBeingSentWhenEnteringSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fLaptopJustGotFixed );
#endif #endif
// Flugente: militia movement: can we order militia reinforcements from( sSrcMapX, sSrcMapY ) to( sMapX, sMapY ) ?
BOOLEAN CanRequestMilitiaReinforcements( INT16 sMapX, INT16 sMapY, INT16 sSrcMapX, INT16 sSrcMapY );
#endif #endif
+7
View File
@@ -1074,7 +1074,14 @@ void HandleDialogue( )
if( QItem->uiSpecialEventFlag & DIALOGUE_SPECIAL_EVENT_TRIGGERPREBATTLEINTERFACE ) if( QItem->uiSpecialEventFlag & DIALOGUE_SPECIAL_EVENT_TRIGGERPREBATTLEINTERFACE )
{ {
UnLockPauseState(); UnLockPauseState();
// Flugente: what hideous idiocy is this? We cast a UINT32 as GROUP*? This is likely to return garbage.
// Why the hell not use the id instead?
InitPreBattleInterface( (GROUP*)QItem->uiSpecialEventData, TRUE ); InitPreBattleInterface( (GROUP*)QItem->uiSpecialEventData, TRUE );
/*GROUP* pGroup = GetGroup( (UINT8)QItem->uiSpecialEventData );
if ( pGroup )
InitPreBattleInterface( pGroup, TRUE );*/
} }
if( QItem->uiSpecialEventFlag & DIALOGUE_ADD_EVENT_FOR_SOLDIER_UPDATE_BOX ) if( QItem->uiSpecialEventFlag & DIALOGUE_ADD_EVENT_FOR_SOLDIER_UPDATE_BOX )
{ {
+3
View File
@@ -4010,6 +4010,9 @@ void MoveOneMilitiaEquipmentSet(INT16 sSourceX, INT16 sSourceY, INT16 sTargetX,
void MoveMilitiaEquipment(INT16 sSourceX, INT16 sSourceY, INT16 sTargetX, INT16 sTargetY, UINT8 usElites, UINT8 usRegulars, UINT8 usGreens) void MoveMilitiaEquipment(INT16 sSourceX, INT16 sSourceY, INT16 sTargetX, INT16 sTargetY, UINT8 usElites, UINT8 usRegulars, UINT8 usGreens)
{ {
if ( !gGameExternalOptions.fMilitiaUseSectorInventory )
return;
// atm there is no class-specific selection, but that might change in the future // atm there is no class-specific selection, but that might change in the future
for (UINT8 i = 0; i < usElites; ++i) for (UINT8 i = 0; i < usElites; ++i)
{ {
+19 -17
View File
@@ -206,23 +206,24 @@ void PrepareMilitiaForTactical( BOOLEAN fPrepareAll)
SECTORINFO *pSector; SECTORINFO *pSector;
INT32 x; INT32 x;
UINT8 ubGreen, ubRegs, ubElites; UINT8 ubGreen, ubRegs, ubElites;
if( gbWorldSectorZ > 0 ) if( gbWorldSectorZ > 0 )
return; return;
// Do we have a loaded sector? // Do we have a loaded sector?
if ( gWorldSectorX ==0 && gWorldSectorY == 0 ) if ( gWorldSectorX == 0 && gWorldSectorY == 0 )
return; return;
for (int i=0; i<TOTAL_SOLDIERS; i++) //for (int i=0; i<TOTAL_SOLDIERS; i++)
{ {
//CHRISL: What's this assert for? //CHRISL: What's this assert for?
//Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || !TileIsOutOfBounds(MercPtrs[i]->sGridNo)); //Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || !TileIsOutOfBounds(MercPtrs[i]->sGridNo));
} }
pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ]; pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
ubGreen = pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ]; ubGreen = MilitiaInSectorOfRank( gWorldSectorX, gWorldSectorY, GREEN_MILITIA );
ubRegs = pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]; ubRegs = MilitiaInSectorOfRank( gWorldSectorX, gWorldSectorY, REGULAR_MILITIA );
ubElites = pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; ubElites = MilitiaInSectorOfRank( gWorldSectorX, gWorldSectorY, ELITE_MILITIA );
// Prevent militia from just waiting on the border // Prevent militia from just waiting on the border
gTacticalStatus.Team[MILITIA_TEAM].bAwareOfOpposition = (pSector->uiFlags & SF_PLAYER_KNOWS_ENEMIES_ARE_HERE) != 0; gTacticalStatus.Team[MILITIA_TEAM].bAwareOfOpposition = (pSector->uiFlags & SF_PLAYER_KNOWS_ENEMIES_ARE_HERE) != 0;
@@ -270,7 +271,7 @@ void PrepareMilitiaForTactical( BOOLEAN fPrepareAll)
// } // }
// } // }
for (int i=0; i<TOTAL_SOLDIERS; i++) //for (int i=0; i<TOTAL_SOLDIERS; i++)
{ {
//CHRISL: What's this assert for? //CHRISL: What's this assert for?
//Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || !TileIsOutOfBounds(MercPtrs[i]->sGridNo)); //Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || !TileIsOutOfBounds(MercPtrs[i]->sGridNo));
@@ -279,10 +280,10 @@ void PrepareMilitiaForTactical( BOOLEAN fPrepareAll)
void HandleMilitiaPromotions( void ) void HandleMilitiaPromotions( void )
{ {
UINT8 cnt; UINT8 cnt;
UINT8 ubMilitiaRank; UINT8 ubMilitiaRank;
SOLDIERTYPE * pTeamSoldier; SOLDIERTYPE* pTeamSoldier;
UINT8 ubPromotions; UINT8 ubPromotions;
gbGreenToElitePromotions = 0; gbGreenToElitePromotions = 0;
gbGreenToRegPromotions = 0; gbGreenToRegPromotions = 0;
@@ -291,7 +292,7 @@ void HandleMilitiaPromotions( void )
cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID;
for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++, pTeamSoldier++) for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; ++cnt, ++pTeamSoldier)
{ {
if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->stats.bLife > 0 ) if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->stats.bLife > 0 )
{ {
@@ -303,18 +304,18 @@ void HandleMilitiaPromotions( void )
{ {
if( ubPromotions == 2 ) if( ubPromotions == 2 )
{ {
gbGreenToElitePromotions++; ++gbGreenToElitePromotions;
gbMilitiaPromotions++; ++gbMilitiaPromotions;
} }
else if( pTeamSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA ) else if( pTeamSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA )
{ {
gbGreenToRegPromotions++; ++gbGreenToRegPromotions;
gbMilitiaPromotions++; ++gbMilitiaPromotions;
} }
else if( pTeamSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA ) else if( pTeamSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA )
{ {
gbRegToElitePromotions++; ++gbRegToElitePromotions;
gbMilitiaPromotions++; ++gbMilitiaPromotions;
} }
} }
@@ -322,6 +323,7 @@ void HandleMilitiaPromotions( void )
} }
} }
} }
if( gbMilitiaPromotions ) if( gbMilitiaPromotions )
{ {
// ATE: Problems here with bringing up message box... // ATE: Problems here with bringing up message box...
+2 -1
View File
@@ -11,6 +11,7 @@
#include "DisplayCover.h" #include "DisplayCover.h"
#include "worldman.h" #include "worldman.h"
#include "Queen Command.h" #include "Queen Command.h"
#include "strategicmap.h"
// sevenfm: need this for correct calculation of traits menu position // sevenfm: need this for correct calculation of traits menu position
extern INT16 gsInterfaceLevel; extern INT16 gsInterfaceLevel;
@@ -501,7 +502,7 @@ ReinforcementSector::Setup( UINT32 aVal )
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ReinforcementNumber, sectornr ) ); pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ReinforcementNumber, sectornr ) );
// grey out if no reinforcements can be called from this sector // grey out if no reinforcements can be called from this sector
if ( !NumNonPlayerTeamMembersInSector( loopX, loopY, MILITIA_TEAM ) ) if ( !CanRequestMilitiaReinforcements( pSoldier->sSectorX, pSoldier->sSectorY, loopX, loopY ) )
{ {
// Set this option off. // Set this option off.
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL )); pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
+10 -4
View File
@@ -93,6 +93,8 @@
#include "LOS.h" // added by SANDRO #include "LOS.h" // added by SANDRO
#include "CampaignStats.h" // added by Flugente #include "CampaignStats.h" // added by Flugente
#include "Interface Panels.h" #include "Interface Panels.h"
#include "Queen Command.h" // added by Flugente
#include "Town Militia.h" // added by Flugente
#endif #endif
#include "ub_config.h" #include "ub_config.h"
@@ -17874,8 +17876,12 @@ BOOLEAN SOLDIERTYPE::OrderArtilleryStrike( UINT32 usSectorNr, INT32 sTargetGridN
} }
else if ( bTeam == MILITIA_TEAM ) else if ( bTeam == MILITIA_TEAM )
{ {
nummortars = (SectorInfo[usSectorNr].ubNumberOfCivsAtLevel[GREEN_MILITIA] + SectorInfo[usSectorNr].ubNumberOfCivsAtLevel[REGULAR_MILITIA] + SectorInfo[usSectorNr].ubNumberOfCivsAtLevel[ELITE_MILITIA]) / gSkillTraitValues.usVOMortarCountDivisor; UINT8 militia_green = MilitiaInSectorOfRank( sSectorX, sSectorY, GREEN_MILITIA );
numshells = gSkillTraitValues.usVOMortarPointsAdmin * SectorInfo[usSectorNr].ubNumberOfCivsAtLevel[GREEN_MILITIA] + gSkillTraitValues.usVOMortarPointsTroop * SectorInfo[usSectorNr].ubNumberOfCivsAtLevel[REGULAR_MILITIA] + gSkillTraitValues.usVOMortarPointsElite * SectorInfo[usSectorNr].ubNumberOfCivsAtLevel[ELITE_MILITIA]; UINT8 militia_troop = MilitiaInSectorOfRank( sSectorX, sSectorY, REGULAR_MILITIA );
UINT8 militia_elite = MilitiaInSectorOfRank( sSectorX, sSectorY, ELITE_MILITIA );
nummortars = (militia_green + militia_troop + militia_elite) / gSkillTraitValues.usVOMortarCountDivisor;
numshells = gSkillTraitValues.usVOMortarPointsAdmin * militia_green + gSkillTraitValues.usVOMortarPointsTroop * militia_troop + gSkillTraitValues.usVOMortarPointsElite * militia_elite;
} }
if ( gSkillTraitValues.usVOMortarShellDivisor * nummortars < 1 ) if ( gSkillTraitValues.usVOMortarShellDivisor * nummortars < 1 )
@@ -22110,8 +22116,8 @@ BOOLEAN IsValidArtilleryOrderSector( INT16 sSectorX, INT16 sSectorY, INT8 bSecto
if ( bSectorZ > 0 || sSectorX < 1 || sSectorX >= MAP_WORLD_X - 1 || sSectorY < 1 || sSectorY >= MAP_WORLD_Y - 1 ) if ( bSectorZ > 0 || sSectorX < 1 || sSectorX >= MAP_WORLD_X - 1 || sSectorY < 1 || sSectorY >= MAP_WORLD_Y - 1 )
return FALSE; return FALSE;
UINT16 usEnemies = (UINT16)NumEnemiesInAnySector( sSectorX, sSectorY, bSectorZ ); UINT16 usEnemies = (UINT16)NumNonPlayerTeamMembersInSector( sSectorX, sSectorY, ENEMY_TEAM );
UINT16 usMilitia = (UINT16)GetNumberOfMilitiaInSector( sSectorX, sSectorY, (INT16)bSectorZ ); UINT16 usMilitia = (UINT16)NumNonPlayerTeamMembersInSector( sSectorX, sSectorY, MILITIA_TEAM );
UINT16 usMercs = (UINT16)PlayerMercsInSector( (UINT8)sSectorX, (UINT8)sSectorY, (UINT8)bSectorZ ); UINT16 usMercs = (UINT16)PlayerMercsInSector( (UINT8)sSectorX, (UINT8)sSectorY, (UINT8)bSectorZ );
SECTORINFO *pSectorInfo = &(SectorInfo[SECTOR( sSectorX, sSectorY )]); SECTORINFO *pSectorInfo = &(SectorInfo[SECTOR( sSectorX, sSectorY )]);
+7 -10
View File
@@ -55,6 +55,7 @@
#include "Map Edgepoints.h" #include "Map Edgepoints.h"
#include "Campaign.h" // added by Flugente for HighestPlayerProgressPercentage() #include "Campaign.h" // added by Flugente for HighestPlayerProgressPercentage()
#include "CampaignStats.h" // added by Flugente #include "CampaignStats.h" // added by Flugente
#include "Town Militia.h" // added by Flugente
BOOLEAN gfOriginalList = TRUE; BOOLEAN gfOriginalList = TRUE;
@@ -2825,17 +2826,13 @@ void SectorAddAssassins( INT16 sMapX, INT16 sMapY, INT16 sMapZ )
if ( sMapZ > 0 ) if ( sMapZ > 0 )
return; return;
SECTORINFO *pSector = &SectorInfo[ SECTOR( sMapX, sMapY ) ];
if ( !pSector )
return;
// does not work atm, time gets reset too early // does not work atm, time gets reset too early
// not if we have recently been in this sector // not if we have recently been in this sector
//if ( pSector->uiTimeCurrentSectorWasLastLoaded + 10 > GetWorldTotalMin() ) //if ( pSector->uiTimeCurrentSectorWasLastLoaded + 10 > GetWorldTotalMin() )
//return; //return;
// do not spawn if militia size is very small (we will be spotted much easier by the player) // do not spawn if militia size is very small (we will be spotted much easier by the player)
UINT32 totalmilitia = pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; UINT32 totalmilitia = NumNonPlayerTeamMembersInSector( sMapX, sMapY, MILITIA_TEAM );
if ( totalmilitia < gGameExternalOptions.usAssassinMinimumMilitia ) if ( totalmilitia < gGameExternalOptions.usAssassinMinimumMilitia )
return; return;
@@ -2856,16 +2853,16 @@ void SectorAddAssassins( INT16 sMapX, INT16 sMapY, INT16 sMapZ )
return; return;
// now count militia, and which type (green, regular, elite) is most numerous - that will be the best type to blend in // now count militia, and which type (green, regular, elite) is most numerous - that will be the best type to blend in
UINT8 militiacnt = pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ]; UINT8 militiacnt = MilitiaInSectorOfRank( sMapX, sMapY, GREEN_MILITIA );
UINT8 militiadisguise = GREEN_MILITIA; UINT8 militiadisguise = GREEN_MILITIA;
if ( pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] > militiacnt ) if ( MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA ) > militiacnt )
{ {
militiacnt = pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]; militiacnt = MilitiaInSectorOfRank( sMapX, sMapY, REGULAR_MILITIA );
militiadisguise = REGULAR_MILITIA; militiadisguise = REGULAR_MILITIA;
} }
if ( pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] > militiacnt )
if ( MilitiaInSectorOfRank( sMapX, sMapY, ELITE_MILITIA ) > militiacnt )
{ {
militiacnt = pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
militiadisguise = ELITE_MILITIA; militiadisguise = ELITE_MILITIA;
} }
+6 -3
View File
@@ -34,6 +34,7 @@
#include "MessageBoxScreen.h" #include "MessageBoxScreen.h"
#include "Quests.h" #include "Quests.h"
#include "Creature Spreading.h" #include "Creature Spreading.h"
#include "Queen Command.h" // added by Flugente
#endif #endif
#ifdef JA2UB #ifdef JA2UB
@@ -307,12 +308,14 @@ BOOLEAN InternalInitSectorExitMenu( UINT8 ubDirection, INT32 sAdditionalData )//
if( gTacticalStatus.fEnemyInSector ) if( gTacticalStatus.fEnemyInSector )
{ {
if( gExitDialog.fMultipleSquadsInSector ) if( gExitDialog.fMultipleSquadsInSector )
{ //We have multiple squads in a hostile sector. That means that we can't load the adjacent sector. {
//We have multiple squads in a hostile sector. That means that we can't load the adjacent sector.
gExitDialog.fGotoSectorDisabled = TRUE; gExitDialog.fGotoSectorDisabled = TRUE;
gExitDialog.fGotoSector = FALSE; gExitDialog.fGotoSector = FALSE;
} }
else if( GetNumberOfMilitiaInSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) else if ( gbWorldSectorZ <= 0 && NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, MILITIA_TEAM ) )
{ //Leaving this sector will result in militia being forced to fight the battle, can't load adjacent sector. {
//Leaving this sector will result in militia being forced to fight the battle, can't load adjacent sector.
gExitDialog.fGotoSectorDisabled = TRUE; gExitDialog.fGotoSectorDisabled = TRUE;
gExitDialog.fGotoSector = FALSE; gExitDialog.fGotoSector = FALSE;
} }
+3
View File
@@ -2902,6 +2902,9 @@ extern STR16 szIMPGearWebSiteText[];
extern STR16 szIMPGearDropDownText[]; extern STR16 szIMPGearDropDownText[];
extern STR16 szIMPGearDropDownNoneText[]; extern STR16 szIMPGearDropDownNoneText[];
// Flugente: militia movement
extern STR16 szMilitiaStrategicMovementText[];
#define TACTICAL_INVENTORY_DIALOG_NUM 16 #define TACTICAL_INVENTORY_DIALOG_NUM 16
#define TACTICAL_COVER_DIALOG_NUM 16 #define TACTICAL_COVER_DIALOG_NUM 16
+2 -1
View File
@@ -124,6 +124,7 @@ extern INT32 giFlashHighlightedItemBaseTime;
//extern INT32 giCompatibleItemBaseTime;//Moa:removed (see HandleMouseInCompatableItemForMapSectorInventory) //extern INT32 giCompatibleItemBaseTime;//Moa:removed (see HandleMouseInCompatableItemForMapSectorInventory)
extern INT32 giAnimateRouteBaseTime; extern INT32 giAnimateRouteBaseTime;
extern INT32 giPotHeliPathBaseTime; extern INT32 giPotHeliPathBaseTime;
extern INT32 giPotMilitiaPathBaseTime;
extern INT32 giClickHeliIconBaseTime; extern INT32 giClickHeliIconBaseTime;
extern INT32 giExitToTactBaseTime; extern INT32 giExitToTactBaseTime;
extern UINT32 guiSectorLocatorBaseTime; extern UINT32 guiSectorLocatorBaseTime;
@@ -540,12 +541,12 @@ void ResetJA2ClockGlobalTimers( void )
{ {
UINT32 uiCurrentTime = GetJA2Clock(); UINT32 uiCurrentTime = GetJA2Clock();
guiCompressionStringBaseTime = uiCurrentTime; guiCompressionStringBaseTime = uiCurrentTime;
giFlashHighlightedItemBaseTime = uiCurrentTime; giFlashHighlightedItemBaseTime = uiCurrentTime;
//giCompatibleItemBaseTime = uiCurrentTime;//Moa: removed (see HandleMouseInCompatableItemForMapSectorInventory) //giCompatibleItemBaseTime = uiCurrentTime;//Moa: removed (see HandleMouseInCompatableItemForMapSectorInventory)
giAnimateRouteBaseTime = uiCurrentTime; giAnimateRouteBaseTime = uiCurrentTime;
giPotHeliPathBaseTime = uiCurrentTime; giPotHeliPathBaseTime = uiCurrentTime;
giPotMilitiaPathBaseTime = uiCurrentTime;
giClickHeliIconBaseTime = uiCurrentTime; giClickHeliIconBaseTime = uiCurrentTime;
giExitToTactBaseTime = uiCurrentTime; giExitToTactBaseTime = uiCurrentTime;
guiSectorLocatorBaseTime = uiCurrentTime; guiSectorLocatorBaseTime = uiCurrentTime;
+12
View File
@@ -10029,6 +10029,18 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
// WANNE: Some Chinese specific strings that needs to be in unicode! // WANNE: Some Chinese specific strings that needs to be in unicode!
STR16 ChineseSpecString1 = L"%"; //defined in _ChineseText.cpp as this file is already unicode STR16 ChineseSpecString1 = L"%"; //defined in _ChineseText.cpp as this file is already unicode
STR16 ChineseSpecString2 = L"*%3d%%%"; //defined in _ChineseText.cpp as this file is already unicode STR16 ChineseSpecString2 = L"*%3d%%%"; //defined in _ChineseText.cpp as this file is already unicode
+12
View File
@@ -10040,4 +10040,16 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
#endif //DUTCH #endif //DUTCH
+12
View File
@@ -10078,4 +10078,16 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
#endif //ENGLISH #endif //ENGLISH
+12
View File
@@ -10026,4 +10026,16 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
#endif //FRENCH #endif //FRENCH
+12
View File
@@ -9857,4 +9857,16 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
#endif //GERMAN #endif //GERMAN
+12
View File
@@ -10036,4 +10036,16 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
#endif //ITALIAN #endif //ITALIAN
+12
View File
@@ -10051,4 +10051,16 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
#endif //POLISH #endif //POLISH
+12
View File
@@ -10024,5 +10024,17 @@ STR16 szIMPGearDropDownNoneText[] =
L"No additional items", L"No additional items",
}; };
STR16 szMilitiaStrategicMovementText[] =
{
L"We cannot relay orders to this sector, militia command not possible.",
L"Unassigned",
L"Group No.",
L"Next",
L"ETA",
L"Group %d (new)",
L"Group %d",
};
#endif //RUSSIAN #endif //RUSSIAN