diff --git a/Init.cpp b/Init.cpp index 5a84d835..8ef9e3db 100644 --- a/Init.cpp +++ b/Init.cpp @@ -367,6 +367,27 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) strcat(fileName, SAMSITESFILENAME); if ( !ReadInSAMInfo(fileName) ) return FALSE; + + // Lesh: army externalization + strcpy(fileName, directoryName); + strcat(fileName, COMPOSITIONFILENAME); + if ( !ReadInPatrolInfo(fileName) ) + return FALSE; + + strcpy(fileName, directoryName); + strcat(fileName, GARRISONFILENAME); + if ( !ReadInGarrisonInfo(fileName) ) + return FALSE; + + strcpy(fileName, directoryName); + strcat(fileName, PATROLFILENAME); + if ( !ReadInPatrolInfo(fileName) ) + return FALSE; + + strcpy(fileName, directoryName); + strcat(fileName, COMPOSITIONFILENAME); + if ( !ReadInArmyCompositionInfo(fileName) ) + return FALSE; strcpy(fileName, directoryName); strcat(fileName, EXPLOSIONDATAFILENAME); diff --git a/Strategic/AI Viewer.cpp b/Strategic/AI Viewer.cpp index 0d18c660..542b9adc 100644 --- a/Strategic/AI Viewer.cpp +++ b/Strategic/AI Viewer.cpp @@ -204,7 +204,7 @@ extern BOOLEAN gfQueenAIAwake; extern INT32 giReinforcementPool; extern UINT32 guiEventListCurrNodes, guiEventListPeekNodes; extern INT32 giReinforcementPoints, giRequestPoints; -extern ARMY_COMPOSITION gArmyComp[ NUM_ARMY_COMPOSITIONS ]; +extern ARMY_COMPOSITION gArmyComp[ MAX_ARMY_COMPOSITIONS ]; extern GARRISON_GROUP *gGarrisonGroup; extern INT32 giGarrisonArraySize; diff --git a/Strategic/Strategic AI.cpp b/Strategic/Strategic AI.cpp index 1d511f69..eb3b58dc 100644 --- a/Strategic/Strategic AI.cpp +++ b/Strategic/Strategic AI.cpp @@ -200,15 +200,18 @@ BOOLEAN gfUseAlternateQueenPosition = FALSE; #define SAI_PADDING_BYTES 97 INT8 gbPadding[SAI_PADDING_BYTES]; //patrol group info plus padding -#define SAVED_PATROL_GROUPS 50 +#define SAVED_PATROL_GROUPS MAX_PATROL_GROUPS PATROL_GROUP *gPatrolGroup = NULL; //army composition info plus padding -#define SAVED_ARMY_COMPOSITIONS 60 -ARMY_COMPOSITION gArmyComp[ NUM_ARMY_COMPOSITIONS ]; +#define SAVED_ARMY_COMPOSITIONS MAX_ARMY_COMPOSITIONS +ARMY_COMPOSITION gArmyComp[ MAX_ARMY_COMPOSITIONS ]; //garrison info plus padding -#define SAVED_GARRISON_GROUPS 100 +#define SAVED_GARRISON_GROUPS MAX_GARRISON_GROUPS GARRISON_GROUP *gGarrisonGroup = NULL; +// +UINT8 NUM_ARMY_COMPOSITIONS; + extern UINT8 gubNumGroupsArrivedSimultaneously; //This refers to the number of force points that are *saved* for the AI to use. This is basically an array of each @@ -239,158 +242,158 @@ extern BOOLEAN TeleportSoldier( SOLDIERTYPE *pSoldier, INT16 sGridNo, BOOLEAN fF //If you change the MAX_STRATEGIC_TEAM_SIZE, then all the garrison sizes (start, desired) will have to be changed accordingly. -ARMY_COMPOSITION gOrigArmyComp[ NUM_ARMY_COMPOSITIONS ] = -{ //COMPOSITION PRIORITY ELITE% TROOP% ADMIN DESIRED# START# PADDING - // START% - QUEEN_DEFENCE, 100, 100, 0, 0, 32, 32, {0,0,0,0,0,0,0,0,0,0}, - MEDUNA_DEFENCE, 95, 55, 45, 0, 16, 20, {0,0,0,0,0,0,0,0,0,0}, - MEDUNA_SAMSITE, 96, 65, 35, 0, 20, 20, {0,0,0,0,0,0,0,0,0,0}, - LEVEL1_DEFENCE, 40, 20, 80, 0, 12, 20, {0,0,0,0,0,0,0,0,0,0}, - LEVEL2_DEFENCE, 30, 10, 90, 0, 10, 20, {0,0,0,0,0,0,0,0,0,0}, - LEVEL3_DEFENCE, 20, 5, 95, 0, 8, 20, {0,0,0,0,0,0,0,0,0,0}, - ORTA_DEFENCE, 90, 50, 50, 0, 18, 19, {0,0,0,0,0,0,0,0,0,0}, - EAST_GRUMM_DEFENCE, 80, 20, 80, 0, 15, 15, {0,0,0,0,0,0,0,0,0,0}, - WEST_GRUMM_DEFENCE, 70, 0, 100, 40, 15, 15, {0,0,0,0,0,0,0,0,0,0}, - GRUMM_MINE, 85, 25, 75, 45, 15, 15, {0,0,0,0,0,0,0,0,0,0}, - OMERTA_WELCOME_WAGON, 0, 0, 100, 0, 0, 3, {0,0,0,0,0,0,0,0,0,0}, - BALIME_DEFENCE, 60, 45, 55, 20, 10, 4, {0,0,0,0,0,0,0,0,0,0}, - TIXA_PRISON, 80, 10, 90, 15, 15, 15, {0,0,0,0,0,0,0,0,0,0}, - TIXA_SAMSITE, 85, 10, 90, 0, 12, 12, {0,0,0,0,0,0,0,0,0,0}, - ALMA_DEFENCE, 74, 15, 85, 0, 11, 20, {0,0,0,0,0,0,0,0,0,0}, - ALMA_MINE, 80, 20, 80, 45, 15, 20, {0,0,0,0,0,0,0,0,0,0}, - CAMBRIA_DEFENCE, 50, 0, 100, 30, 10, 6, {0,0,0,0,0,0,0,0,0,0}, - CAMBRIA_MINE, 60, 15, 90, 40, 11, 6, {0,0,0,0,0,0,0,0,0,0}, - CHITZENA_DEFENCE, 30, 0, 100, 75, 12, 10, {0,0,0,0,0,0,0,0,0,0}, - CHITZENA_MINE, 40, 0, 100, 75, 10, 10, {0,0,0,0,0,0,0,0,0,0}, - CHITZENA_SAMSITE, 75, 10, 90, 0, 9, 9, {0,0,0,0,0,0,0,0,0,0}, - DRASSEN_AIRPORT, 30, 0, 100, 85, 12, 10, {0,0,0,0,0,0,0,0,0,0}, - DRASSEN_DEFENCE, 20, 0, 100, 80, 10, 8, {0,0,0,0,0,0,0,0,0,0}, - DRASSEN_MINE, 35, 0, 100, 75, 11, 9, {0,0,0,0,0,0,0,0,0,0}, - DRASSEN_SAMSITE, 50, 0, 100, 0, 10, 10, {0,0,0,0,0,0,0,0,0,0}, - ROADBLOCK, 20, 2, 98, 0, 8, 0, {0,0,0,0,0,0,0,0,0,0}, - SANMONA_SMALL, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, -}; +ARMY_COMPOSITION gOrigArmyComp[ MAX_ARMY_COMPOSITIONS ];// = +//{ //COMPOSITION PRIORITY ELITE% TROOP% ADMIN DESIRED# START# PADDING +// // START% +// QUEEN_DEFENCE, 100, 100, 0, 0, 32, 32, {0,0,0,0,0,0,0,0,0,0}, +// MEDUNA_DEFENCE, 95, 55, 45, 0, 16, 20, {0,0,0,0,0,0,0,0,0,0}, +// MEDUNA_SAMSITE, 96, 65, 35, 0, 20, 20, {0,0,0,0,0,0,0,0,0,0}, +// LEVEL1_DEFENCE, 40, 20, 80, 0, 12, 20, {0,0,0,0,0,0,0,0,0,0}, +// LEVEL2_DEFENCE, 30, 10, 90, 0, 10, 20, {0,0,0,0,0,0,0,0,0,0}, +// LEVEL3_DEFENCE, 20, 5, 95, 0, 8, 20, {0,0,0,0,0,0,0,0,0,0}, +// ORTA_DEFENCE, 90, 50, 50, 0, 18, 19, {0,0,0,0,0,0,0,0,0,0}, +// EAST_GRUMM_DEFENCE, 80, 20, 80, 0, 15, 15, {0,0,0,0,0,0,0,0,0,0}, +// WEST_GRUMM_DEFENCE, 70, 0, 100, 40, 15, 15, {0,0,0,0,0,0,0,0,0,0}, +// GRUMM_MINE, 85, 25, 75, 45, 15, 15, {0,0,0,0,0,0,0,0,0,0}, +// OMERTA_WELCOME_WAGON, 0, 0, 100, 0, 0, 3, {0,0,0,0,0,0,0,0,0,0}, +// BALIME_DEFENCE, 60, 45, 55, 20, 10, 4, {0,0,0,0,0,0,0,0,0,0}, +// TIXA_PRISON, 80, 10, 90, 15, 15, 15, {0,0,0,0,0,0,0,0,0,0}, +// TIXA_SAMSITE, 85, 10, 90, 0, 12, 12, {0,0,0,0,0,0,0,0,0,0}, +// ALMA_DEFENCE, 74, 15, 85, 0, 11, 20, {0,0,0,0,0,0,0,0,0,0}, +// ALMA_MINE, 80, 20, 80, 45, 15, 20, {0,0,0,0,0,0,0,0,0,0}, +// CAMBRIA_DEFENCE, 50, 0, 100, 30, 10, 6, {0,0,0,0,0,0,0,0,0,0}, +// CAMBRIA_MINE, 60, 15, 90, 40, 11, 6, {0,0,0,0,0,0,0,0,0,0}, +// CHITZENA_DEFENCE, 30, 0, 100, 75, 12, 10, {0,0,0,0,0,0,0,0,0,0}, +// CHITZENA_MINE, 40, 0, 100, 75, 10, 10, {0,0,0,0,0,0,0,0,0,0}, +// CHITZENA_SAMSITE, 75, 10, 90, 0, 9, 9, {0,0,0,0,0,0,0,0,0,0}, +// DRASSEN_AIRPORT, 30, 0, 100, 85, 12, 10, {0,0,0,0,0,0,0,0,0,0}, +// DRASSEN_DEFENCE, 20, 0, 100, 80, 10, 8, {0,0,0,0,0,0,0,0,0,0}, +// DRASSEN_MINE, 35, 0, 100, 75, 11, 9, {0,0,0,0,0,0,0,0,0,0}, +// DRASSEN_SAMSITE, 50, 0, 100, 0, 10, 10, {0,0,0,0,0,0,0,0,0,0}, +// ROADBLOCK, 20, 2, 98, 0, 8, 0, {0,0,0,0,0,0,0,0,0,0}, +// SANMONA_SMALL, 0, 0, 0, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +//}; //Patrol definitions //NOTE: A point containing 0 is actually the same as SEC_A1, but because nobody is using SEC_A1 in any // of the patrol groups, I am coding 0 to be ignored. //NOTE: Must have at least two points. -PATROL_GROUP gOrigPatrolGroup[] = -{ //SIZE PRIORITY POINT1 POINT2 POINT3 POINT4 MOD GROUPID WEIGHT PENDING - // DAY100 GROUP ID - 8, 40, SEC_B1, SEC_C1, SEC_C3, SEC_A3, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 6, 35, SEC_B4, SEC_B7, SEC_C7, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 6, 25, SEC_A8, SEC_B8, SEC_B9, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 6, 30, SEC_B10, SEC_B12, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 7, 45, SEC_A11, SEC_A14, SEC_D14, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //5 - 6, 50, SEC_C8, SEC_C9, SEC_D9, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 55, SEC_D3, SEC_G3, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 10, 50, SEC_D6, SEC_D7, SEC_F7, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 10, 55, SEC_E8, SEC_E11, SEC_F11, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 10, 60, SEC_E12, SEC_E15, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //10 - 12, 60, SEC_G4, SEC_G7, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 65, SEC_G10, SEC_G12, SEC_F12, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 65, SEC_G13, SEC_G15, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 10, 65, SEC_H15, SEC_J15, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 14, 65, SEC_H12, SEC_J12, SEC_J13, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //15 - 13, 70, SEC_H9, SEC_I9, SEC_I10, SEC_J10, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 11, 70, SEC_K11, SEC_K14, SEC_J14, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 75, SEC_J2, SEC_K2, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 80, SEC_I3, SEC_J3, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 80, SEC_J6, SEC_K6, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //20 - 13, 85, SEC_K7, SEC_K10, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 90, SEC_L10, SEC_M10, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 90, SEC_N9, SEC_N10, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 80, SEC_L7, SEC_L8, SEC_M8, SEC_M9, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 14, 80, SEC_H4, SEC_H5, SEC_I5, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //25 - 7, 40, SEC_D4, SEC_E4, SEC_E5, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 7, 50, SEC_C10, SEC_C11, SEC_D11, SEC_D12, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 8, 40, SEC_A15, SEC_C15, SEC_C16, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - 12, 30, SEC_L13, SEC_M13, SEC_M14, SEC_L14, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //29 -}; -#define PATROL_GROUPS 29 +PATROL_GROUP gOrigPatrolGroup[MAX_PATROL_GROUPS];// = +//{ //SIZE PRIORITY POINT1 POINT2 POINT3 POINT4 MOD GROUPID WEIGHT PENDING +// // DAY100 GROUP ID +// 8, 40, SEC_B1, SEC_C1, SEC_C3, SEC_A3, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 6, 35, SEC_B4, SEC_B7, SEC_C7, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 6, 25, SEC_A8, SEC_B8, SEC_B9, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 6, 30, SEC_B10, SEC_B12, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 7, 45, SEC_A11, SEC_A14, SEC_D14, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //5 +// 6, 50, SEC_C8, SEC_C9, SEC_D9, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 55, SEC_D3, SEC_G3, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 10, 50, SEC_D6, SEC_D7, SEC_F7, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 10, 55, SEC_E8, SEC_E11, SEC_F11, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 10, 60, SEC_E12, SEC_E15, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //10 +// 12, 60, SEC_G4, SEC_G7, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 65, SEC_G10, SEC_G12, SEC_F12, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 65, SEC_G13, SEC_G15, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 10, 65, SEC_H15, SEC_J15, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 14, 65, SEC_H12, SEC_J12, SEC_J13, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //15 +// 13, 70, SEC_H9, SEC_I9, SEC_I10, SEC_J10, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 11, 70, SEC_K11, SEC_K14, SEC_J14, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 75, SEC_J2, SEC_K2, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 80, SEC_I3, SEC_J3, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 80, SEC_J6, SEC_K6, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //20 +// 13, 85, SEC_K7, SEC_K10, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 90, SEC_L10, SEC_M10, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 90, SEC_N9, SEC_N10, 0, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 80, SEC_L7, SEC_L8, SEC_M8, SEC_M9, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 14, 80, SEC_H4, SEC_H5, SEC_I5, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //25 +// 7, 40, SEC_D4, SEC_E4, SEC_E5, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 7, 50, SEC_C10, SEC_C11, SEC_D11, SEC_D12, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 8, 40, SEC_A15, SEC_C15, SEC_C16, 0, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// 12, 30, SEC_L13, SEC_M13, SEC_M14, SEC_L14, -1, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //29 +//}; +//#define PATROL_GROUPS 29 -GARRISON_GROUP gOrigGarrisonGroup[] = -{ //SECTOR MILITARY WEIGHT UNUSED - // COMPOSITION GROUP ID - SEC_P3, QUEEN_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_O3, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_O4, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_N3, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_N4, MEDUNA_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //5 - SEC_N5, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_M3, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_M4, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_M5, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_N6, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //10 - SEC_M2, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_L3, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_L4, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_L5, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_M6, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //15 - SEC_N7, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_L2, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_K3, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_K5, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_L6, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //20 - SEC_M7, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_N8, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_K4, ORTA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_G1, WEST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_G2, EAST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //25 - SEC_H1, WEST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_H2, EAST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_H3, GRUMM_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_A9, OMERTA_WELCOME_WAGON, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_L11, BALIME_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //30 - SEC_L12, BALIME_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_J9, TIXA_PRISON, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_I8, TIXA_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_H13, ALMA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_H14, ALMA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //35 - SEC_I13, ALMA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_I14, ALMA_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_F8, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_F9, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_G8, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //40 - SEC_G9, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_H8, CAMBRIA_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_A2, CHITZENA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_B2, CHITZENA_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_D2, CHITZENA_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //45 - SEC_B13, DRASSEN_AIRPORT, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_C13, DRASSEN_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_D13, DRASSEN_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_D15, DRASSEN_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_G12, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //50 - SEC_M10, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_G6, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_C9, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_K10, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_G7, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //55 - SEC_G3, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - SEC_C5, SANMONA_SMALL, 0, 0, {0,0,0,0,0,0,0,0,0,0}, - //57 -}; +GARRISON_GROUP gOrigGarrisonGroup[MAX_GARRISON_GROUPS];// = +//{ //SECTOR MILITARY WEIGHT UNUSED +// // COMPOSITION GROUP ID +// SEC_P3, QUEEN_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_O3, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_O4, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_N3, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_N4, MEDUNA_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //5 +// SEC_N5, MEDUNA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_M3, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_M4, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_M5, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_N6, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //10 +// SEC_M2, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_L3, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_L4, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_L5, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_M6, LEVEL2_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //15 +// SEC_N7, LEVEL1_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_L2, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_K3, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_K5, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_L6, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //20 +// SEC_M7, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_N8, LEVEL3_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_K4, ORTA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_G1, WEST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_G2, EAST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //25 +// SEC_H1, WEST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_H2, EAST_GRUMM_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_H3, GRUMM_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_A9, OMERTA_WELCOME_WAGON, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_L11, BALIME_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //30 +// SEC_L12, BALIME_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_J9, TIXA_PRISON, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_I8, TIXA_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_H13, ALMA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_H14, ALMA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //35 +// SEC_I13, ALMA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_I14, ALMA_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_F8, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_F9, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_G8, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //40 +// SEC_G9, CAMBRIA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_H8, CAMBRIA_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_A2, CHITZENA_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_B2, CHITZENA_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_D2, CHITZENA_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //45 +// SEC_B13, DRASSEN_AIRPORT, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_C13, DRASSEN_DEFENCE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_D13, DRASSEN_MINE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_D15, DRASSEN_SAMSITE, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_G12, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //50 +// SEC_M10, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_G6, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_C9, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_K10, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_G7, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //55 +// SEC_G3, ROADBLOCK, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// SEC_C5, SANMONA_SMALL, 0, 0, {0,0,0,0,0,0,0,0,0,0}, +// //57 +//}; //Various decision functions and utils to help make those decisions. BOOLEAN AdjacentSectorIsImportantAndUndefended( UINT8 ubSectorID ); @@ -1044,9 +1047,8 @@ void InitStrategicAI() GROUP *pGroup; UINT8 ubNumTroops; INT32 iPercentElitesBonus; - INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize; -DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); //Initialize the basic variables. @@ -1054,8 +1056,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); gbPadding2[1] = 0; gbPadding2[2] = 0; gfExtraElites = FALSE; - giGarrisonArraySize = 0; - giPatrolArraySize = 0; + //giGarrisonArraySize = 0; // Lesh: already counted from xml + //giPatrolArraySize = 0; // Lesh: already counted from xml giForcePercentage = 0; giArmyAlertness = 0; giArmyAlertnessDecay = 0; @@ -1164,7 +1166,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); } else { - for( i = 0; i <= NUM_ARMY_COMPOSITIONS; i++ ) + for( i = 0; i < NUM_ARMY_COMPOSITIONS; i++ ) { if ( i != OMERTA_WELCOME_WAGON ) { @@ -1177,7 +1179,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); } break; case DIF_LEVEL_HARD: - for( i = 0; i <= NUM_ARMY_COMPOSITIONS; i++ ) + for( i = 0; i < NUM_ARMY_COMPOSITIONS; i++ ) { if ( i != OMERTA_WELCOME_WAGON ) { @@ -1188,7 +1190,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); } } case DIF_LEVEL_INSANE: - for( i = 0; i <= NUM_ARMY_COMPOSITIONS; i++ ) + for( i = 0; i < NUM_ARMY_COMPOSITIONS; i++ ) { if ( i != OMERTA_WELCOME_WAGON ) { @@ -1201,7 +1203,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); break; } //initialize the patrol group definitions - giPatrolArraySize = sizeof( gOrigPatrolGroup ) / sizeof( PATROL_GROUP ); + // Lesh: giPatrolArraySize already calculated while reading xml + //giPatrolArraySize = sizeof( gOrigPatrolGroup ) / sizeof( PATROL_GROUP ); if( !gPatrolGroup ) { //Allocate it (otherwise, we just overwrite it because the size never changes) gPatrolGroup = (PATROL_GROUP*)MemAlloc( sizeof( gOrigPatrolGroup ) ); @@ -1213,7 +1216,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); memset( gubPatrolReinforcementsDenied, 0, giPatrolArraySize ); //initialize the garrison group definitions - giGarrisonArraySize = sizeof( gOrigGarrisonGroup ) / sizeof( GARRISON_GROUP ); + // Lesh: giGarrisonArraySize already calculated while reading xml + //giGarrisonArraySize = sizeof( gOrigGarrisonGroup ) / sizeof( GARRISON_GROUP ); if( !gGarrisonGroup ) { gGarrisonGroup = (GARRISON_GROUP*)MemAlloc( sizeof( gOrigGarrisonGroup ) ); @@ -1404,11 +1408,17 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic3"); //} } + // Lesh: new declaration of sam sites + for (i=0; i < NUMBER_OF_SAMS; i++) + { + SectorInfo[ pSamList[i] ].uiFlags |= SF_SAM_SITE; + } + //Setup the flags for the four sam sites. - SectorInfo[SEC_D2].uiFlags |= SF_SAM_SITE; - SectorInfo[SEC_D15].uiFlags |= SF_SAM_SITE; - SectorInfo[SEC_I8].uiFlags |= SF_SAM_SITE; - SectorInfo[SEC_N4].uiFlags |= SF_SAM_SITE; + //SectorInfo[SEC_D2].uiFlags |= SF_SAM_SITE; + //SectorInfo[SEC_D15].uiFlags |= SF_SAM_SITE; + //SectorInfo[SEC_I8].uiFlags |= SF_SAM_SITE; + //SectorInfo[SEC_N4].uiFlags |= SF_SAM_SITE; //final thing to do is choose 1 cache map out of 5 possible maps. Simply select the sector randomly, //set up the flags to use the alternate map, then place 8-12 regular troops there (no ai though). @@ -3803,8 +3813,8 @@ void EvolveQueenPriorityPhase( BOOLEAN fForceChange ) INT32 i, index, num, iFactor; INT32 iChange, iNew, iNumSoldiers, iNumPromotions; SECTORINFO *pSector; - UINT8 ubOwned[ NUM_ARMY_COMPOSITIONS ]; - UINT8 ubTotal[ NUM_ARMY_COMPOSITIONS ]; + UINT8 ubOwned[ MAX_ARMY_COMPOSITIONS ]; + UINT8 ubTotal[ MAX_ARMY_COMPOSITIONS ]; UINT8 ubNewPhase; ubNewPhase = CurrentPlayerProgressPercentage() / 10; INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize; @@ -3841,8 +3851,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic7"); //are controlled by her, the desired number will be increased as well as the priority. On the other //hand, if she doesn't own those sectors, the values will be decreased instead. All values are based off of //the originals. - memset( ubOwned, 0, NUM_ARMY_COMPOSITIONS ); - memset( ubTotal, 0, NUM_ARMY_COMPOSITIONS ); + memset( ubOwned, 0, MAX_ARMY_COMPOSITIONS ); + memset( ubTotal, 0, MAX_ARMY_COMPOSITIONS ); //Record the values required to calculate the percentage of each composition type that the queen controls. for( i = 0; i < giGarrisonArraySize; i++ ) diff --git a/Strategic/Strategic AI.h b/Strategic/Strategic AI.h index 26dfde2b..e25429d3 100644 --- a/Strategic/Strategic AI.h +++ b/Strategic/Strategic AI.h @@ -98,32 +98,32 @@ enum DRASSEN_MINE, DRASSEN_SAMSITE, //Sam site near Drassen (least importance to queen of all samsites) ROADBLOCK, //General outside city roadblocks -- enhance chance of ambush? - SANMONA_SMALL, - NUM_ARMY_COMPOSITIONS + SANMONA_SMALL }; +extern UINT8 NUM_ARMY_COMPOSITIONS; typedef struct ARMY_COMPOSITION { INT32 iReadability; //contains the enumeration which is useless, but helps readability. - INT8 bPriority; - INT8 bElitePercentage; - INT8 bTroopPercentage; - INT8 bAdminPercentage; - INT8 bDesiredPopulation; - INT8 bStartPopulation; - INT8 bPadding[10]; + INT8 bPriority; + INT8 bElitePercentage; + INT8 bTroopPercentage; + INT8 bAdminPercentage; + INT8 bDesiredPopulation; + INT8 bStartPopulation; + INT8 bPadding[10]; }ARMY_COMPOSITION; //Defines the patrol groups -- movement groups. typedef struct PATROL_GROUP { - INT8 bSize; - INT8 bPriority; - UINT8 ubSectorID[4]; - INT8 bFillPermittedAfterDayMod100; + INT8 bSize; + INT8 bPriority; + UINT8 ubSectorID[4]; + INT8 bFillPermittedAfterDayMod100; UINT8 ubGroupID; - INT8 bWeight; + INT8 bWeight; UINT8 ubPendingGroupID; INT8 bPadding[10]; }PATROL_GROUP; @@ -132,11 +132,14 @@ typedef struct PATROL_GROUP typedef struct GARRISON_GROUP { UINT8 ubSectorID; - UINT8 ubComposition; - INT8 bWeight; + UINT8 ubComposition; + INT8 bWeight; UINT8 ubPendingGroupID; - INT8 bPadding[10]; + INT8 bPadding[10]; }GARRISON_GROUP; +#define MAX_GARRISON_GROUPS 100 +#define MAX_PATROL_GROUPS 50 +#define MAX_ARMY_COMPOSITIONS 60 #endif \ No newline at end of file diff --git a/Strategic/XML_Army.cpp b/Strategic/XML_Army.cpp new file mode 100644 index 00000000..34c43fc4 --- /dev/null +++ b/Strategic/XML_Army.cpp @@ -0,0 +1,901 @@ +#ifdef PRECOMPILEDHEADERS + #include "Strategic All.h" + #include "XML.h" +#else + #include + #include "XML.h" +#endif + +#define MAX_CHAR_DATA_LENGTH 500 + +extern GARRISON_GROUP gOrigGarrisonGroup[ MAX_GARRISON_GROUPS ]; +extern PATROL_GROUP gOrigPatrolGroup[ MAX_PATROL_GROUPS ]; +extern ARMY_COMPOSITION gOrigArmyComp[ MAX_ARMY_COMPOSITIONS ]; +extern INT32 giGarrisonArraySize; +extern INT32 giPatrolArraySize; + + +// Garrison externalization +typedef enum +{ + GARRISON_ELEMENT_NONE = 0, + GARRISON_ELEMENT_GARRISON_INFO, + GARRISON_ELEMENT_GARRISON, + GARRISON_ELEMENT_SECTOR, + GARRISON_ELEMENT_COMPOSITION +} GARRISON_PARSE_STAGE; + +typedef struct +{ + UINT8 ubSectorID; + UINT8 ubComposition; + BOOLEAN fValidSector; +} garrisonInfo; + +typedef struct +{ + GARRISON_PARSE_STAGE curElement; + + INT8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + garrisonInfo curGarrisonInfo; + UINT32 uiGarrisonCount; + + UINT32 currentDepth; + UINT32 maxReadDepth; +} garrisonParseData; + +static void XMLCALL +garrisonStartElementHandle(void *userData, const char *name, const char **atts) +{ + garrisonParseData * pData = (garrisonParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element? + { + + if(strcmp(name, "GARRISON_INFO") == 0 && pData->curElement == GARRISON_ELEMENT_NONE) + { + pData->curElement = GARRISON_ELEMENT_GARRISON_INFO; + memset( gOrigGarrisonGroup, 0, sizeof(gOrigGarrisonGroup) ); + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "GARRISON") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON_INFO) + { + pData->curElement = GARRISON_ELEMENT_GARRISON; + memset( &pData->curGarrisonInfo, 0, sizeof(garrisonInfo) ); + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Sector") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON) + { + pData->curElement = GARRISON_ELEMENT_SECTOR; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Composition") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON) + { + pData->curElement = GARRISON_ELEMENT_COMPOSITION; + pData->maxReadDepth++; //we are not skipping this element + } + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; + +} + +static void XMLCALL +garrisonCharacterDataHandle(void *userData, const char *str, int len) +{ + garrisonParseData * pData = (garrisonParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); +} + + +static void XMLCALL +garrisonEndElementHandle(void *userData, const char *name) +{ + garrisonParseData * pData = (garrisonParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading + { + if(strcmp(name, "GARRISON_INFO") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON_INFO) + { + pData->curElement = GARRISON_ELEMENT_NONE; + giGarrisonArraySize = pData->uiGarrisonCount; + } + else if(strcmp(name, "GARRISON") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON) + { + pData->curElement = GARRISON_ELEMENT_GARRISON_INFO; + + if ( pData->curGarrisonInfo.fValidSector && pData->uiGarrisonCount < MAX_GARRISON_GROUPS ) + { + gOrigGarrisonGroup[ pData->uiGarrisonCount ].ubSectorID = pData->curGarrisonInfo.ubSectorID; + gOrigGarrisonGroup[ pData->uiGarrisonCount ].ubComposition = pData->curGarrisonInfo.ubComposition; + pData->uiGarrisonCount++; + } + } + else if(strcmp(name, "Sector") == 0 && pData->curElement == GARRISON_ELEMENT_SECTOR) + { + UINT8 x, y; + pData->curElement = GARRISON_ELEMENT_GARRISON; + + y = (UINT8)pData->szCharData[0] & 0x1F; + x = (UINT8)atol(&pData->szCharData[1]); + if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) + { + pData->curGarrisonInfo.fValidSector = TRUE; + pData->curGarrisonInfo.ubSectorID = SECTOR(x,y); + } + else + { + pData->curGarrisonInfo.fValidSector = FALSE; + } + } + else if(strcmp(name, "Composition") == 0 && pData->curElement == GARRISON_ELEMENT_COMPOSITION) + { + pData->curElement = GARRISON_ELEMENT_GARRISON; + pData->curGarrisonInfo.ubComposition = (UINT8) atol(pData->szCharData); + } + pData->maxReadDepth--; + } + + pData->currentDepth--; +} + +BOOLEAN ReadInGarrisonInfo(STR fileName) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + garrisonParseData pData; + + + // Open weapons file + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + //Read in block + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; //add a null terminator + + FileClose( hFile ); + + + XML_SetElementHandler(parser, garrisonStartElementHandle, garrisonEndElementHandle); + XML_SetCharacterDataHandler(parser, garrisonCharacterDataHandle); + + + memset(&pData,0,sizeof(pData)); + XML_SetUserData(parser, &pData); + giGarrisonArraySize = 0; + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in GarrisonGroups.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + XML_ParserFree(parser); + + return TRUE; +} + + +BOOLEAN WriteInGarrisonInfo(STR fileName) +{ + HWFILE hFile; + + hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + if ( !hFile ) + return( FALSE ); + + { + INT8 cnt; + + + FilePrintf(hFile,"\r\n"); + for(cnt = 0; cnt < 57; cnt++) + { + FilePrintf(hFile,"\t\r\n"); + + FilePrintf(hFile,"\t\t%c%d\r\n", + (gOrigGarrisonGroup[cnt].ubSectorID / 16 + 0x41), + (gOrigGarrisonGroup[cnt].ubSectorID % 16 + 1)); + + FilePrintf(hFile,"\t\t%d\r\n", + gOrigGarrisonGroup[cnt].ubComposition); + + FilePrintf(hFile,"\t\r\n"); + } + FilePrintf(hFile,"\r\n"); + } + FileClose( hFile ); + + return TRUE; +} + + +// Patrol externalization +typedef enum +{ + PATROL_ELEMENT_NONE = 0, + PATROL_ELEMENT_PATROL_INFO, + PATROL_ELEMENT_PATROL, + PATROL_ELEMENT_SIZE, + PATROL_ELEMENT_PRIORITY, + PATROL_ELEMENT_WAYPOINTS, + PATROL_ELEMENT_SECTOR1, + PATROL_ELEMENT_SECTOR2, + PATROL_ELEMENT_SECTOR3, + PATROL_ELEMENT_SECTOR4 +} PATROL_PARSE_STAGE; + +typedef struct +{ + BOOLEAN fErrorState; + INT8 bSize; + INT8 bPriority; + UINT8 ubSectorID[4]; +} patrolInfo; + +typedef struct +{ + PATROL_PARSE_STAGE curElement; + + INT8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + patrolInfo curPatrolInfo; + UINT32 uiPatrolCount; + + UINT32 currentDepth; + UINT32 maxReadDepth; +} patrolParseData; + +static void XMLCALL +patrolStartElementHandle(void *userData, const char *name, const char **atts) +{ + patrolParseData * pData = (patrolParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element? + { + + if(strcmp(name, "PATROL_INFO") == 0 && pData->curElement == PATROL_ELEMENT_NONE) + { + pData->curElement = PATROL_ELEMENT_PATROL_INFO; + memset( gOrigPatrolGroup, 0, sizeof(gOrigPatrolGroup) ); + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "PATROL") == 0 && pData->curElement == PATROL_ELEMENT_PATROL_INFO) + { + pData->curElement = PATROL_ELEMENT_PATROL; + memset( &pData->curPatrolInfo, 0, sizeof(patrolInfo) ); + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Size") == 0 && pData->curElement == PATROL_ELEMENT_PATROL) + { + pData->curElement = PATROL_ELEMENT_SIZE; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Priority") == 0 && pData->curElement == PATROL_ELEMENT_PATROL) + { + pData->curElement = PATROL_ELEMENT_PRIORITY; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Waypoints") == 0 && pData->curElement == PATROL_ELEMENT_PATROL) + { + pData->curElement = PATROL_ELEMENT_WAYPOINTS; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Sector1") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS) + { + pData->curElement = PATROL_ELEMENT_SECTOR1; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Sector2") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS) + { + pData->curElement = PATROL_ELEMENT_SECTOR2; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Sector3") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS) + { + pData->curElement = PATROL_ELEMENT_SECTOR3; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Sector4") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS) + { + pData->curElement = PATROL_ELEMENT_SECTOR4; + pData->maxReadDepth++; //we are not skipping this element + } + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; + +} + +static void XMLCALL +patrolCharacterDataHandle(void *userData, const char *str, int len) +{ + patrolParseData * pData = (patrolParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); +} + + +static void XMLCALL +patrolEndElementHandle(void *userData, const char *name) +{ + patrolParseData * pData = (patrolParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading + { + if(strcmp(name, "PATROL_INFO") == 0 && pData->curElement == PATROL_ELEMENT_PATROL_INFO) + { + pData->curElement = PATROL_ELEMENT_NONE; + giPatrolArraySize = pData->uiPatrolCount; + } + else if(strcmp(name, "PATROL") == 0 && pData->curElement == PATROL_ELEMENT_PATROL) + { + pData->curElement = PATROL_ELEMENT_PATROL_INFO; + + if ( !pData->curPatrolInfo.fErrorState && pData->uiPatrolCount < MAX_PATROL_GROUPS ) + { + gOrigPatrolGroup[ pData->uiPatrolCount ].bSize = pData->curPatrolInfo.bSize; + gOrigPatrolGroup[ pData->uiPatrolCount ].bPriority = pData->curPatrolInfo.bPriority; + gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[0] = pData->curPatrolInfo.ubSectorID[0]; + gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[1] = pData->curPatrolInfo.ubSectorID[1]; + gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[2] = pData->curPatrolInfo.ubSectorID[2]; + gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[3] = pData->curPatrolInfo.ubSectorID[3]; + pData->uiPatrolCount++; + } + } + else if(strcmp(name, "Size") == 0 && pData->curElement == PATROL_ELEMENT_SIZE) + { + pData->curElement = PATROL_ELEMENT_PATROL; + pData->curPatrolInfo.bSize = (INT8) atol(pData->szCharData); + } + else if(strcmp(name, "Priority") == 0 && pData->curElement == PATROL_ELEMENT_PRIORITY) + { + pData->curElement = PATROL_ELEMENT_PATROL; + pData->curPatrolInfo.bPriority = (INT8) atol(pData->szCharData); + + if ( pData->curPatrolInfo.bPriority < 0 ) + pData->curPatrolInfo.bPriority = 0; + else if ( pData->curPatrolInfo.bPriority > 100 ) + pData->curPatrolInfo.bPriority = 100; + } + else if(strcmp(name, "Waypoints") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS) + { + pData->curElement = PATROL_ELEMENT_PATROL; + } + else if(strcmp(name, "Sector1") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR1) + { + pData->curElement = PATROL_ELEMENT_WAYPOINTS; + + if ( strcmp(pData->szCharData, "0") == 0 ) + { + pData->curPatrolInfo.ubSectorID[0] = 0; + } + else + { + UINT8 x, y; + y = (UINT8)pData->szCharData[0] & 0x1F; + x = (UINT8)atol(&pData->szCharData[1]); + if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) + { + pData->curPatrolInfo.ubSectorID[0] = SECTOR(x,y); + } + else + { + pData->curPatrolInfo.fErrorState++; + } + } + } + else if(strcmp(name, "Sector2") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR2) + { + pData->curElement = PATROL_ELEMENT_WAYPOINTS; + + if ( strcmp(pData->szCharData, "0") == 0 ) + { + pData->curPatrolInfo.ubSectorID[1] = 0; + } + else + { + UINT8 x, y; + y = (UINT8)pData->szCharData[0] & 0x1F; + x = (UINT8)atol(&pData->szCharData[1]); + if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) + { + pData->curPatrolInfo.ubSectorID[1] = SECTOR(x,y); + } + else + { + pData->curPatrolInfo.fErrorState++; + } + } + } + else if(strcmp(name, "Sector3") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR3) + { + pData->curElement = PATROL_ELEMENT_WAYPOINTS; + + if ( strcmp(pData->szCharData, "0") == 0 ) + { + pData->curPatrolInfo.ubSectorID[2] = 0; + } + else + { + UINT8 x, y; + y = (UINT8)pData->szCharData[0] & 0x1F; + x = (UINT8)atol(&pData->szCharData[1]); + if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) + { + pData->curPatrolInfo.ubSectorID[2] = SECTOR(x,y); + } + else + { + pData->curPatrolInfo.fErrorState++; + } + } + } + else if(strcmp(name, "Sector4") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR4) + { + pData->curElement = PATROL_ELEMENT_WAYPOINTS; + + if ( strcmp(pData->szCharData, "0") == 0 ) + { + pData->curPatrolInfo.ubSectorID[3] = 0; + } + else + { + UINT8 x, y; + y = (UINT8)pData->szCharData[0] & 0x1F; + x = (UINT8)atol(&pData->szCharData[1]); + if ( x > 0 && x <= 16 && y > 0 && y <= 16 ) + { + pData->curPatrolInfo.ubSectorID[3] = SECTOR(x,y); + } + else + { + pData->curPatrolInfo.fErrorState++; + } + } + } + pData->maxReadDepth--; + } + + pData->currentDepth--; +} + + +BOOLEAN ReadInPatrolInfo(STR fileName) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + patrolParseData pData; + + + // Open weapons file + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + //Read in block + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; //add a null terminator + + FileClose( hFile ); + + + XML_SetElementHandler(parser, patrolStartElementHandle, patrolEndElementHandle); + XML_SetCharacterDataHandler(parser, patrolCharacterDataHandle); + + + memset(&pData,0,sizeof(pData)); + XML_SetUserData(parser, &pData); + giPatrolArraySize = 0; + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in PatrolGroups.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + XML_ParserFree(parser); + + return TRUE; +} + + +BOOLEAN WriteInPatrolInfo(STR fileName) +{ + HWFILE hFile; + + hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + if ( !hFile ) + return( FALSE ); + + { + INT8 cnt, i; + + + FilePrintf(hFile,"\r\n"); + for(cnt = 0; cnt < 29; cnt++) + { + FilePrintf(hFile,"\t\r\n"); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigPatrolGroup[cnt].bSize); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigPatrolGroup[cnt].bPriority); + + FilePrintf(hFile,"\t\t\r\n"); + + for (i=0; i<4; i++) + { + if ( gOrigPatrolGroup[cnt].ubSectorID[i] ) + { + FilePrintf(hFile,"\t\t\t%c%d\r\n", + i+1, + (gOrigPatrolGroup[cnt].ubSectorID[i] / 16 + 0x41), + (gOrigPatrolGroup[cnt].ubSectorID[i] % 16 + 1), + i+1); + } + else + { + FilePrintf(hFile,"\t\t\t0\r\n", i+1, i+1); + } + } + + FilePrintf(hFile,"\t\t\r\n"); + FilePrintf(hFile,"\t\r\n"); + } + FilePrintf(hFile,"\r\n"); + } + FileClose( hFile ); + + return TRUE; +} + + + + +// Army composition externalization +typedef enum +{ + COMPOSITION_ELEMENT_NONE = 0, + COMPOSITION_ELEMENT_COMPOSITION_INFO, + COMPOSITION_ELEMENT_COMPOSITION, + COMPOSITION_ELEMENT_INDEX, + COMPOSITION_ELEMENT_PRIORITY, + COMPOSITION_ELEMENT_ELITE_PERCENTAGE, + COMPOSITION_ELEMENT_TROOP_PERCENTAGE, + COMPOSITION_ELEMENT_ADMIN_PERCENTAGE, + COMPOSITION_ELEMENT_DESIRED_POPULATION, + COMPOSITION_ELEMENT_START_POPULATION +} COMPOSITION_PARSE_STAGE; + +typedef struct +{ + INT32 iIndex; + INT8 bPriority; + INT8 bElitePercentage; + INT8 bTroopPercentage; + INT8 bAdminPercentage; + INT8 bDesiredPopulation; + INT8 bStartPopulation; +} compositionInfo; + +typedef struct +{ + COMPOSITION_PARSE_STAGE curElement; + + INT8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + compositionInfo curCompositionInfo; + INT32 iHighestIndex; + + UINT32 currentDepth; + UINT32 maxReadDepth; +} compositionParseData; + +static void XMLCALL +compositionStartElementHandle(void *userData, const char *name, const char **atts) +{ + compositionParseData * pData = (compositionParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element? + { + + if(strcmp(name, "COMPOSITION_INFO") == 0 && pData->curElement == COMPOSITION_ELEMENT_NONE) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION_INFO; + memset( gOrigArmyComp, 0, sizeof(gOrigArmyComp) ); + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "COMPOSITION") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION_INFO) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + memset( &pData->curCompositionInfo, 0, sizeof(compositionInfo) ); + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Index") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_INDEX; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "Priority") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_PRIORITY; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "ElitePercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_ELITE_PERCENTAGE; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "TroopPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_TROOP_PERCENTAGE; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "AdminPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_ADMIN_PERCENTAGE; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "DesiredPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_DESIRED_POPULATION; + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "StartPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_START_POPULATION; + pData->maxReadDepth++; //we are not skipping this element + } + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; + +} + +static void XMLCALL +compositionCharacterDataHandle(void *userData, const char *str, int len) +{ + compositionParseData * pData = (compositionParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); +} + + +static void XMLCALL +compositionEndElementHandle(void *userData, const char *name) +{ + compositionParseData * pData = (compositionParseData *) userData; + + if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading + { + if(strcmp(name, "COMPOSITION_INFO") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION_INFO) + { + pData->curElement = COMPOSITION_ELEMENT_NONE; + NUM_ARMY_COMPOSITIONS = (UINT8)(pData->iHighestIndex + 1); + } + else if(strcmp(name, "COMPOSITION") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION_INFO; + + if ( pData->curCompositionInfo.iIndex < MAX_ARMY_COMPOSITIONS ) + { + gOrigArmyComp[ pData->curCompositionInfo.iIndex ].iReadability = pData->curCompositionInfo.iIndex; + gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bPriority = pData->curCompositionInfo.bPriority; + gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bElitePercentage = pData->curCompositionInfo.bElitePercentage; + gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bTroopPercentage = pData->curCompositionInfo.bTroopPercentage; + gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bAdminPercentage = pData->curCompositionInfo.bAdminPercentage; + gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bDesiredPopulation = pData->curCompositionInfo.bDesiredPopulation; + gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bStartPopulation = pData->curCompositionInfo.bStartPopulation; + } + } + else if(strcmp(name, "Index") == 0 && pData->curElement == COMPOSITION_ELEMENT_INDEX) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + pData->curCompositionInfo.iIndex = (INT32) atol(pData->szCharData); + if ( pData->curCompositionInfo.iIndex < MAX_ARMY_COMPOSITIONS ) + { + if ( pData->curCompositionInfo.iIndex > pData->iHighestIndex ) + { + pData->iHighestIndex = pData->curCompositionInfo.iIndex; + } + } + } + else if(strcmp(name, "Priority") == 0 && pData->curElement == COMPOSITION_ELEMENT_PRIORITY) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + pData->curCompositionInfo.bPriority = (INT8) atol(pData->szCharData); + if ( pData->curCompositionInfo.bPriority < 0 ) + pData->curCompositionInfo.bPriority = 0; + else if ( pData->curCompositionInfo.bPriority > 100 ) + pData->curCompositionInfo.bPriority = 100; + } + else if(strcmp(name, "ElitePercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_ELITE_PERCENTAGE) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + pData->curCompositionInfo.bElitePercentage = (INT8) atol(pData->szCharData); + if ( pData->curCompositionInfo.bElitePercentage < 0 ) + pData->curCompositionInfo.bElitePercentage = 0; + else if ( pData->curCompositionInfo.bElitePercentage > 100 ) + pData->curCompositionInfo.bElitePercentage = 100; + } + else if(strcmp(name, "TroopPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_TROOP_PERCENTAGE) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + pData->curCompositionInfo.bTroopPercentage = (INT8) atol(pData->szCharData); + if ( pData->curCompositionInfo.bTroopPercentage < 0 ) + pData->curCompositionInfo.bTroopPercentage = 0; + else if ( pData->curCompositionInfo.bTroopPercentage > 100 ) + pData->curCompositionInfo.bTroopPercentage = 100; + } + else if(strcmp(name, "AdminPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_ADMIN_PERCENTAGE) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + pData->curCompositionInfo.bAdminPercentage = (INT8) atol(pData->szCharData); + if ( pData->curCompositionInfo.bAdminPercentage < 0 ) + pData->curCompositionInfo.bAdminPercentage = 0; + else if ( pData->curCompositionInfo.bAdminPercentage > 100 ) + pData->curCompositionInfo.bAdminPercentage = 100; + } + else if(strcmp(name, "DesiredPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_DESIRED_POPULATION) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + pData->curCompositionInfo.bDesiredPopulation = (INT8) atol(pData->szCharData); + if ( pData->curCompositionInfo.bDesiredPopulation < 0 ) + pData->curCompositionInfo.bDesiredPopulation = 1; + } + else if(strcmp(name, "StartPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_START_POPULATION) + { + pData->curElement = COMPOSITION_ELEMENT_COMPOSITION; + pData->curCompositionInfo.bStartPopulation = (INT8) atol(pData->szCharData); + if ( pData->curCompositionInfo.bStartPopulation < 0 ) + pData->curCompositionInfo.bStartPopulation = 1; + } + pData->maxReadDepth--; + } + + pData->currentDepth--; +} + +BOOLEAN ReadInArmyCompositionInfo(STR fileName) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + compositionParseData pData; + + // Open weapons file + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + //Read in block + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; //add a null terminator + + FileClose( hFile ); + + + XML_SetElementHandler(parser, compositionStartElementHandle, compositionEndElementHandle); + XML_SetCharacterDataHandler(parser, compositionCharacterDataHandle); + + + memset(&pData,0,sizeof(pData)); + XML_SetUserData(parser, &pData); + NUM_ARMY_COMPOSITIONS = 0; + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in ArmyComposition.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + XML_ParserFree(parser); + + return TRUE; +} + + +BOOLEAN WriteInArmyCompositionInfo(STR fileName) +{ + HWFILE hFile; + + hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + if ( !hFile ) + return( FALSE ); + + { + INT8 cnt; + + + FilePrintf(hFile,"\r\n"); + for(cnt = 0; cnt < NUM_ARMY_COMPOSITIONS; cnt++) + { + FilePrintf(hFile,"\t\r\n"); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigArmyComp[cnt].iReadability ); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigArmyComp[cnt].bPriority); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigArmyComp[cnt].bElitePercentage); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigArmyComp[cnt].bTroopPercentage); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigArmyComp[cnt].bAdminPercentage); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigArmyComp[cnt].bDesiredPopulation); + + FilePrintf(hFile,"\t\t%d\r\n", gOrigArmyComp[cnt].bStartPopulation); + + FilePrintf(hFile,"\t\r\n"); + } + FilePrintf(hFile,"\r\n"); + } + FileClose( hFile ); + + return TRUE; +} + + diff --git a/Tactical/XML.h b/Tactical/XML.h index 7dc3f604..524380b4 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -38,44 +38,49 @@ typedef PARSE_STAGE; #define ENEMYITEMCHOICESFILENAME "EnemyItemChoices.xml" #define IMPITEMCHOICESFILENAME "IMPItemChoices.xml" -#define TONYINVENTORYFILENAME "NPCInventory\\TonyInventory.xml" -#define DEVININVENTORYFILENAME "NPCInventory\\DevinInventory.xml" -#define FRANZINVENTORYFILENAME "NPCInventory\\FranzInventory.xml" -#define KEITHINVENTORYFILENAME "NPCInventory\\KeithInventory.xml" -#define SAMINVENTORYFILENAME "NPCInventory\\SamInventory.xml" -#define JAKEINVENTORYFILENAME "NPCInventory\\JakeInventory.xml" -#define HOWARDINVENTORYFILENAME "NPCInventory\\HowardInventory.xml" -#define GABBYINVENTORYFILENAME "NPCInventory\\GabbyInventory.xml" -#define FRANKINVENTORYFILENAME "NPCInventory\\FrankInventory.xml" -#define ELGININVENTORYFILENAME "NPCInventory\\ElginInventory.xml" -#define MANNYINVENTORYFILENAME "NPCInventory\\MannyInventory.xml" -#define HERVEINVENTORYFILENAME "NPCInventory\\HerveInventory.xml" -#define PETERINVENTORYFILENAME "NPCInventory\\PeterInventory.xml" -#define ALBERTOINVENTORYFILENAME "NPCInventory\\AlbertoInventory.xml" -#define CARLOINVENTORYFILENAME "NPCInventory\\CarloInventory.xml" -#define MICKEYINVENTORYFILENAME "NPCInventory\\MickeyInventory.xml" -#define ARNIEINVENTORYFILENAME "NPCInventory\\ArnieInventory.xml" -#define PERKOINVENTORYFILENAME "NPCInventory\\PerkoInventory.xml" -#define FREDOINVENTORYFILENAME "NPCInventory\\FredoInventory.xml" +#define TONYINVENTORYFILENAME "NPCInventory\\TonyInventory.xml" +#define DEVININVENTORYFILENAME "NPCInventory\\DevinInventory.xml" +#define FRANZINVENTORYFILENAME "NPCInventory\\FranzInventory.xml" +#define KEITHINVENTORYFILENAME "NPCInventory\\KeithInventory.xml" +#define SAMINVENTORYFILENAME "NPCInventory\\SamInventory.xml" +#define JAKEINVENTORYFILENAME "NPCInventory\\JakeInventory.xml" +#define HOWARDINVENTORYFILENAME "NPCInventory\\HowardInventory.xml" +#define GABBYINVENTORYFILENAME "NPCInventory\\GabbyInventory.xml" +#define FRANKINVENTORYFILENAME "NPCInventory\\FrankInventory.xml" +#define ELGININVENTORYFILENAME "NPCInventory\\ElginInventory.xml" +#define MANNYINVENTORYFILENAME "NPCInventory\\MannyInventory.xml" +#define HERVEINVENTORYFILENAME "NPCInventory\\HerveInventory.xml" +#define PETERINVENTORYFILENAME "NPCInventory\\PeterInventory.xml" +#define ALBERTOINVENTORYFILENAME "NPCInventory\\AlbertoInventory.xml" +#define CARLOINVENTORYFILENAME "NPCInventory\\CarloInventory.xml" +#define MICKEYINVENTORYFILENAME "NPCInventory\\MickeyInventory.xml" +#define ARNIEINVENTORYFILENAME "NPCInventory\\ArnieInventory.xml" +#define PERKOINVENTORYFILENAME "NPCInventory\\PerkoInventory.xml" +#define FREDOINVENTORYFILENAME "NPCInventory\\FredoInventory.xml" -#define BOBBYRAYSTRINGSFILENAME "BobbyRayStrings.xml" -#define AMMOCALIBERSTRINGSFILENAME "AmmoCaliberStrings.xml" +#define BOBBYRAYSTRINGSFILENAME "BobbyRayStrings.xml" +#define AMMOCALIBERSTRINGSFILENAME "AmmoCaliberStrings.xml" -#define SOUNDSFILENAME "Sounds\\Sounds.xml" -#define BURSTSOUNDSFILENAME "Sounds\\BurstSounds.xml" +#define SOUNDSFILENAME "Sounds\\Sounds.xml" +#define BURSTSOUNDSFILENAME "Sounds\\BurstSounds.xml" #define EXPLOSIONDATAFILENAME "ExplosionData.xml" + #define CITYTABLEFILENAME "Map\\Cities.xml" #define MOVEMENTCOSTFILENAME "Map\\MovementCosts.xml" #define ALTSECTORSFILENAME "Map\\AltSectors.xml" #define SAMSITESFILENAME "Map\\SamSites.xml" +#define GARRISONFILENAME "Army\\GarrisonGroups.xml" +#define PATROLFILENAME "Army\\PatrolGroups.xml" +#define COMPOSITIONFILENAME "Army\\ArmyComposition.xml" + // WANNE: drops filename -#define ENEMYWEAPONDROPSFILENAME "EnemyWeaponDrops.xml" -#define ENEMYAMMODROPSFILENAME "EnemyAmmoDrops.xml" -#define ENEMYEXPLOSIVEDROPSFILENAME "EnemyExplosiveDrops.xml" -#define ENEMYARMOURDROPSFILENAME "EnemyArmourDrops.xml" -#define ENEMYMISCDROPSFILENAME "EnemyMiscDrops.xml" +#define ENEMYWEAPONDROPSFILENAME "EnemyWeaponDrops.xml" +#define ENEMYAMMODROPSFILENAME "EnemyAmmoDrops.xml" +#define ENEMYEXPLOSIVEDROPSFILENAME "EnemyExplosiveDrops.xml" +#define ENEMYARMOURDROPSFILENAME "EnemyArmourDrops.xml" +#define ENEMYMISCDROPSFILENAME "EnemyMiscDrops.xml" extern BOOLEAN ReadInItemStats(STR fileName, BOOLEAN localizedVersion); @@ -163,4 +168,11 @@ extern BOOLEAN WriteInAltSectors(STR fileName); extern BOOLEAN ReadInSAMInfo(STR fileName); extern BOOLEAN WriteInSAMInfo(STR fileName); +// Lesh: army externalization +extern BOOLEAN ReadInGarrisonInfo(STR fileName); +extern BOOLEAN WriteInGarrisonInfo(STR fileName); +extern BOOLEAN ReadInPatrolInfo(STR fileName); +extern BOOLEAN WriteInPatrolInfo(STR fileName); +extern BOOLEAN ReadInArmyCompositionInfo(STR fileName); +extern BOOLEAN WriteInArmyCompositionInfo(STR fileName); #endif \ No newline at end of file