New feature: enemy combat jeeps fill the role between infantry and tanks. For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&goto=344628&#msg_344628

This is savegame compatible. GameDir >= r2305 required.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8114 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2016-03-20 18:45:51 +00:00
parent b8c0036396
commit 9e97538d89
75 changed files with 1614 additions and 772 deletions
+4 -2
View File
@@ -304,7 +304,7 @@ STR16 EditMercAttitudes[6] = { L"Defensive",L"Brave Loner",L"Brave Buddy",
#define MAX_REBELTYPES 6 #define MAX_REBELTYPES 6
#define MAX_CIVTYPES 6 #define MAX_CIVTYPES 6
#else #else
#define MAX_ENEMYTYPES 7 #define MAX_ENEMYTYPES 11
//#define MAX_ENEMYRANDOMTYPES 5 //#define MAX_ENEMYRANDOMTYPES 5
#define MAX_CREATURETYPES 8 #define MAX_CREATURETYPES 8
#define MAX_REBELTYPES 7 #define MAX_REBELTYPES 7
@@ -318,7 +318,7 @@ INT8 bCreatureArray[MAX_CREATURETYPES]={ ADULTFEMALEMONSTER };
INT8 bRebelArray[MAX_REBELTYPES]={ RANDOM, MANCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE }; INT8 bRebelArray[MAX_REBELTYPES]={ RANDOM, MANCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE };
INT8 bCivArray[MAX_CIVTYPES]={ RANDOM, MANCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE }; INT8 bCivArray[MAX_CIVTYPES]={ RANDOM, MANCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE };
#else #else
INT8 bEnemyArray[MAX_ENEMYTYPES]={ RANDOM, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE, TANK_NW, TANK_NE }; INT8 bEnemyArray[MAX_ENEMYTYPES] = {RANDOM, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE, TANK_NW, TANK_NE, COMBAT_JEEP};
INT8 bCreatureArray[MAX_CREATURETYPES]={ BLOODCAT, LARVAE_MONSTER, INFANT_MONSTER, YAF_MONSTER, YAM_MONSTER, ADULTFEMALEMONSTER, AM_MONSTER, QUEENMONSTER }; INT8 bCreatureArray[MAX_CREATURETYPES]={ BLOODCAT, LARVAE_MONSTER, INFANT_MONSTER, YAF_MONSTER, YAM_MONSTER, ADULTFEMALEMONSTER, AM_MONSTER, QUEENMONSTER };
INT8 bRebelArray[MAX_REBELTYPES]={ RANDOM, FATCIV, MANCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE }; INT8 bRebelArray[MAX_REBELTYPES]={ RANDOM, FATCIV, MANCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE };
INT8 bCivArray[MAX_CIVTYPES]={ RANDOM, FATCIV, MANCIV, MINICIV, DRESSCIV, HATKIDCIV, KIDCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE, INT8 bCivArray[MAX_CIVTYPES]={ RANDOM, FATCIV, MANCIV, MINICIV, DRESSCIV, HATKIDCIV, KIDCIV, REGMALE, BIGMALE, STOCKYMALE, REGFEMALE,
@@ -2161,6 +2161,7 @@ void ChangeBodyType( INT8 bOffset ) //+1 or -1 only
case JEEP: case JEEP:
case TANK_NW: case TANK_NW:
case TANK_NE: case TANK_NE:
case COMBAT_JEEP:
gpSelected->pSoldier->flags.uiStatusFlags |= SOLDIER_VEHICLE; gpSelected->pSoldier->flags.uiStatusFlags |= SOLDIER_VEHICLE;
break; break;
} }
@@ -2503,6 +2504,7 @@ void DisplayBodyTypeInfo()
case AM_MONSTER: swprintf( str, pDisplayBodyTypeInfoText[25] ); break; case AM_MONSTER: swprintf( str, pDisplayBodyTypeInfoText[25] ); break;
case QUEENMONSTER: swprintf( str, pDisplayBodyTypeInfoText[26] ); break; case QUEENMONSTER: swprintf( str, pDisplayBodyTypeInfoText[26] ); break;
case BLOODCAT: swprintf( str, pDisplayBodyTypeInfoText[27] ); break; case BLOODCAT: swprintf( str, pDisplayBodyTypeInfoText[27] ); break;
case COMBAT_JEEP: swprintf( str, pDisplayBodyTypeInfoText[28] ); break;
} }
DrawEditorInfoBox( str, FONT10ARIAL, iScreenWidthOffset + 490, 2 * iScreenHeightOffset + 364, 70, 20 ); DrawEditorInfoBox( str, FONT10ARIAL, iScreenWidthOffset + 490, 2 * iScreenHeightOffset + 364, 70, 20 );
} }
+16 -6
View File
@@ -1377,6 +1377,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.fAllowTanksDrivingOverPeople = iniReader.ReadBoolean("Tactical Gameplay Settings","ALLOW_TANKS_DRIVING_OVER_PEOPLE", TRUE); gGameExternalOptions.fAllowTanksDrivingOverPeople = iniReader.ReadBoolean("Tactical Gameplay Settings","ALLOW_TANKS_DRIVING_OVER_PEOPLE", TRUE);
gGameExternalOptions.ubCarsRammingMaxStructureArmour = iniReader.ReadInteger("Tactical Gameplay Settings","CARS_RAMMING_MAX_STRUCTURE_ARMOUR", 30, 0, 255); gGameExternalOptions.ubCarsRammingMaxStructureArmour = iniReader.ReadInteger("Tactical Gameplay Settings","CARS_RAMMING_MAX_STRUCTURE_ARMOUR", 30, 0, 255);
gGameExternalOptions.ubEnemyJeepsRammingMaxStructureArmour = iniReader.ReadInteger( "Tactical Gameplay Settings", "ENEMY_JEEP_RAMMING_MAX_STRUCTURE_ARMOUR", 38, 0, 255 );
gGameExternalOptions.ubTanksRammingMaxStructureArmour = iniReader.ReadInteger("Tactical Gameplay Settings","TANKS_RAMMING_MAX_STRUCTURE_ARMOUR", 70, 0, 255); gGameExternalOptions.ubTanksRammingMaxStructureArmour = iniReader.ReadInteger("Tactical Gameplay Settings","TANKS_RAMMING_MAX_STRUCTURE_ARMOUR", 70, 0, 255);
gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleMode = iniReader.ReadInteger("Tactical Gameplay Settings","AP_SHARED_AMONG_PASSENGERS_AND_VEHICLE_MODE", 3, 0, 3); gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleMode = iniReader.ReadInteger("Tactical Gameplay Settings","AP_SHARED_AMONG_PASSENGERS_AND_VEHICLE_MODE", 3, 0, 3);
@@ -1973,15 +1974,21 @@ void LoadGameExternalOptions()
gGameExternalOptions.gASDResource_Cost[ASD_MONEY] = 1; gGameExternalOptions.gASDResource_Cost[ASD_MONEY] = 1;
gGameExternalOptions.gASDResource_Cost[ASD_FUEL] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_FUEL", 10, 1, 100 ); gGameExternalOptions.gASDResource_Cost[ASD_FUEL] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_FUEL", 10, 1, 100 );
gGameExternalOptions.gASDResource_Cost[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_HELI", 100000, 10000, 1000000 ); gGameExternalOptions.gASDResource_Cost[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_HELI", 30000, 1, 1000000 );
gGameExternalOptions.gASDResource_Cost[ASD_JEEP] = 50000; gGameExternalOptions.gASDResource_Cost[ASD_JEEP] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_JEEP", 20000, 1, 1000000 );
gGameExternalOptions.gASDResource_Cost[ASD_TANK] = 200000; gGameExternalOptions.gASDResource_Cost[ASD_TANK] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_TANK", 50000, 1, 1000000 );
gGameExternalOptions.gASDResource_BuyTime[ASD_MONEY] = 0; gGameExternalOptions.gASDResource_BuyTime[ASD_MONEY] = 0;
gGameExternalOptions.gASDResource_BuyTime[ASD_FUEL] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_FUEL", 60 * 8, 1, 60 * 48 ); gGameExternalOptions.gASDResource_BuyTime[ASD_FUEL] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_FUEL", 60 * 8, 1, 60 * 48 );
gGameExternalOptions.gASDResource_BuyTime[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_HELI", 60 * 20, 1, 60 * 48 ); gGameExternalOptions.gASDResource_BuyTime[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_HELI", 60 * 20, 1, 60 * 48 );
gGameExternalOptions.gASDResource_BuyTime[ASD_JEEP] = 60 * 12; gGameExternalOptions.gASDResource_BuyTime[ASD_JEEP] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_JEEP", 60 * 12, 1, 60 * 48 );
gGameExternalOptions.gASDResource_BuyTime[ASD_TANK] = 60 * 24; gGameExternalOptions.gASDResource_BuyTime[ASD_TANK] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_TANK", 60 * 24, 1, 60 * 48 );
gGameExternalOptions.fASDAssignsTanks = iniReader.ReadBoolean( "Strategic Additional Enemy AI Settings", "ASD_ASSIGNS_TANKS", TRUE );
gGameExternalOptions.fASDAssignsJeeps = iniReader.ReadBoolean( "Strategic Additional Enemy AI Settings", "ASD_ASSIGNS_JEEPS", TRUE );
gGameExternalOptions.gASDResource_Fuel_Tank = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_FUEL_REQUIRED_TANK", 100, 0, 10000 );
gGameExternalOptions.gASDResource_Fuel_Jeep = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_FUEL_REQUIRED_JEEP", 20, 0, 10000 );
// Flugente: enemy heli // Flugente: enemy heli
//################# Enemy Helicopter Settings ################## //################# Enemy Helicopter Settings ##################
@@ -2236,8 +2243,11 @@ void LoadGameExternalOptions()
gGameExternalOptions.fArmyUsesTanksInAttacks = iniReader.ReadBoolean("Strategic Gameplay Settings","ARMY_USES_TANKS_IN_ATTACKS", FALSE); gGameExternalOptions.fArmyUsesTanksInAttacks = iniReader.ReadBoolean("Strategic Gameplay Settings","ARMY_USES_TANKS_IN_ATTACKS", FALSE);
gGameExternalOptions.fArmyUsesTanksInPatrols = iniReader.ReadBoolean("Strategic Gameplay Settings","ARMY_USES_TANKS_IN_PATROLS", FALSE); gGameExternalOptions.fArmyUsesTanksInPatrols = iniReader.ReadBoolean("Strategic Gameplay Settings","ARMY_USES_TANKS_IN_PATROLS", FALSE);
gGameExternalOptions.usTankMinimumProgress = iniReader.ReadInteger("Strategic Gameplay Settings","TANK_MINIMUM_PROGRESS", 0, 0, 100); gGameExternalOptions.usTankMinimumProgress = iniReader.ReadInteger("Strategic Gameplay Settings","TANK_MINIMUM_PROGRESS", 60, 0, 100);
gGameExternalOptions.fArmyUsesJeepsInAttacks = iniReader.ReadBoolean( "Strategic Gameplay Settings", "ARMY_USES_JEEPS_IN_ATTACKS", FALSE );
gGameExternalOptions.fArmyUsesJeepsInPatrols = iniReader.ReadBoolean( "Strategic Gameplay Settings", "ARMY_USES_JEEPS_IN_PATROLS", FALSE );
gGameExternalOptions.usJeepMinimumProgress = iniReader.ReadInteger( "Strategic Gameplay Settings", "JEEP_MINIMUM_PROGRESS", 30, 0, 100 );
// WANNE: This is just a debug setting. Only in debug version we set that property to TRUE. // WANNE: This is just a debug setting. Only in debug version we set that property to TRUE.
// In Release version this should always be set to FALSE // In Release version this should always be set to FALSE
+11
View File
@@ -616,6 +616,12 @@ typedef struct
INT32 gASDResource_Cost[ASD_RESOURCE_MAX]; INT32 gASDResource_Cost[ASD_RESOURCE_MAX];
INT32 gASDResource_BuyTime[ASD_RESOURCE_MAX]; INT32 gASDResource_BuyTime[ASD_RESOURCE_MAX];
BOOLEAN fASDAssignsTanks;
BOOLEAN fASDAssignsJeeps;
INT32 gASDResource_Fuel_Tank;
INT32 gASDResource_Fuel_Jeep;
// Flugente: enemy heli // Flugente: enemy heli
BOOLEAN fEnemyHeliActive; BOOLEAN fEnemyHeliActive;
UINT8 usEnemyHeliMinimumProgress; UINT8 usEnemyHeliMinimumProgress;
@@ -831,6 +837,10 @@ typedef struct
BOOLEAN fArmyUsesTanksInPatrols; BOOLEAN fArmyUsesTanksInPatrols;
UINT8 usTankMinimumProgress; UINT8 usTankMinimumProgress;
BOOLEAN fArmyUsesJeepsInAttacks;
BOOLEAN fArmyUsesJeepsInPatrols;
UINT8 usJeepMinimumProgress;
// WANNE: Always use "prof.dat". // WANNE: Always use "prof.dat".
BOOLEAN fUseDifficultyBasedProfDat; BOOLEAN fUseDifficultyBasedProfDat;
@@ -1460,6 +1470,7 @@ typedef struct
BOOLEAN fAllowTanksDrivingOverPeople; BOOLEAN fAllowTanksDrivingOverPeople;
UINT8 ubCarsRammingMaxStructureArmour; UINT8 ubCarsRammingMaxStructureArmour;
UINT8 ubEnemyJeepsRammingMaxStructureArmour;
UINT8 ubTanksRammingMaxStructureArmour; UINT8 ubTanksRammingMaxStructureArmour;
UINT8 ubAPSharedAmongPassengersAndVehicleMode; UINT8 ubAPSharedAmongPassengersAndVehicleMode;
+9 -9
View File
@@ -15,9 +15,9 @@
#ifdef JA2EDITOR #ifdef JA2EDITOR
#ifdef JA2UB #ifdef JA2UB
CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.8113 (Development Build)" };
#else #else
CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.8113 (Development Build)" };
#endif #endif
// ------------------------------ // ------------------------------
@@ -27,11 +27,11 @@
//DEBUG BUILD VERSION //DEBUG BUILD VERSION
#ifdef JA2UB #ifdef JA2UB
CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.8113 (Development Build)" };
#elif defined (JA113DEMO) #elif defined (JA113DEMO)
CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.8113 (Development Build)" };
#else #else
CHAR16 zVersionLabel[256] = { L"Debug: v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Debug: v1.13.8113 (Development Build)" };
#endif #endif
#elif defined CRIPPLED_VERSION #elif defined CRIPPLED_VERSION
@@ -46,16 +46,16 @@
//RELEASE BUILD VERSION //RELEASE BUILD VERSION
#ifdef JA2UB #ifdef JA2UB
CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.8113 (Development Build)" };
#elif defined (JA113DEMO) #elif defined (JA113DEMO)
CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.8113 (Development Build)" };
#else #else
CHAR16 zVersionLabel[256] = { L"Release v1.13.8105 (Development Build)" }; CHAR16 zVersionLabel[256] = { L"Release v1.13.8113 (Development Build)" };
#endif #endif
#endif #endif
CHAR8 czVersionNumber[16] = { "Build 16.03.12" }; //YY.MM.DD CHAR8 czVersionNumber[16] = { "Build 16.03.20" }; //YY.MM.DD
CHAR16 zTrackingNumber[16] = { L"Z" }; CHAR16 zTrackingNumber[16] = { L"Z" };
// SAVE_GAME_VERSION is defined in header, change it there // SAVE_GAME_VERSION is defined in header, change it there
+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 ENEMY_JEEPS 165 // Flugente: enemy jeeps
#define ENEMY_HELICOPTERS 164 // Flugente: enemy helicopters #define ENEMY_HELICOPTERS 164 // Flugente: enemy helicopters
#define DRUG_SYSTEM_REDONE 163 // Flugente: reworked the drug system #define DRUG_SYSTEM_REDONE 163 // Flugente: reworked the drug system
#define MILITIA_PATH_PLOTTING 162 // Flugente: the player can plot militia paths in strategic, similar to player or helicopter travel #define MILITIA_PATH_PLOTTING 162 // Flugente: the player can plot militia paths in strategic, similar to player or helicopter travel
@@ -83,7 +84,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 ENEMY_HELICOPTERS #define SAVE_GAME_VERSION ENEMY_JEEPS
//#define RUSSIANGOLD //#define RUSSIANGOLD
#ifdef __cplusplus #ifdef __cplusplus
+3 -1
View File
@@ -84,9 +84,10 @@
#include "AimArchives.h" #include "AimArchives.h"
#include "connect.h" #include "connect.h"
#include "DynamicDialogueWidget.h" // added by Flugente for InitMyBoxes() #include "DynamicDialogueWidget.h" // added by Flugente for InitMyBoxes()
#include "Animation Data.h" // added by Flugente
extern INT16 APBPConstants[TOTAL_APBP_VALUES] = {0}; extern INT16 APBPConstants[TOTAL_APBP_VALUES] = {0};
extern INT16 gubMaxActionPoints[28];//MAXBODYTYPES = 28... JUST GETTING IT TO WORK NOW. GOTTHARD 7/2/08 extern INT16 gubMaxActionPoints[TOTALBODYTYPES];//MAXBODYTYPES = 28... JUST GETTING IT TO WORK NOW. GOTTHARD 7/2/08
extern BOOLEAN GetCDromDriveLetter( STR8 pString ); extern BOOLEAN GetCDromDriveLetter( STR8 pString );
// The InitializeGame function is responsible for setting up all data and Gaming Engine // The InitializeGame function is responsible for setting up all data and Gaming Engine
@@ -1870,4 +1871,5 @@ void SetupMaxActionPointsAnimation()
gubMaxActionPoints[ELDORADO] = APBPConstants[AP_VEHICLE_MAXIMUM]; gubMaxActionPoints[ELDORADO] = APBPConstants[AP_VEHICLE_MAXIMUM];
gubMaxActionPoints[ICECREAMTRUCK] = APBPConstants[AP_VEHICLE_MAXIMUM]; gubMaxActionPoints[ICECREAMTRUCK] = APBPConstants[AP_VEHICLE_MAXIMUM];
gubMaxActionPoints[JEEP] = APBPConstants[AP_VEHICLE_MAXIMUM]; gubMaxActionPoints[JEEP] = APBPConstants[AP_VEHICLE_MAXIMUM];
gubMaxActionPoints[COMBAT_JEEP] = APBPConstants[AP_VEHICLE_MAXIMUM];
} }
+2 -2
View File
@@ -156,7 +156,7 @@ Incident_Stats::AddStat( SOLDIERTYPE* pSoldier, UINT8 aType )
case ENEMY_TEAM: case ENEMY_TEAM:
{ {
if ( TANK(pSoldier) ) if ( ARMED_VEHICLE( pSoldier ) )
group = CAMPAIGNHISTORY_SD_ENEMY_TANK; group = CAMPAIGNHISTORY_SD_ENEMY_TANK;
else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR ) else if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR )
group = CAMPAIGNHISTORY_SD_ENEMY_ADMIN; group = CAMPAIGNHISTORY_SD_ENEMY_ADMIN;
@@ -226,7 +226,7 @@ Incident_Stats::AddStat( SOLDIERTYPE* pSoldier, UINT8 aType )
break; break;
} }
if ( TANK(pSoldier) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
if ( pSoldier->bSide == 0 ) if ( pSoldier->bSide == 0 )
usIncidentFlags |= INCIDENT_TANKS_PLAYERSIDE; usIncidentFlags |= INCIDENT_TANKS_PLAYERSIDE;
+21 -17
View File
@@ -162,7 +162,7 @@ void ViewCreaturesCallback( GUI_BUTTON *btn, INT32 reason );
void ExtractAndUpdatePopulations(); void ExtractAndUpdatePopulations();
void PrintEnemyPopTable(); void PrintEnemyPopTable();
void PrintEnemiesKilledTable(); void PrintEnemiesKilledTable();
UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites, UINT8 ubTanks ); UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites, UINT8 ubTanks, UINT8 ubJeeps );
void BlitGroupIcon( UINT8 ubIconType, UINT8 ubIconColor, UINT32 uiX, UINT32 uiY, HVOBJECT hVObject ); void BlitGroupIcon( UINT8 ubIconType, UINT8 ubIconColor, UINT32 uiX, UINT32 uiY, HVOBJECT hVObject );
void PrintDetailedEnemiesInSectorInfo( INT32 iScreenX, INT32 iScreenY, UINT8 ubSectorX, UINT8 ubSectorY ); void PrintDetailedEnemiesInSectorInfo( INT32 iScreenX, INT32 iScreenY, UINT8 ubSectorX, UINT8 ubSectorY );
@@ -495,7 +495,7 @@ void RenderStationaryGroups()
else if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks ) else 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, pSector->ubNumJeeps );
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 )
@@ -541,14 +541,13 @@ void RenderMovingGroupsAndMercs()
GROUP *pGroup; GROUP *pGroup;
HVOBJECT hVObject; HVOBJECT hVObject;
INT32 x, y; INT32 x, y;
UINT8 ubNumTroops, ubNumAdmins, ubNumElites, ubNumTanks; UINT8 ubNumTroops, ubNumAdmins, ubNumElites, ubNumTanks, ubNumJeeps;
float ratio; float ratio;
INT32 minX, maxX, minY, maxY; INT32 minX, maxX, minY, maxY;
UINT8 ubIconType; UINT8 ubIconType;
UINT8 ubIconColor; UINT8 ubIconColor;
UINT8 ubFontColor; UINT8 ubFontColor;
SetFont( FONT10ARIAL ); SetFont( FONT10ARIAL );
SetFontShadow( FONT_NEARBLACK ); SetFontShadow( FONT_NEARBLACK );
@@ -597,12 +596,13 @@ void RenderMovingGroupsAndMercs()
ubNumTroops = pGroup->pEnemyGroup->ubNumTroops;//+ pGroup->pEnemyGroup->ubTroopsInBattle; ubNumTroops = pGroup->pEnemyGroup->ubNumTroops;//+ pGroup->pEnemyGroup->ubTroopsInBattle;
ubNumElites = pGroup->pEnemyGroup->ubNumElites;// + pGroup->pEnemyGroup->ubElitesInBattle; ubNumElites = pGroup->pEnemyGroup->ubNumElites;// + pGroup->pEnemyGroup->ubElitesInBattle;
ubNumTanks = pGroup->pEnemyGroup->ubNumTanks; ubNumTanks = pGroup->pEnemyGroup->ubNumTanks;
ubNumJeeps = pGroup->pEnemyGroup->ubNumJeeps;
// must have one of the three, already checked groupsize! // must have one of the three, already checked groupsize!
Assert( ubNumAdmins || ubNumTroops || ubNumElites || ubNumTanks ); Assert( ubNumAdmins || ubNumTroops || ubNumElites || ubNumTanks || ubNumJeeps );
//determine icon color //determine icon color
ubIconColor = ChooseEnemyIconColor( ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); ubIconColor = ChooseEnemyIconColor( ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
// must have a valid intention // must have a valid intention
Assert( pGroup->pEnemyGroup->ubIntention < NUM_ENEMY_INTENTIONS ); Assert( pGroup->pEnemyGroup->ubIntention < NUM_ENEMY_INTENTIONS );
@@ -727,7 +727,7 @@ void RenderInfoInSector()
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
UINT8 ubNumAdmins=0, ubNumTroops=0, ubNumElites=0, ubNumTanks=0, ubAdminsInBattle=0, ubTroopsInBattle=0, ubElitesInBattle=0, ubTanksInBattle=0, ubNumGroups=0; UINT8 ubNumAdmins = 0, ubNumTroops = 0, ubNumElites = 0, ubNumTanks = 0, ubNumJeeps = 0, ubAdminsInBattle = 0, ubTroopsInBattle = 0, ubElitesInBattle = 0, ubTanksInBattle = 0, ubJeepsInBattle = 0,ubNumGroups = 0;
pSector = &SectorInfo[ SECTOR( ubSectorX, ubSectorY ) ]; pSector = &SectorInfo[ SECTOR( ubSectorX, ubSectorY ) ];
@@ -741,10 +741,12 @@ void RenderInfoInSector()
ubNumElites += pGroup->pEnemyGroup->ubNumElites; ubNumElites += pGroup->pEnemyGroup->ubNumElites;
ubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins; ubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanks += pGroup->pEnemyGroup->ubNumTanks; ubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
ubNumJeeps += pGroup->pEnemyGroup->ubNumJeeps;
ubTroopsInBattle += pGroup->pEnemyGroup->ubTroopsInBattle; ubTroopsInBattle += pGroup->pEnemyGroup->ubTroopsInBattle;
ubElitesInBattle += pGroup->pEnemyGroup->ubElitesInBattle; ubElitesInBattle += pGroup->pEnemyGroup->ubElitesInBattle;
ubAdminsInBattle += pGroup->pEnemyGroup->ubAdminsInBattle; ubAdminsInBattle += pGroup->pEnemyGroup->ubAdminsInBattle;
ubTanksInBattle += pGroup->pEnemyGroup->ubTanksInBattle; ubTanksInBattle += pGroup->pEnemyGroup->ubTanksInBattle;
ubJeepsInBattle += pGroup->pEnemyGroup->ubJeepsInBattle;
ubNumGroups++; ubNumGroups++;
} }
pGroup = pGroup->next; pGroup = pGroup->next;
@@ -761,17 +763,19 @@ void RenderInfoInSector()
MilitiaInSectorOfRank( ubSectorX, ubSectorY, GREEN_MILITIA ), MilitiaInSectorOfRank( ubSectorX, ubSectorY, REGULAR_MILITIA ), MilitiaInSectorOfRank( ubSectorX, ubSectorY, ELITE_MILITIA ) ); 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, %d:%d Jeeps)",
pSector->ubAdminsInBattle, pSector->ubNumAdmins, pSector->ubAdminsInBattle, pSector->ubNumAdmins,
pSector->ubTroopsInBattle, pSector->ubNumTroops, pSector->ubTroopsInBattle, pSector->ubNumTroops,
pSector->ubElitesInBattle, pSector->ubNumElites, pSector->ubElitesInBattle, pSector->ubNumElites,
pSector->ubTanksInBattle, pSector->ubNumTanks ); pSector->ubTanksInBattle, pSector->ubNumTanks,
pSector->ubJeepsInBattle, pSector->ubNumJeeps );
yp += 10; yp += 10;
mprintf( 280, yp, L"%d Groups: (%d:%d Admins, %d:%d Troops, %d:%d Elites, %d:%d Tanks)", ubNumGroups, mprintf( 280, yp, L"%d Groups: (%d:%d Admins, %d:%d Troops, %d:%d Elites, %d:%d Tanks, %d:%d Jeeps)", ubNumGroups,
ubAdminsInBattle, ubNumAdmins, ubAdminsInBattle, ubNumAdmins,
ubTroopsInBattle, ubNumTroops, ubTroopsInBattle, ubNumTroops,
ubElitesInBattle, ubNumElites, ubElitesInBattle, ubNumElites,
ubTanksInBattle, ubNumTanks ); ubTanksInBattle, ubNumTanks,
ubJeepsInBattle, ubNumJeeps );
yp += 10; yp += 10;
SetFontForeground( FONT_WHITE ); SetFontForeground( FONT_WHITE );
@@ -1274,7 +1278,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
gfRenderViewer = TRUE; gfRenderViewer = TRUE;
if( gsSelSectorY > 1 ) if( gsSelSectorY > 1 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-16, 0, 11, 5, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-16, 0, 11, 5, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX; pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY; pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 10; pGroup->uiTraverseTime = 10;
@@ -1286,7 +1290,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
} }
if( gsSelSectorY < 16 ) if( gsSelSectorY < 16 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+16, 0, 8, 8, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+16, 0, 8, 8, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX; pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY; pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 12; pGroup->uiTraverseTime = 12;
@@ -1298,7 +1302,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
} }
if( gsSelSectorX > 1 ) if( gsSelSectorX > 1 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-1, 0, 11, 5, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-1, 0, 11, 5, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX; pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY; pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 11; pGroup->uiTraverseTime = 11;
@@ -1310,7 +1314,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
} }
if( gsSelSectorX < 16 ) if( gsSelSectorX < 16 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, 0, 14, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, 0, 14, 0, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX; pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY; pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 13; pGroup->uiTraverseTime = 13;
@@ -1833,7 +1837,7 @@ void PrintEnemiesKilledTable()
UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites, UINT8 ubTanks ) UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites, UINT8 ubTanks, UINT8 ubJeeps )
{ {
UINT8 ubIconColor; UINT8 ubIconColor;
@@ -1844,7 +1848,7 @@ UINT8 ChooseEnemyIconColor( UINT8 ubAdmins, UINT8 ubTroops, UINT8 ubElites, UINT
// Orange Mixed, no elites (Admins + Troops) // Orange Mixed, no elites (Admins + Troops)
// Burgundy Mixed, with elites (Elites + (Admins OR Troops)) // Burgundy Mixed, with elites (Elites + (Admins OR Troops))
Assert( ubAdmins || ubTroops || ubElites ||ubTanks ); Assert( ubAdmins || ubTroops || ubElites || ubTanks || ubJeeps );
if ( ubElites ) if ( ubElites )
{ {
+34 -10
View File
@@ -196,6 +196,13 @@ void UpdateASD( )
if ( !(gASD_Flags & ASDFACT_HELI_UNLOCKED) && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usEnemyHeliMinimumProgress ) if ( !(gASD_Flags & ASDFACT_HELI_UNLOCKED) && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usEnemyHeliMinimumProgress )
SetASDFlag( ASDFACT_HELI_UNLOCKED ); SetASDFlag( ASDFACT_HELI_UNLOCKED );
if ( !(gASD_Flags & ASDFACT_JEEP_UNLOCKED) && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usJeepMinimumProgress )
SetASDFlag( ASDFACT_JEEP_UNLOCKED );
if ( !(gASD_Flags & ASDFACT_TANK_UNLOCKED) && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usTankMinimumProgress )
SetASDFlag( ASDFACT_TANK_UNLOCKED );
// determine whether we need to buy new toys // determine whether we need to buy new toys
ASDDecideOnPurchases(); ASDDecideOnPurchases();
@@ -250,10 +257,10 @@ void ASDDecideOnPurchases()
// how many would we like to have? Note that this refers to the ones in our pool, the vehicles awarded to enemy groups are no longer accounted for // how many would we like to have? Note that this refers to the ones in our pool, the vehicles awarded to enemy groups are no longer accounted for
needed_jeep = min( 10, 2 + highestplayerprogress / 10 ); needed_jeep = min( 10, 2 + highestplayerprogress / 10 );
// if we already unlocked tanks, we want less jeeps // if we already unlocked tanks, we no longer want jeeps - they are replaced by tanks
if ( gASD_Flags & ASDFACT_TANK_UNLOCKED ) if ( gASD_Flags & ASDFACT_TANK_UNLOCKED )
{ {
needed_jeep = max( 4, 12 - highestplayerprogress / 10 ); needed_jeep = 0;
} }
// how many are needed? // how many are needed?
@@ -1411,20 +1418,16 @@ void UpdateAndDamageEnemyHeliIfFound( INT16 sSectorX, INT16 sSectorY, INT16 sSec
} }
//////////////////////////////////////////// enemy tanks ///////////////////////////////////////////////////////// //////////////////////////////////////////// enemy tanks /////////////////////////////////////////////////////////
// TODO: ini this
INT32 gASDResource_Cost_Fuel_Tank = 100; // how many units of fuel a tank needs (used upon creation)
INT32 gASDResource_Cost_Fuel_Jeep = 20;
UINT32 ASDResourceCostFuel( UINT8 aType ) UINT32 ASDResourceCostFuel( UINT8 aType )
{ {
switch ( aType ) switch ( aType )
{ {
case ASD_TANK: case ASD_TANK:
return gASDResource_Cost_Fuel_Tank; return gGameExternalOptions.gASDResource_Fuel_Tank;
break; break;
case ASD_JEEP: case ASD_JEEP:
return gASDResource_Cost_Fuel_Jeep; return gGameExternalOptions.gASDResource_Fuel_Jeep;
break; break;
} }
@@ -1434,8 +1437,7 @@ UINT32 ASDResourceCostFuel( UINT8 aType )
// if ASD has tanks, it can allow the queen to upgrade soldiers to tanks // if ASD has tanks, it can allow the queen to upgrade soldiers to tanks
BOOLEAN ASDSoldierUpgradeToTank( ) BOOLEAN ASDSoldierUpgradeToTank( )
{ {
// TODO: ini val for feature if ( gGameExternalOptions.fASDActive && gGameExternalOptions.fASDAssignsTanks )
if ( gGameExternalOptions.fASDActive && 0 )
{ {
if ( gASD_Flags & ASDFACT_TANK_UNLOCKED ) if ( gASD_Flags & ASDFACT_TANK_UNLOCKED )
{ {
@@ -1454,3 +1456,25 @@ BOOLEAN ASDSoldierUpgradeToTank( )
return FALSE; return FALSE;
} }
BOOLEAN ASDSoldierUpgradeToJeep( )
{
if ( gGameExternalOptions.fASDActive && gGameExternalOptions.fASDAssignsJeeps )
{
if ( gASD_Flags & ASDFACT_JEEP_UNLOCKED )
{
if ( gASDResource[ASD_JEEP] )
{
gASDResource[ASD_JEEP] = max( 0, gASDResource[ASD_JEEP] - 1 );
return TRUE;
}
}
}
else
{
gASDResource[ASD_JEEP] = max( 0, gASDResource[ASD_JEEP] - 1 );
return TRUE;
}
return FALSE;
}
+1
View File
@@ -118,5 +118,6 @@ UINT32 ASDResourceCostFuel( UINT8 aType );
// if ASD is used, any tanks the queen uses in mobile attacks come from its pool, and we have to account for that // if ASD is used, any tanks the queen uses in mobile attacks come from its pool, and we have to account for that
BOOLEAN ASDSoldierUpgradeToTank( ); BOOLEAN ASDSoldierUpgradeToTank( );
BOOLEAN ASDSoldierUpgradeToJeep( );
#endif //__ASD_H #endif //__ASD_H
+89 -36
View File
@@ -167,7 +167,7 @@ typedef struct AUTORESOLVE_STRUCT
UINT8 ubEnemyLeadership; UINT8 ubEnemyLeadership;
UINT8 ubPlayerLeadership; UINT8 ubPlayerLeadership;
UINT8 ubMercs, ubCivs, ubEnemies; UINT8 ubMercs, ubCivs, ubEnemies;
UINT8 ubAdmins, ubTroops, ubElites, ubTanks; UINT8 ubAdmins, ubTroops, ubElites, ubTanks, ubJeeps;
UINT8 ubYMCreatures, ubYFCreatures, ubAMCreatures, ubAFCreatures; UINT8 ubYMCreatures, ubYFCreatures, ubAMCreatures, ubAFCreatures;
UINT8 ubAliveMercs, ubAliveCivs, ubAliveEnemies; UINT8 ubAliveMercs, ubAliveCivs, ubAliveEnemies;
UINT8 ubMercCols, ubMercRows; UINT8 ubMercCols, ubMercRows;
@@ -228,10 +228,11 @@ typedef struct AUTORESOLVE_STRUCT
#define CELL_EPC 0x00100000 #define CELL_EPC 0x00100000
#define CELL_ROBOT 0x00200000 #define CELL_ROBOT 0x00200000
#define CELL_TANK 0x00400000 #define CELL_TANK 0x00400000
#define CELL_JEEP 0x00800000
//Combined flags //Combined flags
#define CELL_PLAYER ( CELL_MERC | CELL_MILITIA ) #define CELL_PLAYER ( CELL_MERC | CELL_MILITIA )
#define CELL_ENEMY ( CELL_ELITE | CELL_TROOP | CELL_ADMIN | CELL_TANK ) #define CELL_ENEMY ( CELL_ELITE | CELL_TROOP | CELL_ADMIN | CELL_TANK | CELL_JEEP )
#define CELL_CREATURE ( CELL_AF_CREATURE | CELL_AM_CREATURE | CELL_YF_CREATURE | CELL_YM_CREATURE ) #define CELL_CREATURE ( CELL_AF_CREATURE | CELL_AM_CREATURE | CELL_YF_CREATURE | CELL_YM_CREATURE )
#define CELL_FEMALECREATURE ( CELL_AF_CREATURE | CELL_YF_CREATURE ) #define CELL_FEMALECREATURE ( CELL_AF_CREATURE | CELL_YF_CREATURE )
#define CELL_MALECREATURE ( CELL_AM_CREATURE | CELL_YM_CREATURE ) #define CELL_MALECREATURE ( CELL_AM_CREATURE | CELL_YM_CREATURE )
@@ -290,6 +291,8 @@ enum
MILITIA1F_FACE, MILITIA1F_FACE,
MILITIA2F_FACE, MILITIA2F_FACE,
MILITIA3F_FACE, MILITIA3F_FACE,
JEEP_FACE,
JEEP_WRECK,
}; };
extern void CreateDestroyMapInvButton(); extern void CreateDestroyMapInvButton();
@@ -434,6 +437,8 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
SECTORINFO *pSector; SECTORINFO *pSector;
INT32 i; INT32 i;
UINT8 ubNumEnemies[ NUM_ENEMY_RANKS ]; UINT8 ubNumEnemies[ NUM_ENEMY_RANKS ];
UINT8 ubNumTanks = 0;
UINT8 ubNumJeeps = 0;
UINT8 ubRankIndex; UINT8 ubRankIndex;
//Clear any possible battle locator //Clear any possible battle locator
@@ -442,13 +447,11 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
pGroup = gpGroupList; pGroup = gpGroupList;
pSector = &SectorInfo[ SECTOR( ubSectorX, ubSectorY ) ]; pSector = &SectorInfo[ SECTOR( ubSectorX, ubSectorY ) ];
UINT8 ubNumTanks = 0;
// if we're doing this from the Pre-Battle interface, gpAR is NULL, and RemoveAutoResolveInterface(0 won't happen, so // if we're doing this from the Pre-Battle interface, gpAR is NULL, and RemoveAutoResolveInterface(0 won't happen, so
// we must process the enemies killed right here & give out loyalty bonuses as if the battle had been fought & won // we must process the enemies killed right here & give out loyalty bonuses as if the battle had been fought & won
if( !gpAR ) if( !gpAR )
{ {
GetNumberOfEnemiesInSector( ubSectorX, ubSectorY, &ubNumEnemies[ 0 ], &ubNumEnemies[ 1 ], &ubNumEnemies[ 2 ], &ubNumTanks ); GetNumberOfEnemiesInSector( ubSectorX, ubSectorY, &ubNumEnemies[0], &ubNumEnemies[1], &ubNumEnemies[2], &ubNumTanks, &ubNumJeeps );
for ( ubRankIndex = 0; ubRankIndex < NUM_ENEMY_RANKS; ++ubRankIndex ) for ( ubRankIndex = 0; ubRankIndex < NUM_ENEMY_RANKS; ++ubRankIndex )
{ {
@@ -479,6 +482,7 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
pSector->ubNumElites = 0; pSector->ubNumElites = 0;
pSector->ubNumAdmins = 0; pSector->ubNumAdmins = 0;
pSector->ubNumTanks = 0; pSector->ubNumTanks = 0;
pSector->ubNumJeeps = 0;
pSector->ubNumCreatures = 0; pSector->ubNumCreatures = 0;
pSector->bLastKnownEnemies = 0; pSector->bLastKnownEnemies = 0;
//Remove the mobile forces here, but only if battle is over. //Remove the mobile forces here, but only if battle is over.
@@ -764,9 +768,9 @@ void AssociateEnemiesWithStrategicGroups()
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; //how many soldiers of the type do we still have to assign to a group? UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps; //how many soldiers of the type do we still have to assign to a group?
UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites, ubISNumTanks; UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites, ubISNumTanks, ubISNumJeeps;
UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup, ubNumTanksInGroup; UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup, ubNumTanksInGroup, ubNumJeepsInGroup;
INT32 i; INT32 i;
UINT8 pSectors[4]; UINT8 pSectors[4];
UINT8 ubDirAmount; UINT8 ubDirAmount;
@@ -782,6 +786,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumTroops = pSector->ubNumTroops; ubNumTroops = pSector->ubNumTroops;
ubNumElites = pSector->ubNumElites; ubNumElites = pSector->ubNumElites;
ubNumTanks = pSector->ubNumTanks; ubNumTanks = pSector->ubNumTanks;
ubNumJeeps = pSector->ubNumJeeps;
//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 - first assign enemies from those stationary groups //Stationary groups have a group ID of 0 - first assign enemies from those stationary groups
@@ -793,6 +798,12 @@ void AssociateEnemiesWithStrategicGroups()
gpEnemies[i].uiFlags |= CELL_ASSIGNED; gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumTanks--; ubNumTanks--;
} }
else if ( gpEnemies[i].uiFlags & CELL_JEEP && ubNumJeeps )
{
gpEnemies[i].pSoldier->ubGroupID = 0;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumJeeps--;
}
else if ( gpEnemies[i].uiFlags & CELL_ELITE && ubNumElites ) else if ( gpEnemies[i].uiFlags & CELL_ELITE && ubNumElites )
{ {
gpEnemies[ i ].pSoldier->ubGroupID = 0; gpEnemies[ i ].pSoldier->ubGroupID = 0;
@@ -817,8 +828,9 @@ void AssociateEnemiesWithStrategicGroups()
ubNumTroops = gpAR->ubTroops - pSector->ubNumTroops; ubNumTroops = gpAR->ubTroops - pSector->ubNumTroops;
ubNumElites = gpAR->ubElites - pSector->ubNumElites; ubNumElites = gpAR->ubElites - pSector->ubNumElites;
ubNumTanks = gpAR->ubTanks - pSector->ubNumTanks; ubNumTanks = gpAR->ubTanks - pSector->ubNumTanks;
ubNumJeeps = gpAR->ubJeeps - pSector->ubNumJeeps;
if( !ubNumElites && !ubNumTroops && !ubNumAdmins && !ubNumTanks ) if ( !ubNumElites && !ubNumTroops && !ubNumAdmins && !ubNumTanks && !ubNumJeeps )
{ //All troops accounted for. { //All troops accounted for.
return; return;
} }
@@ -833,6 +845,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops; ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops;
ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins; ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks; ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks;
ubNumJeepsInGroup = pGroup->pEnemyGroup->ubNumJeeps;
for( i = 0; i < gpAR->ubEnemies; i++ ) for( i = 0; i < gpAR->ubEnemies; i++ )
{ {
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) //has this soldier already been assigned to a cell and therefore a group (while processing the static enemies above) ? if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) //has this soldier already been assigned to a cell and therefore a group (while processing the static enemies above) ?
@@ -844,6 +857,13 @@ void AssociateEnemiesWithStrategicGroups()
ubNumTanks--; ubNumTanks--;
ubNumTanksInGroup--; ubNumTanksInGroup--;
} }
else if ( ubNumJeeps && ubNumJeepsInGroup && gpEnemies[i].uiFlags & CELL_JEEP )
{
gpEnemies[i].pSoldier->ubGroupID = pGroup->ubGroupID;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumJeeps--;
ubNumJeepsInGroup--;
}
else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE) else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE)
{ {
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
@@ -883,6 +903,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops; ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops;
ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins; ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks; ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks;
ubNumJeepsInGroup = pGroup->pEnemyGroup->ubNumJeeps;
for( i = 0; i < gpAR->ubEnemies; i++ ) for( i = 0; i < gpAR->ubEnemies; i++ )
{ {
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
@@ -894,6 +915,13 @@ void AssociateEnemiesWithStrategicGroups()
ubNumTanks--; ubNumTanks--;
ubNumTanksInGroup--; ubNumTanksInGroup--;
} }
else if ( ubNumJeeps && ubNumJeepsInGroup && gpEnemies[i].uiFlags & CELL_JEEP )
{
gpEnemies[i].pSoldier->ubGroupID = pGroup->ubGroupID;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumJeeps--;
ubNumJeepsInGroup--;
}
else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE) else if (ubNumElites && ubNumElitesInGroup && gpEnemies[i].uiFlags & CELL_ELITE)
{ {
gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID;
@@ -932,10 +960,11 @@ void AssociateEnemiesWithStrategicGroups()
ubISNumTroops = pSector->ubNumTroops; ubISNumTroops = pSector->ubNumTroops;
ubISNumElites = pSector->ubNumElites; ubISNumElites = pSector->ubNumElites;
ubISNumTanks = pSector->ubNumTanks; ubISNumTanks = pSector->ubNumTanks;
ubISNumJeeps = pSector->ubNumJeeps;
for( i = 0; i < gpAR->ubEnemies; ++i ) for( i = 0; i < gpAR->ubEnemies; ++i )
{ {
if( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks <= gubReinforcementMinEnemyStaticGroupSize ) break; //if group would be left understaffed, it wont reinforce - go chceck another sector (what if are there more groups here?) if ( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks + ubISNumJeeps <= gubReinforcementMinEnemyStaticGroupSize ) break; //if group would be left understaffed, it wont reinforce - go chceck another sector (what if are there more groups here?)
if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) )
{ {
@@ -948,6 +977,15 @@ void AssociateEnemiesWithStrategicGroups()
ubISNumTanks--; ubISNumTanks--;
ubNumTanks--; ubNumTanks--;
} }
else if ( gpEnemies[i].uiFlags & CELL_JEEP && ubISNumJeeps && ubNumJeeps )
{
gpEnemies[i].pSoldier->ubGroupID = 0;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
gpEnemies[i].pSoldier->sSectorX = SECTORX( pSectors[ubCurrSI] );
gpEnemies[i].pSoldier->sSectorY = SECTORY( pSectors[ubCurrSI] );
ubISNumJeeps--;
ubNumJeeps--;
}
else if ( gpEnemies[i].uiFlags & CELL_ELITE && ubISNumElites && ubNumElites ) else if ( gpEnemies[i].uiFlags & CELL_ELITE && ubISNumElites && ubNumElites )
{ {
gpEnemies[ i ].pSoldier->ubGroupID = 0; gpEnemies[ i ].pSoldier->ubGroupID = 0;
@@ -980,7 +1018,7 @@ void AssociateEnemiesWithStrategicGroups()
} }
/*at this point, all enemies should have been assigned to their cell and group. If not, there is a bug around /*at this point, all enemies should have been assigned to their cell and group. If not, there is a bug around
Because number and type of cells should be computed for the same composition of enemies as the one we see in this function, it should not happen though*/ Because number and type of cells should be computed for the same composition of enemies as the one we see in this function, it should not happen though*/
AssertMsg(!(ubISNumAdmins & ubISNumTroops & ubISNumElites & ubISNumTanks), "Mapping between actual enemies and autoresolve cells is wrong."); AssertMsg( !(ubISNumAdmins & ubISNumTroops & ubISNumElites & ubISNumTanks & ubISNumJeeps), "Mapping between actual enemies and autoresolve cells is wrong." );
} }
@@ -1090,14 +1128,16 @@ void CalculateSoldierCells( BOOLEAN fReset )
if( gubEnemyEncounterCode != CREATURE_ATTACK_CODE ) if( gubEnemyEncounterCode != CREATURE_ATTACK_CODE )
{ {
if ( index < gpAR->ubTanks ) if ( index < gpAR->ubElites )
gpEnemies[index].uiFlags = CELL_TANK; gpEnemies[index].uiFlags = CELL_ELITE;
else if ( index < gpAR->ubTanks + gpAR->ubElites ) else if ( index < gpAR->ubElites + gpAR->ubTroops )
gpEnemies[ index ].uiFlags = CELL_ELITE; gpEnemies[index].uiFlags = CELL_TROOP;
else if ( index < gpAR->ubTanks + gpAR->ubElites + gpAR->ubTroops ) else if ( index < gpAR->ubElites + gpAR->ubTroops + gpAR->ubAdmins )
gpEnemies[ index ].uiFlags = CELL_TROOP;
else
gpEnemies[index].uiFlags = CELL_ADMIN; gpEnemies[index].uiFlags = CELL_ADMIN;
else if ( index < gpAR->ubElites + gpAR->ubTroops + gpAR->ubAdmins + gpAR->ubTanks )
gpEnemies[index].uiFlags = CELL_TANK;
else
gpEnemies[index].uiFlags = CELL_JEEP;
} }
else else
{ {
@@ -1177,6 +1217,8 @@ void RenderSoldierCell( SOLDIERCELL *pCell )
BltVideoObjectFromIndex( FRAME_BUFFER, gpAR->iFaces, CREATURE_SKULL, pCell->xp + 3 + x, pCell->yp + 3, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObjectFromIndex( FRAME_BUFFER, gpAR->iFaces, CREATURE_SKULL, pCell->xp + 3 + x, pCell->yp + 3, VO_BLT_SRCTRANSPARENCY, NULL );
else if ( (pCell->uiFlags & CELL_TANK) ) else if ( (pCell->uiFlags & CELL_TANK) )
BltVideoObjectFromIndex( FRAME_BUFFER, gpAR->iFaces, TANK_WRECK, pCell->xp + 3 + x, pCell->yp + 3, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObjectFromIndex( FRAME_BUFFER, gpAR->iFaces, TANK_WRECK, pCell->xp + 3 + x, pCell->yp + 3, VO_BLT_SRCTRANSPARENCY, NULL );
else if ( (pCell->uiFlags & CELL_JEEP) )
BltVideoObjectFromIndex( FRAME_BUFFER, gpAR->iFaces, JEEP_WRECK, pCell->xp + 3 + x, pCell->yp + 3, VO_BLT_SRCTRANSPARENCY, NULL );
else else
BltVideoObjectFromIndex( FRAME_BUFFER, gpAR->iFaces, HUMAN_SKULL, pCell->xp+3+x, pCell->yp+3, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObjectFromIndex( FRAME_BUFFER, gpAR->iFaces, HUMAN_SKULL, pCell->xp+3+x, pCell->yp+3, VO_BLT_SRCTRANSPARENCY, NULL );
} }
@@ -2182,6 +2224,7 @@ void CreateAutoResolveInterface()
gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY; gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY;
swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[ STR_AR_ADMINISTRATOR_NAME ] ); swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[ STR_AR_ADMINISTRATOR_NAME ] );
} }
for ( i = 0; i < gpAR->ubTanks; ++i, ++index ) for ( i = 0; i < gpAR->ubTanks; ++i, ++index )
{ {
gpEnemies[index].pSoldier = TacticalCreateEnemyTank(); gpEnemies[index].pSoldier = TacticalCreateEnemyTank();
@@ -2191,6 +2234,17 @@ void CreateAutoResolveInterface()
gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY; gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY;
swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[STR_AR_TANK_NAME] ); swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[STR_AR_TANK_NAME] );
} }
for ( i = 0; i < gpAR->ubJeeps; ++i, ++index )
{
gpEnemies[index].pSoldier = TacticalCreateEnemyJeep( );
gpEnemies[index].uiVObjectID = gpAR->iFaces;
gpEnemies[index].usIndex = JEEP_FACE;
gpEnemies[index].pSoldier->sSectorX = gpAR->ubSectorX;
gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY;
swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[STR_AR_JEEP_NAME] );
}
AssociateEnemiesWithStrategicGroups(); AssociateEnemiesWithStrategicGroups();
} }
else else
@@ -2900,8 +2954,8 @@ void CalculateAutoResolveInfo()
{ {
// GetNumberOfEnemiesInSector( gpAR->ubSectorX, gpAR->ubSectorY, // GetNumberOfEnemiesInSector( gpAR->ubSectorX, gpAR->ubSectorY,
GetNumberOfEnemiesInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY, GetNumberOfEnemiesInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY,
&gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites, &gpAR->ubTanks ); &gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites, &gpAR->ubTanks, &gpAR->ubJeeps );
gpAR->ubEnemies = (UINT8)min( gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubElites + gpAR->ubTanks, MAX_AR_TEAM_SIZE ); gpAR->ubEnemies = (UINT8)min( gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubElites + gpAR->ubTanks + gpAR->ubJeeps, MAX_AR_TEAM_SIZE );
} }
else else
{ {
@@ -2987,20 +3041,22 @@ void ResetAutoResolveInterface()
//Make sure the number of enemy portraits is the same as needed. //Make sure the number of enemy portraits is the same as needed.
//The debug keypresses may add or remove more than one at a time. //The debug keypresses may add or remove more than one at a time.
while ( gpAR->ubElites + gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubTanks > gpAR->ubEnemies ) while ( gpAR->ubElites + gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubTanks + gpAR->ubJeeps > gpAR->ubEnemies )
{ {
switch( PreRandom( 5 ) ) switch( PreRandom( 5 ) )
{ {
case 0: if( gpAR->ubElites ) { gpAR->ubElites--; break; } case 0: if ( gpAR->ubElites ) { gpAR->ubElites--; break; }
case 1: case 2: if( gpAR->ubAdmins ) { gpAR->ubAdmins--; break; } case 1: if ( gpAR->ubAdmins ) { gpAR->ubAdmins--; break; }
case 3: case 4: if( gpAR->ubTroops ) { gpAR->ubTroops--; break; } case 2: if ( gpAR->ubTroops ) { gpAR->ubTroops--; break; }
case 3: if ( gpAR->ubTanks ) { gpAR->ubTanks--; break; }
case 4: if ( gpAR->ubJeeps ) { gpAR->ubJeeps--; break; }
} }
} }
while ( gpAR->ubElites + gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubTanks < gpAR->ubEnemies ) while ( gpAR->ubElites + gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubTanks + gpAR->ubJeeps< gpAR->ubEnemies )
{ {
switch( PreRandom( 5 ) ) switch( PreRandom( 5 ) )
{ {
case 0: gpAR->ubElites++; break; case 0: gpAR->ubElites++; break;
case 1: case 2: gpAR->ubAdmins++; break; case 1: case 2: gpAR->ubAdmins++; break;
case 3: case 4: gpAR->ubTroops++; break; case 3: case 4: gpAR->ubTroops++; break;
} }
@@ -4066,7 +4122,7 @@ BOOLEAN FireTankCannon( SOLDIERCELL *pAttacker )
pSoldier = pAttacker->pSoldier; pSoldier = pAttacker->pSoldier;
// we need to be a tank to do this... // we need to be a tank to do this...
if ( !pSoldier || (pAttacker->uiFlags & CELL_TANK) == 0 || pSoldier->ubSoldierClass != SOLDIER_CLASS_TANK ) if ( !pSoldier || (pAttacker->uiFlags & CELL_TANK) == 0 || pSoldier->ubSoldierClass != SOLDIER_CLASS_TANK || COMBAT_JEEP( pSoldier ) )
return FALSE; return FALSE;
// a tank has several guns, don't fire the main gun all the time // a tank has several guns, don't fire the main gun all the time
@@ -4296,7 +4352,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
usAttack *= 1.5; usAttack *= 1.5;
} }
// if our target is a tank, we use heavy weapons if we have any // if our target is a tank, we use heavy weapons if we have any
else if ( TANK( pTarget->pSoldier ) && FireAntiTankWeapon( pAttacker ) ) else if ( ARMED_VEHICLE( pTarget->pSoldier ) && FireAntiTankWeapon( pAttacker ) )
{ {
fAntiTank = TRUE; fAntiTank = TRUE;
@@ -4454,10 +4510,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
UINT8 ubAmmoType = Magazine[Item[(&pAttacker->pSoldier->inv[pAttacker->bWeaponSlot])->usItem].ubClassIndex].ubAmmoType; UINT8 ubAmmoType = Magazine[Item[(&pAttacker->pSoldier->inv[pAttacker->bWeaponSlot])->usItem].ubClassIndex].ubAmmoType;
if ( AmmoTypes[ubAmmoType].antiTank ) ubImpact *= AmmoTypes[ubAmmoType].dDamageModifierTank;
{
ubImpact *= 2;
}
iRandom = Random( 100 ); iRandom = Random( 100 );
if ( iRandom < 15 ) if ( iRandom < 15 )
@@ -4646,7 +4699,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
default : default :
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) ) if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++; gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++;
else if ( TANK( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows.. else if ( ARMED_VEHICLE( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows..
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsTanks++; gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsTanks++;
else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum ) else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum )
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsHostiles++; gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsHostiles++;
@@ -4794,7 +4847,7 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
} }
//bullet hit -- play an impact sound and a merc hit sound //bullet hit -- play an impact sound and a merc hit sound
if ( TANK( pTarget->pSoldier ) ) if ( ARMED_VEHICLE( pTarget->pSoldier ) )
PlayAutoResolveSample( (UINT8)(S_METAL_IMPACT1 + PreRandom( 3 )), RATE_11025, 50, 1, MIDDLEPAN ); PlayAutoResolveSample( (UINT8)(S_METAL_IMPACT1 + PreRandom( 3 )), RATE_11025, 50, 1, MIDDLEPAN );
else else
PlayAutoResolveSample( (UINT8)(BULLET_IMPACT_1+PreRandom(3)), RATE_11025, 50, 1, MIDDLEPAN ); PlayAutoResolveSample( (UINT8)(BULLET_IMPACT_1+PreRandom(3)), RATE_11025, 50, 1, MIDDLEPAN );
@@ -4860,7 +4913,7 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
default : default :
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) ) if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++; gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++;
else if ( TANK( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows.. else if ( ARMED_VEHICLE( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows..
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsTanks++; gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsTanks++;
else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum ) else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum )
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsHostiles++; gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsHostiles++;
@@ -4949,7 +5002,7 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
{ //Normal death { //Normal death
if( gpAR->fSound ) if( gpAR->fSound )
{ {
if ( TANK( pTarget->pSoldier ) ) if ( ARMED_VEHICLE( pTarget->pSoldier ) )
PlayAutoResolveSample( (UINT8)(S_RAID_TB_BOMB), RATE_11025, 50, 1, MIDDLEPAN ); PlayAutoResolveSample( (UINT8)(S_RAID_TB_BOMB), RATE_11025, 50, 1, MIDDLEPAN );
else else
pTarget->pSoldier->DoMercBattleSound( BATTLE_SOUND_DIE1 ); pTarget->pSoldier->DoMercBattleSound( BATTLE_SOUND_DIE1 );
+6 -6
View File
@@ -339,25 +339,25 @@ void GeneratePatrolGroups()
GROUP *pGroup; GROUP *pGroup;
UINT8 ubNumTroops; UINT8 ubNumTroops;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 )); ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_C7, 0, ubNumTroops, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_C7, 0, ubNumTroops, 0, 0, 0 );
pGroup->ubTransportationMask = CAR; pGroup->ubTransportationMask = CAR;
AddWaypointToPGroup( pGroup, 8, 3 ); //C8 AddWaypointToPGroup( pGroup, 8, 3 ); //C8
AddWaypointToPGroup( pGroup, 7, 3 ); //C7 AddWaypointToPGroup( pGroup, 7, 3 ); //C7
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 )); ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_D9, 0, ubNumTroops, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_D9, 0, ubNumTroops, 0, 0, 0 );
AddWaypointToPGroup( pGroup, 9, 5 ); //E9 AddWaypointToPGroup( pGroup, 9, 5 ); //E9
AddWaypointToPGroup( pGroup, 9, 4 ); //D9 AddWaypointToPGroup( pGroup, 9, 4 ); //D9
pGroup->ubTransportationMask = TRUCK; pGroup->ubTransportationMask = TRUCK;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 )); ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_B9, 0, ubNumTroops, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_B9, 0, ubNumTroops, 0, 0, 0 );
AddWaypointToPGroup( pGroup, 12, 2 ); //B12 AddWaypointToPGroup( pGroup, 12, 2 ); //B12
AddWaypointToPGroup( pGroup, 9, 2 ); //B9 AddWaypointToPGroup( pGroup, 9, 2 ); //B9
pGroup->ubTransportationMask = FOOT; pGroup->ubTransportationMask = FOOT;
ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 )); ubNumTroops = (UINT8)(3 + gGameOptions.ubDifficultyLevel + Random( 3 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A14, 0, ubNumTroops, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A14, 0, ubNumTroops, 0, 0, 0 );
pGroup->ubMoveType = ENDTOEND_FORWARDS; pGroup->ubMoveType = ENDTOEND_FORWARDS;
AddWaypointToPGroup( pGroup, 13, 1 ); //A13 AddWaypointToPGroup( pGroup, 13, 1 ); //A13
AddWaypointToPGroup( pGroup, 15, 1 ); //A15 AddWaypointToPGroup( pGroup, 15, 1 ); //A15
@@ -368,13 +368,13 @@ void GeneratePatrolGroups()
pGroup->ubTransportationMask = TRACKED; pGroup->ubTransportationMask = TRACKED;
ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 )); ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N6, 0, ubNumTroops, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N6, 0, ubNumTroops, 0, 0, 0 );
AddWaypointToPGroup( pGroup, 9, 14 ); //N9 AddWaypointToPGroup( pGroup, 9, 14 ); //N9
AddWaypointToPGroup( pGroup, 6, 14 ); //N6 AddWaypointToPGroup( pGroup, 6, 14 ); //N6
pGroup->ubTransportationMask = CAR; pGroup->ubTransportationMask = CAR;
ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 )); ubNumTroops = (UINT8)(5 + gGameOptions.ubDifficultyLevel * 2 + Random( 4 ));
pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N10, 0, ubNumTroops, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N10, 0, ubNumTroops, 0, 0, 0 );
AddWaypointToPGroup( pGroup, 10, 11 ); //K10 AddWaypointToPGroup( pGroup, 10, 11 ); //K10
AddWaypointToPGroup( pGroup, 10, 14 ); //N10 AddWaypointToPGroup( pGroup, 10, 14 ); //N10
pGroup->ubTransportationMask = CAR; pGroup->ubTransportationMask = CAR;
+8 -2
View File
@@ -528,7 +528,10 @@ typedef struct SECTORINFO
FLOAT dFortification_MaxPossible; // the amount of fortification that can still be done in this sector, given the current layout plans. Is updated every time we unload a sector FLOAT dFortification_MaxPossible; // the amount of fortification that can still be done in this sector, given the current layout plans. Is updated every time we unload a sector
FLOAT dFortification_UnappliedProgress; // progress done via assignment work. As we cannot update unloaded sectors, update happens once sector is loaded FLOAT dFortification_UnappliedProgress; // progress done via assignment work. As we cannot update unloaded sectors, update happens once sector is loaded
INT8 bPadding[ 4 ]; UINT8 ubNumJeeps;
UINT8 ubJeepsInBattle;
INT8 bPadding[ 22 ];
}SECTORINFO; }SECTORINFO;
@@ -574,7 +577,10 @@ typedef struct UNDERGROUND_SECTORINFO
FLOAT dFortification_MaxPossible; // the amount of fortification that can still be done in this sector, given the current layout plans. Is updated every time we unload a sector FLOAT dFortification_MaxPossible; // the amount of fortification that can still be done in this sector, given the current layout plans. Is updated every time we unload a sector
FLOAT dFortification_UnappliedProgress; // progress done via assignment work. As we cannot update unloaded sectors, update happens once sector is loaded FLOAT dFortification_UnappliedProgress; // progress done via assignment work. As we cannot update unloaded sectors, update happens once sector is loaded
INT8 bPadding[16]; UINT8 ubNumJeeps;
UINT8 ubJeepsInBattle;
INT8 bPadding[14];
//no padding left! //no padding left!
}UNDERGROUND_SECTORINFO; }UNDERGROUND_SECTORINFO;
+42 -27
View File
@@ -126,13 +126,13 @@ BOOLEAN AddEnemiesToInitialSectorH7();
UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pubNumTanks ); UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pubNumTanks );
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks );
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps );
void InitJa25InitialEnemiesInSector(); void InitJa25InitialEnemiesInSector();
void InitJa25UnderGroundSectors(); void InitJa25UnderGroundSectors();
void InitNumberOfEnemiesInAboveGroundSectors( ); void InitNumberOfEnemiesInAboveGroundSectors( );
void InitNumberOfEnemiesInUnderGroundSectors( ); void InitNumberOfEnemiesInUnderGroundSectors( );
void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8 bBloodCatPlacements ); void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8 bBloodCatPlacements );
void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps );
void ResetJa25SectorProbabilities(); void ResetJa25SectorProbabilities();
BOOLEAN InitJa25StrategicSectorAI( BOOLEAN fReset ); BOOLEAN InitJa25StrategicSectorAI( BOOLEAN fReset );
@@ -281,17 +281,18 @@ BOOLEAN AddEnemiesToInitialSectorH7()
UINT8 ubNumTroops; UINT8 ubNumTroops;
UINT8 ubNumElites; UINT8 ubNumElites;
UINT8 ubNumTanks; UINT8 ubNumTanks;
UINT8 ubNumJeeps;
UINT8 ubNumRemovedAdmins=0; UINT8 ubNumRemovedAdmins=0;
UINT8 ubNumRemovedTroops=0; UINT8 ubNumRemovedTroops=0;
UINT8 ubNumRemovedElites=0; UINT8 ubNumRemovedElites=0;
UINT8 ubNumRemovedTanks=0; UINT8 ubNumRemovedTanks=0;
UINT8 ubNumRemovedJeeps=0;
ubSector = SECTOR( JA2_5_START_SECTOR_X, JA2_5_START_SECTOR_Y ); ubSector = SECTOR( JA2_5_START_SECTOR_X, JA2_5_START_SECTOR_Y );
//Get the number of enemies in the guard post sector //Get the number of enemies in the guard post sector
GetNumberOfJA25EnemiesInSector( 8, MAP_ROW_H, 0, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfJA25EnemiesInSector( 8, MAP_ROW_H, 0, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
//determine the #of enemies to travel to the initial heli sector //determine the #of enemies to travel to the initial heli sector
if( ubNumAdmins > 1 ) if( ubNumAdmins > 1 )
@@ -306,13 +307,17 @@ BOOLEAN AddEnemiesToInitialSectorH7()
if( ubNumTanks > 1 ) if( ubNumTanks > 1 )
ubNumRemovedTanks = ubNumTanks / 3 + + Random( 3 ); ubNumRemovedTanks = ubNumTanks / 3 + + Random( 3 );
if( ubNumJeeps > 1 )
ubNumRemovedJeeps = ubNumJeeps / 3 + + Random( 3 );
//deduct the # that are moving from the # in the guard post sector //deduct the # that are moving from the # in the guard post sector
// SetNumberJa25EnemiesInSurfaceSector( SEC_H8, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites) ); // SetNumberJa25EnemiesInSurfaceSector( SEC_H8, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites) );
SetNumberJa25EnemiesInSector( 8, MAP_ROW_H, 0, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites), (UINT8)(ubNumTanks-ubNumRemovedTanks) ); SetNumberJa25EnemiesInSector( 8, MAP_ROW_H, 0, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites),
(UINT8)(ubNumTanks-ubNumRemovedTanks), (UINT8)(ubNumJeeps-ubNumRemovedJeeps) );
uiWorldMin = GetWorldTotalMin(); uiWorldMin = GetWorldTotalMin();
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, ubNumRemovedAdmins, ubNumRemovedTroops, ubNumRemovedElites, ubNumRemovedTanks ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, ubNumRemovedAdmins, ubNumRemovedTroops, ubNumRemovedElites, ubNumRemovedTanks, ubNumRemovedJeeps );
if( pGroup == NULL ) if( pGroup == NULL )
{ {
@@ -403,19 +408,19 @@ void InitJa25UnderGroundSectors()
*/ */
} }
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ) void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps )
{ {
//if its a ground level //if its a ground level
if( bSectorZ == 0 ) if( bSectorZ == 0 )
{ {
SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
} }
//its an underground level //its an underground level
else else
{ {
SetNumberJa25EnemiesInUnderGroundSector( sSectorX, sSectorY, bSectorZ, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInUnderGroundSector( sSectorX, sSectorY, bSectorZ, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
} }
} }
@@ -857,6 +862,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
UINT8 ubNumTroops=0; UINT8 ubNumTroops=0;
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks; UINT8 ubNumTanks;
UINT8 ubNumJeeps;
//Mine Sector Level 1 //Mine Sector Level 1
switch( gGameOptions.ubDifficultyLevel ) switch( gGameOptions.ubDifficultyLevel )
@@ -877,7 +883,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 13, 9, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 13, 9, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
//Power Generator Level 1 //Power Generator Level 1
@@ -899,7 +905,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 13, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 13, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
//Tunnel First Part, Level 1 //Tunnel First Part, Level 1
@@ -921,7 +927,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
//Tunnel Second Part, Level 1 //Tunnel Second Part, Level 1
@@ -943,7 +949,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
@@ -966,7 +972,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 6 + Random( 4 ); ubNumElites = 6 + Random( 4 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 15, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
//Complex, Level 2, K15 //Complex, Level 2, K15
@@ -988,7 +994,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 10 + Random( 2 ); ubNumElites = 10 + Random( 2 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 11, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 15, 11, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
//Complex, Level 2, L15 //Complex, Level 2, L15
@@ -1010,7 +1016,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 14 + Random( 2 ); ubNumElites = 14 + Random( 2 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 12, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 15, 12, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
//Complex, Level 3, L15 //Complex, Level 3, L15
@@ -1032,7 +1038,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 15 + Random( 0 ); ubNumElites = 15 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 12, 3, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 15, 12, 3, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
} }
void InitJa25SaveStruct() void InitJa25SaveStruct()
@@ -1325,10 +1331,11 @@ void AddEnemiesToFirstTunnelSector()
UINT8 ubNumTroops=0; UINT8 ubNumTroops=0;
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0;
NumEnemiesToAttackFirstTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); NumEnemiesToAttackFirstTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
} }
void AddEnemiesToSecondTunnelSector() void AddEnemiesToSecondTunnelSector()
@@ -1337,17 +1344,19 @@ void AddEnemiesToSecondTunnelSector()
UINT8 ubNumTroops=0; UINT8 ubNumTroops=0;
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0;
NumEnemiesToAttackSecondTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); NumEnemiesToAttackSecondTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
} }
UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks ) UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps )
{ {
UINT8 ubNumAdmins=0; UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0; UINT8 ubNumTroops=0;
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0;
//if the player blew up the fan, add a ton of enemies to the sector //if the player blew up the fan, add a ton of enemies to the sector
//1st Tunnel Sector //1st Tunnel Sector
@@ -1382,15 +1391,19 @@ UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8
if( pTanks ) if( pTanks )
*pTanks = ubNumTanks; *pTanks = ubNumTanks;
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks ); if( pJeeps )
*pJeeps = ubNumJeeps;
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps );
} }
UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks ) UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps )
{ {
UINT8 ubNumAdmins=0; UINT8 ubNumAdmins=0;
UINT8 ubNumTroops=0; UINT8 ubNumTroops=0;
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0;
//if the player blew up the fan, add a ton of enemies to the sector //if the player blew up the fan, add a ton of enemies to the sector
//1st Tunnel Sector //1st Tunnel Sector
@@ -1422,8 +1435,10 @@ UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT
*pElites = ubNumElites; *pElites = ubNumElites;
if( pTanks ) if( pTanks )
*pTanks = ubNumTanks; *pTanks = ubNumTanks;
if( pJeeps )
*pJeeps = ubNumJeeps;
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks ); return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps );
} }
@@ -2186,7 +2201,7 @@ BOOLEAN HandleAddEnemiesToSectorPlayerIsntIn( INT16 sSaiSector, UINT8 ubNumEnemi
gubEnemyEncounterCode = ENEMY_INVASION_CODE; gubEnemyEncounterCode = ENEMY_INVASION_CODE;
} }
SetNumberJa25EnemiesInSector( sSectorX, sSectorY, bSectorZ, 0, ubNumEnemies, 0, 0 ); SetNumberJa25EnemiesInSector( sSectorX, sSectorY, bSectorZ, 0, ubNumEnemies, 0, 0, 0 );
SetThisSectorAsEnemyControlled( sSectorX, sSectorY, bSectorZ, FALSE ); SetThisSectorAsEnemyControlled( sSectorX, sSectorY, bSectorZ, FALSE );
@@ -2231,7 +2246,7 @@ if ( gGameUBOptions.pJA2UB == TRUE )
if( gJa25AiSectorStruct[ sSaiSector ].bSectorZ == 0 ) if( gJa25AiSectorStruct[ sSaiSector ].bSectorZ == 0 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( sSector, 0, ubNumEnemies, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( sSector, 0, ubNumEnemies, 0, 0, 0 );
if( sGridNo != -1 ) if( sGridNo != -1 )
{ {
+4 -4
View File
@@ -188,12 +188,12 @@ BOOLEAN ShouldEnemiesBeAddedToInitialSector();
void InitJa25StrategicAi(); void InitJa25StrategicAi();
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps );
void InitJa25SaveStruct(); void InitJa25SaveStruct();
void InitJa25StrategicAiBloodcats( ); void InitJa25StrategicAiBloodcats( );
extern void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); extern void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps );
BOOLEAN SaveJa25SaveInfoToSaveGame( HWFILE hFile ); BOOLEAN SaveJa25SaveInfoToSaveGame( HWFILE hFile );
BOOLEAN LoadJa25SaveInfoFromSavedGame( HWFILE hFile ); BOOLEAN LoadJa25SaveInfoFromSavedGame( HWFILE hFile );
@@ -305,7 +305,7 @@ enum
extern BOOLEAN gfEnemyShouldImmediatelySeekThePlayer; extern BOOLEAN gfEnemyShouldImmediatelySeekThePlayer;
//extern INT32 giNumJA25Sectors; //extern INT32 giNumJA25Sectors;
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps );
void SetJa25SectorOwnedStatus( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, BOOLEAN fPlayerOwned ); void SetJa25SectorOwnedStatus( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, BOOLEAN fPlayerOwned );
INT8 GetTheFurthestSectorPlayerOwns(); INT8 GetTheFurthestSectorPlayerOwns();
void Ja25_UpdateTimeOfEndOfLastBattle( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); void Ja25_UpdateTimeOfEndOfLastBattle( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
@@ -317,7 +317,7 @@ void JA25_HandleUpdateOfStrategicAi();
void SetEnemiesToFindThePlayerMercs(); void SetEnemiesToFindThePlayerMercs();
void HandleSayingDontStayToLongWarningInSectorH8(); void HandleSayingDontStayToLongWarningInSectorH8();
extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks ); extern void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps );
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
BOOLEAN InitJa25StrategicAiDecisions( BOOLEAN fLoadedGame ); BOOLEAN InitJa25StrategicAiDecisions( BOOLEAN fLoadedGame );
+11 -10
View File
@@ -562,7 +562,7 @@ void ShowSAMSitesOnStrategicMap( void );
void MilitiaBoxMaskBtnCallback(MOUSE_REGION * pRegion, INT32 iReason ); void MilitiaBoxMaskBtnCallback(MOUSE_REGION * pRegion, INT32 iReason );
// display potential path, yes or no? // display potential path, yes or no?
void ShowEnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sNumberOfEnemies, UINT16 usNumTanks, UINT8 ubIconPosition ); void ShowEnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sNumberOfEnemies, UINT16 usNumEnemyArmedVehicles, UINT8 ubIconPosition );
void ShowUncertainNumberEnemiesInSector( INT16 sSectorX, INT16 sSectorY ); void ShowUncertainNumberEnemiesInSector( INT16 sSectorX, INT16 sSectorY );
void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubIconPosition ); void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubIconPosition );
@@ -1256,7 +1256,7 @@ INT32 ShowVehicles(INT16 sMapX, INT16 sMapY, INT32 iCount)
} }
void ShowEnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sNumberOfEnemies, UINT16 usNumTanks, UINT8 ubIconPosition ) void ShowEnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sNumberOfEnemies, UINT16 usNumEnemyArmedVehicles, UINT8 ubIconPosition )
{ {
HVOBJECT hIconHandle; HVOBJECT hIconHandle;
INT16 sEnemy, s10xEnemy, sEnemyLessTank; INT16 sEnemy, s10xEnemy, sEnemyLessTank;
@@ -1264,7 +1264,7 @@ void ShowEnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sNumberOfEnemies
// get the video object // get the video object
GetVideoObject(&hIconHandle, guiCHARICONS); GetVideoObject(&hIconHandle, guiCHARICONS);
sEnemyLessTank = sNumberOfEnemies - usNumTanks; sEnemyLessTank = sNumberOfEnemies - usNumEnemyArmedVehicles;
// no 10x icon for easy enemy quantity gauge in low resolution // no 10x icon for easy enemy quantity gauge in low resolution
if (iResolution >= _640x480 && iResolution < _800x600) if (iResolution >= _640x480 && iResolution < _800x600)
@@ -1285,17 +1285,17 @@ void ShowEnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sNumberOfEnemies
{ {
// Flugente: the tank icon has is 4 icons wide and 2 rows high, thus this odd code bit // Flugente: the tank icon has is 4 icons wide and 2 rows high, thus this odd code bit
// if we want to display a tank and have not yet done so, pick the first position that still has enough space to the right // if we want to display a tank and have not yet done so, pick the first position that still has enough space to the right
if ( usNumTanks && secondtankrowstart < 0 && ( ubIconPosition % MERC_ICONS_PER_LINE ) < 3 ) if ( usNumEnemyArmedVehicles && secondtankrowstart < 0 && (ubIconPosition % MERC_ICONS_PER_LINE) < 3 )
{ {
DrawMapBoxIcon( hIconHandle, ENEMY_TANK_BIG, sSectorX, sSectorY, ubIconPosition ); DrawMapBoxIcon( hIconHandle, ENEMY_TANK_BIG, sSectorX, sSectorY, ubIconPosition );
secondtankrowstart = ubIconPosition + 6; secondtankrowstart = ubIconPosition + 6;
ubIconPosition += 4; ubIconPosition += 4;
} }
// if this is the second row of a tank, don't draw anything // if this is the second row of a tank, don't draw anything
else if ( usNumTanks && secondtankrowstart > -1 && ubIconPosition == secondtankrowstart ) else if ( usNumEnemyArmedVehicles && secondtankrowstart > -1 && ubIconPosition == secondtankrowstart )
{ {
// for now display only one tank icon // for now display only one tank icon
usNumTanks = 0; usNumEnemyArmedVehicles = 0;
ubIconPosition += 4; ubIconPosition += 4;
sEnemy = max( 0, sEnemy - 1 ); sEnemy = max( 0, sEnemy - 1 );
} }
@@ -6598,6 +6598,7 @@ BOOLEAN CanMercsScoutThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubIconPosition ) void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubIconPosition )
{ {
INT16 sNumberOfEnemies = 0; INT16 sNumberOfEnemies = 0;
UINT16 usNumEnemyArmedVehicles = 0;
// ATE: If game has just started, don't do it! // ATE: If game has just started, don't do it!
if ( DidGameJustStart() ) if ( DidGameJustStart() )
@@ -6677,10 +6678,10 @@ void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bS
case KNOWS_HOW_MANY: case KNOWS_HOW_MANY:
{ {
// Flugente: tanks get a special icon, so we need to count them separately // Flugente: tanks get a special icon, so we need to count them separately
UINT16 usNumTanks = NumTanksInSector( sSectorX, sSectorY, ENEMY_TEAM ); usNumEnemyArmedVehicles = NumEnemyArmedVehiclesInSector( sSectorX, sSectorY, ENEMY_TEAM );
// display individual icons for each enemy, starting at the received icon position index // display individual icons for each enemy, starting at the received icon position index
ShowEnemiesInSector( sSectorX, sSectorY, sNumberOfEnemies, usNumTanks, ubIconPosition ); ShowEnemiesInSector( sSectorX, sSectorY, sNumberOfEnemies, usNumEnemyArmedVehicles, ubIconPosition );
} }
break; break;
@@ -6688,10 +6689,10 @@ void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bS
case KNOWS_HOW_MANY_AND_WHERE_GOING: case KNOWS_HOW_MANY_AND_WHERE_GOING:
{ {
// Flugente: tanks get a special icon, so we need to count them separately // Flugente: tanks get a special icon, so we need to count them separately
UINT16 usNumTanks = NumTanksInSector( sSectorX, sSectorY, ENEMY_TEAM ); usNumEnemyArmedVehicles = NumEnemyArmedVehiclesInSector( sSectorX, sSectorY, ENEMY_TEAM );
// display individual icons for each enemy, starting at the received icon position index // display individual icons for each enemy, starting at the received icon position index
ShowEnemiesInSector( sSectorX, sSectorY, sNumberOfEnemies, usNumTanks, ubIconPosition ); ShowEnemiesInSector( sSectorX, sSectorY, sNumberOfEnemies, usNumEnemyArmedVehicles, ubIconPosition );
// display their direction of movement, if valid. // display their direction of movement, if valid.
ShowNonPlayerGroupsInMotion( sSectorX, sSectorY, ENEMY_TEAM ); ShowNonPlayerGroupsInMotion( sSectorX, sSectorY, ENEMY_TEAM );
+6 -3
View File
@@ -227,13 +227,14 @@ void ValidateAndCorrectInBattleCounters( GROUP *pLocGroup )
{ {
if( pGroup->ubSectorX == pLocGroup->ubSectorX && pGroup->ubSectorY == pLocGroup->ubSectorY ) if( pGroup->ubSectorX == pLocGroup->ubSectorX && pGroup->ubSectorY == pLocGroup->ubSectorY )
{ {
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 || pGroup->pEnemyGroup->ubJeepsInBattle )
{ {
++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;
pGroup->pEnemyGroup->ubTanksInBattle = 0; pGroup->pEnemyGroup->ubTanksInBattle = 0;
pGroup->pEnemyGroup->ubJeepsInBattle = 0;
} }
} }
} }
@@ -251,19 +252,21 @@ void ValidateAndCorrectInBattleCounters( GROUP *pLocGroup )
L"If you can provide information on how a previous battle was resolved here or nearby patrol " L"If you can provide information on how a previous battle was resolved here or nearby patrol "
L"(auto resolve, tactical battle, cheat keys, or retreat)," L"(auto resolve, tactical battle, cheat keys, or retreat),"
L"please forward that info (no data files necessary) as well as the following code (very important): " L"please forward that info (no data files necessary) as well as the following code (very important): "
L"G(%02d:%c%d_b%d) A(%02d:%02d) T(%02d:%02d) E(%02d:%02d) C(%02d:%02d) Ta(%02d:%02d)", L"G(%02d:%c%d_b%d) A(%02d:%02d) T(%02d:%02d) E(%02d:%02d) C(%02d:%02d) Ta(%02d:%02d) J(%02d:%02d)",
ubInvalidGroups, pLocGroup->ubSectorY + 'A' - 1, pLocGroup->ubSectorX, pLocGroup->ubSectorZ, ubInvalidGroups, pLocGroup->ubSectorY + 'A' - 1, pLocGroup->ubSectorX, pLocGroup->ubSectorZ,
pSector->ubNumAdmins, pSector->ubAdminsInBattle, pSector->ubNumAdmins, pSector->ubAdminsInBattle,
pSector->ubNumTroops, pSector->ubTroopsInBattle, pSector->ubNumTroops, pSector->ubTroopsInBattle,
pSector->ubNumElites, pSector->ubElitesInBattle, pSector->ubNumElites, pSector->ubElitesInBattle,
pSector->ubNumCreatures, pSector->ubCreaturesInBattle, pSector->ubNumCreatures, pSector->ubCreaturesInBattle,
pSector->ubNumTanks, pSector->ubTanksInBattle ); pSector->ubNumTanks, pSector->ubTanksInBattle,
pSector->ubNumJeeps, pSector->ubJeepsInBattle );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL ); DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
pSector->ubAdminsInBattle = 0; pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubCreaturesInBattle = 0; pSector->ubCreaturesInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0;
} }
} }
#endif #endif
+137 -48
View File
@@ -282,11 +282,11 @@ UINT8 NumNonPlayerTeamMembersInSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubT
return ubNumTroops; return ubNumTroops;
} }
UINT16 NumTanksInSector( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam ) UINT16 NumEnemyArmedVehiclesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
UINT8 ubNum; UINT16 ubNum;
// HEADROCK: This is a TEMPORARY fix to avoid the assertion error. Not sure this is the best solution, // HEADROCK: This is a TEMPORARY fix to avoid the assertion error. Not sure this is the best solution,
// probably isn't. But I need this bit to work. // probably isn't. But I need this bit to work.
@@ -306,18 +306,14 @@ UINT16 NumTanksInSector( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam )
pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )]; pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )];
if ( usTeam == ENEMY_TEAM ) if ( usTeam == ENEMY_TEAM )
ubNum = (UINT16)(pSector->ubNumTanks); ubNum = (UINT16)(pSector->ubNumTanks + pSector->ubNumJeeps);
// TODO
//if ( is_networked )
//ubNumTroops += numenemyLAN( (UINT8)sSectorX, (UINT8)sSectorY ); //hayden
pGroup = gpGroupList; pGroup = gpGroupList;
while ( pGroup ) while ( pGroup )
{ {
if ( pGroup->usGroupTeam == usTeam && !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 + pGroup->pEnemyGroup->ubNumJeeps;
} }
pGroup = pGroup->next; pGroup = pGroup->next;
} }
@@ -383,7 +379,7 @@ UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
return ubNumTroops; return ubNumTroops;
} }
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, UINT8 *pubNumJeeps )
{ {
GROUP *pGroup; GROUP *pGroup;
SECTORINFO *pSector; SECTORINFO *pSector;
@@ -393,7 +389,7 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE ); AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
//Now count the number of mobile groups in the sector. //Now count the number of mobile groups in the sector.
*pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumTanks = 0; *pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumTanks = *pubNumJeeps =0;
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
@@ -403,6 +399,7 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
*pubNumElites += pGroup->pEnemyGroup->ubNumElites; *pubNumElites += pGroup->pEnemyGroup->ubNumElites;
*pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins; *pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
*pubNumTanks += pGroup->pEnemyGroup->ubNumTanks; *pubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
*pubNumJeeps += pGroup->pEnemyGroup->ubNumJeeps;
} }
pGroup = pGroup->next; pGroup = pGroup->next;
} }
@@ -415,10 +412,11 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
*pubNumTroops += pSector->ubNumTroops; *pubNumTroops += pSector->ubNumTroops;
*pubNumElites += pSector->ubNumElites; *pubNumElites += pSector->ubNumElites;
*pubNumTanks += pSector->ubNumTanks; *pubNumTanks += pSector->ubNumTanks;
*pubNumJeeps += pSector->ubNumJeeps;
} }
} }
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks ) void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
GROUP *pGroup; GROUP *pGroup;
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
@@ -427,7 +425,7 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE ); AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
//Now count the number of mobile groups in the sector. //Now count the number of mobile groups in the sector.
*pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumTanks = 0; *pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumTanks = *pubNumJeeps = 0;
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
@@ -437,13 +435,14 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
*pubNumElites += pGroup->pEnemyGroup->ubNumElites; *pubNumElites += pGroup->pEnemyGroup->ubNumElites;
*pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins; *pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
*pubNumTanks += pGroup->pEnemyGroup->ubNumTanks; *pubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
*pubNumJeeps += pGroup->pEnemyGroup->ubNumJeeps;
} }
pGroup = pGroup->next; pGroup = pGroup->next;
} }
} }
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, UINT8 *pubNumJeeps )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
@@ -457,20 +456,22 @@ void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8
*pubNumTroops = pSector->ubNumTroops; *pubNumTroops = pSector->ubNumTroops;
*pubNumElites = pSector->ubNumElites; *pubNumElites = pSector->ubNumElites;
*pubNumTanks = pSector->ubNumTanks; *pubNumTanks = pSector->ubNumTanks;
*pubNumJeeps = pSector->ubNumJeeps;
} }
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, UINT8 *pubNumJeeps )
{ {
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps;
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks ); GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks, pubNumJeeps );
GetNumberOfMobileEnemiesInSector( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfMobileEnemiesInSector( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites; *pubNumElites += ubNumElites;
*pubNumTanks += ubNumTanks; *pubNumTanks += ubNumTanks;
*pubNumJeeps += ubNumJeeps;
} }
void EndTacticalBattleForEnemy() void EndTacticalBattleForEnemy()
@@ -487,6 +488,7 @@ void EndTacticalBattleForEnemy()
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0;
} }
else if( !gbWorldSectorZ ) else if( !gbWorldSectorZ )
{ {
@@ -497,6 +499,7 @@ void EndTacticalBattleForEnemy()
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0;
pSector->ubNumCreatures = 0; pSector->ubNumCreatures = 0;
pSector->ubCreaturesInBattle = 0; pSector->ubCreaturesInBattle = 0;
} }
@@ -516,6 +519,7 @@ void EndTacticalBattleForEnemy()
pGroup->pEnemyGroup->ubElitesInBattle = 0; pGroup->pEnemyGroup->ubElitesInBattle = 0;
pGroup->pEnemyGroup->ubAdminsInBattle = 0; pGroup->pEnemyGroup->ubAdminsInBattle = 0;
pGroup->pEnemyGroup->ubTanksInBattle = 0; pGroup->pEnemyGroup->ubTanksInBattle = 0;
pGroup->pEnemyGroup->ubJeepsInBattle = 0;
} }
pGroup = pGroup->next; pGroup = pGroup->next;
} }
@@ -570,8 +574,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
unsigned ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; unsigned ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps;
unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops, ubTotalTanks = 0; unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops, ubTotalTanks, ubTotalJeeps = 0;
unsigned totalCountOfStationaryEnemies = 0; unsigned totalCountOfStationaryEnemies = 0;
unsigned totalCountOfMobileEnemies = 0; unsigned totalCountOfMobileEnemies = 0;
int sNumSlots; int sNumSlots;
@@ -627,7 +631,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
!pGroup->pEnemyGroup->ubAdminsInBattle && !pGroup->pEnemyGroup->ubAdminsInBattle &&
!pGroup->pEnemyGroup->ubTroopsInBattle && !pGroup->pEnemyGroup->ubTroopsInBattle &&
!pGroup->pEnemyGroup->ubElitesInBattle && !pGroup->pEnemyGroup->ubElitesInBattle &&
!pGroup->pEnemyGroup->ubTanksInBattle) !pGroup->pEnemyGroup->ubTanksInBattle &&
!pGroup->pEnemyGroup->ubJeepsInBattle )
{ {
HandleArrivalOfReinforcements( pGroup ); HandleArrivalOfReinforcements( pGroup );
} }
@@ -665,12 +670,13 @@ BOOLEAN PrepareEnemyForSectorBattle()
// OJW - 20090403 - override max ai in co-op // OJW - 20090403 - override max ai in co-op
if (is_networked && is_server && gMaxEnemiesEnabled == 1) if (is_networked && is_server && gMaxEnemiesEnabled == 1)
{ {
float totalEnemies = (float)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks); float totalEnemies = (float)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks + pSector->ubNumJeeps);
ubTotalAdmins = (unsigned int)(((float)pSector->ubNumAdmins / totalEnemies) * mapMaximumNumberOfEnemies); ubTotalAdmins = (unsigned int)(((float)pSector->ubNumAdmins / totalEnemies) * mapMaximumNumberOfEnemies);
ubTotalTroops = (unsigned int)(((float)pSector->ubNumTroops / totalEnemies) * mapMaximumNumberOfEnemies); ubTotalTroops = (unsigned int)(((float)pSector->ubNumTroops / totalEnemies) * mapMaximumNumberOfEnemies);
ubTotalElites = (unsigned int)(((float)pSector->ubNumElites / totalEnemies) * mapMaximumNumberOfEnemies); ubTotalElites = (unsigned int)(((float)pSector->ubNumElites / totalEnemies) * mapMaximumNumberOfEnemies);
ubTotalTanks = (unsigned int)(((float)pSector->ubNumTanks / totalEnemies) * mapMaximumNumberOfEnemies); ubTotalTanks = (unsigned int)(((float)pSector->ubNumTanks / totalEnemies) * mapMaximumNumberOfEnemies);
totalEnemies = (float)(ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks); ubTotalJeeps = (unsigned int)(((float)pSector->ubNumJeeps / totalEnemies) * mapMaximumNumberOfEnemies);
totalEnemies = (float)(ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks + ubTotalJeeps);
// take care of any rounding losses // take care of any rounding losses
while (totalEnemies < mapMaximumNumberOfEnemies) while (totalEnemies < mapMaximumNumberOfEnemies)
@@ -684,10 +690,12 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSector->ubNumTroops = ubTotalTroops; pSector->ubNumTroops = ubTotalTroops;
pSector->ubNumElites = ubTotalElites; pSector->ubNumElites = ubTotalElites;
pSector->ubNumTanks = ubTotalTanks; pSector->ubNumTanks = ubTotalTanks;
pSector->ubNumJeeps = ubTotalJeeps;
pSector->ubAdminsInBattle = 0; pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0;
} }
else else
{ {
@@ -706,6 +714,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
case SOLDIER_CLASS_ARMY: ubTotalTroops++; break; case SOLDIER_CLASS_ARMY: ubTotalTroops++; break;
case SOLDIER_CLASS_ELITE: ubTotalElites++; break; case SOLDIER_CLASS_ELITE: ubTotalElites++; break;
case SOLDIER_CLASS_TANK: ubTotalTanks++; break; case SOLDIER_CLASS_TANK: ubTotalTanks++; break;
case SOLDIER_CLASS_JEEP: ubTotalJeeps++; break;
} }
} }
curr = curr->next; curr = curr->next;
@@ -714,10 +723,12 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSector->ubNumTroops = ubTotalTroops; pSector->ubNumTroops = ubTotalTroops;
pSector->ubNumElites = ubTotalElites; pSector->ubNumElites = ubTotalElites;
pSector->ubNumTanks = ubTotalTanks; pSector->ubNumTanks = ubTotalTanks;
pSector->ubNumJeeps = ubTotalJeeps;
pSector->ubAdminsInBattle = 0; pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0;
} }
else else
{ {
@@ -725,10 +736,11 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle; ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle;
ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle; ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle;
ubTotalTanks = pSector->ubNumTanks - pSector->ubTanksInBattle; ubTotalTanks = pSector->ubNumTanks - pSector->ubTanksInBattle;
ubTotalJeeps = pSector->ubNumJeeps - pSector->ubJeepsInBattle;
} }
} }
totalCountOfStationaryEnemies = ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks; totalCountOfStationaryEnemies = ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks + ubTotalJeeps;
if( totalCountOfStationaryEnemies > mapMaximumNumberOfEnemies ) if( totalCountOfStationaryEnemies > mapMaximumNumberOfEnemies )
{ {
@@ -743,20 +755,22 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubTotalTroops = min( mapMaximumNumberOfEnemies-ubTotalAdmins, ubTotalTroops ); ubTotalTroops = min( mapMaximumNumberOfEnemies-ubTotalAdmins, ubTotalTroops );
ubTotalElites = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops, ubTotalElites ); ubTotalElites = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops, ubTotalElites );
ubTotalTanks = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops-ubTotalElites, ubTotalTanks ); ubTotalTanks = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops-ubTotalElites, ubTotalTanks );
ubTotalJeeps = min( mapMaximumNumberOfEnemies - ubTotalAdmins - ubTotalTroops - ubTotalElites - ubTotalTanks, ubTotalJeeps );
} }
pSector->ubAdminsInBattle += ubTotalAdmins; pSector->ubAdminsInBattle += ubTotalAdmins;
pSector->ubTroopsInBattle += ubTotalTroops; pSector->ubTroopsInBattle += ubTotalTroops;
pSector->ubElitesInBattle += ubTotalElites; pSector->ubElitesInBattle += ubTotalElites;
pSector->ubTanksInBattle += ubTotalTanks; pSector->ubTanksInBattle += ubTotalTanks;
pSector->ubJeepsInBattle += ubTotalJeeps;
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
if( gfOverrideSector ) if( gfOverrideSector )
{ {
//if there are no troops in the current groups, then we're done. //if there are no troops in the current groups, then we're done.
if( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalTanks ) if ( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalTanks && !ubTotalJeeps )
return FALSE; return FALSE;
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks ); AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks, ubTotalJeeps );
ValidateEnemiesHaveWeapons(); ValidateEnemiesHaveWeapons();
return TRUE; return TRUE;
} }
@@ -783,7 +797,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
//Subtract the total number of stationary enemies from the available slots, as stationary forces take //Subtract the total number of stationary enemies from the available slots, as stationary forces take
//precendence in combat. The mobile forces that could also be in the same sector are considered later if //precendence in combat. The mobile forces that could also be in the same sector are considered later if
//all the slots fill up. //all the slots fill up.
sNumSlots -= ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks; sNumSlots -= ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks + ubTotalJeeps;
//Now, process all of the groups and search for both enemy and player groups in the sector. //Now, process all of the groups and search for both enemy and player groups in the sector.
//For enemy groups, we fill up the slots until we have none left or all of the groups have been //For enemy groups, we fill up the slots until we have none left or all of the groups have been
@@ -850,6 +864,21 @@ BOOLEAN PrepareEnemyForSectorBattle()
pGroup->pEnemyGroup->ubTanksInBattle += ubNumTanks; pGroup->pEnemyGroup->ubTanksInBattle += ubNumTanks;
ubTotalTanks += ubNumTanks; ubTotalTanks += ubNumTanks;
} }
if ( sNumSlots > 0 )
{
//Add jeeps
AssertGE( pGroup->pEnemyGroup->ubNumJeeps, pGroup->pEnemyGroup->ubJeepsInBattle );
ubNumJeeps = pGroup->pEnemyGroup->ubNumJeeps - pGroup->pEnemyGroup->ubJeepsInBattle;
sNumSlots -= ubNumJeeps;
if ( sNumSlots < 0 )
{ //adjust the value to zero
ubNumJeeps += sNumSlots;
sNumSlots = 0;
gfPendingNonPlayerTeam[ENEMY_TEAM] = TRUE;
}
pGroup->pEnemyGroup->ubJeepsInBattle += ubNumJeeps;
ubTotalJeeps += ubNumJeeps;
}
//NOTE: //NOTE:
//no provisions for profile troop leader or retreat groups yet. //no provisions for profile troop leader or retreat groups yet.
} }
@@ -871,12 +900,12 @@ BOOLEAN PrepareEnemyForSectorBattle()
} }
//if there are no troops in the current groups, then we're done. //if there are no troops in the current groups, then we're done.
if( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalTanks ) if ( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalTanks && !ubTotalJeeps )
{ {
return FALSE; return FALSE;
} }
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks ); AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks, ubTotalJeeps );
//Now, we have to go through all of the enemies in the new map, and assign their respective groups if //Now, we have to go through all of the enemies in the new map, and assign their respective groups if
//in a mobile group, but only for the ones that were assigned from the //in a mobile group, but only for the ones that were assigned from the
@@ -895,7 +924,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubNumTroops = pGroup->pEnemyGroup->ubTroopsInBattle; ubNumTroops = pGroup->pEnemyGroup->ubTroopsInBattle;
ubNumElites = pGroup->pEnemyGroup->ubElitesInBattle; ubNumElites = pGroup->pEnemyGroup->ubElitesInBattle;
ubNumTanks = pGroup->pEnemyGroup->ubTanksInBattle; ubNumTanks = pGroup->pEnemyGroup->ubTanksInBattle;
unsigned num = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks; ubNumJeeps = pGroup->pEnemyGroup->ubJeepsInBattle;
unsigned num = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps;
unsigned firstSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; unsigned firstSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
unsigned lastSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID; unsigned lastSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
@@ -974,6 +1004,15 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSoldier->ubGroupID = pGroup->ubGroupID; pSoldier->ubGroupID = pGroup->ubGroupID;
} }
break; break;
case SOLDIER_CLASS_JEEP:
if ( ubNumTanks )
{
num--;
sNumSlots--;
ubNumJeeps--;
pSoldier->ubGroupID = pGroup->ubGroupID;
}
break;
} }
} }
@@ -983,6 +1022,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
AssertEQ( ubNumTroops , 0); AssertEQ( ubNumTroops , 0);
AssertEQ( ubNumAdmins , 0); AssertEQ( ubNumAdmins , 0);
AssertEQ( ubNumTanks , 0); AssertEQ( ubNumTanks , 0);
AssertEQ( ubNumJeeps , 0);
AssertEQ( num , 0);*/ AssertEQ( num , 0);*/
} }
pGroup = pGroup->next; pGroup = pGroup->next;
@@ -996,7 +1036,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
BOOLEAN PrepareEnemyForUndergroundBattle() BOOLEAN PrepareEnemyForUndergroundBattle()
{ {
UNDERGROUND_SECTORINFO *pUnderground; UNDERGROUND_SECTORINFO *pUnderground;
unsigned ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks; unsigned ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks, ubTotalJeeps;
pUnderground = gpUndergroundSectorInfoHead; pUnderground = gpUndergroundSectorInfoHead;
while( pUnderground ) while( pUnderground )
@@ -1011,14 +1051,16 @@ BOOLEAN PrepareEnemyForUndergroundBattle()
ubTotalTroops = (UINT8)(pUnderground->ubNumTroops - pUnderground->ubTroopsInBattle); ubTotalTroops = (UINT8)(pUnderground->ubNumTroops - pUnderground->ubTroopsInBattle);
ubTotalElites = (UINT8)(pUnderground->ubNumElites - pUnderground->ubElitesInBattle); ubTotalElites = (UINT8)(pUnderground->ubNumElites - pUnderground->ubElitesInBattle);
ubTotalTanks = (UINT8)(pUnderground->ubNumTanks - pUnderground->ubTanksInBattle); ubTotalTanks = (UINT8)(pUnderground->ubNumTanks - pUnderground->ubTanksInBattle);
ubTotalJeeps = (UINT8)(pUnderground->ubNumJeeps - pUnderground->ubJeepsInBattle);
pUnderground->ubAdminsInBattle += ubTotalAdmins; pUnderground->ubAdminsInBattle += ubTotalAdmins;
pUnderground->ubTroopsInBattle += ubTotalTroops; pUnderground->ubTroopsInBattle += ubTotalTroops;
pUnderground->ubElitesInBattle += ubTotalElites; pUnderground->ubElitesInBattle += ubTotalElites;
pUnderground->ubTanksInBattle += ubTotalTanks; pUnderground->ubTanksInBattle += ubTotalTanks;
AddSoldierInitListEnemyDefenceSoldiers( pUnderground->ubNumAdmins, pUnderground->ubNumTroops, pUnderground->ubNumElites, pUnderground->ubNumTanks ); pUnderground->ubJeepsInBattle += ubTotalJeeps;
AddSoldierInitListEnemyDefenceSoldiers( pUnderground->ubNumAdmins, pUnderground->ubNumTroops, pUnderground->ubNumElites, pUnderground->ubNumTanks, pUnderground->ubNumJeeps );
ValidateEnemiesHaveWeapons(); ValidateEnemiesHaveWeapons();
} }
return ( ( BOOLEAN) ( pUnderground->ubNumAdmins + pUnderground->ubNumTroops + pUnderground->ubNumElites + pUnderground->ubNumTanks > 0 ) ); return ((BOOLEAN)(pUnderground->ubNumAdmins + pUnderground->ubNumTroops + pUnderground->ubNumElites + pUnderground->ubNumTanks + pUnderground->ubNumJeeps > 0));
} }
pUnderground = pUnderground->next; pUnderground = pUnderground->next;
} }
@@ -1544,7 +1586,7 @@ void AddPossiblePendingEnemiesToBattle()
#endif #endif
UINT8 ubSlots, ubNumAvailable; UINT8 ubSlots, ubNumAvailable;
UINT8 ubNumElites, ubNumTroops, ubNumAdmins, ubNumTanks; UINT8 ubNumElites, ubNumTroops, ubNumAdmins, ubNumTanks, ubNumJeeps;
UINT8 ubNumGroupsInSector; UINT8 ubNumGroupsInSector;
UINT8 ubGroupIndex; UINT8 ubGroupIndex;
GROUP *pGroup; GROUP *pGroup;
@@ -1639,11 +1681,12 @@ void AddPossiblePendingEnemiesToBattle()
//return; //return;
} }
if( pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks ) if ( pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps )
{ {
ubNumElites = ubNumTroops = ubNumAdmins = ubNumTanks = 0; ubNumElites = ubNumTroops = ubNumAdmins = ubNumTanks = ubNumJeeps = 0;
ubNumAvailable = pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks - pSector->ubElitesInBattle - pSector->ubTroopsInBattle - pSector->ubAdminsInBattle - pSector->ubTanksInBattle; ubNumAvailable = pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps
- pSector->ubElitesInBattle - pSector->ubTroopsInBattle - pSector->ubAdminsInBattle - pSector->ubTanksInBattle - pSector->ubJeepsInBattle;
while( ubNumAvailable && ubSlots ) while( ubNumAvailable && ubSlots )
{ {
// So they just magically appear out of nowhere from the edge? // So they just magically appear out of nowhere from the edge?
@@ -1677,6 +1720,14 @@ void AddPossiblePendingEnemiesToBattle()
ubSlots--; ubSlots--;
ubNumTanks++; ubNumTanks++;
} }
else if ( pSector->ubJeepsInBattle < pSector->ubNumJeeps )
{
//Add a jeep
pSector->ubJeepsInBattle++;
ubNumAvailable--;
ubSlots--;
ubNumJeeps++;
}
else else
{ {
AssertMsg( 0, "AddPossiblePendingEnemiesToBattle(): Logic Error -- by Kris" ); AssertMsg( 0, "AddPossiblePendingEnemiesToBattle(): Logic Error -- by Kris" );
@@ -1684,7 +1735,7 @@ void AddPossiblePendingEnemiesToBattle()
} }
if( ubNumAdmins || ubNumTroops || ubNumElites || ubNumTanks ) if ( ubNumAdmins || ubNumTroops || ubNumElites || ubNumTanks || ubNumJeeps )
{ //This group has contributed forces, then add them now, because different { //This group has contributed forces, then add them now, because different
//groups appear on different sides of the map. //groups appear on different sides of the map.
UINT8 ubStrategicInsertionCode = ubPredefinedInsertionCode; UINT8 ubStrategicInsertionCode = ubPredefinedInsertionCode;
@@ -1725,7 +1776,7 @@ void AddPossiblePendingEnemiesToBattle()
if( ubStrategicInsertionCode < INSERTION_CODE_NORTH ||ubStrategicInsertionCode > INSERTION_CODE_WEST ) if( ubStrategicInsertionCode < INSERTION_CODE_NORTH ||ubStrategicInsertionCode > INSERTION_CODE_WEST )
ubStrategicInsertionCode = INSERTION_CODE_NORTH + Random( 4 ); ubStrategicInsertionCode = INSERTION_CODE_NORTH + Random( 4 );
AddEnemiesToBattle( 0, ubStrategicInsertionCode, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, FALSE ); AddEnemiesToBattle( 0, ubStrategicInsertionCode, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, FALSE );
gfPendingNonPlayerTeam[ENEMY_TEAM] = TRUE; gfPendingNonPlayerTeam[ENEMY_TEAM] = TRUE;
} }
} }
@@ -1755,7 +1806,8 @@ void AddPossiblePendingEnemiesToBattle()
pGroup = pGroupInSectorList[ ubGroupIndex]; pGroup = pGroupInSectorList[ ubGroupIndex];
// Flugente fix: check for underflow... // Flugente fix: check for underflow...
UINT8 currentgroupsize = pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle + pGroup->pEnemyGroup->ubTanksInBattle; UINT8 currentgroupsize = pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle
+ pGroup->pEnemyGroup->ubTanksInBattle + pGroup->pEnemyGroup->ubJeepsInBattle;
if ( currentgroupsize > pGroup->ubGroupSize ) if ( currentgroupsize > pGroup->ubGroupSize )
ubNumAvailable = 0; ubNumAvailable = 0;
else else
@@ -1816,25 +1868,32 @@ void AddPossiblePendingEnemiesToBattle()
{ //Add an elite troop { //Add an elite troop
pGroup->pEnemyGroup->ubElitesInBattle++; pGroup->pEnemyGroup->ubElitesInBattle++;
ubSlots--; ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 1, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 1, 0, 0, FALSE );
} }
else if( pGroup->pEnemyGroup->ubTroopsInBattle < pGroup->pEnemyGroup->ubNumTroops ) else if( pGroup->pEnemyGroup->ubTroopsInBattle < pGroup->pEnemyGroup->ubNumTroops )
{ //Add a regular troop. { //Add a regular troop.
pGroup->pEnemyGroup->ubTroopsInBattle++; pGroup->pEnemyGroup->ubTroopsInBattle++;
ubSlots--; ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, 0, FALSE );
} }
else if( pGroup->pEnemyGroup->ubAdminsInBattle < pGroup->pEnemyGroup->ubNumAdmins ) else if( pGroup->pEnemyGroup->ubAdminsInBattle < pGroup->pEnemyGroup->ubNumAdmins )
{ //Add an admin troop { //Add an admin troop
pGroup->pEnemyGroup->ubAdminsInBattle++; pGroup->pEnemyGroup->ubAdminsInBattle++;
ubSlots--; ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 1, 0, 0, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 1, 0, 0, 0, 0, FALSE );
} }
else if( pGroup->pEnemyGroup->ubTanksInBattle < pGroup->pEnemyGroup->ubNumTanks ) else if( pGroup->pEnemyGroup->ubTanksInBattle < pGroup->pEnemyGroup->ubNumTanks )
{ //Add a tank { //Add a tank
pGroup->pEnemyGroup->ubTanksInBattle++; pGroup->pEnemyGroup->ubTanksInBattle++;
ubSlots--; ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 1, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 1, 0, FALSE );
}
else if ( pGroup->pEnemyGroup->ubJeepsInBattle < pGroup->pEnemyGroup->ubNumJeeps )
{
//Add a jeep
pGroup->pEnemyGroup->ubJeepsInBattle++;
ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 0, 1, FALSE );
} }
else else
{ {
@@ -1843,7 +1902,7 @@ void AddPossiblePendingEnemiesToBattle()
pGroup->pEnemyGroup->ubTroopsInBattle++; pGroup->pEnemyGroup->ubTroopsInBattle++;
ubSlots--; ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, 0, FALSE );
} }
} }
@@ -1913,7 +1972,7 @@ void NotifyPlayersOfNewEnemies()
} }
} }
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, BOOLEAN fMagicallyAppeared ) void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, BOOLEAN fMagicallyAppeared )
{ {
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
MAPEDGEPOINTINFO MapEdgepointInfo; MAPEDGEPOINTINFO MapEdgepointInfo;
@@ -1946,6 +2005,8 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
pSector->ubElitesInBattle += ubNumElites; pSector->ubElitesInBattle += ubNumElites;
pSector->ubNumTanks += ubNumTanks; pSector->ubNumTanks += ubNumTanks;
pSector->ubTanksInBattle += ubNumTanks; pSector->ubTanksInBattle += ubNumTanks;
pSector->ubNumJeeps += ubNumJeeps;
pSector->ubJeepsInBattle += ubNumJeeps;
} }
else else
{ {
@@ -1960,13 +2021,15 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
pSector->ubElitesInBattle += ubNumElites; pSector->ubElitesInBattle += ubNumElites;
pSector->ubNumTanks += ubNumTanks; pSector->ubNumTanks += ubNumTanks;
pSector->ubTanksInBattle += ubNumTanks; pSector->ubTanksInBattle += ubNumTanks;
pSector->ubNumJeeps += ubNumJeeps;
pSector->ubJeepsInBattle += ubNumJeeps;
} }
} }
//Because the enemies magically appeared, have one of our soldiers say something... //Because the enemies magically appeared, have one of our soldiers say something...
NotifyPlayersOfNewEnemies(); NotifyPlayersOfNewEnemies();
} }
ubTotalSoldiers = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks; ubTotalSoldiers = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps;
#ifdef JA2UB #ifdef JA2UB
if( gsGridNoForMapEdgePointInfo != -1 ) if( gsGridNoForMapEdgePointInfo != -1 )
@@ -2093,6 +2156,30 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
} }
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 ); UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 );
} }
else if ( ubNumJeeps && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks + ubNumJeeps) && ubNumberOfVehicles < 9 )
{
ubNumJeeps--;
ubTotalSoldiers--;
Assert( pSoldier = TacticalCreateEnemyJeep( ) );
if ( pGroup )
{
pSoldier->ubGroupID = pGroup->ubGroupID;
}
pSoldier->ubInsertionDirection = bDesiredDirection;
//Setup the position
if ( ubCurrSlot < MapEdgepointInfo.ubNumPoints )
{ //using an edgepoint
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = MapEdgepointInfo.sGridNo[ubCurrSlot++];
}
else
{ //no edgepoints left, so put him at the entrypoint.
pSoldier->ubStrategicInsertionCode = ubStrategicInsertionCode;
}
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 );
}
// HEADROCK HAM 3.2: enemy reinforcements arrive with 0 APs. // HEADROCK HAM 3.2: enemy reinforcements arrive with 0 APs.
if (gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 1 || gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 2) if (gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 1 || gGameExternalOptions.ubReinforcementsFirstTurnFreeze == 2)
{ {
@@ -2808,7 +2895,8 @@ BOOLEAN CheckPendingNonPlayerTeam( UINT8 usTeam )
if ( usTeam == ENEMY_TEAM ) if ( usTeam == ENEMY_TEAM )
{ {
if( (pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks) > ( pSector->ubElitesInBattle + pSector->ubTroopsInBattle + pSector->ubAdminsInBattle + pSector->ubTanksInBattle) ) if ( (pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps) >
(pSector->ubElitesInBattle + pSector->ubTroopsInBattle + pSector->ubAdminsInBattle + pSector->ubTanksInBattle + pSector->ubJeepsInBattle) )
return TRUE; return TRUE;
} }
@@ -2821,7 +2909,8 @@ BOOLEAN CheckPendingNonPlayerTeam( UINT8 usTeam )
{ {
if ( usTeam == ENEMY_TEAM ) if ( usTeam == ENEMY_TEAM )
{ {
if ( pGroup->ubGroupSize > pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle + pGroup->pEnemyGroup->ubTanksInBattle ) if ( pGroup->ubGroupSize > pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle
+ pGroup->pEnemyGroup->ubTanksInBattle + pGroup->pEnemyGroup->ubJeepsInBattle )
return TRUE; return TRUE;
} }
else if ( usTeam == MILITIA_TEAM ) else if ( usTeam == MILITIA_TEAM )
+6 -6
View File
@@ -22,13 +22,13 @@ 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 NumTanksInSector( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam ); UINT16 NumEnemyArmedVehiclesInSector( 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, UINT8 *pubNumJeeps );
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks ); void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
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, UINT8 *pubNumJeeps );
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, UINT8 *pubNumJeeps );
//Called when entering a sector so the campaign AI can automatically insert the //Called when entering a sector so the campaign AI can automatically insert the
//correct number of troops of each type based on the current number in the sector //correct number of troops of each type based on the current number in the sector
@@ -36,7 +36,7 @@ void GetNumberOfEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAd
BOOLEAN PrepareEnemyForSectorBattle(); BOOLEAN PrepareEnemyForSectorBattle();
BOOLEAN PrepareEnemyForUndergroundBattle(); BOOLEAN PrepareEnemyForUndergroundBattle();
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, BOOLEAN fMagicallyAppeared ); void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 abNumJeeps, BOOLEAN fMagicallyAppeared );
void AddMilitiaToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumGreens, UINT8 ubNumRegulars, UINT8 ubNumElites, BOOLEAN fMagicallyAppeared ); void AddMilitiaToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumGreens, UINT8 ubNumRegulars, UINT8 ubNumElites, BOOLEAN fMagicallyAppeared );
void AddPossiblePendingEnemiesToBattle(); void AddPossiblePendingEnemiesToBattle();
void EndTacticalBattleForEnemy(); void EndTacticalBattleForEnemy();
+33 -17
View File
@@ -33,20 +33,21 @@
UINT8 gubReinforcementMinEnemyStaticGroupSize = 12; UINT8 gubReinforcementMinEnemyStaticGroupSize = 12;
UINT32 guiMilitiaReinforceTurn = 0, guiMilitiaArrived = 0;//dnl ch68 090913 UINT32 guiMilitiaReinforceTurn = 0, guiMilitiaArrived = 0;//dnl ch68 090913
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks ) void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps;
UINT16 pusMoveDir[4][3]; //first column in this matrix is number of sector, except for 4th row UINT16 pusMoveDir[4][3]; //first column in this matrix is number of sector, except for 4th row
UINT8 ubDirNumber, ubIndex; UINT8 ubDirNumber, ubIndex;
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks ); GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks, pubNumJeeps );
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites; *pubNumElites += ubNumElites;
*pubNumTanks += ubNumTanks; *pubNumTanks += ubNumTanks;
*pubNumJeeps += ubNumJeeps;
if( !gGameExternalOptions.gfAllowReinforcements ) if( !gGameExternalOptions.gfAllowReinforcements )
return; return;
@@ -56,21 +57,23 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
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 )
{ //take number of the involved sector, find its X and Y coordintes and then ask for number of troops there { //take number of the involved sector, find its X and Y coordintes and then ask for number of troops there
GetNumberOfStationaryEnemiesInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfStationaryEnemiesInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
while( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks > gubReinforcementMinEnemyStaticGroupSize) //count how many of static group will reinforce the battle, but leave minimal group size to guard while ( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks + ubNumJeeps > gubReinforcementMinEnemyStaticGroupSize ) //count how many of static group will reinforce the battle, but leave minimal group size to guard
{ {
if( ubNumElites ) if( ubNumElites )
{ {
*pubNumElites += 1; *pubNumElites += 1;
ubNumElites--; ubNumElites--;
}else if( ubNumTroops ) }
else if( ubNumTroops )
{ {
*pubNumTroops += 1; *pubNumTroops += 1;
ubNumTroops--; ubNumTroops--;
}else if( ubNumAdmins ) }
else if( ubNumAdmins )
{ {
*pubNumAdmins += 1; *pubNumAdmins += 1;
ubNumAdmins--; ubNumAdmins--;
@@ -80,24 +83,30 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
*pubNumTanks += 1; *pubNumTanks += 1;
ubNumTanks--; ubNumTanks--;
} }
else if ( ubNumJeeps )
{
*pubNumJeeps += 1;
ubNumJeeps--;
}
} }
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ), ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites; *pubNumElites += ubNumElites;
*pubNumTanks += ubNumTanks; *pubNumTanks += ubNumTanks;
*pubNumJeeps += ubNumJeeps;
} }
} }
UINT8 NumEnemiesInFiveSectors( INT16 sMapX, INT16 sMapY ) UINT8 NumEnemiesInFiveSectors( INT16 sMapX, INT16 sMapY )
{ {
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps;
GetNumberOfEnemiesInFiveSectors( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks ); GetNumberOfEnemiesInFiveSectors( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps );
return ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks; return ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps;
} }
BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY ) BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY )
@@ -255,28 +264,35 @@ UINT8 DoReinforcementAsPendingNonPlayer( INT16 sMapX, INT16 sMapY, UINT8 usTeam
(pThisSector->ubNumElites)++; (pThisSector->ubNumElites)++;
(pSector->ubNumElites)--; (pSector->ubNumElites)--;
(pThisSector->ubElitesInBattle)++; (pThisSector->ubElitesInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 1, 0, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 1, 0, 0, FALSE );
} }
else if( pSector->ubNumTroops ) else if( pSector->ubNumTroops )
{ {
(pThisSector->ubNumTroops)++; (pThisSector->ubNumTroops)++;
(pSector->ubNumTroops)--; (pSector->ubNumTroops)--;
(pThisSector->ubTroopsInBattle)++; (pThisSector->ubTroopsInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 1, 0, 0, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 1, 0, 0, 0, FALSE );
} }
else if( pSector->ubNumAdmins ) else if( pSector->ubNumAdmins )
{ {
(pThisSector->ubNumAdmins)++; (pThisSector->ubNumAdmins)++;
(pSector->ubNumAdmins)--; (pSector->ubNumAdmins)--;
(pThisSector->ubAdminsInBattle)++; (pThisSector->ubAdminsInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 1, 0, 0, 0, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 1, 0, 0, 0, 0, FALSE );
} }
else if( pSector->ubNumTanks ) else if( pSector->ubNumTanks )
{ {
(pThisSector->ubNumTanks)++; (pThisSector->ubNumTanks)++;
(pSector->ubNumTanks)--; (pSector->ubNumTanks)--;
(pThisSector->ubTanksInBattle)++; (pThisSector->ubTanksInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 0, 1, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 0, 1, 0, FALSE );
}
else if ( pSector->ubNumJeeps )
{
(pThisSector->ubNumJeeps)++;
(pSector->ubNumJeeps)--;
(pThisSector->ubJeepsInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 0, 0, 0, 0, 1, FALSE );
} }
return (UINT8)pusMoveDir[ ubIndex ][ 2 ]; return (UINT8)pusMoveDir[ ubIndex ][ 2 ];
+1 -1
View File
@@ -2,7 +2,7 @@
#define __REINFORCEMENT_H__ #define __REINFORCEMENT_H__
//For Autoresolve (mostly) //For Autoresolve (mostly)
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks ); void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY ); BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY );
UINT8 GetAdjacentSectors( UINT8 pSectors[4], INT16 sSectorX, INT16 sSectorY ); UINT8 GetAdjacentSectors( UINT8 pSectors[4], INT16 sSectorX, INT16 sSectorY );
UINT8 CountAllMilitiaInFiveSectors(INT16 sMapX, INT16 sMapY); UINT8 CountAllMilitiaInFiveSectors(INT16 sMapX, INT16 sMapY);
+455 -223
View File
File diff suppressed because it is too large Load Diff
+8 -3
View File
@@ -700,7 +700,7 @@ BOOLEAN AddWaypointStrategicIDToPGroup( GROUP *pGroup, UINT32 uiSectorID )
//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, UINT8 ubNumJeeps )
{ {
GROUP *pNew; GROUP *pNew;
AssertMsg( uiSector >= 0 && uiSector <= 255, String( "CreateNewEnemyGroup with out of range value of %d", uiSector ) ); AssertMsg( uiSector >= 0 && uiSector <= 255, String( "CreateNewEnemyGroup with out of range value of %d", uiSector ) );
@@ -711,7 +711,7 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
AssertMsg( pNew->pEnemyGroup, "MemAlloc failure during enemy group creation." ); AssertMsg( pNew->pEnemyGroup, "MemAlloc failure during enemy group creation." );
memset( pNew->pEnemyGroup, 0, sizeof( ENEMYGROUP ) ); memset( pNew->pEnemyGroup, 0, sizeof( ENEMYGROUP ) );
// Make sure group is not bigger than allowed! // Make sure group is not bigger than allowed!
while (ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks > gGameExternalOptions.iMaxEnemyGroupSize) while ( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps > gGameExternalOptions.iMaxEnemyGroupSize )
{ {
if (ubNumTroops) if (ubNumTroops)
{ {
@@ -729,6 +729,10 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
{ {
ubNumTanks--; ubNumTanks--;
} }
else if ( ubNumJeeps )
{
ubNumJeeps--;
}
} }
pNew->pWaypoints = NULL; pNew->pWaypoints = NULL;
pNew->ubSectorX = (UINT8)SECTORX( uiSector ); pNew->ubSectorX = (UINT8)SECTORX( uiSector );
@@ -743,7 +747,8 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
pNew->pEnemyGroup->ubNumTroops = ubNumTroops; pNew->pEnemyGroup->ubNumTroops = ubNumTroops;
pNew->pEnemyGroup->ubNumElites = ubNumElites; pNew->pEnemyGroup->ubNumElites = ubNumElites;
pNew->pEnemyGroup->ubNumTanks = ubNumTanks; pNew->pEnemyGroup->ubNumTanks = ubNumTanks;
pNew->ubGroupSize = (UINT8)(ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks); pNew->pEnemyGroup->ubNumJeeps = ubNumJeeps;
pNew->ubGroupSize = (UINT8)(ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps);
pNew->ubTransportationMask = FOOT; pNew->ubTransportationMask = FOOT;
pNew->fVehicle = FALSE; pNew->fVehicle = FALSE;
pNew->ubCreatedSectorID = pNew->ubOriginalSector; pNew->ubCreatedSectorID = pNew->ubOriginalSector;
+4 -2
View File
@@ -73,7 +73,9 @@ typedef struct ENEMYGROUP
// WDS - New AI // WDS - New AI
UINT8 ubNumTanks; UINT8 ubNumTanks;
UINT8 ubTanksInBattle; UINT8 ubTanksInBattle;
INT8 bPadding[18]; UINT8 ubNumJeeps;
UINT8 ubJeepsInBattle;
INT8 bPadding[16];
}ENEMYGROUP; }ENEMYGROUP;
//NOTE: ALL FLAGS ARE CLEARED WHENEVER A GROUP ARRIVES IN A SECTOR, OR ITS WAYPOINTS ARE //NOTE: ALL FLAGS ARE CLEARED WHENEVER A GROUP ARRIVES IN A SECTOR, OR ITS WAYPOINTS ARE
@@ -181,7 +183,7 @@ 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 ubNumTanksm, UINT8 ubNumJeeps );
GROUP* CreateNewMilitiaGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites ); GROUP* CreateNewMilitiaGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites );
+2
View File
@@ -89,6 +89,7 @@ BOOLEAN LuaUnderground::InitializeSectorList()
sectorData.getValue("numTroops", s->ubNumTroops); sectorData.getValue("numTroops", s->ubNumTroops);
sectorData.getValue("numElites", s->ubNumElites); sectorData.getValue("numElites", s->ubNumElites);
sectorData.getValue("numTanks", s->ubNumTanks); sectorData.getValue("numTanks", s->ubNumTanks);
sectorData.getValue("numJeeps", s->ubNumJeeps );
sectorData.getValue("numBloodcats", s->ubNumBloodcats); sectorData.getValue("numBloodcats", s->ubNumBloodcats);
sectorData.getValue("numCreatures", s->ubNumCreatures); sectorData.getValue("numCreatures", s->ubNumCreatures);
@@ -106,6 +107,7 @@ BOOLEAN LuaUnderground::InitializeSectorList()
m_log << "\t\tTroops: " << static_cast<int>(s->ubNumTroops) << LF; m_log << "\t\tTroops: " << static_cast<int>(s->ubNumTroops) << LF;
m_log << "\t\tElites: " << static_cast<int>(s->ubNumElites) << LF; m_log << "\t\tElites: " << static_cast<int>(s->ubNumElites) << LF;
m_log << "\t\tTanks: " << static_cast<int>(s->ubNumTanks) << LF; m_log << "\t\tTanks: " << static_cast<int>(s->ubNumTanks) << LF;
m_log << "\t\tJeeps: " << static_cast<int>(s->ubNumJeeps) << LF;
m_log << "\t- Creature population" << LF; m_log << "\t- Creature population" << LF;
m_log << "\t\tBloodcats: " << static_cast<int>(s->ubNumBloodcats) << LF; m_log << "\t\tBloodcats: " << static_cast<int>(s->ubNumBloodcats) << LF;
m_log << "\t\tCrepitus: " << static_cast<int>(s->ubNumCreatures) << LF; m_log << "\t\tCrepitus: " << static_cast<int>(s->ubNumCreatures) << LF;
+33 -42
View File
@@ -5349,56 +5349,47 @@ BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile )
UINT32 uiNumBytesRead = 0; UINT32 uiNumBytesRead = 0;
UINT32 uiSize = sizeof(StrategicMapElement); UINT32 uiSize = sizeof(StrategicMapElement);
if ( guiCurrentSaveGameVersion < MILITIA_MOVEMENT )
if ( guiCurrentSaveGameVersion >= MILITIA_MOVEMENT )
{
for ( UINT16 i = 0; i < MAP_WORLD_X * MAP_WORLD_Y; ++i )
{
// Load the strategic map information
FileRead( hFile, &StrategicMap[i], uiSize, &uiNumBytesRead );
if ( uiNumBytesRead != uiSize )
{
return(FALSE);
}
}
}
else
{
uiSize = 41; uiSize = 41;
for ( UINT16 i = 0; i < MAP_WORLD_X * MAP_WORLD_Y; ++i ) for ( UINT16 i = 0; i < MAP_WORLD_X * MAP_WORLD_Y; ++i )
{
// Load the strategic map information
FileRead( hFile, &StrategicMap[i], uiSize, &uiNumBytesRead );
if ( uiNumBytesRead != uiSize )
{
return(FALSE);
}
StrategicMap[i].usFlags = 0;
}
}
// Load the Sector Info
for ( int sectorID = 0; sectorID <= 255; ++sectorID )
{ {
FileRead( hFile, &SectorInfo[sectorID], sizeof(SECTORINFO), &uiNumBytesRead ); // Load the strategic map information
if ( uiNumBytesRead != sizeof(SECTORINFO) ) FileRead( hFile, &StrategicMap[i], uiSize, &uiNumBytesRead );
if ( uiNumBytesRead != uiSize )
{ {
return(FALSE); return(FALSE);
} }
// Flugente: changes in SECTORINFO require a weird-looking remapping if ( guiCurrentSaveGameVersion < MILITIA_MOVEMENT )
if ( guiCurrentSaveGameVersion < PRISONER_EXPANSION ) StrategicMap[i].usFlags = 0;
{ }
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_GENERAL] = 0;
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_CIVILIAN] = 0; // Load the Sector Info
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_SECRET1] = 0; uiSize = sizeof(SECTORINFO);
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_SECRET2] = 0; if ( guiCurrentSaveGameVersion < ENEMY_JEEPS )
SectorInfo[sectorID].ubNumTanks = SectorInfo[sectorID].uiInterrogationHundredsLeft[PRISONER_GENERAL]; uiSize = 116;
SectorInfo[sectorID].ubTanksInBattle = SectorInfo[sectorID].uiInterrogationHundredsLeft[PRISONER_CIVILIAN];
} for ( int sectorID = 0; sectorID <= 255; ++sectorID )
{
FileRead( hFile, &SectorInfo[sectorID], uiSize, &uiNumBytesRead );
if ( uiNumBytesRead != uiSize )
{
return(FALSE);
} }
// Flugente: changes in SECTORINFO require a weird-looking remapping
if ( guiCurrentSaveGameVersion < PRISONER_EXPANSION )
{
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_GENERAL] = 0;
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_CIVILIAN] = 0;
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_SECRET1] = 0;
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_SECRET2] = 0;
SectorInfo[sectorID].ubNumTanks = SectorInfo[sectorID].uiInterrogationHundredsLeft[PRISONER_GENERAL];
SectorInfo[sectorID].ubTanksInBattle = SectorInfo[sectorID].uiInterrogationHundredsLeft[PRISONER_CIVILIAN];
}
}
// uiSize = sizeof( SECTORINFO ) * 256; // uiSize = sizeof( SECTORINFO ) * 256;
// FileRead( hFile, SectorInfo, uiSize, &uiNumBytesRead ); // FileRead( hFile, SectorInfo, uiSize, &uiNumBytesRead );
// if( uiNumBytesRead != uiSize) // if( uiNumBytesRead != uiSize)
+36 -4
View File
@@ -1118,6 +1118,7 @@ ANI_SPEED_DEF gubAnimWalkSpeeds[ TOTALBODYTYPES ] =
-10, (FLOAT)4.0, //ELDORADO -10, (FLOAT)4.0, //ELDORADO
-10, (FLOAT)4.0, //ICECREAMTRUCK -10, (FLOAT)4.0, //ICECREAMTRUCK
-10, (FLOAT)4.0, //JEEP -10, (FLOAT)4.0, //JEEP
-10, (FLOAT)4.0, //COMBAT_JEEP
}; };
extern INT16 gubMaxActionPoints[TOTALBODYTYPES] = {0}; extern INT16 gubMaxActionPoints[TOTALBODYTYPES] = {0};
@@ -3592,7 +3593,10 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ TANK_NW ][ TANK_SHOOT ] = TANKNW_SHOOT; gubAnimSurfaceIndex[ TANK_NW ][ TANK_SHOOT ] = TANKNW_SHOOT;
gubAnimSurfaceIndex[ TANK_NW ][ TANK_BURST ] = TANKNW_SHOOT; gubAnimSurfaceIndex[ TANK_NW ][ TANK_BURST ] = TANKNW_SHOOT;
gubAnimSurfaceIndex[ TANK_NW ][ VEHICLE_DIE ] = TANKNW_DIE; gubAnimSurfaceIndex[ TANK_NW ][ VEHICLE_DIE ] = TANKNW_DIE;
gubAnimSurfaceCorpseID[ TANK_NW ][ STANDING ] = TANK1_DEAD; gubAnimSurfaceCorpseID[TANK_NW][STANDING] = TANK1_DEAD;
gubAnimSurfaceCorpseID[TANK_NW][WALKING] = TANK1_DEAD;
gubAnimSurfaceCorpseID[TANK_NW][RUNNING] = TANK1_DEAD;
gubAnimSurfaceCorpseID[TANK_NW][WALK_BACKWARDS] = TANK1_DEAD;
// TANK // TANK
gubAnimSurfaceIndex[ TANK_NE ][ STANDING ] = TANKNE_READY; gubAnimSurfaceIndex[ TANK_NE ][ STANDING ] = TANKNE_READY;
@@ -3603,6 +3607,9 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ TANK_NE ][ TANK_BURST ] = TANKNE_SHOOT; gubAnimSurfaceIndex[ TANK_NE ][ TANK_BURST ] = TANKNE_SHOOT;
gubAnimSurfaceIndex[ TANK_NE ][ VEHICLE_DIE ] = TANKNE_DIE; gubAnimSurfaceIndex[ TANK_NE ][ VEHICLE_DIE ] = TANKNE_DIE;
gubAnimSurfaceCorpseID[ TANK_NE ][ STANDING ] = TANK2_DEAD; gubAnimSurfaceCorpseID[ TANK_NE ][ STANDING ] = TANK2_DEAD;
gubAnimSurfaceCorpseID[ TANK_NE ][WALKING] = TANK2_DEAD;
gubAnimSurfaceCorpseID[ TANK_NE ][RUNNING] = TANK2_DEAD;
gubAnimSurfaceCorpseID[ TANK_NE ][WALK_BACKWARDS] = TANK2_DEAD;
// ELDORADO // ELDORADO
gubAnimSurfaceIndex[ ELDORADO ][ STANDING ] = ELDORADO_BASIC; gubAnimSurfaceIndex[ ELDORADO ][ STANDING ] = ELDORADO_BASIC;
@@ -3610,21 +3617,45 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ ELDORADO ][ RUNNING ] = ELDORADO_BASIC; gubAnimSurfaceIndex[ ELDORADO ][ RUNNING ] = ELDORADO_BASIC;
gubAnimSurfaceIndex[ ELDORADO ][ WALK_BACKWARDS ] = ELDORADO_BASIC; gubAnimSurfaceIndex[ ELDORADO ][ WALK_BACKWARDS ] = ELDORADO_BASIC;
gubAnimSurfaceIndex[ ELDORADO ][ VEHICLE_DIE ] = ELDORADO_DIE; gubAnimSurfaceIndex[ ELDORADO ][ VEHICLE_DIE ] = ELDORADO_DIE;
gubAnimSurfaceCorpseID[ELDORADO][STANDING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ELDORADO][WALKING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ELDORADO][RUNNING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ELDORADO][WALK_BACKWARDS] = ICECREAM_DEAD;
// ICECREAMTRUCK // ICECREAMTRUCK
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ STANDING ] = ICECREAMTRUCK_BASIC; gubAnimSurfaceIndex[ ICECREAMTRUCK ][ STANDING ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ WALKING ] = ICECREAMTRUCK_BASIC; gubAnimSurfaceIndex[ ICECREAMTRUCK ][ WALKING ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ RUNNING ] = ICECREAMTRUCK_BASIC; gubAnimSurfaceIndex[ ICECREAMTRUCK ][ RUNNING ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ WALK_BACKWARDS ] = ICECREAMTRUCK_BASIC; gubAnimSurfaceIndex[ ICECREAMTRUCK ][ WALK_BACKWARDS ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ VEHICLE_DIE ] = HUMVEE_DIE; gubAnimSurfaceIndex[ ICECREAMTRUCK ][ VEHICLE_DIE ] = HUMVEE_DIE;
gubAnimSurfaceCorpseID[ ICECREAMTRUCK ][ STANDING ] = ICECREAM_DEAD; gubAnimSurfaceCorpseID[ICECREAMTRUCK][STANDING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ICECREAMTRUCK][WALKING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ICECREAMTRUCK][RUNNING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ICECREAMTRUCK][WALK_BACKWARDS] = ICECREAM_DEAD;
// JEEP // JEEP
gubAnimSurfaceIndex[ JEEP ][ STANDING ] = JEEP_BASIC; gubAnimSurfaceIndex[ JEEP ][ STANDING ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ WALKING ] = JEEP_BASIC; gubAnimSurfaceIndex[ JEEP ][ WALKING ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ RUNNING ] = JEEP_BASIC; gubAnimSurfaceIndex[ JEEP ][ RUNNING ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ WALK_BACKWARDS ] = JEEP_BASIC; gubAnimSurfaceIndex[ JEEP ][ WALK_BACKWARDS ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ VEHICLE_DIE ] = JEEP_DIE; gubAnimSurfaceIndex[ JEEP ][ VEHICLE_DIE ] = JEEP_DIE;
gubAnimSurfaceCorpseID[JEEP][STANDING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[JEEP][WALKING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[JEEP][RUNNING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[JEEP][WALK_BACKWARDS] = ICECREAM_DEAD;
// COMBAT_JEEP
gubAnimSurfaceIndex[COMBAT_JEEP][STANDING] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][WALKING] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][RUNNING] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][WALK_BACKWARDS] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][TANK_SHOOT] = ARMED_CAR_SHOOT;
gubAnimSurfaceIndex[COMBAT_JEEP][TANK_BURST] = ARMED_CAR_SHOOT;
gubAnimSurfaceIndex[COMBAT_JEEP][VEHICLE_DIE] = ARMED_CAR_DIE;
gubAnimSurfaceCorpseID[COMBAT_JEEP][STANDING] = HUMMER_DEAD;
gubAnimSurfaceCorpseID[COMBAT_JEEP][WALKING] = HUMMER_DEAD;
gubAnimSurfaceCorpseID[COMBAT_JEEP][RUNNING] = HUMMER_DEAD;
gubAnimSurfaceCorpseID[COMBAT_JEEP][WALK_BACKWARDS] = HUMMER_DEAD;
} }
BOOLEAN LoadAnimationStateInstructions( ) BOOLEAN LoadAnimationStateInstructions( )
@@ -3991,6 +4022,7 @@ INT8 GetBodyTypePaletteSubstitutionCode( SOLDIERTYPE *pSoldier, UINT8 ubBodyType
case ROBOTNOWEAPON: case ROBOTNOWEAPON:
case TANK_NW: case TANK_NW:
case TANK_NE: case TANK_NE:
case COMBAT_JEEP:
return( 0 ); return( 0 );
} }
+11
View File
@@ -472,6 +472,10 @@ AnimationSurfaceType gAnimSurfaceDatabase[ NUMANIMATIONSURFACETYPES ] =
JEEP_BASIC, "ANIMS\\VEHICLES\\JEEP.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1, JEEP_BASIC, "ANIMS\\VEHICLES\\JEEP.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
JEEP_DIE, "ANIMS\\VEHICLES\\HM_WREK.STI", NO_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1, JEEP_DIE, "ANIMS\\VEHICLES\\HM_WREK.STI", NO_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1,
ARMED_CAR_READY, "ANIMS\\VEHICLES\\LATV_ROT.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
ARMED_CAR_SHOOT, "ANIMS\\VEHICLES\\LATV_SHT.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
ARMED_CAR_DIE, "ANIMS\\VEHICLES\\LATV_DIE.STI", S_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1,
BODYEXPLODE, "ANIMS\\S_MERC\\BOD_BLOW.STI", NO_STRUCT, 0, 1, TO_INIT, NULL, NULL, 0, -1, BODYEXPLODE, "ANIMS\\S_MERC\\BOD_BLOW.STI", NO_STRUCT, 0, 1, TO_INIT, NULL, NULL, 0, -1,
//<SB> crouch throwing //<SB> crouch throwing
@@ -802,6 +806,13 @@ AnimationStructureType gAnimStructureDatabase[ TOTALBODYTYPES ][ NUM_STRUCT_IDS
"ANIMS\\STRUCTDATA\\JEEP.JSD", NULL, "ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default "ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
//COMBAT_JEEP
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
}; };
+5
View File
@@ -66,6 +66,7 @@ enum SoldierBodyTypes
ELDORADO, ELDORADO,
ICECREAMTRUCK, ICECREAMTRUCK,
JEEP, JEEP,
COMBAT_JEEP, // Flugente, smeagol & DepressivesBrot: lightly armored tactical vehicle
TOTALBODYTYPES TOTALBODYTYPES
@@ -503,6 +504,10 @@ typedef enum
JEEP_BASIC, JEEP_BASIC,
JEEP_DIE, JEEP_DIE,
ARMED_CAR_READY,
ARMED_CAR_SHOOT,
ARMED_CAR_DIE,
BODYEXPLODE, BODYEXPLODE,
//<SB> crouch throwing //<SB> crouch throwing
+1
View File
@@ -321,6 +321,7 @@ void DoneFadeOutKilledQueen( void )
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubTroopsInBattle = 0; SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubTroopsInBattle = 0;
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubElitesInBattle = 0; SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubElitesInBattle = 0;
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubTanksInBattle = 0; SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubTanksInBattle = 0;
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubJeepsInBattle = 0;
// ATE: banish elliot... dead or alive // ATE: banish elliot... dead or alive
gMercProfiles[ ELLIOT ].sSectorX = 0; gMercProfiles[ ELLIOT ].sSectorX = 0;
+49 -17
View File
@@ -44,7 +44,7 @@ int gCivPreservedTempFileVersion[256];
BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *pNode, GROUP *pGroup = NULL ); BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *pNode, GROUP *pGroup = NULL );
BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks ); BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
BOOLEAN gfRestoringEnemySoldiersFromTempFile = FALSE; BOOLEAN gfRestoringEnemySoldiersFromTempFile = FALSE;
BOOLEAN gfRestoringCiviliansFromTempFile = FALSE; BOOLEAN gfRestoringCiviliansFromTempFile = FALSE;
@@ -105,8 +105,8 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
#endif #endif
INT8 bSectorZ; INT8 bSectorZ;
UINT8 ubSectorID; UINT8 ubSectorID;
UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0; UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0, ubNumJeeps = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks; UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps;
gfRestoringEnemySoldiersFromTempFile = TRUE; gfRestoringEnemySoldiersFromTempFile = TRUE;
@@ -255,6 +255,7 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
ubStrategicTroops = pSector->ubNumTroops; ubStrategicTroops = pSector->ubNumTroops;
ubStrategicAdmins = pSector->ubNumAdmins; ubStrategicAdmins = pSector->ubNumAdmins;
ubStrategicTanks = pSector->ubNumTanks; ubStrategicTanks = pSector->ubNumTanks;
ubStrategicJeeps = pSector->ubNumJeeps;
ubStrategicCreatures = pSector->ubNumCreatures; ubStrategicCreatures = pSector->ubNumCreatures;
} }
else else
@@ -262,7 +263,7 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
SECTORINFO *pSector; SECTORINFO *pSector;
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubStrategicCreatures = pSector->ubNumCreatures; ubStrategicCreatures = pSector->ubNumCreatures;
GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks ); GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks, &ubStrategicJeeps );
} }
for( i = 0; i < slots; i++ ) for( i = 0; i < slots; i++ )
@@ -359,6 +360,16 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
} }
} }
break; break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( curr->pBasicPlacement ) )
{
++ubNumJeeps;
if ( ubNumJeeps < ubStrategicJeeps )
{
AddPlacementToWorld( curr );
}
}
break;
} }
break; break;
} }
@@ -386,14 +397,16 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
} }
//now add any extra enemies that have arrived since the temp file was made. //now add any extra enemies that have arrived since the temp file was made.
if( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks ) if ( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks || ubStrategicJeeps > ubNumJeeps )
{ {
ubStrategicTroops = ( ubStrategicTroops > ubNumTroops ) ? ubStrategicTroops - ubNumTroops : 0; ubStrategicTroops = ( ubStrategicTroops > ubNumTroops ) ? ubStrategicTroops - ubNumTroops : 0;
ubStrategicElites = ( ubStrategicElites > ubNumElites ) ? ubStrategicElites - ubNumElites : 0; ubStrategicElites = ( ubStrategicElites > ubNumElites ) ? ubStrategicElites - ubNumElites : 0;
ubStrategicAdmins = ( ubStrategicAdmins > ubNumAdmins ) ? ubStrategicAdmins - ubNumAdmins : 0; ubStrategicAdmins = ( ubStrategicAdmins > ubNumAdmins ) ? ubStrategicAdmins - ubNumAdmins : 0;
ubStrategicTanks = ( ubStrategicTanks > ubNumTanks ) ? ubStrategicTanks - ubNumTanks : 0; ubStrategicTanks = ( ubStrategicTanks > ubNumTanks ) ? ubStrategicTanks - ubNumTanks : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks ); ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks, ubStrategicJeeps );
} }
if( ubStrategicCreatures > ubNumCreatures ) if( ubStrategicCreatures > ubNumCreatures )
{ {
ubStrategicCreatures; //not sure if this wil ever happen. If so, needs to be handled. ubStrategicCreatures; //not sure if this wil ever happen. If so, needs to be handled.
@@ -675,8 +688,8 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
#endif #endif
INT8 bSectorZ; INT8 bSectorZ;
UINT8 ubSectorID; UINT8 ubSectorID;
UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0; UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0, ubNumJeeps = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks; UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps;
gfRestoringEnemySoldiersFromTempFile = TRUE; gfRestoringEnemySoldiersFromTempFile = TRUE;
@@ -716,16 +729,17 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
ubNumTroops = pSector->ubNumTroops; ubNumTroops = pSector->ubNumTroops;
ubNumAdmins = pSector->ubNumAdmins; ubNumAdmins = pSector->ubNumAdmins;
ubNumTanks = pSector->ubNumTanks; ubNumTanks = pSector->ubNumTanks;
ubNumJeeps = pSector->ubNumJeeps;
ubNumCreatures = pSector->ubNumCreatures; ubNumCreatures = pSector->ubNumCreatures;
} }
if( !( gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) ) if( !( gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{ {
// Get the number of enemies form the temp file // Get the number of enemies form the temp file
CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( &ubStrategicElites, &ubStrategicTroops, &ubStrategicAdmins, &ubStrategicCreatures, &ubStrategicTanks ); CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( &ubStrategicElites, &ubStrategicTroops, &ubStrategicAdmins, &ubStrategicCreatures, &ubStrategicTanks, &ubStrategicJeeps );
//If any of the counts differ from what is in memory //If any of the counts differ from what is in memory
if( ubStrategicElites != ubNumElites || ubStrategicTroops != ubNumTroops || ubStrategicAdmins != ubNumAdmins || ubStrategicCreatures != ubNumCreatures || ubStrategicTanks != ubNumTanks ) if ( ubStrategicElites != ubNumElites || ubStrategicTroops != ubNumTroops || ubStrategicAdmins != ubNumAdmins || ubStrategicCreatures != ubNumCreatures || ubStrategicTanks != ubNumTanks || ubStrategicJeeps != ubNumJeeps )
{ {
//remove the file //remove the file
RemoveEnemySoldierTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); RemoveEnemySoldierTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
@@ -734,7 +748,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
} }
//reset //reset
ubNumElites = ubNumTroops = ubNumAdmins = ubNumCreatures = ubNumTanks = 0; ubNumElites = ubNumTroops = ubNumAdmins = ubNumCreatures = ubNumTanks = ubNumJeeps = 0;
//Open the file for reading //Open the file for reading
@@ -875,6 +889,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
ubStrategicTroops = pSector->ubNumTroops; ubStrategicTroops = pSector->ubNumTroops;
ubStrategicAdmins = pSector->ubNumAdmins; ubStrategicAdmins = pSector->ubNumAdmins;
ubStrategicTanks = pSector->ubNumTanks; ubStrategicTanks = pSector->ubNumTanks;
ubStrategicJeeps = pSector->ubNumJeeps;
ubStrategicCreatures = pSector->ubNumCreatures; ubStrategicCreatures = pSector->ubNumCreatures;
} }
else else
@@ -882,7 +897,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
SECTORINFO *pSector; SECTORINFO *pSector;
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubStrategicCreatures = pSector->ubNumCreatures; ubStrategicCreatures = pSector->ubNumCreatures;
GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks ); GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks, &ubStrategicJeeps );
} }
for( i = 0; i < slots; i++ ) for( i = 0; i < slots; i++ )
@@ -969,6 +984,16 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
} }
} }
break; break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( curr->pBasicPlacement ) )
{
++ubNumJeeps;
if ( ubNumJeeps <= ubStrategicJeeps )
{
//def: AddPlacementToWorld( curr );
}
}
break;
} }
break; break;
} }
@@ -994,21 +1019,21 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
} }
//now add any extra enemies that have arrived since the temp file was made. //now add any extra enemies that have arrived since the temp file was made.
if( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks ) if ( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks || ubStrategicJeeps > ubNumJeeps )
{ {
ubStrategicTroops = ( ubStrategicTroops > ubNumTroops ) ? ubStrategicTroops - ubNumTroops : 0; ubStrategicTroops = ( ubStrategicTroops > ubNumTroops ) ? ubStrategicTroops - ubNumTroops : 0;
ubStrategicElites = ( ubStrategicElites > ubNumElites ) ? ubStrategicElites - ubNumElites : 0; ubStrategicElites = ( ubStrategicElites > ubNumElites ) ? ubStrategicElites - ubNumElites : 0;
ubStrategicAdmins = ( ubStrategicAdmins > ubNumAdmins ) ? ubStrategicAdmins - ubNumAdmins : 0; ubStrategicAdmins = ( ubStrategicAdmins > ubNumAdmins ) ? ubStrategicAdmins - ubNumAdmins : 0;
ubStrategicTanks = ( ubStrategicTanks > ubNumTanks ) ? ubStrategicTanks - ubNumTanks : 0; ubStrategicTanks = ( ubStrategicTanks > ubNumTanks ) ? ubStrategicTanks - ubNumTanks : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks ); ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks, ubStrategicJeeps );
} }
if( ubStrategicCreatures > ubNumCreatures ) if( ubStrategicCreatures > ubNumCreatures )
{ {
ubStrategicCreatures; //not sure if this wil ever happen. If so, needs to be handled. ubStrategicCreatures; //not sure if this wil ever happen. If so, needs to be handled.
} }
//set the number of enemies in the sector //set the number of enemies in the sector
if( bSectorZ ) if( bSectorZ )
{ {
@@ -1593,7 +1618,7 @@ BOOLEAN NewWayOfSavingEnemyAndCivliansToTempFile( INT16 sSectorX, INT16 sSectorY
BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks ) BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
// SOLDIERINITNODE *curr; // SOLDIERINITNODE *curr;
SOLDIERCREATE_STRUCT tempDetailedPlacement; SOLDIERCREATE_STRUCT tempDetailedPlacement;
@@ -1617,6 +1642,7 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
*pubNumRegulars = 0; *pubNumRegulars = 0;
*pubNumAdmins = 0; *pubNumAdmins = 0;
*pubNumTanks = 0; *pubNumTanks = 0;
*pubNumJeeps = 0;
*pubNumCreatures = 0; *pubNumCreatures = 0;
//STEP ONE: Set up the temp file to read from. //STEP ONE: Set up the temp file to read from.
@@ -1785,6 +1811,12 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
(*pubNumTanks)++; (*pubNumTanks)++;
} }
break; break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( (&tempDetailedPlacement) ) )
{
(*pubNumJeeps)++;
}
break;
} }
/* /*
while( curr ) while( curr )
+3
View File
@@ -5315,6 +5315,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
} }
} }
#include "Strategic AI.h"
// Flugente: callback after deciding what tactical function to use // Flugente: callback after deciding what tactical function to use
void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue ) void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue )
{ {
@@ -5356,6 +5357,8 @@ void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue )
break; break;
case 8: case 8:
ExecuteStrategicAIAction( NPC_ACTION_SEND_SOLDIERS_TO_DRASSEN, 0, 0 );
break;
default: default:
break; break;
} }
+79 -4
View File
@@ -1156,13 +1156,21 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
return( GAME_SCREEN ); return( GAME_SCREEN );
} }
usRandom = (UINT16)Random( 12 ); // Flugente hack
if( usRandom < 3 ) /*if ( Water(usMapPos) )
pSoldier = TacticalCreateEnemyBoat( );
else
pSoldier = TacticalCreateEnemyJeep( );*/
usRandom = (UINT16)Random( 20 );
if( usRandom < 5 )
pSoldier = TacticalCreateAdministrator(); pSoldier = TacticalCreateAdministrator();
else if( usRandom < 6 ) else if( usRandom < 10 )
pSoldier = TacticalCreateArmyTroop(); pSoldier = TacticalCreateArmyTroop();
else if ( usRandom < 9 ) else if ( usRandom < 12 )
pSoldier = TacticalCreateEnemyTank( ); pSoldier = TacticalCreateEnemyTank( );
else if ( usRandom < 15 )
pSoldier = TacticalCreateEnemyJeep( );
else else
pSoldier = TacticalCreateEliteEnemy( ); pSoldier = TacticalCreateEliteEnemy( );
@@ -1178,6 +1186,7 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break; case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break; case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
case SOLDIER_CLASS_TANK: pSector->ubNumTanks++; pSector->ubTanksInBattle++; break; case SOLDIER_CLASS_TANK: pSector->ubNumTanks++; pSector->ubTanksInBattle++; break;
case SOLDIER_CLASS_JEEP: pSector->ubNumJeeps++; pSector->ubJeepsInBattle++; break;
} }
} }
else else
@@ -1191,6 +1200,7 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break; case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break; case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
case SOLDIER_CLASS_TANK: pSector->ubNumTanks++; pSector->ubTanksInBattle++; break; case SOLDIER_CLASS_TANK: pSector->ubNumTanks++; pSector->ubTanksInBattle++; break;
case SOLDIER_CLASS_JEEP: pSector->ubNumJeeps++; pSector->ubJeepsInBattle++; break;
} }
} }
} }
@@ -1205,6 +1215,71 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
return( GAME_SCREEN ); return( GAME_SCREEN );
} }
/*void TankBattlefun()
{
int teamsize = 1;
for ( int i = 0; i < teamsize; ++i)
{
{
SOLDIERTYPE *pSoldier = TacticalCreateTankFuntime(ENEMY_TEAM);
if( pSoldier )
{
if( !gbWorldSectorZ )
{
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
switch( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
}
}
else
{
UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
if( pSector )
{
switch( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
}
}
}
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
//pSoldier->usStrategicInsertionData = gMapInformation.sSouthGridNo;
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
AllTeamsLookForAll( NO_INTERRUPTS );
}
}
{
SOLDIERTYPE *pSoldier = TacticalCreateTankFuntime(MILITIA_TEAM);
if( pSoldier )
{
pSoldier->ubSoldierClass = SOLDIER_CLASS_ELITE_MILITIA;
if( !gbWorldSectorZ )
{
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
pSector->ubNumberOfCivsAtLevel[ELITE_MILITIA]++;
}
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_SOUTH;
//pSoldier->usStrategicInsertionData = gMapInformation.sSouthGridNo;
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
AllTeamsLookForAll( NO_INTERRUPTS );
}
}
}
}*/
UINT32 UIHandleEnterEditMode( UI_EVENT *pUIEvent ) UINT32 UIHandleEnterEditMode( UI_EVENT *pUIEvent )
{ {
+3 -3
View File
@@ -2365,7 +2365,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
} }
/////////////////// ANTI-TANK AMMO /////////////////// ANTI-TANK AMMO
if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank ) if ( AmmoTypes[Magazine[Item[gpItemDescObject->usItem].ubClassIndex].ubAmmoType].dDamageModifierTank >= 0.1f )
{ {
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 1 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 1 ]); swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 1 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 1 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr ); SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -5946,8 +5946,8 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
} }
/////////////////// ANTI-TANK AMMO /////////////////// ANTI-TANK AMMO
if ( ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank && !fComparisonMode ) || if ( (AmmoTypes[Magazine[Item[gpItemDescObject->usItem].ubClassIndex].ubAmmoType].dDamageModifierTank >= 0.1f && !fComparisonMode) ||
( fComparisonMode && AmmoTypes[Magazine[Item[ gpComparedItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank ) ) (fComparisonMode && AmmoTypes[Magazine[Item[gpComparedItemDescObject->usItem].ubClassIndex].ubAmmoType].dDamageModifierTank >= 0.1f ) )
{ {
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 1, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 1, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++; cnt++;
+1 -1
View File
@@ -2024,7 +2024,7 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
swprintf( NameStr, zGrod[0] ); swprintf( NameStr, zGrod[0] );
} }
//Legion //Legion
else if ( TANK( pSoldier ) ) else if ( ARMED_VEHICLE( pSoldier ) )
{ {
swprintf( NameStr, gNewVehicle[164].NewVehicleStrings ); swprintf( NameStr, gNewVehicle[164].NewVehicleStrings );
} }
+25 -17
View File
@@ -91,7 +91,7 @@ ARMY_GUN_CHOICE_TYPE gExtendedArmyGunChoices[SOLDIER_GUN_CHOICE_SELECTIONS][ARMY
ARMY_GUN_CHOICE_TYPE gArmyItemChoices[SOLDIER_GUN_CHOICE_SELECTIONS][MAX_ITEM_TYPES]; ARMY_GUN_CHOICE_TYPE gArmyItemChoices[SOLDIER_GUN_CHOICE_SELECTIONS][MAX_ITEM_TYPES];
void RandomlyChooseWhichItemsAreDroppable( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass ); void RandomlyChooseWhichItemsAreDroppable( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass );
void EquipTank( SOLDIERCREATE_STRUCT *pp ); void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp, BOOLEAN fTank = TRUE );
void ChooseKitsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bKitClass ); void ChooseKitsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bKitClass );
void ChooseMiscGearForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bMiscClass ); void ChooseMiscGearForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bMiscClass );
@@ -251,13 +251,13 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
return; return;
} }
if ( TANK( pp ) ) if ( ARMED_VEHICLE( pp ) )
{ {
EquipTank( pp ); EquipArmouredVehicle( pp, TANK( pp ) );
return; return;
} }
Assert( ( bSoldierClass >= SOLDIER_CLASS_NONE ) && ( bSoldierClass <= SOLDIER_CLASS_ELITE_MILITIA ) || bSoldierClass == SOLDIER_CLASS_TANK ); Assert( (bSoldierClass >= SOLDIER_CLASS_NONE) && (bSoldierClass <= SOLDIER_CLASS_ELITE_MILITIA) || bSoldierClass == SOLDIER_CLASS_TANK || bSoldierClass == SOLDIER_CLASS_JEEP );
Assert( ( bEquipmentRating >= 0 ) && ( bEquipmentRating <= 4 ) ); Assert( ( bEquipmentRating >= 0 ) && ( bEquipmentRating <= 4 ) );
// equipment level is modified by 1/10 of the difficulty percentage, -5, so it's between -5 to +5 // equipment level is modified by 1/10 of the difficulty percentage, -5, so it's between -5 to +5
@@ -3406,23 +3406,32 @@ UINT16 SelectStandardArmyGun( UINT8 uiGunLevel, INT8 bSoldierClass )
void EquipTank( SOLDIERCREATE_STRUCT *pp ) void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp, BOOLEAN fTank )
{ {
// tanks get special equipment, and they drop nothing (MGs are hard-mounted & non-removable) // tanks get special equipment, and they drop nothing (MGs are hard-mounted & non-removable)
// main cannon // tanks get a main cannon and a MG, other vehicles just get the MG
CreateItem( TANK_CANNON, ( INT8 )( 80 + Random( 21 ) ), &( pp->Inv[ HANDPOS ]) ); if ( fTank )
pp->Inv[ HANDPOS ].fFlags |= OBJECT_UNDROPPABLE; {
CreateItem( TANK_CANNON, ( INT8 )( 80 + Random( 21 ) ), &( pp->Inv[ HANDPOS ]) );
pp->Inv[ HANDPOS ].fFlags |= OBJECT_UNDROPPABLE;
// machine gun // tanks don't deplete shells or ammo...
CreateItems( MINIMI, ( INT8 )( 80 + Random( 21 ) ), 1, &gTempObject ); CreateItems( TANK_SHELL, 100, 1, &gTempObject );
gTempObject.fFlags |= OBJECT_UNDROPPABLE; gTempObject.fFlags |= OBJECT_UNDROPPABLE;
PlaceObjectInSoldierCreateStruct( pp, &gTempObject ); PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
// tanks don't deplete shells or ammo... // machine gun
CreateItems( TANK_SHELL, 100, 1, &gTempObject ); CreateItems( MINIMI, (INT8)(80 + Random( 21 )), 1, &gTempObject );
gTempObject.fFlags |= OBJECT_UNDROPPABLE; gTempObject.fFlags |= OBJECT_UNDROPPABLE;
PlaceObjectInSoldierCreateStruct( pp, &gTempObject ); PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
}
else
{
// machine gun
CreateItems( MINIMI, (INT8)(80 + Random( 21 )), 1, &(pp->Inv[HANDPOS]) );
pp->Inv[HANDPOS].fFlags |= OBJECT_UNDROPPABLE;
}
// armour equal to spectra all over (for vs explosives) // armour equal to spectra all over (for vs explosives)
CreateItem( SPECTRA_VEST, 100, &(pp->Inv[ VESTPOS ]) ); CreateItem( SPECTRA_VEST, 100, &(pp->Inv[ VESTPOS ]) );
@@ -3431,7 +3440,6 @@ void EquipTank( SOLDIERCREATE_STRUCT *pp )
pp->Inv[ HELMETPOS ].fFlags |= OBJECT_UNDROPPABLE; pp->Inv[ HELMETPOS ].fFlags |= OBJECT_UNDROPPABLE;
CreateItem( SPECTRA_LEGGINGS, 100, &(pp->Inv[ LEGPOS ]) ); CreateItem( SPECTRA_LEGGINGS, 100, &(pp->Inv[ LEGPOS ]) );
pp->Inv[ LEGPOS ].fFlags |= OBJECT_UNDROPPABLE; pp->Inv[ LEGPOS ].fFlags |= OBJECT_UNDROPPABLE;
} }
+2 -2
View File
@@ -3229,7 +3229,7 @@ void SwapObjs(SOLDIERTYPE* pSoldier, int leftSlot, int rightSlot, BOOLEAN fPerma
{ {
SwapObjs(&pSoldier->inv[ leftSlot ], &pSoldier->inv[ rightSlot ]); SwapObjs(&pSoldier->inv[ leftSlot ], &pSoldier->inv[ rightSlot ]);
if(fPermanent && !TANK(pSoldier))//dnl ch64 290813 for current tank don't go further as it lead to invalid animation if ( fPermanent && !ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813 for current tank don't go further as it lead to invalid animation
{ {
//old usItem for the left slot is now stored in the right slot, and vice versa //old usItem for the left slot is now stored in the right slot, and vice versa
HandleTacticalEffectsOfEquipmentChange(pSoldier, leftSlot, pSoldier->inv[ rightSlot ].usItem, pSoldier->inv[ leftSlot ].usItem); HandleTacticalEffectsOfEquipmentChange(pSoldier, leftSlot, pSoldier->inv[ rightSlot ].usItem, pSoldier->inv[ leftSlot ].usItem);
@@ -8953,7 +8953,7 @@ void CheckEquipmentForDamage( SOLDIERTYPE *pSoldier, INT32 iDamage )
BOOLEAN fBlowsUp; BOOLEAN fBlowsUp;
UINT8 ubNumberOfObjects; UINT8 ubNumberOfObjects;
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
return; return;
} }
+7 -7
View File
@@ -2047,7 +2047,7 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p
ubPosType = TORSO_TARGET_POS; ubPosType = TORSO_TARGET_POS;
} }
} }
else if ( TANK( pSoldier ) ) else if ( ARMED_VEHICLE( pSoldier ) )
{ {
// high up! // high up!
//ubPosType = HEAD_TARGET_POS; //ubPosType = HEAD_TARGET_POS;
@@ -2184,7 +2184,7 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p
// robot is 1/3 the height of regular people // robot is 1/3 the height of regular people
*pdZPos = *pdZPos / 3; *pdZPos = *pdZPos / 3;
} }
else if ( TANK ( pSoldier ) ) else if ( ARMED_VEHICLE( pSoldier ) )
{ {
*pdZPos = (*pdZPos * 4) / 3; *pdZPos = (*pdZPos * 4) / 3;
} }
@@ -2311,7 +2311,7 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
fSmell = HasThermalOptics( pStartSoldier); fSmell = HasThermalOptics( pStartSoldier);
} }
if ( TANK( pStartSoldier ) ) if ( ARMED_VEHICLE( pStartSoldier ) )
{ {
INT16 sDistance; INT16 sDistance;
@@ -2352,7 +2352,7 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
// anv: special check for vehicles - since they're no longer transparent, we need to check for visibility // anv: special check for vehicles - since they're no longer transparent, we need to check for visibility
// of all substructures, also vehicle will be noticed even if just part of it is sticking around the corner // of all substructures, also vehicle will be noticed even if just part of it is sticking around the corner
if( pEndSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && ( !TANK( pEndSoldier ) || gGameExternalOptions.fEnemyTanksAnyPartVisible ) ) if ( pEndSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && (!ARMED_VEHICLE( pEndSoldier ) || gGameExternalOptions.fEnemyTanksAnyPartVisible) )
{ {
STRUCTURE *pBase = pEndSoldier->pLevelNode->pStructureData; STRUCTURE *pBase = pEndSoldier->pLevelNode->pStructureData;
if( pBase == NULL ) if( pBase == NULL )
@@ -2917,7 +2917,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
{ {
usExpGain /= 2; usExpGain /= 2;
} }
else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTarget ) || TANK( pTarget ) ) else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTarget ) || ARMED_VEHICLE( pTarget ) )
{ {
// no exp from shooting a vehicle that you can't damage and can't move! // no exp from shooting a vehicle that you can't damage and can't move!
usExpGain = 0; usExpGain = 0;
@@ -3305,7 +3305,7 @@ INT32 HandleBulletStructureInteraction( BULLET * pBullet, STRUCTURE * pStructure
//else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE ) //else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE )
//{ //{
// stops if using HE ammo // stops if using HE ammo
else if ( AmmoTypes[ubAmmoType].highExplosive && !AmmoTypes[ubAmmoType].antiTank ) else if ( AmmoTypes[ubAmmoType].highExplosive && AmmoTypes[ubAmmoType].dDamageModifierTank < 0.1f )
{ {
*pfHit = TRUE; *pfHit = TRUE;
return( 0 ); return( 0 );
@@ -3457,7 +3457,7 @@ INT32 CTGTHandleBulletStructureInteraction( BULLET * pBullet, STRUCTURE * pStruc
//else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE ) //else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE )
//{ //{
// stops if using HE ammo // stops if using HE ammo
else if ( AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ][0]->data.gun.ubGunAmmoType].highExplosive && !AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ][0]->data.gun.ubGunAmmoType].antiTank ) else if ( AmmoTypes[pBullet->pFirer->inv[pBullet->pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType].highExplosive && AmmoTypes[pBullet->pFirer->inv[pBullet->pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType].dDamageModifierTank < 0.1f )
{ {
return( pBullet->iImpact ); return( pBullet->iImpact );
} }
+6 -6
View File
@@ -3585,7 +3585,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
// //
gMercProfiles[ pSoldierOld->ubProfile ].bLife = 0; gMercProfiles[ pSoldierOld->ubProfile ].bLife = 0;
if ( !(pSoldierOld->flags.uiStatusFlags & SOLDIER_VEHICLE) && !TANK( pSoldierOld) ) if ( !(pSoldierOld->flags.uiStatusFlags & SOLDIER_VEHICLE) && !ARMED_VEHICLE( pSoldierOld ) )
{ {
if ( pSoldierOld->ubAttackerID != NOBODY ) if ( pSoldierOld->ubAttackerID != NOBODY )
{ {
@@ -7021,16 +7021,16 @@ void RemoveStaticEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{ {
SECTORINFO *pSectorInfo = &(SectorInfo[SECTOR( sMapX, sMapY )]); SECTORINFO *pSectorInfo = &(SectorInfo[SECTOR( sMapX, sMapY )]);
pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = 0; pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = pSectorInfo->ubNumJeeps = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = 0; pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = 0;
} }
else else
{ {
UNDERGROUND_SECTORINFO *pSectorInfo; UNDERGROUND_SECTORINFO *pSectorInfo;
pSectorInfo = FindUnderGroundSector( sMapX, sMapY, bMapZ ); pSectorInfo = FindUnderGroundSector( sMapX, sMapY, bMapZ );
pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = 0; pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = pSectorInfo->ubNumJeeps = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = 0; pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = 0;
} }
} }
@@ -10485,7 +10485,7 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
{ {
enemysidestrength += pSoldier->GetSurrenderStrength(); enemysidestrength += pSoldier->GetSurrenderStrength();
if ( pSoldier->ubProfile != NO_PROFILE || TANK(pSoldier) ) if ( pSoldier->ubProfile != NO_PROFILE || ARMED_VEHICLE(pSoldier) )
fNoSurrender = TRUE; fNoSurrender = TRUE;
} }
} }
+10 -7
View File
@@ -2621,7 +2621,10 @@ if(!GridNoOnVisibleWorldTile(iDestination))
fPathingForPlayer = ( (s->bTeam == gbPlayerNum) && (!gTacticalStatus.fAutoBandageMode) && !(s->flags.uiStatusFlags & SOLDIER_PCUNDERAICONTROL) ); fPathingForPlayer = ( (s->bTeam == gbPlayerNum) && (!gTacticalStatus.fAutoBandageMode) && !(s->flags.uiStatusFlags & SOLDIER_PCUNDERAICONTROL) );
fNonFenceJumper = !( IS_MERC_BODY_TYPE( s ) ) || (UsingNewInventorySystem() == true && FindBackpackOnSoldier( s ) != ITEM_NOT_FOUND);//Moa: added backpack check fNonFenceJumper = !( IS_MERC_BODY_TYPE( s ) ) || (UsingNewInventorySystem() == true && FindBackpackOnSoldier( s ) != ITEM_NOT_FOUND);//Moa: added backpack check
fNonSwimmer = !( IS_MERC_BODY_TYPE( s ) );
// Flugente: nonswimmers are those who are not mercs and not boats
fNonSwimmer = !(IS_MERC_BODY_TYPE( s ) );
if ( fNonSwimmer ) if ( fNonSwimmer )
{ {
if ( Water( sDestination, ubLevel ) ) if ( Water( sDestination, ubLevel ) )
@@ -2638,13 +2641,13 @@ if(!GridNoOnVisibleWorldTile(iDestination))
fVehicleIgnoreObstacles = TRUE; fVehicleIgnoreObstacles = TRUE;
} }
// AI can't press shift, let's assume only tanks ram through (we wouldn't want AI cars to get destroyed kamikazing through walls, no matter how funny that would be) // AI can't press shift, let's assume only tanks ram through (we wouldn't want AI cars to get destroyed kamikazing through walls, no matter how funny that would be)
else if( !fPathingForPlayer && TANK(s) ) else if ( !fPathingForPlayer && ARMED_VEHICLE( s ) )
{ {
fVehicleIgnoreObstacles = TRUE; fVehicleIgnoreObstacles = TRUE;
} }
if( fVehicleIgnoreObstacles && if( fVehicleIgnoreObstacles &&
( ( gGameExternalOptions.fAllowCarsDrivingOverPeople && !TANK(s) ) || ((gGameExternalOptions.fAllowCarsDrivingOverPeople && !ARMED_VEHICLE( s )) ||
( gGameExternalOptions.fAllowTanksDrivingOverPeople && TANK(s) ) ) ) (gGameExternalOptions.fAllowTanksDrivingOverPeople && ARMED_VEHICLE( s ))) )
{ {
fPathAroundPeople = FALSE; fPathAroundPeople = FALSE;
} }
@@ -2846,9 +2849,9 @@ if(!GridNoOnVisibleWorldTile(iDestination))
else else
{ {
if (ISWATER(gubWorldMovementCosts[iOrigination][0][ubLevel]) && ISWATER(gubWorldMovementCosts[iDestination][0][ubLevel])) if (ISWATER(gubWorldMovementCosts[iOrigination][0][ubLevel]) && ISWATER(gubWorldMovementCosts[iDestination][0][ubLevel]))
iWaterToWater = 1; iWaterToWater = 1;
else else
iWaterToWater = 0; iWaterToWater = 0;
} }
//setup Q and first path record //setup Q and first path record
@@ -4617,7 +4620,7 @@ INT32 PlotPath( SOLDIERTYPE *pSold, INT32 sDestGridNo, INT8 bCopyRoute, INT8 bPl
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_RUN]; sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_RUN];
break; break;
case WALKING: case WALKING:
if (!(pSold->MercInWater()) && ( (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIRE ) )) if ( 0 && !(pSold->MercInWater()) && ( (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIRE ) ))
{ {
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY]; sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY];
} }
+17 -15
View File
@@ -57,9 +57,9 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState );
INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8 bLevel ) INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8 bLevel )
{ {
// SANDRO - Note: this procedure was changed a bit // SANDRO - Note: this procedure was changed a bit
INT16 sAPCost = 0; INT16 sAPCost = 0;
INT16 sSwitchValue; INT16 sSwitchValue;
BOOLEAN fHiddenStructVisible; // Used for hidden struct visiblity BOOLEAN fHiddenStructVisible; // Used for hidden struct visiblity
// SANDRO - removed AP cost of moving stealthy or reversed outside this procedure // SANDRO - removed AP cost of moving stealthy or reversed outside this procedure
@@ -67,7 +67,7 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8
// switchValue = BackupGridCost[gridno]; // switchValue = BackupGridCost[gridno];
//else //else
sSwitchValue = gubWorldMovementCosts[sGridNo][bDir][ bLevel ]; sSwitchValue = gubWorldMovementCosts[sGridNo][bDir][ bLevel ];
// Check reality vs what the player knows.... // Check reality vs what the player knows....
if ( pSoldier->bTeam == gbPlayerNum ) if ( pSoldier->bTeam == gbPlayerNum )
@@ -83,15 +83,16 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8
} }
} }
} }
//ddd window //ddd window
if ( sSwitchValue == TRAVELCOST_JUMPABLEWINDOW if ( sSwitchValue == TRAVELCOST_JUMPABLEWINDOW
|| sSwitchValue == TRAVELCOST_JUMPABLEWINDOW_N || sSwitchValue == TRAVELCOST_JUMPABLEWINDOW_N
|| sSwitchValue == TRAVELCOST_JUMPABLEWINDOW_W) || sSwitchValue == TRAVELCOST_JUMPABLEWINDOW_W)
{ {
if (bDir & 1) if (bDir & 1)
return -1; return -1;
} }
//ddd if we don't check this condition, then when we approach to the tile with a window, when the distance to that tile will be 1 //ddd if we don't check this condition, then when we approach to the tile with a window, when the distance to that tile will be 1
//we'll get nice message, that the way is blocked //we'll get nice message, that the way is blocked
if ( sSwitchValue == TRAVELCOST_NOT_STANDING)// || sSwitchValue == TRAVELCOST_JUMPABLEWINDOW) if ( sSwitchValue == TRAVELCOST_NOT_STANDING)// || sSwitchValue == TRAVELCOST_JUMPABLEWINDOW)
@@ -106,6 +107,7 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8
{ {
return -1; return -1;
} }
sSwitchValue = DoorTravelCost( pSoldier, sGridNo, (UINT8) sSwitchValue, (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), NULL ); sSwitchValue = DoorTravelCost( pSoldier, sGridNo, (UINT8) sSwitchValue, (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), NULL );
} }
else if (gfPlotPathToExitGrid && sSwitchValue == TRAVELCOST_EXITGRID) else if (gfPlotPathToExitGrid && sSwitchValue == TRAVELCOST_EXITGRID)
@@ -138,20 +140,20 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8
case TRAVELCOST_DEBRIS : sAPCost += APBPConstants[AP_MOVEMENT_RUBBLE]; case TRAVELCOST_DEBRIS : sAPCost += APBPConstants[AP_MOVEMENT_RUBBLE];
break; break;
case TRAVELCOST_SHORE : sAPCost += APBPConstants[AP_MOVEMENT_SHORE]; // wading shallow water case TRAVELCOST_SHORE : sAPCost += APBPConstants[AP_MOVEMENT_SHORE]; // wading shallow water
if (!IS_MERC_BODY_TYPE( pSoldier )) if ( !IS_MERC_BODY_TYPE( pSoldier ) )
{ {
return -1; return -1;
} }
break; break;
case TRAVELCOST_KNEEDEEP : sAPCost += APBPConstants[AP_MOVEMENT_LAKE]; // wading waist/chest deep - very slow case TRAVELCOST_KNEEDEEP : sAPCost += APBPConstants[AP_MOVEMENT_LAKE]; // wading waist/chest deep - very slow
if (!IS_MERC_BODY_TYPE( pSoldier )) if ( !IS_MERC_BODY_TYPE( pSoldier ) )
{ {
return -1; return -1;
} }
break; break;
case TRAVELCOST_DEEPWATER: sAPCost += APBPConstants[AP_MOVEMENT_OCEAN]; // can swim, so it's faster than wading case TRAVELCOST_DEEPWATER: sAPCost += APBPConstants[AP_MOVEMENT_OCEAN]; // can swim, so it's faster than wading
if (!IS_MERC_BODY_TYPE( pSoldier )) if ( !IS_MERC_BODY_TYPE( pSoldier ) )
{ {
return -1; return -1;
} }
@@ -1474,7 +1476,7 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
sBreathPerAP = APBPConstants[BP_PER_AP_MIN_EFFORT]; sBreathPerAP = APBPConstants[BP_PER_AP_MIN_EFFORT];
// OK, check if we are in water and are waling/standing // OK, check if we are in water and are waling/standing
if ( pSoldier->MercInWater( ) ) if ( 0 && pSoldier->MercInWater( ) )
{ {
switch( usAnimState ) switch( usAnimState )
{ {
@@ -2481,7 +2483,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime,
} }
} }
if ( AM_A_ROBOT( pSoldier ) || TANK( pSoldier ) || ubForceRaiseGunCost == 2 )//dnl ch64 300813 robots and tanks cannot do this //dnl ch69 150913 need option to override raise gun cost if ( AM_A_ROBOT( pSoldier ) || ARMED_VEHICLE( pSoldier ) || ubForceRaiseGunCost == 2 )//dnl ch64 300813 robots and tanks cannot do this //dnl ch69 150913 need option to override raise gun cost
{ {
fAddingRaiseGunCost = FALSE; fAddingRaiseGunCost = FALSE;
} }
@@ -2632,7 +2634,7 @@ INT16 MinPtsToMove(SOLDIERTYPE *pSoldier)
INT16 sCost; INT16 sCost;
INT32 sGridNo; INT32 sGridNo;
if ( TANK( pSoldier ) && !gGameExternalOptions.fEnemyTanksCanMoveInTactical ) if ( ARMED_VEHICLE( pSoldier ) && !gGameExternalOptions.fEnemyTanksCanMoveInTactical )
{ {
return(sLowest);//dnl ch64 290813 100AP made INT8 return obsolete return(sLowest);//dnl ch64 290813 100AP made INT8 return obsolete
} }
@@ -2837,7 +2839,7 @@ void DeductAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE* pObj )
{ {
// tanks never run out of MG ammo! // tanks never run out of MG ammo!
// unlimited cannon ammo is handled in AI // unlimited cannon ammo is handled in AI
if ( TANK( pSoldier ) && !Item[pObj->usItem].cannon ) if ( ARMED_VEHICLE( pSoldier ) && !Item[pObj->usItem].cannon )
return; return;
if ( Item[pObj->usItem].cannon ) if ( Item[pObj->usItem].cannon )
@@ -4031,7 +4033,7 @@ INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAim
Assert(pSoldier != NULL); Assert(pSoldier != NULL);
Assert(&pSoldier->inv[HANDPOS] != NULL); Assert(&pSoldier->inv[HANDPOS] != NULL);
#ifndef dnlCALCBESTSHOT//dnl ch69 150913 if this is turn on we get incorrect APs as MinAPsToShootOrStab always include raise gun cost #ifndef dnlCALCBESTSHOT//dnl ch69 150913 if this is turn on we get incorrect APs as MinAPsToShootOrStab always include raise gun cost
if (!TANK(pSoldier) && !( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_FIREREADY | ANIM_FIRE )))//dnl ch64 310813 if (!ARMED_VEHICLE(pSoldier) && !( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_FIREREADY | ANIM_FIRE )))//dnl ch64 310813
{ {
// Weapon not ready, check aiming from hip, else add raise gun cost // Weapon not ready, check aiming from hip, else add raise gun cost
//if (!pSoldier->IsValidShotFromHip(bAimTime,sTargetGridNo)) //if (!pSoldier->IsValidShotFromHip(bAimTime,sTargetGridNo))
@@ -4238,7 +4240,7 @@ INT32 GetBPCostPer10APsForGunHolding( SOLDIERTYPE * pSoldier, BOOLEAN fEstimate
return 0; return 0;
if ( !(gAnimControl[ pSoldier->usAnimState ].uiFlags & (ANIM_FIRE | ANIM_FIREREADY) ) && !fEstimate ) // don't if weapon not raised, but do if we are gonna estimate the cost if ( !(gAnimControl[ pSoldier->usAnimState ].uiFlags & (ANIM_FIRE | ANIM_FIREREADY) ) && !fEstimate ) // don't if weapon not raised, but do if we are gonna estimate the cost
return 0; return 0;
if ( TANK( pSoldier ) || AM_A_ROBOT( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) )
return 0; return 0;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// THE BASIC COST FOR HOLDING THE GUN RAISED (per AP) // THE BASIC COST FOR HOLDING THE GUN RAISED (per AP)
@@ -4379,7 +4381,7 @@ INT32 GetBPCostForRecoilkick( SOLDIERTYPE * pSoldier )
return 0; return 0;
if ( Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usItemClass != IC_GUN && Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usItemClass != IC_LAUNCHER ) if ( Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usItemClass != IC_GUN && Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usItemClass != IC_LAUNCHER )
return 0; return 0;
if ( TANK( pSoldier ) || AM_A_ROBOT( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) )
return 0; return 0;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// THE GUN RECOIL KICK ENERGY COST // THE GUN RECOIL KICK ENERGY COST
+2 -1
View File
@@ -3949,7 +3949,7 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
default : default :
if ( CREATURE_OR_BLOODCAT( pSoldier ) ) if ( CREATURE_OR_BLOODCAT( pSoldier ) )
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++; gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++;
else if ( TANK( pSoldier ) ) else if ( ARMED_VEHICLE( pSoldier ) )
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsTanks++; gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsTanks++;
else if ( pSoldier->bTeam == CIV_TEAM && !pSoldier->aiData.bNeutral && pSoldier->bSide != gbPlayerNum ) else if ( pSoldier->bTeam == CIV_TEAM && !pSoldier->aiData.bNeutral && pSoldier->bSide != gbPlayerNum )
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsHostiles++; gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsHostiles++;
@@ -4209,6 +4209,7 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier )
case QUEENMONSTER: case QUEENMONSTER:
case TANK_NW: case TANK_NW:
case TANK_NE: case TANK_NE:
case COMBAT_JEEP:
pSoldier->stats.bLife = 0; pSoldier->stats.bLife = 0;
break; break;
+20 -19
View File
@@ -5122,7 +5122,7 @@ UINT16 SelectFireAnimation( SOLDIERTYPE *pSoldier, UINT8 ubHeight )
return(TANK_SHOOT); return(TANK_SHOOT);
} }
if ( TANK(pSoldier) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
return(TANK_BURST); return(TANK_BURST);
} }
@@ -5474,7 +5474,7 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady, BOOL
return(INVALID_ANIMATION); return(INVALID_ANIMATION);
} }
if ( TANK(pSoldier) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
return(INVALID_ANIMATION); return(INVALID_ANIMATION);
} }
@@ -8095,7 +8095,7 @@ void SOLDIERTYPE::TurnSoldier( void )
if ( ((gAnimControl[this->usAnimState].uiFlags & ANIM_FIREREADY) && if ( ((gAnimControl[this->usAnimState].uiFlags & ANIM_FIREREADY) &&
this->flags.bTurningFromPronePosition == TURNING_FROM_PRONE_OFF) || this->flags.bTurningFromPronePosition == TURNING_FROM_PRONE_OFF) ||
this->ubBodyType == ROBOTNOWEAPON || this->ubBodyType == ROBOTNOWEAPON ||
TANK(this) ) ARMED_VEHICLE( this ) )
{ {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "TurnSoldier: EVENT_InitNewSoldierAnim" ) ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "TurnSoldier: EVENT_InitNewSoldierAnim" ) );
this->EVENT_InitNewSoldierAnim( SelectFireAnimation( this, gAnimControl[this->usAnimState].ubEndHeight ), 0, FALSE ); this->EVENT_InitNewSoldierAnim( SelectFireAnimation( this, gAnimControl[this->usAnimState].ubEndHeight ), 0, FALSE );
@@ -8175,7 +8175,7 @@ void SOLDIERTYPE::TurnSoldier( void )
// Don't do anything if we are at dest direction! // Don't do anything if we are at dest direction!
if ( this->ubDirection == this->pathing.bDesiredDirection ) if ( this->ubDirection == this->pathing.bDesiredDirection )
{ {
if ( TANK(this) ) if ( ARMED_VEHICLE( this ) )
{ {
if ( this->iTuringSoundID != NO_SAMPLE ) if ( this->iTuringSoundID != NO_SAMPLE )
{ {
@@ -8324,7 +8324,7 @@ void SOLDIERTYPE::TurnSoldier( void )
} }
} }
if ( TANK(this) ) if ( ARMED_VEHICLE( this ) )
{ {
if ( this->iTuringSoundID == NO_SAMPLE ) if ( this->iTuringSoundID == NO_SAMPLE )
{ {
@@ -9871,22 +9871,23 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
// OK, If we are a vehicle.... damage vehicle...( people inside... ) // OK, If we are a vehicle.... damage vehicle...( people inside... )
if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE ) if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE )
{ {
if ( TANK( this ) ) if ( ubReason == TAKE_DAMAGE_GUNFIRE )
{ {
//sLifeDeduct = (sLifeDeduct * 2) / 3; ;
} }
else if ( ubReason == TAKE_DAMAGE_EXPLOSION )
{
if ( ARMED_VEHICLE( this ) )
;
else else
{ {
if ( ubReason == TAKE_DAMAGE_GUNFIRE ) if ( sLifeDeduct > 50 )
{ {
sLifeDeduct /= 3;
}
else if ( ubReason == TAKE_DAMAGE_EXPLOSION && sLifeDeduct > 50 )
{
// boom! // boom!
sLifeDeduct *= 2; sLifeDeduct *= 2;
} }
} }
}
VehicleTakeDamage( this->bVehicleID, ubReason, sLifeDeduct, this->sGridNo, ubAttacker ); VehicleTakeDamage( this->bVehicleID, ubReason, sLifeDeduct, this->sGridNo, ubAttacker );
HandleTakeDamageDeath( this, bOldLife, ubReason ); HandleTakeDamageDeath( this, bOldLife, ubReason );
@@ -15992,7 +15993,7 @@ UINT32 SOLDIERTYPE::GetSurrenderStrength( )
value *= 0.75f; value *= 0.75f;
// tanks won't surrender that easy // tanks won't surrender that easy
if ( TANK( this ) ) if ( ARMED_VEHICLE( this ) )
value *= 10; value *= 10;
return value; return value;
@@ -16036,8 +16037,8 @@ BOOLEAN SOLDIERTYPE::CanBeCaptured( )
// if this guy is not already handcuffed, and is not an NPC // if this guy is not already handcuffed, and is not an NPC
if ( !(this->usSoldierFlagMask & SOLDIER_POW) && this->ubProfile == NO_PROFILE ) if ( !(this->usSoldierFlagMask & SOLDIER_POW) && this->ubProfile == NO_PROFILE )
{ {
// tanks cannot be captured // armed vehicles cannot be captured
if ( this->ubSoldierClass == SOLDIER_CLASS_TANK ) if ( ARMED_VEHICLE(this) )
return FALSE; return FALSE;
// enemies can be captured // enemies can be captured
@@ -18241,7 +18242,7 @@ BOOLEAN SOLDIERTYPE::CanMedicAI( )
return FALSE; return FALSE;
// this is not for tanks // this is not for tanks
if ( TANK( this ) ) if ( ARMED_VEHICLE( this ) )
return FALSE; return FALSE;
if ( HAS_SKILL_TRAIT( this, DOCTOR_NT ) ) if ( HAS_SKILL_TRAIT( this, DOCTOR_NT ) )
@@ -18273,7 +18274,7 @@ BOOLEAN SOLDIERTYPE::AIDoctorFriend( )
return FALSE; return FALSE;
// this is not for tanks // this is not for tanks
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
return FALSE; return FALSE;
// if this guy is wounded, heal him (should always be the case, otherwise this function was called needlessly) // if this guy is wounded, heal him (should always be the case, otherwise this function was called needlessly)
@@ -20504,7 +20505,7 @@ BOOLEAN SOLDIERTYPE::IsValidShotFromHip( INT16 bAimTime, INT32 iTrgGridNo )
return(FALSE); return(FALSE);
} }
// robots and tanks cannot do this // robots and tanks cannot do this
if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813 if ( AM_A_ROBOT( this ) || ARMED_VEHICLE( this ) )//dnl ch64 300813
{ {
return(FALSE); return(FALSE);
} }
@@ -20556,7 +20557,7 @@ BOOLEAN SOLDIERTYPE::IsValidPistolFastShot( INT16 bAimTime, INT32 iTrgGridNo )
return(FALSE); return(FALSE);
} }
// robots and tanks cannot do this // robots and tanks cannot do this
if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813 if ( AM_A_ROBOT( this ) || ARMED_VEHICLE( this ) )//dnl ch64 300813
{ {
return(FALSE); return(FALSE);
} }
+1
View File
@@ -332,6 +332,7 @@ enum
SOLDIER_CLASS_MINER, SOLDIER_CLASS_MINER,
SOLDIER_CLASS_ZOMBIE, SOLDIER_CLASS_ZOMBIE,
SOLDIER_CLASS_TANK, SOLDIER_CLASS_TANK,
SOLDIER_CLASS_JEEP,
SOLDIER_CLASS_MAX, SOLDIER_CLASS_MAX,
}; };
+46 -3
View File
@@ -606,7 +606,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
pCreateStruct->fPlayerPlan = 0; pCreateStruct->fPlayerPlan = 0;
} }
if ( is_networked && TANK( pCreateStruct ) ) if ( is_networked && ARMED_VEHICLE( pCreateStruct ) )
{ {
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank"); ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank");
return NULL; return NULL;
@@ -802,7 +802,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
Soldier.bOldLife = Soldier.stats.bLifeMax; Soldier.bOldLife = Soldier.stats.bLifeMax;
// Flugente: disease can affect a soldier's health // Flugente: disease can affect a soldier's health
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && Soldier.ubSoldierClass != SOLDIER_CLASS_TANK ) if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && !ARMED_VEHICLE((&Soldier)) )
{ {
UINT8 sector = SECTOR( Soldier.sSectorX, Soldier.sSectorY ); UINT8 sector = SECTOR( Soldier.sSectorX, Soldier.sSectorY );
UINT16 population = GetSectorPopulation( Soldier.sSectorX, Soldier.sSectorY ); UINT16 population = GetSectorPopulation( Soldier.sSectorX, Soldier.sSectorY );
@@ -1073,6 +1073,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
case JEEP: case JEEP:
case TANK_NW: case TANK_NW:
case TANK_NE: case TANK_NE:
case COMBAT_JEEP:
Soldier.flags.uiStatusFlags |= SOLDIER_VEHICLE; Soldier.flags.uiStatusFlags |= SOLDIER_VEHICLE;
@@ -1115,6 +1116,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
*/ */
case TANK_NW: case TANK_NW:
case TANK_NE: case TANK_NE:
case COMBAT_JEEP:
ubVehicleID = TANK_CAR; ubVehicleID = TANK_CAR;
break; break;
@@ -1704,7 +1706,7 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
// Flugente: soldier profiles // Flugente: soldier profiles
// silversurfer: Don't replace tanks! // silversurfer: Don't replace tanks!
if ( !TANK( pCreateStruct ) ) if ( !ARMED_VEHICLE( pCreateStruct ) )
{ {
// We have a function for this // We have a function for this
INT8 type = pSoldier->GetSoldierProfileType( pCreateStruct->bTeam ); INT8 type = pSoldier->GetSoldierProfileType( pCreateStruct->bTeam );
@@ -2476,6 +2478,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
break; break;
case SOLDIER_CLASS_TANK: case SOLDIER_CLASS_TANK:
case SOLDIER_CLASS_JEEP:
pp->bExpLevel = bp->bRelativeAttributeLevel; pp->bExpLevel = bp->bRelativeAttributeLevel;
break; break;
@@ -3127,6 +3130,46 @@ SOLDIERTYPE* TacticalCreateEnemyTank()
return( pSoldier ); return( pSoldier );
} }
SOLDIERTYPE* TacticalCreateEnemyJeep( )
{
BASIC_SOLDIERCREATE_STRUCT bp;
SOLDIERCREATE_STRUCT pp;
UINT8 ubID;
SOLDIERTYPE * pSoldier;
if ( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI )
{
pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_JEEP );
if ( pSoldier )
return pSoldier;
}
memset( &bp, 0, sizeof(BASIC_SOLDIERCREATE_STRUCT) );
RandomizeRelativeLevel( &(bp.bRelativeAttributeLevel), SOLDIER_CLASS_ELITE );
RandomizeRelativeLevel( &(bp.bRelativeEquipmentLevel), SOLDIER_CLASS_ELITE );
bp.bTeam = ENEMY_TEAM;
bp.bOrders = SEEKENEMY;
bp.bAttitude = (INT8)Random( MAXATTITUDES );
bp.ubBodyType = COMBAT_JEEP;
bp.ubSoldierClass = SOLDIER_CLASS_JEEP;
CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp );
pSoldier = TacticalCreateSoldier( &pp, &ubID );
if ( pSoldier )
{
// send soldier to centre of map, roughly
pSoldier->aiData.sNoiseGridno = (CENTRAL_GRIDNO + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) * WORLD_COLS);
pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION;
// Flugente: why would a vehicle's armour depend on game progress? Always give them 100 HP
pSoldier->stats.bLifeMax = 100;
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
}
return(pSoldier);
}
//USED BY STRATEGIC AI and AUTORESOLVE //USED BY STRATEGIC AI and AUTORESOLVE
// should to be succeeded by TacticalCreateArmyTroop/EliteEnemy and AddSoldierToVehicle // should to be succeeded by TacticalCreateArmyTroop/EliteEnemy and AddSoldierToVehicle
SOLDIERTYPE* TacticalCreateJeep() SOLDIERTYPE* TacticalCreateJeep()
+1
View File
@@ -443,6 +443,7 @@ SOLDIERTYPE* TacticalCreateZombie(); // Flugente Zombies
SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass, INT16 sX, INT16 sY ); // Flugente: added sector coordinates SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass, INT16 sX, INT16 sY ); // Flugente: added sector coordinates
SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType ); SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType );
SOLDIERTYPE* TacticalCreateEnemyTank(); SOLDIERTYPE* TacticalCreateEnemyTank();
SOLDIERTYPE* TacticalCreateEnemyJeep( );
SOLDIERTYPE* TacticalCreateJeep(); SOLDIERTYPE* TacticalCreateJeep();
// Flugente: create an armed civilian // Flugente: create an armed civilian
+71 -19
View File
@@ -591,7 +591,7 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
// First check if this guy has a profile and if so check his location such that it matches! // First check if this guy has a profile and if so check his location such that it matches!
// Get profile from placement info // Get profile from placement info
if ( TANK( curr->pBasicPlacement ) ) if ( ARMED_VEHICLE( curr->pBasicPlacement ) )
{ {
while (1) while (1)
{ {
@@ -804,7 +804,7 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld: create soldier")); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld: create soldier"));
if ( is_networked && ( TANK( (&tempDetailedPlacement) ) || tempDetailedPlacement.fOnRoof ) ) if ( is_networked && (ARMED_VEHICLE( (&tempDetailedPlacement) ) || tempDetailedPlacement.fOnRoof) )
return TRUE; return TRUE;
pSoldier = TacticalCreateSoldier( &tempDetailedPlacement, &ubID ); pSoldier = TacticalCreateSoldier( &tempDetailedPlacement, &ubID );
@@ -1019,7 +1019,7 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
return ubNumAdded; return ubNumAdded;
} }
void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks ) void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks, UINT8 ubTotalJeeps )
{ {
SOLDIERINITNODE *mark; SOLDIERINITNODE *mark;
SOLDIERINITNODE *curr; SOLDIERINITNODE *curr;
@@ -1029,6 +1029,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
UINT8 ubTroopPDSlots = 0, ubTroopDSlots = 0, ubTroopPSlots = 0, ubTroopBSlots = 0; UINT8 ubTroopPDSlots = 0, ubTroopDSlots = 0, ubTroopPSlots = 0, ubTroopBSlots = 0;
UINT8 ubAdminPDSlots = 0, ubAdminDSlots = 0, ubAdminPSlots = 0, ubAdminBSlots = 0; UINT8 ubAdminPDSlots = 0, ubAdminDSlots = 0, ubAdminPSlots = 0, ubAdminBSlots = 0;
UINT8 ubTankPDSlots = 0, ubTankDSlots = 0, ubTankPSlots = 0, ubTankBSlots = 0; UINT8 ubTankPDSlots = 0, ubTankDSlots = 0, ubTankPSlots = 0, ubTankBSlots = 0;
UINT8 ubJeepPDSlots = 0, ubJeepDSlots = 0, ubJeepPSlots = 0, ubJeepBSlots = 0;
UINT8 ubFreeSlots; UINT8 ubFreeSlots;
UINT8 *pCurrSlots=NULL; UINT8 *pCurrSlots=NULL;
UINT8 *pCurrTotal=NULL; UINT8 *pCurrTotal=NULL;
@@ -1046,7 +1047,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//of each type of enemy may not be the same. Elites will choose the best placements, then army, then //of each type of enemy may not be the same. Elites will choose the best placements, then army, then
//administrators. //administrators.
ubMaxNum = ubTotalAdmin + ubTotalTroops + ubTotalElite + ubTotalTanks; ubMaxNum = ubTotalAdmin + ubTotalTroops + ubTotalElite + ubTotalTanks + ubTotalJeeps;
AssertLE (ubMaxNum, gGameExternalOptions.ubGameMaximumNumberOfEnemies); AssertLE (ubMaxNum, gGameExternalOptions.ubGameMaximumNumberOfEnemies);
@@ -1096,6 +1097,18 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
else else
ubTroopBSlots++; ubTroopBSlots++;
break; break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( curr->pDetailedPlacement ) )
{
if ( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement )
ubJeepPDSlots++;
else if ( curr->pBasicPlacement->fPriorityExistance )
ubJeepPSlots++;
else if ( curr->pDetailedPlacement )
ubJeepDSlots++;
else
ubJeepBSlots++;
}
case SOLDIER_CLASS_TANK: case SOLDIER_CLASS_TANK:
if ( TANK( curr->pDetailedPlacement ) ) if ( TANK( curr->pDetailedPlacement ) )
{ {
@@ -1117,7 +1130,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//ADD PLACEMENTS WITH PRIORITY EXISTANCE WITH DETAILED PLACEMENT INFORMATION FIRST //ADD PLACEMENTS WITH PRIORITY EXISTANCE WITH DETAILED PLACEMENT INFORMATION FIRST
//we now have the numbers of available slots for each soldier class, so loop through three times //we now have the numbers of available slots for each soldier class, so loop through three times
//and randomly choose some (or all) of the matching slots to fill. This is done randomly. //and randomly choose some (or all) of the matching slots to fill. This is done randomly.
for( ubCurrClass = SOLDIER_CLASS_ADMINISTRATOR; ubCurrClass <= SOLDIER_CLASS_ARMY + 1; ubCurrClass++ ) for( ubCurrClass = SOLDIER_CLASS_ADMINISTRATOR; ubCurrClass <= SOLDIER_CLASS_ARMY + 2; ++ubCurrClass )
{ {
//First, prepare the counters. //First, prepare the counters.
switch( ubCurrClass ) switch( ubCurrClass )
@@ -1139,6 +1152,11 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
pCurrSlots = &ubTankPDSlots; pCurrSlots = &ubTankPDSlots;
pCurrTotal = &ubTotalTanks; pCurrTotal = &ubTotalTanks;
break; break;
case SOLDIER_CLASS_ARMY + 2:// SOLDIER_CLASS_JEEP
ubCurrClass = SOLDIER_CLASS_JEEP;
pCurrSlots = &ubJeepPDSlots;
pCurrTotal = &ubTotalJeeps;
break;
} }
//Now, loop through the priority existance and detailed placement section of the list. //Now, loop through the priority existance and detailed placement section of the list.
curr = gSoldierInitHead; curr = gSoldierInitHead;
@@ -1321,6 +1339,12 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
curr->pBasicPlacement->ubBodyType = TANK_NW; curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--; ubTotalTanks--;
} }
else if ( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--;
}
else else
Assert(0); Assert(0);
if( AddPlacementToWorld( curr ) ) if( AddPlacementToWorld( curr ) )
@@ -1406,18 +1430,34 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
curr = gSoldierInitHead; curr = gSoldierInitHead;
while( curr && ubFreeSlots && ubMaxNum ) while( curr && ubFreeSlots && ubMaxNum )
{ {
if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM && ubTotalTanks && !GridNoIndoors( curr->pBasicPlacement->usStartingGridNo )) if ( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM && !GridNoIndoors( curr->pBasicPlacement->usStartingGridNo ) && (ubTotalTanks || ubTotalJeeps) )
{ {
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK; if ( ubTotalJeeps )
curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--;
if( AddPlacementToWorld( curr ) )
{ {
ubMaxNum--; curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--;
if( AddPlacementToWorld( curr ) )
{
ubMaxNum--;
}
else
return;
ubFreeSlots--;
}
else if ( ubTotalTanks )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK;
curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--;
if ( AddPlacementToWorld( curr ) )
{
ubMaxNum--;
}
else
return;
ubFreeSlots--;
} }
else
return;
ubFreeSlots--;
} }
curr = curr->next; curr = curr->next;
} }
@@ -1456,6 +1496,12 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
curr->pBasicPlacement->ubBodyType = TANK_NW; curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--; ubTotalTanks--;
} }
else if ( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--;
}
else else
Assert(0); Assert(0);
/* DISABLE THE OVERRIDE FOR NOW... /* DISABLE THE OVERRIDE FOR NOW...
@@ -1546,7 +1592,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
// silversurfer: Replace body type. Militia tanks are not allowed. // silversurfer: Replace body type. Militia tanks are not allowed.
if( curr->pBasicPlacement->fDetailedPlacement ) if( curr->pBasicPlacement->fDetailedPlacement )
{ {
if ( TANK( curr->pDetailedPlacement ) ) if ( ARMED_VEHICLE( curr->pDetailedPlacement ) )
{ {
curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 ); curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank // check for better spot next to the tank so the militia doesn't get stuck in the tank
@@ -1555,7 +1601,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr->pBasicPlacement->usStartingGridNo = iNewSpot; curr->pBasicPlacement->usStartingGridNo = iNewSpot;
} }
} }
else if ( TANK( curr->pBasicPlacement ) ) else if ( ARMED_VEHICLE( curr->pBasicPlacement ) )
{ {
curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 ); curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank // check for better spot next to the tank so the militia doesn't get stuck in the tank
@@ -1563,14 +1609,17 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
if( iNewSpot != NOWHERE) if( iNewSpot != NOWHERE)
curr->pBasicPlacement->usStartingGridNo = iNewSpot; curr->pBasicPlacement->usStartingGridNo = iNewSpot;
} }
if( curr->pDetailedPlacement ) if( curr->pDetailedPlacement )
{ //delete the detailed placement information. {
//delete the detailed placement information.
delete( curr->pDetailedPlacement ); delete( curr->pDetailedPlacement );
curr->pDetailedPlacement = NULL; curr->pDetailedPlacement = NULL;
curr->pBasicPlacement->fDetailedPlacement = FALSE; curr->pBasicPlacement->fDetailedPlacement = FALSE;
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeAttributeLevel ), curr->pBasicPlacement->ubSoldierClass ); RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeAttributeLevel ), curr->pBasicPlacement->ubSoldierClass );
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeEquipmentLevel ), curr->pBasicPlacement->ubSoldierClass ); RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeEquipmentLevel ), curr->pBasicPlacement->ubSoldierClass );
} }
if( AddPlacementToWorld( curr ) ) if( AddPlacementToWorld( curr ) )
{ {
ubMaxNum--; ubMaxNum--;
@@ -1726,7 +1775,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr->pBasicPlacement->bAttitude = (INT8) Random( MAXATTITUDES ); curr->pBasicPlacement->bAttitude = (INT8) Random( MAXATTITUDES );
// silversurfer: Replace body type. Militia tanks are not allowed. // silversurfer: Replace body type. Militia tanks are not allowed.
if ( TANK(curr->pBasicPlacement) ) if ( ARMED_VEHICLE( curr->pBasicPlacement ) )
{ {
curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 ); curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank // check for better spot next to the tank so the militia doesn't get stuck in the tank
@@ -1734,14 +1783,17 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
if( iNewSpot != NOWHERE) if( iNewSpot != NOWHERE)
curr->pBasicPlacement->usStartingGridNo = iNewSpot; curr->pBasicPlacement->usStartingGridNo = iNewSpot;
} }
if( curr->pDetailedPlacement ) if( curr->pDetailedPlacement )
{ //delete the detailed placement information. {
//delete the detailed placement information.
delete( curr->pDetailedPlacement ); delete( curr->pDetailedPlacement );
curr->pDetailedPlacement = NULL; curr->pDetailedPlacement = NULL;
curr->pBasicPlacement->fDetailedPlacement = FALSE; curr->pBasicPlacement->fDetailedPlacement = FALSE;
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeAttributeLevel), curr->pBasicPlacement->ubSoldierClass ); RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeAttributeLevel), curr->pBasicPlacement->ubSoldierClass );
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeEquipmentLevel), curr->pBasicPlacement->ubSoldierClass ); RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeEquipmentLevel), curr->pBasicPlacement->ubSoldierClass );
} }
if( AddPlacementToWorld( curr ) ) if( AddPlacementToWorld( curr ) )
{ {
ubMaxNum--; ubMaxNum--;
+1 -1
View File
@@ -40,7 +40,7 @@ void RemoveSoldierNodeFromInitList( SOLDIERINITNODE *pNode );
SOLDIERINITNODE* FindSoldierInitNodeWithID( UINT16 usID ); SOLDIERINITNODE* FindSoldierInitNodeWithID( UINT16 usID );
UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum ); UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum );
void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks ); void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks, UINT8 ubTotalJeeps );
void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNumInfants, void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNumInfants,
UINT8 ubNumYoungMales, UINT8 ubNumYoungFemales, UINT8 ubNumAdultMales, UINT8 ubNumYoungMales, UINT8 ubNumYoungFemales, UINT8 ubNumAdultMales,
UINT8 ubNumAdultFemales ); UINT8 ubNumAdultFemales );
+2
View File
@@ -1024,6 +1024,7 @@ BOOLEAN LoadMercProfiles(void)
case ELDORADO: case ELDORADO:
case ICECREAMTRUCK: case ICECREAMTRUCK:
case JEEP: case JEEP:
case COMBAT_JEEP:
gProfilesVehicle[uiLoop].ProfilId = uiLoop; gProfilesVehicle[uiLoop].ProfilId = uiLoop;
break; break;
// Make it an RPC // Make it an RPC
@@ -1051,6 +1052,7 @@ BOOLEAN LoadMercProfiles(void)
case ELDORADO: case ELDORADO:
case ICECREAMTRUCK: case ICECREAMTRUCK:
case JEEP: case JEEP:
case COMBAT_JEEP:
gProfilesVehicle[uiLoop].ProfilId = uiLoop; gProfilesVehicle[uiLoop].ProfilId = uiLoop;
break; break;
// RPC or NPC // RPC or NPC
+2 -2
View File
@@ -224,11 +224,11 @@ INT8 TileIsClear( SOLDIERTYPE *pSoldier, INT8 bDirection, INT32 sGridNo, INT8 b
} }
// anv: vehicles can ram people // anv: vehicles can ram people
if ( !TANK(pSoldier) && gGameExternalOptions.fAllowCarsDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && pSoldier->usSoldierFlagMask2 & SOLDIER_RAM_THROUGH_OBSTACLES ) if ( !ARMED_VEHICLE( pSoldier ) && gGameExternalOptions.fAllowCarsDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && pSoldier->usSoldierFlagMask2 & SOLDIER_RAM_THROUGH_OBSTACLES )
{ {
return( MOVE_TILE_CLEAR ); return( MOVE_TILE_CLEAR );
} }
else if( TANK(pSoldier) && gGameExternalOptions.fAllowTanksDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) else if ( ARMED_VEHICLE( pSoldier ) && gGameExternalOptions.fAllowTanksDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{ {
return( MOVE_TILE_CLEAR ); return( MOVE_TILE_CLEAR );
} }
+3 -1
View File
@@ -32,9 +32,11 @@
#define CREATURE_OR_BLOODCAT( p ) ( (p->flags.uiStatusFlags & SOLDIER_MONSTER) || p->ubBodyType == BLOODCAT ) #define CREATURE_OR_BLOODCAT( p ) ( (p->flags.uiStatusFlags & SOLDIER_MONSTER) || p->ubBodyType == BLOODCAT )
#define COMBAT_JEEP( p ) ( p->ubBodyType == COMBAT_JEEP )
#define TANK( p ) (p->ubBodyType == TANK_NE || p->ubBodyType == TANK_NW ) #define TANK( p ) (p->ubBodyType == TANK_NE || p->ubBodyType == TANK_NW )
#define ARMED_VEHICLE( p ) ( TANK( p ) || COMBAT_JEEP(p) )
//#define OK_ENTERABLE_VEHICLE( p ) ( ( p->flags.uiStatusFlags & SOLDIER_VEHICLE ) && !TANK( p ) && p->stats.bLife >= OKLIFE ) //#define OK_ENTERABLE_VEHICLE( p ) ( ( p->flags.uiStatusFlags & SOLDIER_VEHICLE ) && !TANK( p ) && p->stats.bLife >= OKLIFE )
#define OK_ENTERABLE_VEHICLE( p ) ( ( p->flags.uiStatusFlags & SOLDIER_VEHICLE ) && (!TANK( p ) || !(p->flags.uiStatusFlags & SOLDIER_ENEMY) ) && p->stats.bLife >= OKLIFE ) #define OK_ENTERABLE_VEHICLE( p ) ( ( p->flags.uiStatusFlags & SOLDIER_VEHICLE ) && (!ARMED_VEHICLE( p ) || !(p->flags.uiStatusFlags & SOLDIER_ENEMY) ) && p->stats.bLife >= OKLIFE )
#endif #endif
+1 -1
View File
@@ -60,7 +60,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
return; return;
// WANNE: No tooltips on bloodcats, bugs, tanks, roboter // WANNE: No tooltips on bloodcats, bugs, tanks, roboter
if ( CREATURE_OR_BLOODCAT( pSoldier ) || TANK ( pSoldier ) || if ( CREATURE_OR_BLOODCAT( pSoldier ) || ARMED_VEHICLE( pSoldier ) ||
AM_A_ROBOT( pSoldier)) AM_A_ROBOT( pSoldier))
{ {
return; return;
+1 -1
View File
@@ -1969,7 +1969,7 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
} }
} }
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
// reduce interrupt possibilities for tanks! // reduce interrupt possibilities for tanks!
iPoints /= 2; iPoints /= 2;
+1
View File
@@ -4962,6 +4962,7 @@ void ChangeSoldiersBodyType( UINT8 ubBodyType, BOOLEAN fCreateNewPalette )
case TANK_NW: case TANK_NW:
case TANK_NE: case TANK_NE:
case COMBAT_JEEP:
pSoldier->flags.uiStatusFlags |= SOLDIER_VEHICLE; pSoldier->flags.uiStatusFlags |= SOLDIER_VEHICLE;
//pSoldier->inv[ HANDPOS ].usItem = TANK_CANNON; //pSoldier->inv[ HANDPOS ].usItem = TANK_CANNON;
+37 -24
View File
@@ -3320,7 +3320,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{ {
iHitChance = 100; iHitChance = 100;
} }
else if ( AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) || CREATURE_OR_BLOODCAT( pTargetSoldier ) || (SOLDIER_CLASS_MILITIA(pTargetSoldier->ubSoldierClass) && (gGameExternalOptions.ubMilitiaDropEquipment != 2)) ) // added militia here - SANDRO else if ( AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) || CREATURE_OR_BLOODCAT( pTargetSoldier ) || (SOLDIER_CLASS_MILITIA( pTargetSoldier->ubSoldierClass ) && (gGameExternalOptions.ubMilitiaDropEquipment != 2)) ) // added militia here - SANDRO
{ {
iHitChance = 0; iHitChance = 0;
} }
@@ -3653,7 +3653,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
} }
// Give some experience // Give some experience
if ( iHitChance > 0 && pSoldier->bTeam == gbPlayerNum && pTargetSoldier->bTeam != gbPlayerNum && !(pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( pTargetSoldier ) && !TANK( pTargetSoldier ) ) if ( iHitChance > 0 && pSoldier->bTeam == gbPlayerNum && pTargetSoldier->bTeam != gbPlayerNum && !(pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( pTargetSoldier ) && !ARMED_VEHICLE( pTargetSoldier ) )
{ {
if (fFailure == FALSE) if (fFailure == FALSE)
{ {
@@ -3778,7 +3778,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
} }
} }
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) ) if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) )
{ {
ubExpGain = 0; ubExpGain = 0;
} }
@@ -3828,7 +3828,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
} }
} }
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) ) if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) )
{ {
ubExpGain = 0; ubExpGain = 0;
} }
@@ -6996,7 +6996,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
iPenalty = ((iMaxRange - (iRange-iAccRangeMod) * 3) * 10) / (17 * CELL_X_SIZE); iPenalty = ((iMaxRange - (iRange-iAccRangeMod) * 3) * 10) / (17 * CELL_X_SIZE);
if ( iPenalty < 0 ) if ( iPenalty < 0 )
iChance += iPenalty; iChance += iPenalty;
if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) ) if ( ARMED_VEHICLE( pSoldier ) && (iRange / CELL_X_SIZE < MaxNormalDistanceVisible( )) )
iChance -= 2 * ( MaxNormalDistanceVisible() - (iRange / CELL_X_SIZE) ); iChance -= 2 * ( MaxNormalDistanceVisible() - (iRange / CELL_X_SIZE) );
// Like the above modifier, only this applies to long range weapons trying to be used in close quater. Penalty will result when within 10% of max range // Like the above modifier, only this applies to long range weapons trying to be used in close quater. Penalty will result when within 10% of max range
iPenalty = (((iRange - iMinRange - iAccRangeMod) * 12) * 10) / (17 * CELL_X_SIZE); iPenalty = (((iRange - iMinRange - iAccRangeMod) * 12) * 10) / (17 * CELL_X_SIZE);
@@ -7005,7 +7005,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// Effects of visual range // Effects of visual range
// From for JA2.5: 3% bonus/penalty for each tile different from range NORMAL_RANGE. // From for JA2.5: 3% bonus/penalty for each tile different from range NORMAL_RANGE.
if (!TANK(pSoldier)) // WANNE: No penalty on the tank if ( !ARMED_VEHICLE( pSoldier ) ) // WANNE: No penalty on the tank
iPenalty = 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE; iPenalty = 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE;
if ( fCantSeeTarget ){ if ( fCantSeeTarget ){
// CHRISL: There are conditions where iSightRange can still return 0. If that happens, the result is that "impossible" shots are actually easier then // CHRISL: There are conditions where iSightRange can still return 0. If that happens, the result is that "impossible" shots are actually easier then
@@ -7043,7 +7043,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
switch( gAnimControl[ pTarget->usAnimState ].ubHeight ) switch( gAnimControl[ pTarget->usAnimState ].ubHeight )
{ {
case ANIM_CROUCH: case ANIM_CROUCH:
if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE ) if ( ARMED_VEHICLE( pSoldier ) && iRange < MIN_TANK_RANGE )
{ {
// 13% penalty per tile closer than min range // 13% penalty per tile closer than min range
iChance -= (INT32)(13 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE )); iChance -= (INT32)(13 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ));
@@ -7063,7 +7063,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
} }
break; break;
case ANIM_PRONE: case ANIM_PRONE:
if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE ) if ( ARMED_VEHICLE( pSoldier ) && iRange < MIN_TANK_RANGE )
{ {
// 25% penalty per tile closer than min range // 25% penalty per tile closer than min range
iChance -= (INT32)(25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ) * iPenalty); iChance -= (INT32)(25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ) * iPenalty);
@@ -7204,7 +7204,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// if target sees us, he may have a chance to dodge before the gun goes off // if target sees us, he may have a chance to dodge before the gun goes off
// but ability to dodge is reduced if crouched or prone! // but ability to dodge is reduced if crouched or prone!
if (pTarget->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY && !TANK( pTarget ) && !(pSoldier->ubBodyType != QUEENMONSTER) ) if ( pTarget->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY && !ARMED_VEHICLE( pTarget ) && !(pSoldier->ubBodyType != QUEENMONSTER) )
{ {
iPenalty = ( EffectiveAgility( pTarget, FALSE ) / 5 + EffectiveExpLevel( pTarget ) * 2); iPenalty = ( EffectiveAgility( pTarget, FALSE ) / 5 + EffectiveExpLevel( pTarget ) * 2);
switch( gAnimControl[ pTarget->usAnimState ].ubHeight ) switch( gAnimControl[ pTarget->usAnimState ].ubHeight )
@@ -7219,7 +7219,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// reduce dodge ability by the attacker's stats // reduce dodge ability by the attacker's stats
iBonus = ( EffectiveDexterity( pSoldier, FALSE ) / 5 + EffectiveExpLevel( pSoldier ) * 2); iBonus = ( EffectiveDexterity( pSoldier, FALSE ) / 5 + EffectiveExpLevel( pSoldier ) * 2);
if ( TANK( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) ) if ( ARMED_VEHICLE( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) )
{ {
// reduce ability to track shots // reduce ability to track shots
iBonus = iBonus / 2; iBonus = iBonus / 2;
@@ -7235,7 +7235,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
iChance -= iPenalty; iChance -= iPenalty;
} }
} }
else if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE ) else if ( ARMED_VEHICLE( pSoldier ) && iRange < MIN_TANK_RANGE )
{ {
// 25% penalty per tile closer than min range // 25% penalty per tile closer than min range
iChance -= 25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ); iChance -= 25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
@@ -7802,7 +7802,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// be an effective CTH of only 1/5000 (50 chances to get a 1 out of 100 CTH, hehehe) // be an effective CTH of only 1/5000 (50 chances to get a 1 out of 100 CTH, hehehe)
if (iChance <= gGameExternalOptions.ubMinimumCTH) if (iChance <= gGameExternalOptions.ubMinimumCTH)
{ {
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
// allow absolute minimums // allow absolute minimums
iChance = 0; iChance = 0;
@@ -8626,12 +8626,12 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
if ( iPenalty < 0 ) if ( iPenalty < 0 )
{ {
// No penalty on tanks // No penalty on tanks
//if (!TANK(pSoldier)) //if (!ARMED_VEHICLE(pSoldier))
iChance += iPenalty; iChance += iPenalty;
} }
//iChance -= 20 * iRange / iMaxRange; //iChance -= 20 * iRange / iMaxRange;
if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) ) if ( ARMED_VEHICLE( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) )
{ {
// tank; penalize at close range! // tank; penalize at close range!
// 2 percent per tile closer than max visible distance // 2 percent per tile closer than max visible distance
@@ -8655,7 +8655,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// range less penalized, and longer range more penalized // range less penalized, and longer range more penalized
// WANNE: No penalty on the tank // WANNE: No penalty on the tank
if (!TANK(pSoldier)) if (!ARMED_VEHICLE(pSoldier))
iChance += 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE; iChance += 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE;
// if aiming at the head, reduce chance to hit // if aiming at the head, reduce chance to hit
if (ubAimPos == AIM_SHOT_HEAD) if (ubAimPos == AIM_SHOT_HEAD)
@@ -9567,15 +9567,31 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
ubAmmoType = Explosive[Item[usAttackingWeapon].ubClassIndex].ubFragType; ubAmmoType = Explosive[Item[usAttackingWeapon].ubClassIndex].ubFragType;
} }
if ( TANK( pTarget ) ) // Flugente: ammotype can alter the damage dealt
FLOAT damagefactor = AmmoTypes[ubAmmoType].dDamageModifierLife;
if ( pTarget->IsZombie( ) )
{ {
if ( !AmmoTypes[ubAmmoType].antiTank ) damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierZombie;
}
else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
if ( COMBAT_JEEP( pTarget ) || AM_A_ROBOT( pTarget ) )
{ {
// ping! damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierArmouredVehicle;
return( 0 ); }
else if ( TANK( pTarget ) )
{
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierTank;
}
else
{
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierCivilianVehicle;
} }
} }
iOrigImpact = iOrigImpact * damagefactor;
// plus/minus up to 25% due to "random" factors (major organs hit or missed, // plus/minus up to 25% due to "random" factors (major organs hit or missed,
// lucky lighter in breast pocket, divine intervention on behalf of "Rev"...) // lucky lighter in breast pocket, divine intervention on behalf of "Rev"...)
iFluke = PreRandom(51) - 25; // gives (0 to 50 -25)->-25% to +25% iFluke = PreRandom(51) - 25; // gives (0 to 50 -25)->-25% to +25%
@@ -9622,9 +9638,6 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
pTarget->iLastArmourProtection += iTotalArmourProtection; pTarget->iLastArmourProtection += iTotalArmourProtection;
} }
// Flugente: ammotype can alter the damage dealt
iImpact *= AmmoTypes[ubAmmoType].dDamageModifierLife;
// calc minimum damage // calc minimum damage
if ( AmmoTypes[ubAmmoType].zeroMinimumDamage ) if ( AmmoTypes[ubAmmoType].zeroMinimumDamage )
{ {
@@ -9654,14 +9667,14 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
} }
// Flugente: if this is cryo ammo, freeze target. // Flugente: if this is cryo ammo, freeze target.
if ( !TANK( pTarget ) && !(pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE) && AmmoTypes[ubAmmoType].ammoflag & AMMO_CRYO ) if ( !ARMED_VEHICLE( pTarget ) && !(pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE) && AmmoTypes[ubAmmoType].ammoflag & AMMO_CRYO )
{ {
pTarget->usSkillCooldown[SOLDIER_COOLDOWN_CRYO] += 2; pTarget->usSkillCooldown[SOLDIER_COOLDOWN_CRYO] += 2;
ShutupaYoFace( pTarget->iFaceIndex ); ShutupaYoFace( pTarget->iFaceIndex );
} }
if ( iImpact > 0 && !TANK( pTarget ) ) if ( iImpact > 0 && !ARMED_VEHICLE( pTarget ) )
{ {
// Flugente: any bullet can have drug effects it set so in the magazine item // Flugente: any bullet can have drug effects it set so in the magazine item
if ( ammoitem != NOTHING ) if ( ammoitem != NOTHING )
+4 -1
View File
@@ -252,7 +252,6 @@ typedef struct
INT32 multipleBulletDamageDivisor; INT32 multipleBulletDamageDivisor;
UINT16 highExplosive; UINT16 highExplosive;
UINT8 explosionSize; //0=none, 1=small, 2=medium, 3=large UINT8 explosionSize; //0=none, 1=small, 2=medium, 3=large
BOOLEAN antiTank;
BOOLEAN dart; BOOLEAN dart;
BOOLEAN knife; BOOLEAN knife;
UINT16 monsterSpit; UINT16 monsterSpit;
@@ -272,6 +271,10 @@ typedef struct
// Flugente: modifiers for life and breath damage, 1.0 being the unmodified value // Flugente: modifiers for life and breath damage, 1.0 being the unmodified value
FLOAT dDamageModifierLife; FLOAT dDamageModifierLife;
FLOAT dDamageModifierBreath; FLOAT dDamageModifierBreath;
FLOAT dDamageModifierTank;
FLOAT dDamageModifierArmouredVehicle;
FLOAT dDamageModifierCivilianVehicle;
FLOAT dDamageModifierZombie;
} AMMOTYPE; } AMMOTYPE;
+41 -8
View File
@@ -71,7 +71,6 @@ ammotypeStartElementHandle(void *userData, const XML_Char *name, const XML_Char
strcmp(name, "spreadPattern") == 0 || strcmp(name, "spreadPattern") == 0 ||
strcmp(name, "highExplosive") == 0 || strcmp(name, "highExplosive") == 0 ||
strcmp(name, "explosionSize") == 0 || strcmp(name, "explosionSize") == 0 ||
strcmp(name, "antiTank") == 0 ||
strcmp(name, "dart") == 0 || strcmp(name, "dart") == 0 ||
strcmp(name, "knife") == 0 || strcmp(name, "knife") == 0 ||
strcmp(name, "ignoreArmour") == 0 || strcmp(name, "ignoreArmour") == 0 ||
@@ -83,7 +82,11 @@ ammotypeStartElementHandle(void *userData, const XML_Char *name, const XML_Char
strcmp(name, "dirtModificator") == 0 || strcmp(name, "dirtModificator") == 0 ||
strcmp(name, "ammoflag" ) == 0 || strcmp(name, "ammoflag" ) == 0 ||
strcmp(name, "dDamageModifierLife" ) == 0 || strcmp(name, "dDamageModifierLife" ) == 0 ||
strcmp(name, "dDamageModifierBreath") == 0 )) strcmp(name, "dDamageModifierBreath" ) == 0 ||
strcmp(name, "dDamageModifierTank" ) == 0 ||
strcmp(name, "dDamageModifierArmouredVehicle" ) == 0 ||
strcmp(name, "dDamageModifierCivilianVehicle" ) == 0 ||
strcmp(name, "dDamageModifierZombie") == 0 ))
{ {
pData->curElement = ELEMENT_PROPERTY; pData->curElement = ELEMENT_PROPERTY;
@@ -246,11 +249,6 @@ ammotypeEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT; pData->curElement = ELEMENT;
pData->curAmmoType.explosionSize = (UINT8) atol(pData->szCharData); pData->curAmmoType.explosionSize = (UINT8) atol(pData->szCharData);
} }
else if(strcmp(name, "antiTank") == 0)
{
pData->curElement = ELEMENT;
pData->curAmmoType.antiTank = (BOOLEAN) atol(pData->szCharData);
}
else if(strcmp(name, "dart") == 0) else if(strcmp(name, "dart") == 0)
{ {
pData->curElement = ELEMENT; pData->curElement = ELEMENT;
@@ -312,6 +310,38 @@ ammotypeEndElementHandle(void *userData, const XML_Char *name)
// reasonable values only // reasonable values only
pData->curAmmoType.dDamageModifierBreath = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierBreath ) ); pData->curAmmoType.dDamageModifierBreath = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierBreath ) );
} }
else if ( strcmp( name, "dDamageModifierTank" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierTank = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierTank = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierTank ) );
}
else if ( strcmp( name, "dDamageModifierArmouredVehicle" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierArmouredVehicle = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierArmouredVehicle = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierArmouredVehicle ) );
}
else if ( strcmp( name, "dDamageModifierCivilianVehicle" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierCivilianVehicle = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierCivilianVehicle = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierCivilianVehicle ) );
}
else if ( strcmp( name, "dDamageModifierZombie" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierZombie = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierZombie = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierZombie ) );
}
pData->maxReadDepth--; pData->maxReadDepth--;
} }
@@ -425,7 +455,6 @@ BOOLEAN WriteAmmoTypeStats()
FilePrintf(hFile,"\t\t<multipleBulletDamageDivisor>%d</multipleBulletDamageDivisor>\r\n", AmmoTypes[cnt].multipleBulletDamageDivisor ); FilePrintf(hFile,"\t\t<multipleBulletDamageDivisor>%d</multipleBulletDamageDivisor>\r\n", AmmoTypes[cnt].multipleBulletDamageDivisor );
FilePrintf(hFile,"\t\t<highExplosive>%d</highExplosive>\r\n", AmmoTypes[cnt].highExplosive ); FilePrintf(hFile,"\t\t<highExplosive>%d</highExplosive>\r\n", AmmoTypes[cnt].highExplosive );
FilePrintf(hFile,"\t\t<explosionSize>%d</explosionSize>\r\n", AmmoTypes[cnt].explosionSize ); FilePrintf(hFile,"\t\t<explosionSize>%d</explosionSize>\r\n", AmmoTypes[cnt].explosionSize );
FilePrintf(hFile,"\t\t<antiTank>%d</antiTank>\r\n", AmmoTypes[cnt].antiTank );
FilePrintf(hFile,"\t\t<dart>%d</dart>\r\n", AmmoTypes[cnt].dart ); FilePrintf(hFile,"\t\t<dart>%d</dart>\r\n", AmmoTypes[cnt].dart );
FilePrintf(hFile,"\t\t<knife>%d</knife>\r\n", AmmoTypes[cnt].knife ); FilePrintf(hFile,"\t\t<knife>%d</knife>\r\n", AmmoTypes[cnt].knife );
FilePrintf(hFile,"\t\t<monsterSpit>%d</monsterSpit>\r\n", AmmoTypes[cnt].monsterSpit ); FilePrintf(hFile,"\t\t<monsterSpit>%d</monsterSpit>\r\n", AmmoTypes[cnt].monsterSpit );
@@ -438,6 +467,10 @@ BOOLEAN WriteAmmoTypeStats()
FilePrintf(hFile,"\t\t<ammoflag>%d</ammoflag>\r\n", AmmoTypes[cnt].ammoflag ); FilePrintf(hFile,"\t\t<ammoflag>%d</ammoflag>\r\n", AmmoTypes[cnt].ammoflag );
FilePrintf(hFile,"\t\t<dDamageModifierLife>%4.2f</dDamageModifierLife>\r\n", AmmoTypes[cnt].dDamageModifierLife ); FilePrintf(hFile,"\t\t<dDamageModifierLife>%4.2f</dDamageModifierLife>\r\n", AmmoTypes[cnt].dDamageModifierLife );
FilePrintf(hFile,"\t\t<dDamageModifierBreath>%4.2f</dDamageModifierBreath>\r\n", AmmoTypes[cnt].dDamageModifierBreath ); FilePrintf(hFile,"\t\t<dDamageModifierBreath>%4.2f</dDamageModifierBreath>\r\n", AmmoTypes[cnt].dDamageModifierBreath );
FilePrintf(hFile,"\t\t<dDamageModifierTank>%4.2f</dDamageModifierTank>\r\n", AmmoTypes[cnt].dDamageModifierTank );
FilePrintf(hFile,"\t\t<dDamageModifierArmouredVehicle>%4.2f</dDamageModifierArmouredVehicle>\r\n", AmmoTypes[cnt].dDamageModifierArmouredVehicle );
FilePrintf(hFile,"\t\t<dDamageModifierCivilianVehicle>%4.2f</dDamageModifierCivilianVehicle>\r\n", AmmoTypes[cnt].dDamageModifierCivilianVehicle );
FilePrintf(hFile,"\t\t<dDamageModifierZombie>%4.2f</dDamageModifierZombie>\r\n", AmmoTypes[cnt].dDamageModifierZombie );
FilePrintf(hFile,"\t</AMMOTYPE>\r\n"); FilePrintf(hFile,"\t</AMMOTYPE>\r\n");
} }
+6 -6
View File
@@ -1233,7 +1233,7 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
} }
} }
if ( bFacingDir == DIRECTION_IRRELEVANT && TANK( pSoldier ) ) if ( bFacingDir == DIRECTION_IRRELEVANT && ARMED_VEHICLE( pSoldier ) )
{ {
// always calculate direction for tanks so we have something to work with // always calculate direction for tanks so we have something to work with
bFacingDir = pSoldier->pathing.bDesiredDirection; bFacingDir = pSoldier->pathing.bDesiredDirection;
@@ -1241,7 +1241,7 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
//bSubjectDir = atan8(pSoldier->sX,pSoldier->sY,pOpponent->sX,pOpponent->sY); //bSubjectDir = atan8(pSoldier->sX,pSoldier->sY,pOpponent->sX,pOpponent->sY);
} }
if ( !TANK( pSoldier ) && ( bFacingDir == DIRECTION_IRRELEVANT || (pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT) || (pSubject && pSubject->flags.fMuzzleFlash) ) ) if ( !ARMED_VEHICLE( pSoldier ) && (bFacingDir == DIRECTION_IRRELEVANT || (pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT) || (pSubject && pSubject->flags.fMuzzleFlash)) )
{ {
sDistVisible = MaxNormalDistanceVisible(); sDistVisible = MaxNormalDistanceVisible();
} }
@@ -1385,10 +1385,10 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
} }
// let tanks see and be seen further (at night) // let tanks see and be seen further (at night)
if ( (TANK( pSoldier ) && sDistVisible > 0) || (pSubject && TANK( pSubject ) ) ) if ( (ARMED_VEHICLE( pSoldier ) && sDistVisible > 0) || (pSubject && ARMED_VEHICLE( pSubject )) )
{ {
#if 0 #if 0
if ( TANK(pSoldier) && sDistVisible > 0 && pSubject) if ( ARMED_VEHICLE(pSoldier) && sDistVisible > 0 && pSubject)
{ {
sDistVisible = __max( sDistVisible + 5, pSubject->GetMaxDistanceVisible(pSoldier->sGridNo, pSoldier->pathing.bLevel) ); sDistVisible = __max( sDistVisible + 5, pSubject->GetMaxDistanceVisible(pSoldier->sGridNo, pSoldier->pathing.bLevel) );
} }
@@ -1561,7 +1561,7 @@ INT8 DecideHearing( SOLDIERTYPE * pSoldier )
// calculate the hearing value for the merc... // calculate the hearing value for the merc...
INT8 bHearing; INT8 bHearing;
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
return( -5 ); return( -5 );
} }
@@ -6443,7 +6443,7 @@ void HearNoise(SOLDIERTYPE *pSoldier, UINT8 ubNoiseMaker, INT32 sGridNo, INT8 bL
// (taking into account we are definitely aware of this guy now) // (taking into account we are definitely aware of this guy now)
// skip LOS check if we had to turn and we're a tank. sorry Mr Tank, no looking out of the sides for you! // skip LOS check if we had to turn and we're a tank. sorry Mr Tank, no looking out of the sides for you!
if ( !( bHadToTurn && TANK( pSoldier ) ) ) if ( !(bHadToTurn && ARMED_VEHICLE( pSoldier )) )
{ {
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, bLevel, 0, TRUE, sDistVisible ) ) if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, bLevel, 0, TRUE, sDistVisible ) )
{ {
+8 -4
View File
@@ -346,7 +346,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) // FIXME - this function is named
return; return;
} }
if ( ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && ( (pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !TANK( pSoldier ) ) ) || AM_A_ROBOT( pSoldier ) ) if ( (!gGameExternalOptions.fEnemyTanksCanMoveInTactical && ((pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !ARMED_VEHICLE( pSoldier ))) || AM_A_ROBOT( pSoldier ) )
{ {
// bail out! // bail out!
#ifdef TESTAICONTROL #ifdef TESTAICONTROL
@@ -1235,7 +1235,7 @@ void CancelAIAction(SOLDIERTYPE *pSoldier, UINT8 ubForce)
#endif #endif
// re-enable cover checking, something is new or something strange happened // re-enable cover checking, something is new or something strange happened
if( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !TANK(pSoldier))//dnl ch64 290813 if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813
SkipCoverCheck = FALSE; SkipCoverCheck = FALSE;
// turn off new situation flag to stop this from repeating all the time! // turn off new situation flag to stop this from repeating all the time!
@@ -1501,7 +1501,7 @@ void RefreshAI(SOLDIERTYPE *pSoldier)
if (pSoldier->aiData.bAlertStatus == STATUS_YELLOW) if (pSoldier->aiData.bAlertStatus == STATUS_YELLOW)
SkipCoverCheck = FALSE; SkipCoverCheck = FALSE;
if( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && TANK(pSoldier) )//dnl ch64 290813 tanks don't have move animations if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813 tanks don't have move animations
SkipCoverCheck = TRUE; SkipCoverCheck = TRUE;
// if he's in battle or knows opponents are here // if he's in battle or knows opponents are here
@@ -1589,7 +1589,7 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
// in most cases, merc will change location, or may cause damage to opponents, // in most cases, merc will change location, or may cause damage to opponents,
// so a new cover check will be necessary. Exceptions handled individually. // so a new cover check will be necessary. Exceptions handled individually.
if( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !TANK(pSoldier) )//dnl ch64 290813 if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813
SkipCoverCheck = FALSE; SkipCoverCheck = FALSE;
// reset this field, too // reset this field, too
@@ -2607,6 +2607,10 @@ void HandleAITacticalTraversal( SOLDIERTYPE * pSoldier )
++pSectorInfo->ubNumTanks; ++pSectorInfo->ubNumTanks;
break; break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( pSoldier ) )
++pSectorInfo->ubNumJeeps;
break;
} }
ProcessQueenCmdImplicationsOfDeath( pSoldier ); ProcessQueenCmdImplicationsOfDeath( pSoldier );
+14 -12
View File
@@ -2509,15 +2509,17 @@ INT16 RoamingRange(SOLDIERTYPE *pSoldier, INT32 * pusFromGridNo)
{ {
// JA2 GOLD: give non-NPCs a 5 tile roam range for cover in combat when being shot at // JA2 GOLD: give non-NPCs a 5 tile roam range for cover in combat when being shot at
// anv: and tanks who are technically NPCs // anv: and tanks who are technically NPCs
case STATIONARY: if ( ( pSoldier->ubProfile != NO_PROFILE && !TANK(pSoldier) ) || (pSoldier->aiData.bAlertStatus < STATUS_BLACK && !(pSoldier->aiData.bUnderFire))) case STATIONARY:
{ if ( (pSoldier->ubProfile != NO_PROFILE && !ARMED_VEHICLE( pSoldier )) || (pSoldier->aiData.bAlertStatus < STATUS_BLACK && !(pSoldier->aiData.bUnderFire)) )
return( 0 ); {
} return( 0 );
else }
{ else
return( 5 ); {
} return( 5 );
case ONGUARD: return( 5 ); }
case ONGUARD:
return( 5 );
case CLOSEPATROL: if (pSoldier->aiData.bAlertStatus < STATUS_RED) case CLOSEPATROL: if (pSoldier->aiData.bAlertStatus < STATUS_RED)
{ {
return( 5 ); return( 5 );
@@ -3122,7 +3124,7 @@ UINT8 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 au
continue; continue;
// this is not for tanks // this is not for tanks
if ( TANK(pFriend) ) if ( ARMED_VEHICLE( pFriend ) )
return FALSE; return FALSE;
// skip if this guy is dead // skip if this guy is dead
@@ -3175,7 +3177,7 @@ UINT8 GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 au
continue; continue;
// this is not for tanks // this is not for tanks
if ( TANK(pFriend) ) if ( ARMED_VEHICLE( pFriend ) )
return FALSE; return FALSE;
// skip if this guy is dead, or not wounded (enough) // skip if this guy is dead, or not wounded (enough)
@@ -3224,7 +3226,7 @@ UINT8 GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTe
continue; continue;
// this is not for tanks // this is not for tanks
if ( TANK(pFriend) ) if ( ARMED_VEHICLE( pFriend ) )
return FALSE; return FALSE;
// skip this guy if he is dead or unconscious // skip this guy if he is dead or unconscious
+10 -10
View File
@@ -110,7 +110,7 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier)
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("LoadWeaponIfNeeded: remove payload from its pocket, and add it as the hand weapon's first attachment")); DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("LoadWeaponIfNeeded: remove payload from its pocket, and add it as the hand weapon's first attachment"));
// remove payload from its pocket, and add it as the hand weapon's first attachment // remove payload from its pocket, and add it as the hand weapon's first attachment
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
// don't remove ammo // don't remove ammo
gTempObject = pSoldier->inv[bPayloadPocket]; gTempObject = pSoldier->inv[bPayloadPocket];
@@ -375,7 +375,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
// calculate the maximum possible aiming time // calculate the maximum possible aiming time
#if 0//dnl ch64 270813 maybe I'm wrong but don't see purpose of this #if 0//dnl ch64 270813 maybe I'm wrong but don't see purpose of this
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost; ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost;
@@ -407,7 +407,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
//NumMessage("ubAimTime = ",ubAimTime); //NumMessage("ubAimTime = ",ubAimTime);
//dnl ch59 180813 Find true best chance to hit depending of stance so AI would be more eager to attack //dnl ch59 180813 Find true best chance to hit depending of stance so AI would be more eager to attack
ubChanceToHit = AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING); ubChanceToHit = AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);
if(!TANK(pSoldier))//dnl ch64 270813 if(!ARMED_VEHICLE(pSoldier))//dnl ch64 270813
{ {
if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit) if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit)
ubChanceToHit = ubChanceToHit2; ubChanceToHit = ubChanceToHit2;
@@ -437,7 +437,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
ubAimTime = APBPConstants[AP_MIN_AIM_ATTACK]; ubAimTime = APBPConstants[AP_MIN_AIM_ATTACK];
//dnl ch59 180813 Find true best chance to hit depending of stance for autofire //dnl ch59 180813 Find true best chance to hit depending of stance for autofire
ubChanceToHit = AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING); ubChanceToHit = AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, STANDING);
if(!TANK(pSoldier))//dnl ch64 270813 if(!ARMED_VEHICLE(pSoldier))//dnl ch64 270813
{ {
if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit) if((ubChanceToHit2=AICalcChanceToHitGun(pSoldier, pOpponent->sGridNo, ubAimTime, AIM_SHOT_TORSO, pOpponent->pathing.bLevel, CROUCHING)) > ubChanceToHit)
ubChanceToHit = ubChanceToHit2; ubChanceToHit = ubChanceToHit2;
@@ -514,7 +514,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
pSoldier->usAnimState = usTrueState; pSoldier->usAnimState = usTrueState;
pSoldier->sLastTarget = iTrueLastTarget; pSoldier->sLastTarget = iTrueLastTarget;
} }
if(pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD || TANK(pSoldier) || (Item[pSoldier->usAttackingWeapon].usItemClass & IC_THROWING_KNIFE)) if ( pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD || ARMED_VEHICLE( pSoldier ) || (Item[pSoldier->usAttackingWeapon].usItemClass & IC_THROWING_KNIFE) )
continue; continue;
ubStance = ANIM_CROUCH; ubStance = ANIM_CROUCH;
if(IsValidStance(pSoldier, ubStance)) if(IsValidStance(pSoldier, ubStance))
@@ -1102,7 +1102,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// they won't use them until they have 2+ opponents as long as half life left // they won't use them until they have 2+ opponents as long as half life left
// anv: tanks don't care // anv: tanks don't care
if ( ( ubOpponentCnt < 2 ) && ( pSoldier->stats.bLife > pSoldier->stats.bLifeMax / 2 ) && if ( ( ubOpponentCnt < 2 ) && ( pSoldier->stats.bLife > pSoldier->stats.bLifeMax / 2 ) &&
( !gGameExternalOptions.fEnemyTanksDontSpareShells || !TANK(pSoldier) ) && !gGameExternalOptions.fEnemiesDontSpareLaunchables ) (!gGameExternalOptions.fEnemyTanksDontSpareShells || !ARMED_VEHICLE( pSoldier )) && !gGameExternalOptions.fEnemiesDontSpareLaunchables )
{ {
return; return;
} }
@@ -1110,7 +1110,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
case 2: case 2:
// they won't use them until they have 2+ opponents as long as 3/4 life left // they won't use them until they have 2+ opponents as long as 3/4 life left
if ( (ubOpponentCnt < 2) && ( pSoldier->stats.bLife > (pSoldier->stats.bLifeMax / 4) * 3 ) && if ( (ubOpponentCnt < 2) && ( pSoldier->stats.bLife > (pSoldier->stats.bLifeMax / 4) * 3 ) &&
( !gGameExternalOptions.fEnemyTanksDontSpareShells || !TANK(pSoldier) ) && !gGameExternalOptions.fEnemiesDontSpareLaunchables ) (!gGameExternalOptions.fEnemyTanksDontSpareShells || !ARMED_VEHICLE( pSoldier )) && !gGameExternalOptions.fEnemiesDontSpareLaunchables )
{ {
return; return;
} }
@@ -1350,7 +1350,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
ubChanceToGetThrough = AISoldierToLocationChanceToGetThrough( pSoldier, sGridNo, bOpponentLevel[ubLoop], 0 ); ubChanceToGetThrough = AISoldierToLocationChanceToGetThrough( pSoldier, sGridNo, bOpponentLevel[ubLoop], 0 );
// anv: tanks shouldn't care about chance to get through - can't hit? At least we'll destroy their cover. // anv: tanks shouldn't care about chance to get through - can't hit? At least we'll destroy their cover.
// also AISoldierToLocationChanceToGetThrough used to return 0 for tanks, but that's a different story // also AISoldierToLocationChanceToGetThrough used to return 0 for tanks, but that's a different story
if( ( gGameExternalOptions.fEnemyTanksBlowObstaclesUp && TANK(pSoldier) ) || gGameExternalOptions.fEnemiesBlowObstaclesUp ) if ( (gGameExternalOptions.fEnemyTanksBlowObstaclesUp && ARMED_VEHICLE( pSoldier )) || gGameExternalOptions.fEnemiesBlowObstaclesUp )
{ {
ubChanceToGetThrough = 100; ubChanceToGetThrough = 100;
} }
@@ -1395,7 +1395,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
// this is try to minimize enemies wasting their (few) mortar shells or LAWs // this is try to minimize enemies wasting their (few) mortar shells or LAWs
// they won't use them on less than 2 targets as long as half life left // they won't use them on less than 2 targets as long as half life left
if ((Item[usInHand].mortar || Item[usInHand].rocketlauncher ) && (ubOppsInRange < 2) && if ((Item[usInHand].mortar || Item[usInHand].rocketlauncher ) && (ubOppsInRange < 2) &&
(pSoldier->stats.bLife > (pSoldier->stats.bLifeMax / 2)) && ( !gGameExternalOptions.fEnemyTanksDontSpareShells || !TANK(pSoldier) ) && !gGameExternalOptions.fEnemiesDontSpareLaunchables ) (pSoldier->stats.bLife >( pSoldier->stats.bLifeMax / 2 )) && (!gGameExternalOptions.fEnemyTanksDontSpareShells || !ARMED_VEHICLE( pSoldier )) && !gGameExternalOptions.fEnemiesDontSpareLaunchables )
{ {
continue; // next gridno continue; // next gridno
} }
@@ -2982,7 +2982,7 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s
pBestShot->ubPossible = FALSE; pBestShot->ubPossible = FALSE;
pBestShot->bWeaponIn = NO_SLOT; pBestShot->bWeaponIn = NO_SLOT;
if ( !TANK( pSoldier ) ) if ( !ARMED_VEHICLE( pSoldier ) )
{ {
// AIs never have more than one gun anyway // AIs never have more than one gun anyway
pBestShot->bWeaponIn = FindAIUsableObjClass( pSoldier, IC_GUN ); pBestShot->bWeaponIn = FindAIUsableObjClass( pSoldier, IC_GUN );
+41 -23
View File
@@ -782,7 +782,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
} }
} }
if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && TANK( pSoldier ) ) if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && ARMED_VEHICLE( pSoldier ) )
{ {
return( AI_ACTION_NONE ); return( AI_ACTION_NONE );
} }
@@ -793,6 +793,12 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
// check if standing in tear gas without a gas mask on, or in smoke // check if standing in tear gas without a gas mask on, or in smoke
bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo );
// Flugente: tanks do not care about gas
if ( ARMED_VEHICLE( pSoldier ) )
{
bInGas = FALSE;
}
// if real-time, and not in the way, do nothing 90% of the time (for GUARDS!) // if real-time, and not in the way, do nothing 90% of the time (for GUARDS!)
// unless in water (could've started there), then we better swim to shore! // unless in water (could've started there), then we better swim to shore!
@@ -1875,7 +1881,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
} }
} }
if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && TANK( pSoldier ) ) if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && ARMED_VEHICLE( pSoldier ) )
{ {
return( AI_ACTION_NONE ); return( AI_ACTION_NONE );
} }
@@ -2480,6 +2486,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
// check if standing in tear gas without a gas mask on // check if standing in tear gas without a gas mask on
bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo );
// Flugente: tanks do not care about gas
if ( ARMED_VEHICLE( pSoldier ) )
{
bInGas = FALSE;
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// WHEN LEFT IN GAS, WEAR GAS MASK IF AVAILABLE AND NOT WORN // WHEN LEFT IN GAS, WEAR GAS MASK IF AVAILABLE AND NOT WORN
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -3346,7 +3358,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
} }
//if ( !TANK( pSoldier ) ) //if ( !TANK( pSoldier ) )
if( ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !TANK( pSoldier ) ) && !( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) ) if ( (gGameExternalOptions.fEnemyTanksCanMoveInTactical || !ARMED_VEHICLE( pSoldier )) && !(pSoldier->flags.uiStatusFlags & (SOLDIER_DRIVER | SOLDIER_PASSENGER)) )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: main red ai"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: main red ai");
@@ -4112,7 +4124,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if (pSoldier->aiData.bAttitude == DEFENSIVE) if (pSoldier->aiData.bAttitude == DEFENSIVE)
iChance += 25; iChance += 25;
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
iChance += 50; iChance += 50;
} }
@@ -4184,7 +4196,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
} }
} }
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
// try turning in a random direction as we still can't see anyone. // try turning in a random direction as we still can't see anyone.
if (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints) if (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints)
@@ -4569,6 +4581,12 @@ INT16 ubMinAPCost;
// check if standing in tear gas without a gas mask on // check if standing in tear gas without a gas mask on
bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo );
// Flugente: tanks do not care about gas
if ( ARMED_VEHICLE( pSoldier ) )
{
bInGas = FALSE;
}
// calculate our morale // calculate our morale
pSoldier->aiData.bAIMorale = CalcMorale(pSoldier); pSoldier->aiData.bAIMorale = CalcMorale(pSoldier);
@@ -4675,7 +4693,7 @@ INT16 ubMinAPCost;
// offer surrender? // offer surrender?
#ifdef JA2UB #ifdef JA2UB
#else #else
if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !( gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER ) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !TANK(pSoldier) ) if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) )
{ {
if ( gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector == 0 && gTacticalStatus.Team[ CREATURE_TEAM ].bMenInSector == 0 && NumPCsInSector() < 4 && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector >= NumPCsInSector() * 3 ) if ( gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector == 0 && gTacticalStatus.Team[ CREATURE_TEAM ].bMenInSector == 0 && NumPCsInSector() < 4 && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector >= NumPCsInSector() * 3 )
{ {
@@ -5089,7 +5107,7 @@ INT16 ubMinAPCost;
// if the soldier does have a usable knife somewhere // if the soldier does have a usable knife somewhere
// 0verhaul: And is not a tank! // 0verhaul: And is not a tank!
if (bWeaponIn != NO_SLOT && !TANK( pSoldier) && !( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) ) if ( bWeaponIn != NO_SLOT && !ARMED_VEHICLE( pSoldier ) && !(pSoldier->flags.uiStatusFlags & (SOLDIER_DRIVER | SOLDIER_PASSENGER)) )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"try to stab"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"try to stab");
BestStab.bWeaponIn = bWeaponIn; BestStab.bWeaponIn = bWeaponIn;
@@ -5157,7 +5175,7 @@ INT16 ubMinAPCost;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - even if we don't have any blade, calculate how much damage we could do unarmed // SANDRO - even if we don't have any blade, calculate how much damage we could do unarmed
else if ( !TANK( pSoldier) && !( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) ) else if ( !ARMED_VEHICLE( pSoldier ) && !(pSoldier->flags.uiStatusFlags & (SOLDIER_DRIVER | SOLDIER_PASSENGER)) )
{ {
bWeaponIn = FindAIUsableObjClass( pSoldier, IC_PUNCH ); bWeaponIn = FindAIUsableObjClass( pSoldier, IC_PUNCH );
if (bWeaponIn == NO_SLOT) // if no punch-type weapon found, just calculate it with empty hands if (bWeaponIn == NO_SLOT) // if no punch-type weapon found, just calculate it with empty hands
@@ -5301,7 +5319,7 @@ INT16 ubMinAPCost;
} }
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
} }
if (BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE)) && !(TANK(pSoldier) && ubBestAttackAction == AI_ACTION_FIRE_GUN && BestShot.ubChanceToReallyHit > 20 && Random(2)))//dnl ch64 290813 tank always had better chance to fire from cannon so this will increase probabilty to use machinegun too if ( BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE)) && !(ARMED_VEHICLE( pSoldier ) && ubBestAttackAction == AI_ACTION_FIRE_GUN && BestShot.ubChanceToReallyHit > 20 && Random( 2 )) )//dnl ch64 290813 tank always had better chance to fire from cannon so this will increase probabilty to use machinegun too
{ {
ubBestAttackAction = AI_ACTION_TOSS_PROJECTILE; ubBestAttackAction = AI_ACTION_TOSS_PROJECTILE;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw something"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw something");
@@ -5538,7 +5556,7 @@ INT16 ubMinAPCost;
{ {
#ifndef dnlCALCBESTSHOT//dnl ch69 140913 #ifndef dnlCALCBESTSHOT//dnl ch69 140913
// Do we need to change stance? NB We'll have to ready our gun again // Do we need to change stance? NB We'll have to ready our gun again
if ( !TANK( pSoldier ) && ( pSoldier->bActionPoints >= BestAttack.ubAPCost + GetAPsCrouch( pSoldier, TRUE) + MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST,0, 1 ) ) ) if ( !ARMED_VEHICLE( pSoldier ) && ( pSoldier->bActionPoints >= BestAttack.ubAPCost + GetAPsCrouch( pSoldier, TRUE) + MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST,0, 1 ) ) )
{ {
// since the AI considers shooting chance from standing primarily, if we are not // since the AI considers shooting chance from standing primarily, if we are not
// standing we should always consider a stance change // standing we should always consider a stance change
@@ -5613,7 +5631,7 @@ INT16 ubMinAPCost;
} }
} }
#else #else
if( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !TANK(pSoldier) ) if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !ARMED_VEHICLE( pSoldier ) )
{ {
// first get the direction, as we will need to pass that in to ShootingStanceChange // first get the direction, as we will need to pass that in to ShootingStanceChange
bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(BestAttack.sTarget),CenterY(BestAttack.sTarget)); bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(BestAttack.sTarget),CenterY(BestAttack.sTarget));
@@ -5668,7 +5686,7 @@ INT16 ubMinAPCost;
if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimTime + ubBurstAPs ) if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimTime + ubBurstAPs )
{ {
// Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
iChance = 100; iChance = 100;
} }
@@ -5770,7 +5788,7 @@ L_NEWAIM:
if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimTime + ubBurstAPs ) if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimTime + ubBurstAPs )
{ {
// Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
iChance = 100; iChance = 100;
} }
@@ -6038,7 +6056,7 @@ L_NEWAIM:
if ( (pSoldier->bActionPoints - BestAttack.ubAPCost) >= ubBurstAPs ) if ( (pSoldier->bActionPoints - BestAttack.ubAPCost) >= ubBurstAPs )
{ {
// Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
iChance = 100; iChance = 100;
} }
@@ -6083,7 +6101,7 @@ L_NEWAIM:
} }
// end of tank AI // end of tank AI
if( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && TANK( pSoldier ) ) if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && ARMED_VEHICLE( pSoldier ) )
{ {
return( AI_ACTION_NONE ); return( AI_ACTION_NONE );
} }
@@ -6711,7 +6729,7 @@ INT8 ZombieDecideActionGreen(SOLDIERTYPE *pSoldier)
gubNPCPathCount = 0; gubNPCPathCount = 0;
if( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && TANK( pSoldier ) ) if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && ARMED_VEHICLE( pSoldier ) )
{ {
return( AI_ACTION_NONE ); return( AI_ACTION_NONE );
} }
@@ -7223,7 +7241,7 @@ INT8 ZombieDecideActionYellow(SOLDIERTYPE *pSoldier)
} }
} }
if( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && TANK( pSoldier ) ) if ( !gGameExternalOptions.fEnemyTanksCanMoveInTactical && ARMED_VEHICLE( pSoldier ) )
{ {
return( AI_ACTION_NONE ); return( AI_ACTION_NONE );
} }
@@ -7382,7 +7400,7 @@ INT8 ZombieDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
// RADIO RED ALERT: determine %chance to call others and report contact // RADIO RED ALERT: determine %chance to call others and report contact
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
if( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !TANK( pSoldier ) ) if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !ARMED_VEHICLE( pSoldier ) )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: main red ai"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: main red ai");
@@ -7878,7 +7896,7 @@ INT8 ZombieDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if (pSoldier->aiData.bAttitude == DEFENSIVE) if (pSoldier->aiData.bAttitude == DEFENSIVE)
iChance += 25; iChance += 25;
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
iChance += 50; iChance += 50;
} }
@@ -7897,7 +7915,7 @@ INT8 ZombieDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
} }
} }
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
// try turning in a random direction as we still can't see anyone. // try turning in a random direction as we still can't see anyone.
if (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints) if (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints)
@@ -8174,7 +8192,7 @@ INT8 ZombieDecideActionBlack(SOLDIERTYPE *pSoldier)
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - even if we don't have any blade, calculate how much damage we could do unarmed // SANDRO - even if we don't have any blade, calculate how much damage we could do unarmed
if ( !TANK( pSoldier) ) if ( !ARMED_VEHICLE( pSoldier ) )
{ {
bWeaponIn = FindAIUsableObjClass( pSoldier, IC_PUNCH ); bWeaponIn = FindAIUsableObjClass( pSoldier, IC_PUNCH );
if (bWeaponIn == NO_SLOT) // if no punch-type weapon found, just calculate it with empty hands if (bWeaponIn == NO_SLOT) // if no punch-type weapon found, just calculate it with empty hands
@@ -8518,7 +8536,7 @@ INT8 ZombieDecideActionBlack(SOLDIERTYPE *pSoldier)
if ( (pSoldier->bActionPoints - BestAttack.ubAPCost) >= ubBurstAPs ) if ( (pSoldier->bActionPoints - BestAttack.ubAPCost) >= ubBurstAPs )
{ {
// Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4
if ( TANK( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) )
{ {
iChance = 100; iChance = 100;
} }
@@ -8563,7 +8581,7 @@ INT8 ZombieDecideActionBlack(SOLDIERTYPE *pSoldier)
} }
// end of tank AI // end of tank AI
if( gGameExternalOptions.fEnemyTanksCanMoveInTactical || TANK( pSoldier ) ) if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || ARMED_VEHICLE( pSoldier ) )
{ {
return( AI_ACTION_NONE ); return( AI_ACTION_NONE );
} }
+4 -4
View File
@@ -1617,7 +1617,7 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
sNewWoundAmt = (INT16)(((sNewWoundAmt * (100 + gSkillTraitValues.ubDEDamageOfBombsAndMines)) / 100) + 0.5); sNewWoundAmt = (INT16)(((sNewWoundAmt * (100 + gSkillTraitValues.ubDEDamageOfBombsAndMines)) / 100) + 0.5);
} }
// Heavy Weapons trait bonus damage to tanks // Heavy Weapons trait bonus damage to tanks
if ( HAS_SKILL_TRAIT( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT ) && TANK( pSoldier ) && if ( HAS_SKILL_TRAIT( MercPtrs[ubOwner], HEAVY_WEAPONS_NT ) && ARMED_VEHICLE( pSoldier ) &&
Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL ) Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL )
{ {
sNewWoundAmt = (INT16)(((sNewWoundAmt * (100 + gSkillTraitValues.ubHWDamageTanksBonusPercent * NUM_SKILL_TRAITS( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT ))) / 100) + 0.5); // +30% sNewWoundAmt = (INT16)(((sNewWoundAmt * (100 + gSkillTraitValues.ubHWDamageTanksBonusPercent * NUM_SKILL_TRAITS( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT ))) / 100) + 0.5); // +30%
@@ -1633,7 +1633,7 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
} }
} }
// adjust damage resistance of TANKS // adjust damage resistance of TANKS
if ( TANK( pSoldier ) && gGameOptions.fNewTraitSystem ) if ( ARMED_VEHICLE( pSoldier ) && gGameOptions.fNewTraitSystem )
{ {
sNewWoundAmt = (INT16)(sNewWoundAmt * (100 - gSkillTraitValues.bTanksDamageResistanceModifier) / 100); sNewWoundAmt = (INT16)(sNewWoundAmt * (100 - gSkillTraitValues.bTanksDamageResistanceModifier) / 100);
// another half of this for ordinary grenades // another half of this for ordinary grenades
@@ -1651,7 +1651,7 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
; ;
// we can loose stats due to being hit by the blast // we can loose stats due to being hit by the blast
else if ( gGameOptions.fNewTraitSystem && Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL && else if ( gGameOptions.fNewTraitSystem && Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL &&
!AM_A_ROBOT( pSoldier ) && !(pSoldier->flags.uiStatusFlags & SOLDIER_MONSTER) && !TANK(pSoldier) && !AM_A_ROBOT( pSoldier ) && !(pSoldier->flags.uiStatusFlags & SOLDIER_MONSTER) && !ARMED_VEHICLE( pSoldier ) &&
sNewWoundAmt > 2 && sNewWoundAmt < pSoldier->stats.bLife ) sNewWoundAmt > 2 && sNewWoundAmt < pSoldier->stats.bLife )
{ {
if ( PreRandom( sNewWoundAmt ) > gSkillTraitValues.ubDamageNeededToLoseStats ) if ( PreRandom( sNewWoundAmt ) > gSkillTraitValues.ubDamageNeededToLoseStats )
@@ -4496,7 +4496,7 @@ BOOLEAN SetOffBombsInGridNo( UINT8 ubID, INT32 sGridNo, BOOLEAN fAllBombs, INT8
if ( !fAllBombs && ubID != NOBODY && Item[pObj->usItem].antitankmine ) if ( !fAllBombs && ubID != NOBODY && Item[pObj->usItem].antitankmine )
{ {
// if this is not a vehicle, not a robot and not a tank, don't activate // if this is not a vehicle, not a robot and not a tank, don't activate
if ( !(MercPtrs[ubID]->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( MercPtrs[ubID] ) && !TANK( MercPtrs[ubID] ) ) if ( !(MercPtrs[ubID]->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( MercPtrs[ubID] ) && !ARMED_VEHICLE( MercPtrs[ubID] ) )
continue; continue;
} }
+12 -7
View File
@@ -651,7 +651,11 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
{ {
fVehicleIgnoreObstacles = TRUE; fVehicleIgnoreObstacles = TRUE;
} }
else if( gGameExternalOptions.ubTanksRammingMaxStructureArmour && sSoldierID != NOBODY && TANK( MercPtrs[ sSoldierID ] ) ) else if ( gGameExternalOptions.ubEnemyJeepsRammingMaxStructureArmour && sSoldierID != NOBODY && COMBAT_JEEP( MercPtrs[sSoldierID] ) )
{
fVehicleIgnoreObstacles = TRUE;
}
else if ( gGameExternalOptions.ubTanksRammingMaxStructureArmour && sSoldierID != NOBODY && TANK( MercPtrs[sSoldierID] ) )
{ {
fVehicleIgnoreObstacles = TRUE; fVehicleIgnoreObstacles = TRUE;
} }
@@ -737,15 +741,15 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
// but not monsters and such (they can't fall down due to lack of animations) // but not monsters and such (they can't fall down due to lack of animations)
// also make sure AI won't flatten their allies // also make sure AI won't flatten their allies
if( !( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_ROBOT | SOLDIER_MONSTER ) ) && if( !( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_ROBOT | SOLDIER_MONSTER ) ) &&
( ( !TANK(MercPtrs[ sSoldierID ]) && gGameExternalOptions.fAllowCarsDrivingOverPeople ) || ((!ARMED_VEHICLE( MercPtrs[sSoldierID] ) && gGameExternalOptions.fAllowCarsDrivingOverPeople) ||
( TANK(MercPtrs[ sSoldierID ]) && gGameExternalOptions.fAllowTanksDrivingOverPeople ) ) && (ARMED_VEHICLE( MercPtrs[sSoldierID] ) && gGameExternalOptions.fAllowTanksDrivingOverPeople)) &&
( MercPtrs[ sSoldierID ]->bTeam == gbPlayerNum || MercPtrs[ sSoldierID ]->bTeam != pSoldier->bTeam ) ) ( MercPtrs[ sSoldierID ]->bTeam == gbPlayerNum || MercPtrs[ sSoldierID ]->bTeam != pSoldier->bTeam ) )
{ {
pExistingStructure = pExistingStructure->pNext; pExistingStructure = pExistingStructure->pNext;
// damage people when driving on them // damage people when driving on them
if( fAddingForReal ) if( fAddingForReal )
{ {
if( TANK( MercPtrs[ sSoldierID ] ) ) if ( TANK( MercPtrs[sSoldierID] ) )
{ {
pSoldier->EVENT_SoldierGotHit( 0, Random(10)+5, Random(200)+Random(200), MercPtrs[ sSoldierID ]->ubDirection, 0, sSoldierID, FIRE_WEAPON_VEHICLE_TRAUMA, 0, 0, pSoldier->sGridNo ); pSoldier->EVENT_SoldierGotHit( 0, Random(10)+5, Random(200)+Random(200), MercPtrs[ sSoldierID ]->ubDirection, 0, sSoldierID, FIRE_WEAPON_VEHICLE_TRAUMA, 0, 0, pSoldier->sGridNo );
} }
@@ -771,8 +775,9 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC
else else
{ {
// only if structure is weak enough // only if structure is weak enough
if( ( !TANK(MercPtrs[ sSoldierID ]) && gubMaterialArmour[ pExistingStructure->pDBStructureRef->pDBStructure->ubArmour ] < gGameExternalOptions.ubCarsRammingMaxStructureArmour ) || if ( (!ARMED_VEHICLE( MercPtrs[sSoldierID] ) && gubMaterialArmour[pExistingStructure->pDBStructureRef->pDBStructure->ubArmour] < gGameExternalOptions.ubCarsRammingMaxStructureArmour) ||
( TANK(MercPtrs[ sSoldierID ]) && gubMaterialArmour[ pExistingStructure->pDBStructureRef->pDBStructure->ubArmour ] < gGameExternalOptions.ubTanksRammingMaxStructureArmour ) ) (COMBAT_JEEP( MercPtrs[sSoldierID] ) && gubMaterialArmour[pExistingStructure->pDBStructureRef->pDBStructure->ubArmour] < gGameExternalOptions.ubEnemyJeepsRammingMaxStructureArmour) ||
(TANK( MercPtrs[sSoldierID] ) && gubMaterialArmour[pExistingStructure->pDBStructureRef->pDBStructure->ubArmour] < gGameExternalOptions.ubTanksRammingMaxStructureArmour) )
{ {
// when not just plotting path, really destroy structure // when not just plotting path, really destroy structure
if( fAddingForReal ) if( fAddingForReal )
@@ -1915,7 +1920,7 @@ BOOLEAN DamageStructure( STRUCTURE * pStructure, UINT8 ubDamage, UINT8 ubReason,
gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED; gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
// handle structure revenge - damage to vehicle // handle structure revenge - damage to vehicle
if ( ubOwner != NOBODY && MercPtrs[ubOwner] && !TANK( MercPtrs[ubOwner] ) ) if ( ubOwner != NOBODY && MercPtrs[ubOwner] && !ARMED_VEHICLE( MercPtrs[ubOwner] ) )
{ {
MercPtrs[ ubOwner ]->SoldierTakeDamage( 0, Random(max(0,(ubBaseArmour-10)/5))+max(0,(ubBaseArmour-10)/5), 0, TAKE_DAMAGE_STRUCTURE_EXPLOSION, NOBODY, MercPtrs[ ubOwner ]->sGridNo, 0, TRUE ); MercPtrs[ ubOwner ]->SoldierTakeDamage( 0, Random(max(0,(ubBaseArmour-10)/5))+max(0,(ubBaseArmour-10)/5), 0, TAKE_DAMAGE_STRUCTURE_EXPLOSION, NOBODY, MercPtrs[ ubOwner ]->sGridNo, 0, TRUE );
} }
+1
View File
@@ -1863,6 +1863,7 @@ enum
STR_MILITIAMOVEMENT_NO_STAFF_ABORT, STR_MILITIAMOVEMENT_NO_STAFF_ABORT,
STR_AR_TANK_NAME, STR_AR_TANK_NAME,
STR_AR_JEEP_NAME,
STR_BREATH_REGEN_SLEEP, STR_BREATH_REGEN_SLEEP,
+2
View File
@@ -1546,6 +1546,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"成年公异形", //25 //L"Adt M Monster", L"成年公异形", //25 //L"Adt M Monster",
L"异形女王", //L"Queen Monster", L"异形女王", //L"Queen Monster",
L"血猫", //L"Bloodcat", L"血猫", //L"Bloodcat",
L"Humvee", // TODO.Translate
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3458,6 +3459,7 @@ STR16 gpStrategicString[] =
L"超出战争(地图)范围,民兵移动失败!", //L"War room isn't staffed - militia move aborted!", L"超出战争(地图)范围,民兵移动失败!", //L"War room isn't staffed - militia move aborted!",
L"坦克", //STR_AR_TANK_NAME, L"坦克", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
L"\n每一个小时刷新一次呼吸: %d", //L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP L"\n每一个小时刷新一次呼吸: %d", //L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2
View File
@@ -1548,6 +1548,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"Adt M Monster", //25 L"Adt M Monster", //25
L"Queen Monster", L"Queen Monster",
L"Bloodcat", L"Bloodcat",
L"Humvee", // TODO.Translate
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3456,6 +3457,7 @@ STR16 gpStrategicString[] =
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2
View File
@@ -1544,6 +1544,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"Adt M Monster", //25 L"Adt M Monster", //25
L"Queen Monster", L"Queen Monster",
L"Bloodcat", L"Bloodcat",
L"Humvee",
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3456,6 +3457,7 @@ STR16 gpStrategicString[] =
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME,
L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2
View File
@@ -1550,6 +1550,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"Monstre Adt M", //25 L"Monstre Adt M", //25
L"Monstre Reine", L"Monstre Reine",
L"Chat Sauvg", L"Chat Sauvg",
L"Humvee", // TODO.Translate
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3464,6 +3465,7 @@ STR16 gpStrategicString[] =
L"La salle d'opérations n'est pas ouverte... Le mouvement de la milice a avorté !", L"La salle d'opérations n'est pas ouverte... Le mouvement de la milice a avorté !",
L"Tank", //STR_AR_TANK_NAME, // TODO.Translate L"Tank", //STR_AR_TANK_NAME, // TODO.Translate
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2
View File
@@ -1569,6 +1569,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"Adt M Monster", //25 L"Adt M Monster", //25
L"Queen Monster", L"Queen Monster",
L"Bloodcat", L"Bloodcat",
L"Humvee", // TODO.Translate
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3467,6 +3468,7 @@ STR16 gpStrategicString[] =
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Panzer", //STR_AR_TANK_NAME, L"Panzer", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2
View File
@@ -1545,6 +1545,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"Adt M Monster", //25 L"Adt M Monster", //25
L"Queen Monster", L"Queen Monster",
L"Bloodcat", L"Bloodcat",
L"Humvee", // TODO.Translate
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3451,6 +3452,7 @@ STR16 gpStrategicString[] =
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2
View File
@@ -1548,6 +1548,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"Adt M Monster", //25 L"Adt M Monster", //25
L"Queen Monster", L"Queen Monster",
L"Dziki kot", L"Dziki kot",
L"Humvee", // TODO.Translate
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3462,6 +3463,7 @@ STR16 gpStrategicString[] =
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP L"\nBreath regeneration per hour: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2
View File
@@ -1544,6 +1544,7 @@ STR16 pDisplayBodyTypeInfoText[] =
L"Adt M Monster", //25 L"Adt M Monster", //25
L"Queen Monster", L"Queen Monster",
L"Bloodcat", L"Bloodcat",
L"Humvee", // TODO.Translate
}; };
STR16 pUpdateMercsInfoText[] = STR16 pUpdateMercsInfoText[] =
@@ -3456,6 +3457,7 @@ STR16 gpStrategicString[] =
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Танк", //STR_AR_TANK_NAME, L"Танк", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
L"\nВосстановление дыхания в час: %d", // STR_BREATH_REGEN_SLEEP L"\nВосстановление дыхания в час: %d", // STR_BREATH_REGEN_SLEEP
}; };
+2 -1
View File
@@ -158,8 +158,9 @@ static int LuaGroupCreate( lua_State *L )
UINT8 NumTroops = (UINT8) luaL_checkinteger( L, 3); UINT8 NumTroops = (UINT8) luaL_checkinteger( L, 3);
UINT8 NumElites = (UINT8) luaL_checkinteger( L, 4); UINT8 NumElites = (UINT8) luaL_checkinteger( L, 4);
UINT8 NumTanks = (UINT8) luaL_checkinteger( L, 5); UINT8 NumTanks = (UINT8) luaL_checkinteger( L, 5);
UINT8 NumJeeps = (UINT8)luaL_checkinteger( L, 6 );
GROUP *pGroup = CreateNewEnemyGroupDepartingFromSector( Sector, NumAdmins, NumTroops, NumElites, NumTanks ); GROUP *pGroup = CreateNewEnemyGroupDepartingFromSector( Sector, NumAdmins, NumTroops, NumElites, NumTanks, NumJeeps );
if (pGroup) if (pGroup)
{ {
+47 -47
View File
@@ -101,55 +101,56 @@ void RandomStats ();
void RandomAddEnemy( UINT8 SectorX, UINT8 SectorY, UINT8 Level ) void RandomAddEnemy( UINT8 SectorX, UINT8 SectorY, UINT8 Level )
{ {
UNDERGROUND_SECTORINFO *pSector; UNDERGROUND_SECTORINFO *pSector;
UINT8 ubNumAdmins = 0; UINT8 ubNumAdmins = 0;
UINT8 ubNumTroops = 0; UINT8 ubNumTroops = 0;
UINT8 ubNumElites = 0; UINT8 ubNumElites = 0;
UINT8 ubNumTanks = 0; UINT8 ubNumTanks = 0;
UINT8 ubNumJeeps = 0;
if ( Level != 0 ) if ( Level != 0 )
{ {
pSector = FindUnderGroundSector( SectorX, SectorY, Level ); pSector = FindUnderGroundSector( SectorX, SectorY, Level );
if ( pSector ) if ( pSector )
{
if ( pSector->fVisited != TRUE )
{ {
switch( gGameOptions.ubDifficultyLevel ) if ( pSector->fVisited != TRUE )
{ {
case DIF_LEVEL_EASY: switch( gGameOptions.ubDifficultyLevel )
ubNumAdmins = Random( 0 ); {
ubNumTroops = 10 + Random( 5 ); case DIF_LEVEL_EASY:
ubNumElites = Random( 4 ); ubNumAdmins = Random( 0 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); ubNumTroops = 10 + Random( 5 );
break; ubNumElites = Random( 4 );
case DIF_LEVEL_MEDIUM: SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
ubNumAdmins = Random( 0 ); break;
ubNumTroops = 15 + Random( 8 ); case DIF_LEVEL_MEDIUM:
ubNumElites = 1 + Random( 2 ); ubNumAdmins = Random( 0 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); ubNumTroops = 15 + Random( 8 );
break; ubNumElites = 1 + Random( 2 );
case DIF_LEVEL_HARD: SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
ubNumAdmins = Random( 0 ); break;
ubNumTroops = 20 + Random( 7 ); case DIF_LEVEL_HARD:
ubNumElites = 2 + Random( 2 ); ubNumAdmins = Random( 0 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); ubNumTroops = 20 + Random( 7 );
break; ubNumElites = 2 + Random( 2 );
case DIF_LEVEL_INSANE: SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
ubNumAdmins = Random( 0 ); break;
ubNumTroops = 20 + Random( 3 ); case DIF_LEVEL_INSANE:
ubNumElites = 6 + Random( 3 ); ubNumAdmins = Random( 0 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); ubNumTroops = 20 + Random( 3 );
break; ubNumElites = 6 + Random( 3 );
default: SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
ubNumAdmins = Random( 0 ); break;
ubNumTroops = 10 + Random( 5 ); default:
ubNumElites = Random( 4 ); ubNumAdmins = Random( 0 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); ubNumTroops = 10 + Random( 5 );
break; ubNumElites = Random( 4 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
break;
}
} }
} }
} }
}
else else
{ {
if ( !GetSectorFlagStatus( SectorX, SectorY, Level, SF_ALREADY_VISITED ) ) if ( !GetSectorFlagStatus( SectorX, SectorY, Level, SF_ALREADY_VISITED ) )
@@ -160,32 +161,31 @@ UINT8 ubNumTanks = 0;
ubNumAdmins = Random( 0 ); ubNumAdmins = Random( 0 );
ubNumTroops = 10 + Random( 5 ); ubNumTroops = 10 + Random( 5 );
ubNumElites = Random( 4 ); ubNumElites = Random( 4 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
break; break;
case DIF_LEVEL_MEDIUM: case DIF_LEVEL_MEDIUM:
ubNumAdmins = Random( 0 ); ubNumAdmins = Random( 0 );
ubNumTroops = 15 + Random( 8 ); ubNumTroops = 15 + Random( 8 );
ubNumElites = 1 + Random( 2 ); ubNumElites = 1 + Random( 2 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
break; break;
case DIF_LEVEL_HARD: case DIF_LEVEL_HARD:
ubNumAdmins = Random( 0 ); ubNumAdmins = Random( 0 );
ubNumTroops = 23 + Random( 7); ubNumTroops = 23 + Random( 7);
ubNumElites = 2 + Random( 2 ); ubNumElites = 2 + Random( 2 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
break; break;
case DIF_LEVEL_INSANE: case DIF_LEVEL_INSANE:
ubNumAdmins = Random( 0 ); ubNumAdmins = Random( 0 );
ubNumTroops = 20 + Random( 3 ); ubNumTroops = 20 + Random( 3 );
ubNumElites = 6 + Random( 3 ); ubNumElites = 6 + Random( 3 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
break; break;
default: default:
ubNumAdmins = Random( 0 ); ubNumAdmins = Random( 0 );
ubNumTroops = 10 + Random( 5 ); ubNumTroops = 10 + Random( 5 );
ubNumElites = Random( 4 ); ubNumElites = Random( 4 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps );
break;
break; break;
} }
} }