Add robots to enemy groups (by rftr).

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8956 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Sevenfm
2021-04-03 03:32:40 +00:00
parent 4c7db819ef
commit b6f15b2347
64 changed files with 1033 additions and 766 deletions
+8
View File
@@ -1853,6 +1853,10 @@ void LoadGameExternalOptions()
gGameExternalOptions.fArmyUsesJeepsInPatrols = iniReader.ReadBoolean( "Strategic Gameplay Settings", "ARMY_USES_JEEPS_IN_PATROLS", 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 ); gGameExternalOptions.usJeepMinimumProgress = iniReader.ReadInteger( "Strategic Gameplay Settings", "JEEP_MINIMUM_PROGRESS", 30, 0, 100 );
gGameExternalOptions.fArmyUsesRobotsInAttacks = iniReader.ReadBoolean( "Strategic Gameplay Settings", "ARMY_USES_ROBOTS_IN_ATTACKS", FALSE );
gGameExternalOptions.fArmyUsesRobotsInPatrols = iniReader.ReadBoolean( "Strategic Gameplay Settings", "ARMY_USES_ROBOTS_IN_PATROLS", FALSE );
gGameExternalOptions.usRobotMinimumProgress = iniReader.ReadInteger( "Strategic Gameplay Settings", "ROBOT_MINIMUM_PROGRESS", 45, 0, 100 );
// Kaiden: Vehicle Inventory change - Added INI file Option VEHICLE_INVENTORY // Kaiden: Vehicle Inventory change - Added INI file Option VEHICLE_INVENTORY
gGameExternalOptions.fVehicleInventory = iniReader.ReadBoolean("Strategic Gameplay Settings", "VEHICLE_INVENTORY", TRUE); gGameExternalOptions.fVehicleInventory = iniReader.ReadBoolean("Strategic Gameplay Settings", "VEHICLE_INVENTORY", TRUE);
@@ -2035,18 +2039,22 @@ void LoadGameExternalOptions()
gGameExternalOptions.gASDResource_Cost[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_HELI", 30000, 1, 1000000 ); gGameExternalOptions.gASDResource_Cost[ASD_HELI] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_HELI", 30000, 1, 1000000 );
gGameExternalOptions.gASDResource_Cost[ASD_JEEP] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_JEEP", 20000, 1, 1000000 ); gGameExternalOptions.gASDResource_Cost[ASD_JEEP] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_JEEP", 20000, 1, 1000000 );
gGameExternalOptions.gASDResource_Cost[ASD_TANK] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_TANK", 50000, 1, 1000000 ); gGameExternalOptions.gASDResource_Cost[ASD_TANK] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_TANK", 50000, 1, 1000000 );
gGameExternalOptions.gASDResource_Cost[ASD_ROBOT] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_COST_ROBOT", 25000, 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] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_JEEP", 60 * 12, 1, 60 * 48 ); 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] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_TANK", 60 * 24, 1, 60 * 48 ); gGameExternalOptions.gASDResource_BuyTime[ASD_TANK] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_TANK", 60 * 24, 1, 60 * 48 );
gGameExternalOptions.gASDResource_BuyTime[ASD_ROBOT] = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_TIME_ROBOT", 60 * 12, 1, 60 * 48 );
gGameExternalOptions.fASDAssignsTanks = iniReader.ReadBoolean( "Strategic Additional Enemy AI Settings", "ASD_ASSIGNS_TANKS", TRUE ); 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.fASDAssignsJeeps = iniReader.ReadBoolean( "Strategic Additional Enemy AI Settings", "ASD_ASSIGNS_JEEPS", TRUE );
gGameExternalOptions.fASDAssignsRobots = iniReader.ReadBoolean( "Strategic Additional Enemy AI Settings", "ASD_ASSIGNS_ROBOTS", TRUE );
gGameExternalOptions.gASDResource_Fuel_Tank = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_FUEL_REQUIRED_TANK", 100, 0, 10000 ); 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 ); gGameExternalOptions.gASDResource_Fuel_Jeep = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_FUEL_REQUIRED_JEEP", 20, 0, 10000 );
gGameExternalOptions.gASDResource_Fuel_Robot = iniReader.ReadInteger( "Strategic Additional Enemy AI Settings", "ASD_FUEL_REQUIRED_ROBOT", 0, 0, 10000 );
// Flugente: enemy heli // Flugente: enemy heli
//################# Enemy Helicopter Settings ################## //################# Enemy Helicopter Settings ##################
+7
View File
@@ -223,6 +223,7 @@ enum
ASD_HELI, ASD_HELI,
ASD_JEEP, ASD_JEEP,
ASD_TANK, ASD_TANK,
ASD_ROBOT,
ASD_RESOURCE_MAX ASD_RESOURCE_MAX
}; };
@@ -686,9 +687,11 @@ typedef struct
BOOLEAN fASDAssignsTanks; BOOLEAN fASDAssignsTanks;
BOOLEAN fASDAssignsJeeps; BOOLEAN fASDAssignsJeeps;
BOOLEAN fASDAssignsRobots;
INT32 gASDResource_Fuel_Tank; INT32 gASDResource_Fuel_Tank;
INT32 gASDResource_Fuel_Jeep; INT32 gASDResource_Fuel_Jeep;
INT32 gASDResource_Fuel_Robot;
// Flugente: enemy heli // Flugente: enemy heli
BOOLEAN fEnemyHeliActive; BOOLEAN fEnemyHeliActive;
@@ -947,6 +950,10 @@ typedef struct
BOOLEAN fArmyUsesJeepsInPatrols; BOOLEAN fArmyUsesJeepsInPatrols;
UINT8 usJeepMinimumProgress; UINT8 usJeepMinimumProgress;
BOOLEAN fArmyUsesRobotsInAttacks;
BOOLEAN fArmyUsesRobotsInPatrols;
UINT8 usRobotMinimumProgress;
// WANNE: Always use "prof.dat". // WANNE: Always use "prof.dat".
BOOLEAN fUseDifficultyBasedProfDat; BOOLEAN fUseDifficultyBasedProfDat;
+2 -1
View File
@@ -22,6 +22,7 @@ extern CHAR16 zRevisionNumber[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_ROBOTS 183 // rftr: enemy robots
#define DRAGSTRUCTURE 182 // Flugente: we can drag structures behind us #define DRAGSTRUCTURE 182 // Flugente: we can drag structures behind us
#define DISABILITYFLAGMASK 181 // Flugente: disabilities get a flagmask #define DISABILITYFLAGMASK 181 // Flugente: disabilities get a flagmask
#define PROFILETYPE_STORED 180 // Flugente: the type of each profile is stored in the savegame #define PROFILETYPE_STORED 180 // Flugente: the type of each profile is stored in the savegame
@@ -102,7 +103,7 @@ extern CHAR16 zRevisionNumber[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 DRAGSTRUCTURE #define SAVE_GAME_VERSION ENEMY_ROBOTS
//#define RUSSIANGOLD //#define RUSSIANGOLD
#ifdef __cplusplus #ifdef __cplusplus
+1 -1
View File
@@ -156,7 +156,7 @@ Incident_Stats::AddStat( SOLDIERTYPE* pSoldier, UINT8 aType )
case ENEMY_TEAM: case ENEMY_TEAM:
{ {
if ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( 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;
+4 -4
View File
@@ -1278,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, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-16, 0, 11, 5, 0, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX; pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY; pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 10; pGroup->uiTraverseTime = 10;
@@ -1290,7 +1290,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
} }
if( gsSelSectorY < 16 ) if( gsSelSectorY < 16 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+16, 0, 8, 8, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+16, 0, 8, 8, 0, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX; pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY; pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 12; pGroup->uiTraverseTime = 12;
@@ -1302,7 +1302,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
} }
if( gsSelSectorX > 1 ) if( gsSelSectorX > 1 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-1, 0, 11, 5, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector-1, 0, 11, 5, 0, 0, 0 );
pGroup->ubNextX = (UINT8)gsSelSectorX; pGroup->ubNextX = (UINT8)gsSelSectorX;
pGroup->ubNextY = (UINT8)gsSelSectorY; pGroup->ubNextY = (UINT8)gsSelSectorY;
pGroup->uiTraverseTime = 11; pGroup->uiTraverseTime = 11;
@@ -1314,7 +1314,7 @@ void TestIncoming4SidesCallback( GUI_BUTTON *btn, INT32 reason )
} }
if( gsSelSectorX < 16 ) if( gsSelSectorX < 16 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, 0, 14, 0, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, 0, 14, 0, 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;
+52 -2
View File
@@ -99,12 +99,14 @@ void InitASD( )
gASDResource[ASD_HELI] = 0; gASDResource[ASD_HELI] = 0;
gASDResource[ASD_JEEP] = 2; gASDResource[ASD_JEEP] = 2;
gASDResource[ASD_TANK] = 2; gASDResource[ASD_TANK] = 2;
gASDResource[ASD_ROBOT] = 8;
gASDResource_Ordered[ASD_MONEY] = 0; gASDResource_Ordered[ASD_MONEY] = 0;
gASDResource_Ordered[ASD_FUEL] = 0; gASDResource_Ordered[ASD_FUEL] = 0;
gASDResource_Ordered[ASD_HELI] = 0; gASDResource_Ordered[ASD_HELI] = 0;
gASDResource_Ordered[ASD_JEEP] = 0; gASDResource_Ordered[ASD_JEEP] = 0;
gASDResource_Ordered[ASD_TANK] = 0; gASDResource_Ordered[ASD_TANK] = 0;
gASDResource_Ordered[ASD_ROBOT] = 0;
gASD_Flags = 0; gASD_Flags = 0;
@@ -196,6 +198,8 @@ void UpdateASD( )
if ( !(gASD_Flags & ASDFACT_TANK_UNLOCKED) && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usTankMinimumProgress ) if ( !(gASD_Flags & ASDFACT_TANK_UNLOCKED) && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usTankMinimumProgress )
SetASDFlag( ASDFACT_TANK_UNLOCKED ); SetASDFlag( ASDFACT_TANK_UNLOCKED );
if ( !(gASD_Flags & ASDFACT_ROBOT_UNLOCKED) && HighestPlayerProgressPercentage( ) >= gGameExternalOptions.usRobotMinimumProgress )
SetASDFlag( ASDFACT_ROBOT_UNLOCKED );
// determine whether we need to buy new toys // determine whether we need to buy new toys
ASDDecideOnPurchases(); ASDDecideOnPurchases();
@@ -210,6 +214,7 @@ void ASDDecideOnPurchases()
INT32 needed_heli = 0; INT32 needed_heli = 0;
INT32 needed_tank = 0; INT32 needed_tank = 0;
INT32 needed_jeep = 0; INT32 needed_jeep = 0;
INT32 needed_robot = 0;
UINT16 highestplayerprogress = HighestPlayerProgressPercentage( ); UINT16 highestplayerprogress = HighestPlayerProgressPercentage( );
@@ -275,24 +280,39 @@ void ASDDecideOnPurchases()
needed_fuel += needed_tank * ASDResourceCostFuel( ASD_TANK ); needed_fuel += needed_tank * ASDResourceCostFuel( ASD_TANK );
} }
// do we need new robots?
if ( gASD_Flags & ASDFACT_ROBOT_UNLOCKED )
{
// 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_robot = min( 10, 2 + highestplayerprogress / 10 );
// how many are needed?
needed_robot = max( 0, needed_robot - gASDResource[ASD_ROBOT] );
needed_fuel += needed_robot * ASDResourceCostFuel( ASD_ROBOT );
}
// how much new fuel do we need? // how much new fuel do we need?
needed_fuel = max( 0, needed_fuel - gASDResource[ASD_FUEL] ); needed_fuel = max( 0, needed_fuel - gASDResource[ASD_FUEL] );
// reduce order by what we'e alreay ordered // reduce order by what we'e already ordered
needed_fuel = max( 0, needed_fuel - gASDResource_Ordered[ASD_FUEL] ); needed_fuel = max( 0, needed_fuel - gASDResource_Ordered[ASD_FUEL] );
needed_jeep = max( 0, needed_jeep - gASDResource_Ordered[ASD_JEEP] ); needed_jeep = max( 0, needed_jeep - gASDResource_Ordered[ASD_JEEP] );
needed_tank = max( 0, needed_tank - gASDResource_Ordered[ASD_TANK] ); needed_tank = max( 0, needed_tank - gASDResource_Ordered[ASD_TANK] );
needed_heli = max( 0, needed_heli - gASDResource_Ordered[ASD_HELI] ); needed_heli = max( 0, needed_heli - gASDResource_Ordered[ASD_HELI] );
needed_robot = max( 0, needed_robot - gASDResource_Ordered[ASD_ROBOT] );
// check whether we can afford all new purchases. If we can't, lower your expectations // check whether we can afford all new purchases. If we can't, lower your expectations
while ( needed_fuel * ASDResourceCostMoney( ASD_FUEL ) + while ( needed_fuel * ASDResourceCostMoney( ASD_FUEL ) +
needed_jeep * ASDResourceCostMoney( ASD_JEEP ) + needed_jeep * ASDResourceCostMoney( ASD_JEEP ) +
needed_tank * ASDResourceCostMoney( ASD_TANK ) + needed_tank * ASDResourceCostMoney( ASD_TANK ) +
needed_heli * ASDResourceCostMoney( ASD_HELI ) > gASDResource[ASD_MONEY] ) needed_heli * ASDResourceCostMoney( ASD_HELI ) +
needed_robot * ASDResourceCostMoney( ASD_ROBOT ) > gASDResource[ASD_MONEY] )
{ {
if ( needed_tank ) --needed_tank; if ( needed_tank ) --needed_tank;
else if ( needed_heli ) --needed_heli; else if ( needed_heli ) --needed_heli;
else if ( needed_jeep ) --needed_jeep; else if ( needed_jeep ) --needed_jeep;
else if ( needed_robot ) --needed_robot;
else needed_fuel = max( 0, needed_fuel - 10 ); else needed_fuel = max( 0, needed_fuel - 10 );
} }
@@ -334,6 +354,15 @@ void ASDDecideOnPurchases()
AddStrategicEvent( EVENT_ASD_PURCHASE_HELI, GetWorldTotalMin( ) + ASDResourceDeliveryTime( ASD_HELI ), needed_heli ); AddStrategicEvent( EVENT_ASD_PURCHASE_HELI, GetWorldTotalMin( ) + ASDResourceDeliveryTime( ASD_HELI ), needed_heli );
} }
if ( needed_robot )
{
AddStrategicAIResources( ASD_MONEY, -needed_robot * ASDResourceCostMoney( ASD_ROBOT ) );
gASDResource_Ordered[ASD_ROBOT] += needed_robot;
AddStrategicEvent( EVENT_ASD_PURCHASE_ROBOT, GetWorldTotalMin( ) + ASDResourceDeliveryTime( ASD_ROBOT ), needed_robot );
}
} }
void ASDDecideHeliOperations() void ASDDecideHeliOperations()
@@ -1470,6 +1499,10 @@ UINT32 ASDResourceCostFuel( UINT8 aType )
case ASD_JEEP: case ASD_JEEP:
return gGameExternalOptions.gASDResource_Fuel_Jeep; return gGameExternalOptions.gASDResource_Fuel_Jeep;
break; break;
case ASD_ROBOT:
return gGameExternalOptions.gASDResource_Fuel_Robot;
break;
} }
return 0; return 0;
@@ -1509,3 +1542,20 @@ BOOLEAN ASDSoldierUpgradeToJeep( )
return FALSE; return FALSE;
} }
BOOLEAN ASDSoldierUpgradeToRobot( )
{
if ( gGameExternalOptions.fASDActive && gGameExternalOptions.fASDAssignsRobots )
{
if ( gASD_Flags & ASDFACT_ROBOT_UNLOCKED )
{
if ( gASDResource[ASD_ROBOT] )
{
gASDResource[ASD_ROBOT] = max( 0, gASDResource[ASD_ROBOT] - 1 );
return TRUE;
}
}
}
return FALSE;
}
+2
View File
@@ -49,6 +49,7 @@ void ASDDecideHeliOperations();
#define ASDFACT_HELI_UNLOCKED 0x00000001 // AI is allowed to purchase helicopters #define ASDFACT_HELI_UNLOCKED 0x00000001 // AI is allowed to purchase helicopters
#define ASDFACT_JEEP_UNLOCKED 0x00000002 // AI is allowed to purchase jeeps #define ASDFACT_JEEP_UNLOCKED 0x00000002 // AI is allowed to purchase jeeps
#define ASDFACT_TANK_UNLOCKED 0x00000004 // AI is allowed to purchase tanks #define ASDFACT_TANK_UNLOCKED 0x00000004 // AI is allowed to purchase tanks
#define ASDFACT_ROBOT_UNLOCKED 0x00000008 // AI is allowed to purchase robots
void SetASDFlag( UINT32 aFlag ); void SetASDFlag( UINT32 aFlag );
@@ -121,5 +122,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( ); BOOLEAN ASDSoldierUpgradeToJeep( );
BOOLEAN ASDSoldierUpgradeToRobot( );
#endif //__ASD_H #endif //__ASD_H
+85 -24
View File
@@ -74,6 +74,8 @@
#include "MilitiaIndividual.h" // added by Flugente #include "MilitiaIndividual.h" // added by Flugente
#endif #endif
#pragma optimize("",off)
#include "Reinforcement.h" #include "Reinforcement.h"
//#define INVULNERABILITY //#define INVULNERABILITY
@@ -141,7 +143,7 @@ typedef struct AUTORESOLVE_STRUCT
INT32 iButtonImage[ NUM_AR_BUTTONS ]; INT32 iButtonImage[ NUM_AR_BUTTONS ];
INT32 iFaces; //for generic civs and enemies INT32 iFaces; //for generic civs and enemies
// WDS - make number of mercenaries, etc. be configurable // WDS - make number of mercenaries, etc. be configurable
INT32 iMercFaces[CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS]; //for each merc face //INT32 iMercFaces[CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS]; //for each merc face
INT32 iIndent; INT32 iIndent;
INT32 iInterfaceBuffer; INT32 iInterfaceBuffer;
INT32 iNumMercFaces; INT32 iNumMercFaces;
@@ -168,7 +170,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, ubJeeps; UINT8 ubAdmins, ubTroops, ubElites, ubTanks, ubJeeps, ubRobots;
UINT8 ubYMCreatures, ubYFCreatures, ubAMCreatures, ubAFCreatures; UINT8 ubYMCreatures, ubYFCreatures, ubAMCreatures, ubAFCreatures;
UINT8 ubBloodcats; UINT8 ubBloodcats;
UINT8 ubZombies; UINT8 ubZombies;
@@ -236,10 +238,11 @@ typedef struct AUTORESOLVE_STRUCT
#define CELL_BLOODCAT 0x01000000 #define CELL_BLOODCAT 0x01000000
#define CELL_ZOMBIE 0x02000000 #define CELL_ZOMBIE 0x02000000
#define CELL_BANDIT 0x04000000 #define CELL_BANDIT 0x04000000
#define CELL_ENEMYROBOT 0x08000000
//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 | CELL_JEEP | CELL_BANDIT ) #define CELL_ENEMY ( CELL_ELITE | CELL_TROOP | CELL_ADMIN | CELL_TANK | CELL_JEEP | CELL_BANDIT | CELL_ENEMYROBOT )
#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 )
#define CELL_BUG ( CELL_FEMALECREATURE | CELL_MALECREATURE ) #define CELL_BUG ( CELL_FEMALECREATURE | CELL_MALECREATURE )
@@ -415,6 +418,7 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
UINT8 ubNumEnemies[ NUM_ENEMY_RANKS ]; UINT8 ubNumEnemies[ NUM_ENEMY_RANKS ];
UINT8 ubNumTanks = 0; UINT8 ubNumTanks = 0;
UINT8 ubNumJeeps = 0; UINT8 ubNumJeeps = 0;
UINT8 ubNumRobots = 0;
UINT8 ubRankIndex; UINT8 ubRankIndex;
//Clear any possible battle locator //Clear any possible battle locator
@@ -427,7 +431,7 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
// we must process the enemies killed right here & give out loyalty bonuses as if the battle had been fought & won // 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, &ubNumJeeps ); GetNumberOfEnemiesInSector( ubSectorX, ubSectorY, &ubNumEnemies[0], &ubNumEnemies[1], &ubNumEnemies[2], &ubNumRobots, &ubNumTanks, &ubNumJeeps );
for ( ubRankIndex = 0; ubRankIndex < NUM_ENEMY_RANKS; ++ubRankIndex ) for ( ubRankIndex = 0; ubRankIndex < NUM_ENEMY_RANKS; ++ubRankIndex )
{ {
@@ -459,6 +463,7 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY )
pSector->ubNumAdmins = 0; pSector->ubNumAdmins = 0;
pSector->ubNumTanks = 0; pSector->ubNumTanks = 0;
pSector->ubNumJeeps = 0; pSector->ubNumJeeps = 0;
pSector->ubNumRobots = 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.
@@ -747,9 +752,9 @@ void AssociateEnemiesWithStrategicGroups()
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps; //how many soldiers of the type do we still have to assign to a group? UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots; //how many soldiers of the type do we still have to assign to a group?
UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites, ubISNumTanks, ubISNumJeeps; UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites, ubISNumTanks, ubISNumJeeps, ubISNumRobots;
UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup, ubNumTanksInGroup, ubNumJeepsInGroup; UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup, ubNumTanksInGroup, ubNumJeepsInGroup, ubNumRobotsInGroup;
INT32 i; INT32 i;
UINT8 pSectors[4]; UINT8 pSectors[4];
UINT8 ubDirAmount; UINT8 ubDirAmount;
@@ -769,6 +774,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumElites = pSector->ubNumElites; ubNumElites = pSector->ubNumElites;
ubNumTanks = pSector->ubNumTanks; ubNumTanks = pSector->ubNumTanks;
ubNumJeeps = pSector->ubNumJeeps; ubNumJeeps = pSector->ubNumJeeps;
ubNumRobots = pSector->ubNumRobots;
//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
@@ -786,6 +792,12 @@ void AssociateEnemiesWithStrategicGroups()
gpEnemies[i].uiFlags |= CELL_ASSIGNED; gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumJeeps--; ubNumJeeps--;
} }
else if ( gpEnemies[i].uiFlags & CELL_ENEMYROBOT && ubNumRobots )
{
gpEnemies[i].pSoldier->ubGroupID = 0;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumRobots--;
}
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;
@@ -804,15 +816,16 @@ void AssociateEnemiesWithStrategicGroups()
gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; gpEnemies[ i ].uiFlags |= CELL_ASSIGNED;
ubNumAdmins--; ubNumAdmins--;
} }
} }
ubNumAdmins = gpAR->ubAdmins - pSector->ubNumAdmins; ubNumAdmins = gpAR->ubAdmins - pSector->ubNumAdmins;
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; ubNumJeeps = gpAR->ubJeeps - pSector->ubNumJeeps;
ubNumRobots = gpAR->ubRobots - pSector->ubNumRobots;
if ( !ubNumElites && !ubNumTroops && !ubNumAdmins && !ubNumTanks && !ubNumJeeps ) if ( !ubNumElites && !ubNumTroops && !ubNumAdmins && !ubNumTanks && !ubNumJeeps && !ubNumRobots )
{ //All troops accounted for. { //All troops accounted for.
return; return;
} }
@@ -828,6 +841,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins; ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks; ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks;
ubNumJeepsInGroup = pGroup->pEnemyGroup->ubNumJeeps; ubNumJeepsInGroup = pGroup->pEnemyGroup->ubNumJeeps;
ubNumRobotsInGroup = pGroup->pEnemyGroup->ubNumRobots;
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) ?
@@ -846,6 +860,13 @@ void AssociateEnemiesWithStrategicGroups()
ubNumJeeps--; ubNumJeeps--;
ubNumJeepsInGroup--; ubNumJeepsInGroup--;
} }
else if ( ubNumRobots && ubNumRobotsInGroup && gpEnemies[i].uiFlags & CELL_ENEMYROBOT )
{
gpEnemies[i].pSoldier->ubGroupID = pGroup->ubGroupID;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumRobots--;
ubNumRobotsInGroup--;
}
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;
@@ -886,6 +907,7 @@ void AssociateEnemiesWithStrategicGroups()
ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins; ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins;
ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks; ubNumTanksInGroup = pGroup->pEnemyGroup->ubNumTanks;
ubNumJeepsInGroup = pGroup->pEnemyGroup->ubNumJeeps; ubNumJeepsInGroup = pGroup->pEnemyGroup->ubNumJeeps;
ubNumRobotsInGroup = pGroup->pEnemyGroup->ubNumRobots;
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) )
@@ -904,6 +926,13 @@ void AssociateEnemiesWithStrategicGroups()
ubNumJeeps--; ubNumJeeps--;
ubNumJeepsInGroup--; ubNumJeepsInGroup--;
} }
else if ( ubNumRobots && ubNumRobotsInGroup && gpEnemies[i].uiFlags & CELL_ENEMYROBOT )
{
gpEnemies[i].pSoldier->ubGroupID = pGroup->ubGroupID;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
ubNumRobots--;
ubNumRobotsInGroup--;
}
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;
@@ -943,10 +972,11 @@ void AssociateEnemiesWithStrategicGroups()
ubISNumElites = pSector->ubNumElites; ubISNumElites = pSector->ubNumElites;
ubISNumTanks = pSector->ubNumTanks; ubISNumTanks = pSector->ubNumTanks;
ubISNumJeeps = pSector->ubNumJeeps; ubISNumJeeps = pSector->ubNumJeeps;
ubISNumRobots = pSector->ubNumRobots;
for( i = 0; i < gpAR->ubEnemies; ++i ) for( i = 0; i < gpAR->ubEnemies; ++i )
{ {
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 ( ubISNumAdmins + ubISNumTroops + ubISNumElites + ubISNumTanks + ubISNumJeeps + ubISNumRobots <= 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) )
{ {
@@ -968,6 +998,15 @@ void AssociateEnemiesWithStrategicGroups()
ubISNumJeeps--; ubISNumJeeps--;
ubNumJeeps--; ubNumJeeps--;
} }
else if ( gpEnemies[i].uiFlags & CELL_ENEMYROBOT && ubISNumRobots && ubNumRobots )
{
gpEnemies[i].pSoldier->ubGroupID = 0;
gpEnemies[i].uiFlags |= CELL_ASSIGNED;
gpEnemies[i].pSoldier->sSectorX = SECTORX( pSectors[ubCurrSI] );
gpEnemies[i].pSoldier->sSectorY = SECTORY( pSectors[ubCurrSI] );
ubISNumRobots--;
ubNumRobots--;
}
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;
@@ -1000,7 +1039,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 & ubISNumJeeps), "Mapping between actual enemies and autoresolve cells is wrong." ); AssertMsg( !(ubISNumAdmins & ubISNumTroops & ubISNumElites & ubISNumTanks & ubISNumJeeps & ubISNumRobots), "Mapping between actual enemies and autoresolve cells is wrong." );
} }
@@ -1142,8 +1181,10 @@ void CalculateSoldierCells( BOOLEAN fReset )
gpEnemies[index].uiFlags = CELL_ADMIN; gpEnemies[index].uiFlags = CELL_ADMIN;
else if ( index < gpAR->ubElites + gpAR->ubTroops + gpAR->ubAdmins + gpAR->ubTanks ) else if ( index < gpAR->ubElites + gpAR->ubTroops + gpAR->ubAdmins + gpAR->ubTanks )
gpEnemies[index].uiFlags = CELL_TANK; gpEnemies[index].uiFlags = CELL_TANK;
else else if ( index < gpAR->ubElites + gpAR->ubTroops + gpAR->ubAdmins + gpAR->ubTanks + gpAR->ubJeeps )
gpEnemies[index].uiFlags = CELL_JEEP; gpEnemies[index].uiFlags = CELL_JEEP;
else
gpEnemies[index].uiFlags = CELL_ENEMYROBOT;
} }
} }
} }
@@ -2270,6 +2311,19 @@ void CreateAutoResolveInterface()
} }
else else
{ {
for (i = 0; i < gpAR->ubRobots; ++i, ++index)
{
gpEnemies[index].pSoldier = TacticalCreateEnemyRobot();
gpEnemies[index].pSoldier->sSectorX = gpAR->ubSectorX;
gpEnemies[index].pSoldier->sSectorY = gpAR->ubSectorY;
swprintf( gpEnemies[index].pSoldier->name, gpStrategicString[STR_AR_ROBOT_NAME] );
// reuse madlab's robot's face
VOBJECT_DESC VObjectDesc;
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
sprintf( VObjectDesc.ImageFile, "Faces\\65Face\\%02d.sti", gMercProfiles[ ROBOT ].ubFaceIndex );
AddVideoObject(&VObjectDesc, &gpEnemies[index].uiVObjectID);
}
for ( i = 0; i < gpAR->ubElites; ++i, ++index ) for ( i = 0; i < gpAR->ubElites; ++i, ++index )
{ {
gpEnemies[index].pSoldier = TacticalCreateEliteEnemy(); gpEnemies[index].pSoldier = TacticalCreateEliteEnemy();
@@ -3052,9 +3106,9 @@ void CalculateAutoResolveInfo()
else else
{ {
GetNumberOfEnemiesInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY, GetNumberOfEnemiesInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY,
&gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites, &gpAR->ubTanks, &gpAR->ubJeeps ); &gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites, &gpAR->ubRobots, &gpAR->ubTanks, &gpAR->ubJeeps );
gpAR->ubEnemies = (UINT8)min( gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubElites + gpAR->ubTanks + gpAR->ubJeeps, MAX_AR_TEAM_SIZE ); gpAR->ubEnemies = (UINT8)min( gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubElites + gpAR->ubTanks + gpAR->ubJeeps + gpAR->ubRobots, MAX_AR_TEAM_SIZE );
} }
gfTransferTacticalOppositionToAutoResolve = FALSE; gfTransferTacticalOppositionToAutoResolve = FALSE;
@@ -3114,22 +3168,23 @@ 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->ubJeeps > gpAR->ubEnemies ) while ( gpAR->ubElites + gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubTanks + gpAR->ubJeeps + gpAR->ubRobots > gpAR->ubEnemies )
{ {
switch( PreRandom( 5 ) ) switch( PreRandom( 6 ) )
{ {
case 0: if( gpAR->ubElites ) { gpAR->ubElites--; break; } case 0: if ( gpAR->ubElites ) { gpAR->ubElites--; break; }
case 1: if ( gpAR->ubAdmins ) { gpAR->ubAdmins--; break; } case 1: if ( gpAR->ubAdmins ) { gpAR->ubAdmins--; break; }
case 2: if ( gpAR->ubTroops ) { gpAR->ubTroops--; break; } case 2: if ( gpAR->ubTroops ) { gpAR->ubTroops--; break; }
case 3: if ( gpAR->ubTanks ) { gpAR->ubTanks--; break; } case 3: if ( gpAR->ubTanks ) { gpAR->ubTanks--; break; }
case 4: if ( gpAR->ubJeeps ) { gpAR->ubJeeps--; break; } case 4: if ( gpAR->ubJeeps ) { gpAR->ubJeeps--; break; }
case 5: if ( gpAR->ubRobots ) { gpAR->ubRobots--; break; }
} }
} }
while ( gpAR->ubElites + gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubTanks + gpAR->ubJeeps< gpAR->ubEnemies ) while ( gpAR->ubElites + gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubTanks + gpAR->ubJeeps + gpAR->ubRobots < 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;
} }
@@ -4433,7 +4488,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 ( ARMED_VEHICLE( pTarget->pSoldier ) && FireAntiTankWeapon( pAttacker ) ) else if ( (ARMED_VEHICLE( pTarget->pSoldier ) || ENEMYROBOT( pTarget->pSoldier )) && FireAntiTankWeapon( pAttacker ) )
{ {
fAntiTank = TRUE; fAntiTank = TRUE;
@@ -4801,6 +4856,9 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
// SANDRO - experimental - more specific statistics of mercs // SANDRO - experimental - more specific statistics of mercs
switch(pTarget->pSoldier->ubSoldierClass) switch(pTarget->pSoldier->ubSoldierClass)
{ {
case SOLDIER_CLASS_ROBOT :
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsOthers++;
break;
case SOLDIER_CLASS_ELITE : case SOLDIER_CLASS_ELITE :
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsElites++; gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsElites++;
break; break;
@@ -4970,10 +5028,10 @@ 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 ( ARMED_VEHICLE( pTarget->pSoldier ) ) if ( ARMED_VEHICLE( pTarget->pSoldier ) || ENEMYROBOT( 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 );
if( pTarget->pSoldier->stats.bLife >= CONSCIOUSNESS ) if( pTarget->pSoldier->stats.bLife >= CONSCIOUSNESS )
{ {
@@ -5043,6 +5101,9 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
// SANDRO - new mercs' records // SANDRO - new mercs' records
switch(pTarget->pSoldier->ubSoldierClass) switch(pTarget->pSoldier->ubSoldierClass)
{ {
case SOLDIER_CLASS_ROBOT :
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsOthers++;
break;
case SOLDIER_CLASS_ELITE : case SOLDIER_CLASS_ELITE :
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsElites++; gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsElites++;
break; break;
@@ -5154,10 +5215,10 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
{ //Normal death { //Normal death
if( gpAR->fSound ) if( gpAR->fSound )
{ {
if ( ARMED_VEHICLE( pTarget->pSoldier ) ) if ( ARMED_VEHICLE( pTarget->pSoldier ) || ENEMYROBOT( 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 );
} }
} }
#ifdef INVULNERABILITY #ifdef INVULNERABILITY
+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, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_C7, 0, ubNumTroops, 0, 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, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_D9, 0, ubNumTroops, 0, 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, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_B9, 0, ubNumTroops, 0, 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, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_A14, 0, ubNumTroops, 0, 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, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N6, 0, ubNumTroops, 0, 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, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( SEC_N10, 0, ubNumTroops, 0, 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;
+4 -3
View File
@@ -490,8 +490,9 @@ typedef struct SECTORINFO
UINT8 ubNumTroops; //the actual number of troops here. UINT8 ubNumTroops; //the actual number of troops here.
UINT8 ubNumElites; //the actual number of elites here. UINT8 ubNumElites; //the actual number of elites here.
UINT8 ubNumAdmins; //the actual number of admins here. UINT8 ubNumAdmins; //the actual number of admins here.
UINT8 ubNumRobots; //the actual number of robots here.
UINT8 ubNumCreatures; //only set when immediately before ground attack made! UINT8 ubNumCreatures; //only set when immediately before ground attack made!
UINT8 ubTroopsInBattle, ubElitesInBattle, ubAdminsInBattle, ubCreaturesInBattle; UINT8 ubTroopsInBattle, ubElitesInBattle, ubAdminsInBattle, ubRobotsInBattle, ubCreaturesInBattle;
INT8 bLastKnownEnemies; // -1 means never been there, no idea, otherwise it's what we'd observed most recently INT8 bLastKnownEnemies; // -1 means never been there, no idea, otherwise it's what we'd observed most recently
// while this is being maintained (partially, surely buggy), nothing uses it anymore. ARM // while this is being maintained (partially, surely buggy), nothing uses it anymore. ARM
@@ -591,7 +592,7 @@ typedef struct UNDERGROUND_SECTORINFO
{ {
UINT32 uiFlags; UINT32 uiFlags;
UINT8 ubSectorX, ubSectorY, ubSectorZ; UINT8 ubSectorX, ubSectorY, ubSectorZ;
UINT8 ubNumElites, ubNumTroops, ubNumAdmins, ubNumCreatures; UINT8 ubNumRobots, ubNumElites, ubNumTroops, ubNumAdmins, ubNumCreatures;
UINT8 fVisited; UINT8 fVisited;
INT8 ubTravelRating; //Represents how travelled a sector is. Typically, the higher the travel rating, INT8 ubTravelRating; //Represents how travelled a sector is. Typically, the higher the travel rating,
//the more people go near it. A travel rating of 0 means there are never people //the more people go near it. A travel rating of 0 means there are never people
@@ -602,7 +603,7 @@ typedef struct UNDERGROUND_SECTORINFO
UINT8 ubNumBloodcats; // Bloodcat population UINT8 ubNumBloodcats; // Bloodcat population
UINT8 ubCreatureHabitat; //determines how creatures live in this sector (see creature spreading.c) UINT8 ubCreatureHabitat; //determines how creatures live in this sector (see creature spreading.c)
UINT8 ubElitesInBattle, ubTroopsInBattle, ubAdminsInBattle, ubCreaturesInBattle; UINT8 ubRobotsInBattle, ubElitesInBattle, ubTroopsInBattle, ubAdminsInBattle, ubCreaturesInBattle;
// adding these (should not change struct layout due to padding) // adding these (should not change struct layout due to padding)
UINT8 ubMusicMode, ubUnsed; UINT8 ubMusicMode, ubUnsed;
+7
View File
@@ -592,6 +592,13 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent )
AddStrategicAIResources( ASD_HELI, pEvent->uiParam ); AddStrategicAIResources( ASD_HELI, pEvent->uiParam );
break; break;
case EVENT_ASD_PURCHASE_ROBOT:
ASDReduceOrderedStrategicResources( ASD_ROBOT, pEvent->uiParam );
if ( IsSectorEnemyControlled( gModSettings.usASDSupplyArrivalSectorX, gModSettings.usASDSupplyArrivalSectorY, 0 ) )
AddStrategicAIResources( ASD_ROBOT, pEvent->uiParam );
break;
case EVENT_ENEMY_HELI_UPDATE: case EVENT_ENEMY_HELI_UPDATE:
UpdateEnemyHeli( pEvent->uiParam ); UpdateEnemyHeli( pEvent->uiParam );
break; break;
+1
View File
@@ -125,6 +125,7 @@ enum
EVENT_ASD_PURCHASE_JEEP, EVENT_ASD_PURCHASE_JEEP,
EVENT_ASD_PURCHASE_TANK, EVENT_ASD_PURCHASE_TANK,
EVENT_ASD_PURCHASE_HELI, EVENT_ASD_PURCHASE_HELI,
EVENT_ASD_PURCHASE_ROBOT,
EVENT_ENEMY_HELI_UPDATE, // Flugente: move enemy helicopter to another sector EVENT_ENEMY_HELI_UPDATE, // Flugente: move enemy helicopter to another sector
EVENT_ENEMY_HELI_REPAIR, EVENT_ENEMY_HELI_REPAIR,
+69 -48
View File
@@ -123,15 +123,15 @@ JA25_SECTOR_AI_MANAGER gJa25StrategicAi;
BOOLEAN AddEnemiesToInitialSectorH7(); BOOLEAN AddEnemiesToInitialSectorH7();
UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps ); UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps, UINT8 *pubNumRobots );
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps ); void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, UINT8 ubNumRobots );
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, UINT8 ubNumJeeps ); void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, UINT8 ubNumRobots );
void ResetJa25SectorProbabilities(); void ResetJa25SectorProbabilities();
BOOLEAN InitJa25StrategicSectorAI( BOOLEAN fReset ); BOOLEAN InitJa25StrategicSectorAI( BOOLEAN fReset );
@@ -151,8 +151,8 @@ void FixEnemyCounterInSectorBug();
void AddEnemiesToFirstTunnelSector(); void AddEnemiesToFirstTunnelSector();
void AddEnemiesToSecondTunnelSector(); void AddEnemiesToSecondTunnelSector();
UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps ); UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps, UINT8 *pRobots );
UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps ); UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps, UINT8 *pRobots );
void RemoveAllEnemySoldierInitListLinks(); void RemoveAllEnemySoldierInitListLinks();
INT16 GetGridNoEnemyWillSeekWhenAttacking( INT8 bSaiSector ); INT16 GetGridNoEnemyWillSeekWhenAttacking( INT8 bSaiSector );
void SetH11NumEnemiesInSector(); void SetH11NumEnemiesInSector();
@@ -174,7 +174,7 @@ BOOLEAN Ja25BetaDateToInvalidateExe();
UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pNumTanks, UINT8 *pubNumJeeps ) UINT32 GetNumberOfJA25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 *pNumAdmins, UINT8 *pNumTroops, UINT8 *pNumElites, UINT8 *pNumTanks, UINT8 *pubNumJeeps, UINT8 *pubNumRobots )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
@@ -188,6 +188,7 @@ BOOLEAN Ja25BetaDateToInvalidateExe();
*pNumElites = pSector->ubNumElites; *pNumElites = pSector->ubNumElites;
*pNumTanks = pSector->ubNumTanks; *pNumTanks = pSector->ubNumTanks;
*pubNumJeeps = pSector->ubNumJeeps; *pubNumJeeps = pSector->ubNumJeeps;
*pubNumRobots = pSector->ubNumRobots;
} }
else else
{ {
@@ -201,6 +202,7 @@ BOOLEAN Ja25BetaDateToInvalidateExe();
*pNumElites = pSector->ubNumElites; *pNumElites = pSector->ubNumElites;
*pNumTanks = pSector->ubNumTanks; *pNumTanks = pSector->ubNumTanks;
*pubNumJeeps = pSector->ubNumJeeps; *pubNumJeeps = pSector->ubNumJeeps;
*pubNumRobots = pSector->ubNumRobots;
} }
} }
@@ -283,17 +285,19 @@ BOOLEAN AddEnemiesToInitialSectorH7()
UINT8 ubNumElites; UINT8 ubNumElites;
UINT8 ubNumTanks; UINT8 ubNumTanks;
UINT8 ubNumJeeps; UINT8 ubNumJeeps;
UINT8 ubNumRobots;
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; UINT8 ubNumRemovedJeeps=0;
UINT8 ubNumRemovedRobots=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, &ubNumJeeps ); GetNumberOfJA25EnemiesInSector( 8, MAP_ROW_H, 0, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps, &ubNumRobots );
//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 )
@@ -311,14 +315,17 @@ BOOLEAN AddEnemiesToInitialSectorH7()
if( ubNumJeeps > 1 ) if( ubNumJeeps > 1 )
ubNumRemovedJeeps = ubNumJeeps / 3 + + Random( 3 ); ubNumRemovedJeeps = ubNumJeeps / 3 + + Random( 3 );
if( ubNumRobots > 1 )
ubNumRemovedRobots = ubNumRobots / 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), SetNumberJa25EnemiesInSector( 8, MAP_ROW_H, 0, (UINT8)(ubNumAdmins-ubNumRemovedAdmins), (UINT8)(ubNumTroops-ubNumRemovedTroops), (UINT8)(ubNumElites-ubNumRemovedElites),
(UINT8)(ubNumTanks-ubNumRemovedTanks), (UINT8)(ubNumJeeps-ubNumRemovedJeeps) ); (UINT8)(ubNumTanks-ubNumRemovedTanks), (UINT8)(ubNumJeeps-ubNumRemovedJeeps), (UINT8)(ubNumRobots-ubNumRemovedRobots) );
uiWorldMin = GetWorldTotalMin(); uiWorldMin = GetWorldTotalMin();
pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, ubNumRemovedAdmins, ubNumRemovedTroops, ubNumRemovedElites, ubNumRemovedTanks, ubNumRemovedJeeps ); pGroup = CreateNewEnemyGroupDepartingFromSector( ubSector+1, ubNumRemovedAdmins, ubNumRemovedTroops, ubNumRemovedElites, ubNumRemovedTanks, ubNumRemovedJeeps, ubNumRemovedRobots );
if( pGroup == NULL ) if( pGroup == NULL )
{ {
@@ -409,24 +416,24 @@ void InitJa25UnderGroundSectors()
*/ */
} }
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps ) void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, UINT8 ubNumRobots )
{ {
//if its a ground level //if its a ground level
if( bSectorZ == 0 ) if( bSectorZ == 0 )
{ {
SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//its an underground level //its an underground level
else else
{ {
SetNumberJa25EnemiesInUnderGroundSector( sSectorX, sSectorY, bSectorZ, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInUnderGroundSector( sSectorX, sSectorY, bSectorZ, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
} }
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps ) void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, UINT8 ubNumRobots )
{ {
SECTORINFO* pSector = &SectorInfo[iSectorID]; SECTORINFO* pSector = &SectorInfo[iSectorID];
pSector->ubNumAdmins = ubNumAdmins; pSector->ubNumAdmins = ubNumAdmins;
@@ -434,6 +441,7 @@ void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UI
pSector->ubNumElites = ubNumElites; pSector->ubNumElites = ubNumElites;
pSector->ubNumTanks = ubNumTanks; pSector->ubNumTanks = ubNumTanks;
pSector->ubNumJeeps = ubNumJeeps; pSector->ubNumJeeps = ubNumJeeps;
pSector->ubNumRobots = ubNumRobots;
} }
void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8 bBloodCatPlacements ) void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8 bBloodCatPlacements )
@@ -446,7 +454,7 @@ void SetNumberOfJa25BloodCatsInSector( INT32 iSectorID, INT8 bNumBloodCats, INT8
pSector->bBloodCatPlacements = bBloodCatPlacements; pSector->bBloodCatPlacements = bBloodCatPlacements;
} }
void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps ) void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, UINT8 ubNumRobots )
{ {
UNDERGROUND_SECTORINFO *pSector=NULL; UNDERGROUND_SECTORINFO *pSector=NULL;
@@ -459,6 +467,7 @@ void SetNumberJa25EnemiesInUnderGroundSector( INT16 sSectorX, INT16 sSectorY, IN
pSector->ubNumElites = ubNumElites; pSector->ubNumElites = ubNumElites;
pSector->ubNumTanks = ubNumTanks; pSector->ubNumTanks = ubNumTanks;
pSector->ubNumJeeps = ubNumJeeps; pSector->ubNumJeeps = ubNumJeeps;
pSector->ubNumRobots = ubNumRobots;
} }
void InitNumberOfEnemiesInAboveGroundSectors( ) void InitNumberOfEnemiesInAboveGroundSectors( )
@@ -468,6 +477,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0; UINT8 ubNumJeeps=0;
UINT8 ubNumRobots=0;
//H7 //H7
{ {
@@ -494,7 +504,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_H7, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_H7, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
@@ -525,7 +535,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_H8, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_H8, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//Guard Post //Guard Post
@@ -555,7 +565,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_H9, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_H9, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
// SEC_H10: // SEC_H10:
@@ -584,7 +594,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_H10, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_H10, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//SEC_H11 //SEC_H11
@@ -617,7 +627,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_I9, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_I9, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//First part of town //First part of town
@@ -647,7 +657,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_I10, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_I10, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//Second part of town //Second part of town
@@ -677,7 +687,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_I11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_I11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//SEC_I12: //SEC_I12:
@@ -706,7 +716,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_I12, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_I12, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//Abandoned mine //Abandoned mine
@@ -736,7 +746,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_I13, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_I13, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
// SEC_J11: // SEC_J11:
@@ -765,7 +775,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_J11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_J11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
// SEC_J12: // SEC_J12:
@@ -794,7 +804,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_J12, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_J12, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//Power Generator, Ground Level //Power Generator, Ground Level
@@ -824,7 +834,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_J13, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_J13, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
//Complex, Ground Level //Complex, Ground Level
@@ -854,7 +864,7 @@ void InitNumberOfEnemiesInAboveGroundSectors( )
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_K15, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_K15, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
} }
@@ -865,6 +875,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0; UINT8 ubNumJeeps=0;
UINT8 ubNumRobots=0;
//Mine Sector Level 1 //Mine Sector Level 1
switch( gGameOptions.ubDifficultyLevel ) switch( gGameOptions.ubDifficultyLevel )
@@ -885,7 +896,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 13, 9, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 13, 9, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
//Power Generator Level 1 //Power Generator Level 1
@@ -907,7 +918,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 13, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 13, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
//Tunnel First Part, Level 1 //Tunnel First Part, Level 1
@@ -929,7 +940,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
//Tunnel Second Part, Level 1 //Tunnel Second Part, Level 1
@@ -951,7 +962,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 0 + Random( 0 ); ubNumElites = 0 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
@@ -974,7 +985,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 6 + Random( 4 ); ubNumElites = 6 + Random( 4 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 15, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
//Complex, Level 2, K15 //Complex, Level 2, K15
@@ -996,7 +1007,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 10 + Random( 2 ); ubNumElites = 10 + Random( 2 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 11, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 15, 11, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
//Complex, Level 2, L15 //Complex, Level 2, L15
@@ -1018,7 +1029,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 14 + Random( 2 ); ubNumElites = 14 + Random( 2 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 12, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 15, 12, 2, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
//Complex, Level 3, L15 //Complex, Level 3, L15
@@ -1040,7 +1051,7 @@ void InitNumberOfEnemiesInUnderGroundSectors( )
ubNumElites = 15 + Random( 0 ); ubNumElites = 15 + Random( 0 );
break; break;
} }
SetNumberJa25EnemiesInSector( 15, 12, 3, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 15, 12, 3, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
void InitJa25SaveStruct() void InitJa25SaveStruct()
@@ -1289,7 +1300,7 @@ void HandleAddingEnemiesToTunnelMaps()
else if( AreAnyPlayerMercsStillInSector( 14, 10, 1 ) && else if( AreAnyPlayerMercsStillInSector( 14, 10, 1 ) &&
!AreAnyPlayerMercsStillInSector( 14, 11, 1 ) ) !AreAnyPlayerMercsStillInSector( 14, 11, 1 ) )
{ {
ubNumEnemies = NumEnemiesToAttackFirstTunnelSector( NULL, NULL, NULL, NULL, NULL ); ubNumEnemies = NumEnemiesToAttackFirstTunnelSector( NULL, NULL, NULL, NULL, NULL, NULL );
//Add enemies to the first sector //Add enemies to the first sector
HandleAddEnemiesToSectorPlayerIsntIn( JA25_J14_1, ubNumEnemies ); HandleAddEnemiesToSectorPlayerIsntIn( JA25_J14_1, ubNumEnemies );
@@ -1303,7 +1314,7 @@ void HandleAddingEnemiesToTunnelMaps()
//else if the player is in the second sector //else if the player is in the second sector
else if( AreAnyPlayerMercsStillInSector( 14, 11, 1 ) ) else if( AreAnyPlayerMercsStillInSector( 14, 11, 1 ) )
{ {
ubNumEnemies = NumEnemiesToAttackSecondTunnelSector( NULL, NULL, NULL, NULL, NULL ); ubNumEnemies = NumEnemiesToAttackSecondTunnelSector( NULL, NULL, NULL, NULL, NULL, NULL );
//Add enemies to the first sector //Add enemies to the first sector
HandleAddEnemiesToSectorPlayerIsntIn( JA25_K14_1, ubNumEnemies ); HandleAddEnemiesToSectorPlayerIsntIn( JA25_K14_1, ubNumEnemies );
@@ -1334,10 +1345,11 @@ void AddEnemiesToFirstTunnelSector()
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0; UINT8 ubNumJeeps=0;
UINT8 ubNumRobots=0;
NumEnemiesToAttackFirstTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps ); NumEnemiesToAttackFirstTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps, &ubNumRobots );
SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 14, 10, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
void AddEnemiesToSecondTunnelSector() void AddEnemiesToSecondTunnelSector()
@@ -1347,18 +1359,20 @@ void AddEnemiesToSecondTunnelSector()
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0; UINT8 ubNumJeeps=0;
UINT8 ubNumRobots=0;
NumEnemiesToAttackSecondTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps ); NumEnemiesToAttackSecondTunnelSector( &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps, &ubNumRobots );
SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( 14, 11, 1, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps ) UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps, UINT8 *pRobots )
{ {
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; UINT8 ubNumJeeps=0;
UINT8 ubNumRobots=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
@@ -1396,16 +1410,20 @@ UINT8 NumEnemiesToAttackFirstTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8
if( pJeeps ) if( pJeeps )
*pJeeps = ubNumJeeps; *pJeeps = ubNumJeeps;
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps ); if( pRobots )
*pRobots = ubNumRobots;
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps + ubNumRobots );
} }
UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps ) UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT8 *pElites, UINT8 *pTanks, UINT8 *pJeeps, UINT8 *pRobots )
{ {
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; UINT8 ubNumJeeps=0;
UINT8 ubNumRobots=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
@@ -1439,8 +1457,10 @@ UINT8 NumEnemiesToAttackSecondTunnelSector( UINT8 *pAdmins, UINT8 *pTroops, UINT
*pTanks = ubNumTanks; *pTanks = ubNumTanks;
if( pJeeps ) if( pJeeps )
*pJeeps = ubNumJeeps; *pJeeps = ubNumJeeps;
if( pRobots )
*pRobots = ubNumRobots;
return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps ); return( ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps + ubNumRobots );
} }
@@ -2202,7 +2222,7 @@ BOOLEAN HandleAddEnemiesToSectorPlayerIsntIn( INT16 sSaiSector, UINT8 ubNumEnemi
SetEnemyEncounterCode( ENEMY_INVASION_CODE ); SetEnemyEncounterCode( ENEMY_INVASION_CODE );
} }
SetNumberJa25EnemiesInSector( sSectorX, sSectorY, bSectorZ, 0, ubNumEnemies, 0, 0, 0 ); SetNumberJa25EnemiesInSector( sSectorX, sSectorY, bSectorZ, 0, ubNumEnemies, 0, 0, 0, 0 );
SetThisSectorAsEnemyControlled( sSectorX, sSectorY, bSectorZ, FALSE ); SetThisSectorAsEnemyControlled( sSectorX, sSectorY, bSectorZ, FALSE );
@@ -2248,7 +2268,7 @@ if ( gGameUBOptions.pJA2UB == TRUE )
if( gJa25AiSectorStruct[ sSaiSector ].bSectorZ == 0 ) if( gJa25AiSectorStruct[ sSaiSector ].bSectorZ == 0 )
{ {
pGroup = CreateNewEnemyGroupDepartingFromSector( sSector, 0, ubNumEnemies, 0, 0, 0 ); pGroup = CreateNewEnemyGroupDepartingFromSector( sSector, 0, ubNumEnemies, 0, 0, 0, 0 );
if( sGridNo != -1 ) if( sGridNo != -1 )
{ {
@@ -2841,6 +2861,7 @@ void SetH11NumEnemiesInSector()
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps = 0; UINT8 ubNumJeeps = 0;
UINT8 ubNumRobots = 0;
// SEC_H11: // SEC_H11:
{ {
@@ -2868,7 +2889,7 @@ void SetH11NumEnemiesInSector()
break; break;
} }
SetNumberJa25EnemiesInSurfaceSector( SEC_H11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SEC_H11, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
} }
} }
+2 -2
View File
@@ -188,12 +188,12 @@ BOOLEAN ShouldEnemiesBeAddedToInitialSector();
void InitJa25StrategicAi(); void InitJa25StrategicAi();
void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps ); void SetNumberJa25EnemiesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubJeeps, UINT8 ubRobots );
void InitJa25SaveStruct(); void InitJa25SaveStruct();
void InitJa25StrategicAiBloodcats( ); void InitJa25StrategicAiBloodcats( );
void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps ); void SetNumberJa25EnemiesInSurfaceSector( INT32 iSectorID, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, UINT8 ubNumRobots );
BOOLEAN SaveJa25SaveInfoToSaveGame( HWFILE hFile ); BOOLEAN SaveJa25SaveInfoToSaveGame( HWFILE hFile );
BOOLEAN LoadJa25SaveInfoFromSavedGame( HWFILE hFile ); BOOLEAN LoadJa25SaveInfoFromSavedGame( HWFILE hFile );
+2 -1
View File
@@ -2266,6 +2266,7 @@ int i;
UINT8 ubNumElites=0; UINT8 ubNumElites=0;
UINT8 ubNumTanks=0; UINT8 ubNumTanks=0;
UINT8 ubNumJeeps=0; UINT8 ubNumJeeps=0;
UINT8 ubNumRobots=0;
INT16 sSectorX; INT16 sSectorX;
INT16 sSectorY; INT16 sSectorY;
@@ -2279,7 +2280,7 @@ INT16 sSectorY;
if (i == 5 ) ubNumElites = lua_tointeger(L,i); if (i == 5 ) ubNumElites = lua_tointeger(L,i);
if (i == 6 ) ubNumTanks = lua_tointeger(L,i); if (i == 6 ) ubNumTanks = lua_tointeger(L,i);
} }
SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSurfaceSector( SECTOR( sSectorX, sSectorY ), ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
return 0; return 0;
} }
+8 -5
View File
@@ -233,7 +233,7 @@ 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 || pGroup->pEnemyGroup->ubJeepsInBattle ) if ( pGroup->pEnemyGroup->ubAdminsInBattle || pGroup->pEnemyGroup->ubTroopsInBattle || pGroup->pEnemyGroup->ubElitesInBattle || pGroup->pEnemyGroup->ubTanksInBattle || pGroup->pEnemyGroup->ubJeepsInBattle || pGroup->pEnemyGroup->ubRobotsInBattle )
{ {
++ubInvalidGroups; ++ubInvalidGroups;
pGroup->pEnemyGroup->ubAdminsInBattle = 0; pGroup->pEnemyGroup->ubAdminsInBattle = 0;
@@ -241,6 +241,7 @@ void ValidateAndCorrectInBattleCounters( GROUP *pLocGroup )
pGroup->pEnemyGroup->ubElitesInBattle = 0; pGroup->pEnemyGroup->ubElitesInBattle = 0;
pGroup->pEnemyGroup->ubTanksInBattle = 0; pGroup->pEnemyGroup->ubTanksInBattle = 0;
pGroup->pEnemyGroup->ubJeepsInBattle = 0; pGroup->pEnemyGroup->ubJeepsInBattle = 0;
pGroup->pEnemyGroup->ubRobotsInBattle = 0;
} }
} }
} }
@@ -258,14 +259,15 @@ 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) J(%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) R(%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 ); pSector->ubNumJeeps, pSector->ubJeepsInBattle,
pSector->ubNumRobots, pSector->ubRobotsInBattle );
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;
@@ -273,6 +275,7 @@ void ValidateAndCorrectInBattleCounters( GROUP *pLocGroup )
pSector->ubCreaturesInBattle = 0; pSector->ubCreaturesInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0; pSector->ubJeepsInBattle = 0;
pSector->ubRobotsInBattle = 0;
} }
} }
#endif #endif
@@ -2007,7 +2010,7 @@ void CalculateNonPersistantPBIInfo()
{ {
SetExplicitEnemyEncounterCode( FIGHTING_CREATURES_CODE ); SetExplicitEnemyEncounterCode( FIGHTING_CREATURES_CODE );
} }
else if( pSector->ubAdminsInBattle || pSector->ubTroopsInBattle || pSector->ubElitesInBattle || pSector->ubTanksInBattle || pSector->ubJeepsInBattle ) else if( pSector->ubAdminsInBattle || pSector->ubTroopsInBattle || pSector->ubElitesInBattle || pSector->ubTanksInBattle || pSector->ubJeepsInBattle || pSector->ubRobotsInBattle )
{ {
SetExplicitEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE ); SetExplicitEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE );
SetEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE ); SetEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE );
@@ -2022,7 +2025,7 @@ void CalculateNonPersistantPBIInfo()
{ {
SetExplicitEnemyEncounterCode( FIGHTING_CREATURES_CODE ); SetExplicitEnemyEncounterCode( FIGHTING_CREATURES_CODE );
} }
else if( pSector->ubAdminsInBattle || pSector->ubTroopsInBattle || pSector->ubElitesInBattle || pSector->ubTanksInBattle || pSector->ubJeepsInBattle ) else if( pSector->ubAdminsInBattle || pSector->ubTroopsInBattle || pSector->ubElitesInBattle || pSector->ubTanksInBattle || pSector->ubJeepsInBattle || pSector->ubRobotsInBattle )
{ {
SetExplicitEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE ); SetExplicitEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE );
SetEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE ); SetEnemyEncounterCode( ENTERING_ENEMY_SECTOR_CODE );
+179 -64
View File
@@ -162,7 +162,7 @@ UINT8 NumHostilesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
pSector = FindUnderGroundSector( sSectorX, sSectorY, (UINT8)sSectorZ ); pSector = FindUnderGroundSector( sSectorX, sSectorY, (UINT8)sSectorZ );
if( pSector ) if( pSector )
{ {
ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures + pSector->ubNumJeeps + pSector->ubNumTanks); ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures + pSector->ubNumRobots + pSector->ubNumJeeps + pSector->ubNumTanks);
} }
} }
else else
@@ -172,7 +172,7 @@ UINT8 NumHostilesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
//Count stationary hostiles //Count stationary hostiles
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures + pSector->ubNumJeeps + pSector->ubNumTanks); ubNumHostiles = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumCreatures + pSector->ubNumRobots + pSector->ubNumJeeps + pSector->ubNumTanks);
//Count mobile enemies //Count mobile enemies
pGroup = gpGroupList; pGroup = gpGroupList;
@@ -206,7 +206,7 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
pSector = FindUnderGroundSector( sSectorX, sSectorY, (UINT8)sSectorZ ); pSector = FindUnderGroundSector( sSectorX, sSectorY, (UINT8)sSectorZ );
if( pSector ) if( pSector )
{ {
ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumJeeps + pSector->ubNumTanks); ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumRobots + pSector->ubNumJeeps + pSector->ubNumTanks);
} }
} }
else else
@@ -216,7 +216,7 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
//Count stationary enemies //Count stationary enemies
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumJeeps + pSector->ubNumTanks); ubNumEnemies = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumRobots + pSector->ubNumJeeps + pSector->ubNumTanks);
//Count mobile enemies //Count mobile enemies
pGroup = gpGroupList; pGroup = gpGroupList;
@@ -259,7 +259,7 @@ UINT8 NumNonPlayerTeamMembersInSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubT
if ( ubTeam == ENEMY_TEAM ) if ( ubTeam == ENEMY_TEAM )
{ {
ubNumTroops = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumJeeps + pSector->ubNumTanks); ubNumTroops = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumRobots + pSector->ubNumJeeps + pSector->ubNumTanks);
if ( is_networked ) if ( is_networked )
ubNumTroops += numenemyLAN((UINT8)sSectorX,(UINT8)sSectorY ); //hayden ubNumTroops += numenemyLAN((UINT8)sSectorX,(UINT8)sSectorY ); //hayden
@@ -372,7 +372,7 @@ UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
return( 0 ); return( 0 );
} }
return (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks); return (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumTanks + pSector->ubNumJeeps + pSector->ubNumRobots);
} }
UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY ) UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
@@ -400,13 +400,13 @@ UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
if( pSector->ubGarrisonID == ROADBLOCK ) if( pSector->ubGarrisonID == ROADBLOCK )
{ {
//consider these troops as mobile troops even though they are in a garrison //consider these troops as mobile troops even though they are in a garrison
ubNumTroops += (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumJeeps + pSector->ubNumTanks); ubNumTroops += (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumRobots + pSector->ubNumJeeps + pSector->ubNumTanks);
} }
return ubNumTroops; return ubNumTroops;
} }
void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps ) void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
GROUP *pGroup; GROUP *pGroup;
SECTORINFO *pSector; SECTORINFO *pSector;
@@ -416,7 +416,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 = *pubNumJeeps =0; *pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumRobots = *pubNumTanks = *pubNumJeeps = 0;
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
@@ -425,6 +425,7 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
*pubNumTroops += pGroup->pEnemyGroup->ubNumTroops; *pubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
*pubNumElites += pGroup->pEnemyGroup->ubNumElites; *pubNumElites += pGroup->pEnemyGroup->ubNumElites;
*pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins; *pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
*pubNumRobots += pGroup->pEnemyGroup->ubNumRobots;
*pubNumTanks += pGroup->pEnemyGroup->ubNumTanks; *pubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
*pubNumJeeps += pGroup->pEnemyGroup->ubNumJeeps; *pubNumJeeps += pGroup->pEnemyGroup->ubNumJeeps;
} }
@@ -438,12 +439,13 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
*pubNumAdmins += pSector->ubNumAdmins; *pubNumAdmins += pSector->ubNumAdmins;
*pubNumTroops += pSector->ubNumTroops; *pubNumTroops += pSector->ubNumTroops;
*pubNumElites += pSector->ubNumElites; *pubNumElites += pSector->ubNumElites;
*pubNumRobots += pSector->ubNumRobots;
*pubNumTanks += pSector->ubNumTanks; *pubNumTanks += pSector->ubNumTanks;
*pubNumJeeps += pSector->ubNumJeeps; *pubNumJeeps += pSector->ubNumJeeps;
} }
} }
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, 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 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
GROUP *pGroup; GROUP *pGroup;
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
@@ -452,7 +454,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 = *pubNumJeeps = 0; *pubNumTroops = *pubNumElites = *pubNumAdmins = *pubNumRobots = *pubNumTanks = *pubNumJeeps = 0;
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup ) while( pGroup )
{ {
@@ -461,6 +463,7 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
*pubNumTroops += pGroup->pEnemyGroup->ubNumTroops; *pubNumTroops += pGroup->pEnemyGroup->ubNumTroops;
*pubNumElites += pGroup->pEnemyGroup->ubNumElites; *pubNumElites += pGroup->pEnemyGroup->ubNumElites;
*pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins; *pubNumAdmins += pGroup->pEnemyGroup->ubNumAdmins;
*pubNumRobots += pGroup->pEnemyGroup->ubNumRobots;
*pubNumTanks += pGroup->pEnemyGroup->ubNumTanks; *pubNumTanks += pGroup->pEnemyGroup->ubNumTanks;
*pubNumJeeps += pGroup->pEnemyGroup->ubNumJeeps; *pubNumJeeps += pGroup->pEnemyGroup->ubNumJeeps;
} }
@@ -469,7 +472,7 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
} }
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps ) void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
@@ -482,21 +485,23 @@ void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8
*pubNumAdmins = pSector->ubNumAdmins; *pubNumAdmins = pSector->ubNumAdmins;
*pubNumTroops = pSector->ubNumTroops; *pubNumTroops = pSector->ubNumTroops;
*pubNumElites = pSector->ubNumElites; *pubNumElites = pSector->ubNumElites;
*pubNumRobots = pSector->ubNumRobots;
*pubNumTanks = pSector->ubNumTanks; *pubNumTanks = pSector->ubNumTanks;
*pubNumJeeps = pSector->ubNumJeeps; *pubNumJeeps = pSector->ubNumJeeps;
} }
void GetNumberOfEnemiesInSector( 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 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps; UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, ubNumTanks, ubNumJeeps;
GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumTanks, pubNumJeeps ); GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumRobots, pubNumTanks, pubNumJeeps );
GetNumberOfMobileEnemiesInSector( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps ); GetNumberOfMobileEnemiesInSector( sSectorX, sSectorY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumRobots, &ubNumTanks, &ubNumJeeps );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites; *pubNumElites += ubNumElites;
*pubNumRobots += ubNumRobots;
*pubNumTanks += ubNumTanks; *pubNumTanks += ubNumTanks;
*pubNumJeeps += ubNumJeeps; *pubNumJeeps += ubNumJeeps;
} }
@@ -514,6 +519,7 @@ void EndTacticalBattleForEnemy()
pSector->ubAdminsInBattle = 0; pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubRobotsInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0; pSector->ubJeepsInBattle = 0;
} }
@@ -525,6 +531,7 @@ void EndTacticalBattleForEnemy()
pSector->ubAdminsInBattle = 0; pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubRobotsInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0; pSector->ubJeepsInBattle = 0;
pSector->ubNumCreatures = 0; pSector->ubNumCreatures = 0;
@@ -544,6 +551,7 @@ void EndTacticalBattleForEnemy()
{ {
pGroup->pEnemyGroup->ubTroopsInBattle = 0; pGroup->pEnemyGroup->ubTroopsInBattle = 0;
pGroup->pEnemyGroup->ubElitesInBattle = 0; pGroup->pEnemyGroup->ubElitesInBattle = 0;
pGroup->pEnemyGroup->ubRobotsInBattle = 0;
pGroup->pEnemyGroup->ubAdminsInBattle = 0; pGroup->pEnemyGroup->ubAdminsInBattle = 0;
pGroup->pEnemyGroup->ubTanksInBattle = 0; pGroup->pEnemyGroup->ubTanksInBattle = 0;
pGroup->pEnemyGroup->ubJeepsInBattle = 0; pGroup->pEnemyGroup->ubJeepsInBattle = 0;
@@ -601,8 +609,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
unsigned ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps; unsigned ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, ubNumTanks, ubNumJeeps;
unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops, ubTotalTanks, ubTotalJeeps = 0; unsigned ubTotalAdmins, ubTotalElites, ubTotalRobots, ubTotalTroops, ubTotalTanks, ubTotalJeeps = 0;
unsigned totalCountOfStationaryEnemies = 0; unsigned totalCountOfStationaryEnemies = 0;
unsigned totalCountOfMobileEnemies = 0; unsigned totalCountOfMobileEnemies = 0;
int sNumSlots; int sNumSlots;
@@ -658,6 +666,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
!pGroup->pEnemyGroup->ubAdminsInBattle && !pGroup->pEnemyGroup->ubAdminsInBattle &&
!pGroup->pEnemyGroup->ubTroopsInBattle && !pGroup->pEnemyGroup->ubTroopsInBattle &&
!pGroup->pEnemyGroup->ubElitesInBattle && !pGroup->pEnemyGroup->ubElitesInBattle &&
!pGroup->pEnemyGroup->ubRobotsInBattle &&
!pGroup->pEnemyGroup->ubTanksInBattle && !pGroup->pEnemyGroup->ubTanksInBattle &&
!pGroup->pEnemyGroup->ubJeepsInBattle ) !pGroup->pEnemyGroup->ubJeepsInBattle )
{ {
@@ -698,13 +707,14 @@ 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 + pSector->ubNumJeeps); float totalEnemies = (float)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites + pSector->ubNumRobots + 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);
ubTotalRobots = (unsigned int)(((float)pSector->ubNumRobots / totalEnemies) * mapMaximumNumberOfEnemies);
ubTotalTanks = (unsigned int)(((float)pSector->ubNumTanks / totalEnemies) * mapMaximumNumberOfEnemies); ubTotalTanks = (unsigned int)(((float)pSector->ubNumTanks / totalEnemies) * mapMaximumNumberOfEnemies);
ubTotalJeeps = (unsigned int)(((float)pSector->ubNumJeeps / totalEnemies) * mapMaximumNumberOfEnemies); ubTotalJeeps = (unsigned int)(((float)pSector->ubNumJeeps / totalEnemies) * mapMaximumNumberOfEnemies);
totalEnemies = (float)(ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks + ubTotalJeeps); totalEnemies = (float)(ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalRobots + ubTotalTanks + ubTotalJeeps);
// take care of any rounding losses // take care of any rounding losses
while (totalEnemies < mapMaximumNumberOfEnemies) while (totalEnemies < mapMaximumNumberOfEnemies)
@@ -717,11 +727,13 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSector->ubNumAdmins = ubTotalAdmins; pSector->ubNumAdmins = ubTotalAdmins;
pSector->ubNumTroops = ubTotalTroops; pSector->ubNumTroops = ubTotalTroops;
pSector->ubNumElites = ubTotalElites; pSector->ubNumElites = ubTotalElites;
pSector->ubNumRobots = ubTotalRobots;
pSector->ubNumTanks = ubTotalTanks; pSector->ubNumTanks = ubTotalTanks;
pSector->ubNumJeeps = ubTotalJeeps; pSector->ubNumJeeps = ubTotalJeeps;
pSector->ubAdminsInBattle = 0; pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubRobotsInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0; pSector->ubJeepsInBattle = 0;
} }
@@ -742,6 +754,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
case SOLDIER_CLASS_BANDIT: ubTotalAdmins++; break; case SOLDIER_CLASS_BANDIT: ubTotalAdmins++; break;
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_ROBOT: ubTotalRobots++; break;
case SOLDIER_CLASS_TANK: ubTotalTanks++; break; case SOLDIER_CLASS_TANK: ubTotalTanks++; break;
case SOLDIER_CLASS_JEEP: ubTotalJeeps++; break; case SOLDIER_CLASS_JEEP: ubTotalJeeps++; break;
} }
@@ -751,11 +764,13 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSector->ubNumAdmins = ubTotalAdmins; pSector->ubNumAdmins = ubTotalAdmins;
pSector->ubNumTroops = ubTotalTroops; pSector->ubNumTroops = ubTotalTroops;
pSector->ubNumElites = ubTotalElites; pSector->ubNumElites = ubTotalElites;
pSector->ubNumRobots = ubTotalRobots;
pSector->ubNumTanks = ubTotalTanks; pSector->ubNumTanks = ubTotalTanks;
pSector->ubNumJeeps = ubTotalJeeps; pSector->ubNumJeeps = ubTotalJeeps;
pSector->ubAdminsInBattle = 0; pSector->ubAdminsInBattle = 0;
pSector->ubTroopsInBattle = 0; pSector->ubTroopsInBattle = 0;
pSector->ubElitesInBattle = 0; pSector->ubElitesInBattle = 0;
pSector->ubRobotsInBattle = 0;
pSector->ubTanksInBattle = 0; pSector->ubTanksInBattle = 0;
pSector->ubJeepsInBattle = 0; pSector->ubJeepsInBattle = 0;
} }
@@ -764,12 +779,13 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubTotalAdmins = pSector->ubNumAdmins - pSector->ubAdminsInBattle; ubTotalAdmins = pSector->ubNumAdmins - pSector->ubAdminsInBattle;
ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle; ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle;
ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle; ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle;
ubTotalRobots = pSector->ubNumRobots - pSector->ubRobotsInBattle;
ubTotalTanks = pSector->ubNumTanks - pSector->ubTanksInBattle; ubTotalTanks = pSector->ubNumTanks - pSector->ubTanksInBattle;
ubTotalJeeps = pSector->ubNumJeeps - pSector->ubJeepsInBattle; ubTotalJeeps = pSector->ubNumJeeps - pSector->ubJeepsInBattle;
} }
} }
totalCountOfStationaryEnemies = ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalTanks + ubTotalJeeps; totalCountOfStationaryEnemies = ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalRobots + ubTotalTanks + ubTotalJeeps;
if( totalCountOfStationaryEnemies > mapMaximumNumberOfEnemies ) if( totalCountOfStationaryEnemies > mapMaximumNumberOfEnemies )
{ {
@@ -783,13 +799,15 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubTotalAdmins = min( mapMaximumNumberOfEnemies, ubTotalAdmins ); ubTotalAdmins = min( mapMaximumNumberOfEnemies, ubTotalAdmins );
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 ); ubTotalRobots = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops-ubTotalElites, ubTotalRobots );
ubTotalJeeps = min( mapMaximumNumberOfEnemies - ubTotalAdmins - ubTotalTroops - ubTotalElites - ubTotalTanks, ubTotalJeeps ); ubTotalTanks = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops-ubTotalElites-ubTotalRobots, ubTotalTanks );
ubTotalJeeps = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops-ubTotalElites-ubTotalRobots-ubTotalTanks, ubTotalJeeps );
} }
pSector->ubAdminsInBattle += ubTotalAdmins; pSector->ubAdminsInBattle += ubTotalAdmins;
pSector->ubTroopsInBattle += ubTotalTroops; pSector->ubTroopsInBattle += ubTotalTroops;
pSector->ubElitesInBattle += ubTotalElites; pSector->ubElitesInBattle += ubTotalElites;
pSector->ubRobotsInBattle += ubTotalRobots;
pSector->ubTanksInBattle += ubTotalTanks; pSector->ubTanksInBattle += ubTotalTanks;
pSector->ubJeepsInBattle += ubTotalJeeps; pSector->ubJeepsInBattle += ubTotalJeeps;
@@ -797,9 +815,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
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 && !ubTotalJeeps ) if ( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalTanks && !ubTotalJeeps && !ubTotalRobots)
return FALSE; return FALSE;
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks, ubTotalJeeps ); AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks, ubTotalJeeps, ubTotalRobots );
ValidateEnemiesHaveWeapons(); ValidateEnemiesHaveWeapons();
UnPauseGame(); UnPauseGame();
return TRUE; return TRUE;
@@ -827,7 +845,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 + ubTotalJeeps; sNumSlots -= ubTotalAdmins + ubTotalTroops + ubTotalElites + ubTotalRobots + 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
@@ -881,6 +899,20 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubTotalElites += ubNumElites; ubTotalElites += ubNumElites;
} }
if( sNumSlots > 0 ) if( sNumSlots > 0 )
{ //Add robots
AssertGE(pGroup->pEnemyGroup->ubNumRobots, pGroup->pEnemyGroup->ubRobotsInBattle);
ubNumRobots = pGroup->pEnemyGroup->ubNumRobots - pGroup->pEnemyGroup->ubRobotsInBattle;
sNumSlots -= ubNumRobots;
if( sNumSlots < 0 )
{ //adjust the value to zero
ubNumRobots += sNumSlots;
sNumSlots = 0;
gfPendingNonPlayerTeam[ENEMY_TEAM] = TRUE;
}
pGroup->pEnemyGroup->ubRobotsInBattle += ubNumRobots;
ubTotalRobots += ubNumRobots;
}
if( sNumSlots > 0 )
{ //Add tanks { //Add tanks
AssertGE(pGroup->pEnemyGroup->ubNumTanks, pGroup->pEnemyGroup->ubTanksInBattle); AssertGE(pGroup->pEnemyGroup->ubNumTanks, pGroup->pEnemyGroup->ubTanksInBattle);
ubNumTanks = pGroup->pEnemyGroup->ubNumTanks - pGroup->pEnemyGroup->ubTanksInBattle; ubNumTanks = pGroup->pEnemyGroup->ubNumTanks - pGroup->pEnemyGroup->ubTanksInBattle;
@@ -930,12 +962,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 && !ubTotalJeeps ) if ( !ubTotalAdmins && !ubTotalTroops && !ubTotalElites && !ubTotalRobots && !ubTotalTanks && !ubTotalJeeps )
{ {
return FALSE; return FALSE;
} }
AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks, ubTotalJeeps ); AddSoldierInitListEnemyDefenceSoldiers( ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalRobots, 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
@@ -956,9 +988,10 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubNumAdmins = pGroup->pEnemyGroup->ubAdminsInBattle; ubNumAdmins = pGroup->pEnemyGroup->ubAdminsInBattle;
ubNumTroops = pGroup->pEnemyGroup->ubTroopsInBattle; ubNumTroops = pGroup->pEnemyGroup->ubTroopsInBattle;
ubNumElites = pGroup->pEnemyGroup->ubElitesInBattle; ubNumElites = pGroup->pEnemyGroup->ubElitesInBattle;
ubNumRobots = pGroup->pEnemyGroup->ubRobotsInBattle;
ubNumTanks = pGroup->pEnemyGroup->ubTanksInBattle; ubNumTanks = pGroup->pEnemyGroup->ubTanksInBattle;
ubNumJeeps = pGroup->pEnemyGroup->ubJeepsInBattle; ubNumJeeps = pGroup->pEnemyGroup->ubJeepsInBattle;
unsigned num = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps; unsigned num = ubNumAdmins + ubNumTroops + ubNumElites + ubNumRobots + ubNumTanks + ubNumJeeps;
AssertGE((int)slotsAvailable, sNumSlots); AssertGE((int)slotsAvailable, sNumSlots);
@@ -1028,6 +1061,16 @@ BOOLEAN PrepareEnemyForSectorBattle()
} }
} }
break; break;
case SOLDIER_CLASS_ROBOT:
if( ubNumRobots )
{
num--;
sNumSlots--;
ubNumRobots--;
pSoldier->ubGroupID = pGroup->ubGroupID;
firstSlot = slot + 1;
}
break;
case SOLDIER_CLASS_TANK: case SOLDIER_CLASS_TANK:
if( ubNumTanks ) if( ubNumTanks )
{ {
@@ -1058,6 +1101,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
AssertEQ( ubNumAdmins , 0); AssertEQ( ubNumAdmins , 0);
AssertEQ( ubNumTanks , 0); AssertEQ( ubNumTanks , 0);
AssertEQ( ubNumJeeps , 0); AssertEQ( ubNumJeeps , 0);
AssertEQ( ubNumRobots , 0);
AssertEQ( num , 0);*/ AssertEQ( num , 0);*/
} }
pGroup = pGroup->next; pGroup = pGroup->next;
@@ -1072,7 +1116,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
BOOLEAN PrepareEnemyForUndergroundBattle() BOOLEAN PrepareEnemyForUndergroundBattle()
{ {
UNDERGROUND_SECTORINFO *pUnderground; UNDERGROUND_SECTORINFO *pUnderground;
unsigned ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalTanks, ubTotalJeeps; unsigned ubTotalAdmins, ubTotalTroops, ubTotalElites, ubTotalRobots, ubTotalTanks, ubTotalJeeps;
pUnderground = gpUndergroundSectorInfoHead; pUnderground = gpUndergroundSectorInfoHead;
while( pUnderground ) while( pUnderground )
@@ -1086,18 +1130,20 @@ BOOLEAN PrepareEnemyForUndergroundBattle()
ubTotalAdmins = (UINT8)(pUnderground->ubNumAdmins - pUnderground->ubAdminsInBattle); ubTotalAdmins = (UINT8)(pUnderground->ubNumAdmins - pUnderground->ubAdminsInBattle);
ubTotalTroops = (UINT8)(pUnderground->ubNumTroops - pUnderground->ubTroopsInBattle); ubTotalTroops = (UINT8)(pUnderground->ubNumTroops - pUnderground->ubTroopsInBattle);
ubTotalElites = (UINT8)(pUnderground->ubNumElites - pUnderground->ubElitesInBattle); ubTotalElites = (UINT8)(pUnderground->ubNumElites - pUnderground->ubElitesInBattle);
ubTotalRobots = (UINT8)(pUnderground->ubNumRobots - pUnderground->ubRobotsInBattle);
ubTotalTanks = (UINT8)(pUnderground->ubNumTanks - pUnderground->ubTanksInBattle); ubTotalTanks = (UINT8)(pUnderground->ubNumTanks - pUnderground->ubTanksInBattle);
ubTotalJeeps = (UINT8)(pUnderground->ubNumJeeps - pUnderground->ubJeepsInBattle); 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->ubRobotsInBattle += ubTotalRobots;
pUnderground->ubTanksInBattle += ubTotalTanks; pUnderground->ubTanksInBattle += ubTotalTanks;
pUnderground->ubJeepsInBattle += ubTotalJeeps; pUnderground->ubJeepsInBattle += ubTotalJeeps;
AddSoldierInitListEnemyDefenceSoldiers( pUnderground->ubNumAdmins, pUnderground->ubNumTroops, pUnderground->ubNumElites, pUnderground->ubNumTanks, pUnderground->ubNumJeeps ); AddSoldierInitListEnemyDefenceSoldiers( pUnderground->ubNumAdmins, pUnderground->ubNumTroops, pUnderground->ubNumElites, pUnderground->ubNumRobots, pUnderground->ubNumTanks, pUnderground->ubNumJeeps );
ValidateEnemiesHaveWeapons(); ValidateEnemiesHaveWeapons();
UnPauseGame(); UnPauseGame();
} }
return ((BOOLEAN)(pUnderground->ubNumAdmins + pUnderground->ubNumTroops + pUnderground->ubNumElites + pUnderground->ubNumTanks + pUnderground->ubNumJeeps > 0)); return ((BOOLEAN)(pUnderground->ubNumAdmins + pUnderground->ubNumTroops + pUnderground->ubNumElites + pUnderground->ubNumRobots + pUnderground->ubNumTanks + pUnderground->ubNumJeeps > 0));
} }
pUnderground = pUnderground->next; pUnderground = pUnderground->next;
} }
@@ -1284,6 +1330,16 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
switch( pSoldier->ubSoldierClass ) switch( pSoldier->ubSoldierClass )
{ {
case SOLDIER_CLASS_ROBOT:
if( pGroup->pEnemyGroup->ubNumRobots )
{
pGroup->pEnemyGroup->ubNumRobots--;
}
if( pGroup->pEnemyGroup->ubRobotsInBattle )
{
pGroup->pEnemyGroup->ubRobotsInBattle--;
}
break;
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( !pGroup->pEnemyGroup->ubNumElites ) if( !pGroup->pEnemyGroup->ubNumElites )
@@ -1464,6 +1520,16 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
pSector->ubElitesInBattle--; pSector->ubElitesInBattle--;
} }
break; break;
case SOLDIER_CLASS_ROBOT:
if( pSector->ubNumRobots )
{
pSector->ubNumRobots--;
}
if( pSector->ubRobotsInBattle )
{
pSector->ubRobotsInBattle--;
}
break;
case SOLDIER_CLASS_CREATURE: case SOLDIER_CLASS_CREATURE:
case SOLDIER_CLASS_BANDIT: case SOLDIER_CLASS_BANDIT:
case SOLDIER_CLASS_ZOMBIE: case SOLDIER_CLASS_ZOMBIE:
@@ -1570,6 +1636,16 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
pSector->ubElitesInBattle--; pSector->ubElitesInBattle--;
} }
break; break;
case SOLDIER_CLASS_ROBOT:
if( pSector->ubNumRobots )
{
pSector->ubNumRobots--;
}
if( pSector->ubRobotsInBattle )
{
pSector->ubRobotsInBattle--;
}
break;
case SOLDIER_CLASS_CREATURE: case SOLDIER_CLASS_CREATURE:
case SOLDIER_CLASS_BANDIT: case SOLDIER_CLASS_BANDIT:
case SOLDIER_CLASS_ZOMBIE: case SOLDIER_CLASS_ZOMBIE:
@@ -1662,7 +1738,7 @@ void AddPossiblePendingEnemiesToBattle()
#endif #endif
UINT8 ubSlots, ubNumAvailable; UINT8 ubSlots, ubNumAvailable;
UINT8 ubNumElites, ubNumTroops, ubNumAdmins, ubNumTanks, ubNumJeeps; UINT8 ubNumRobots, ubNumElites, ubNumTroops, ubNumAdmins, ubNumTanks, ubNumJeeps;
UINT8 ubNumGroupsInSector; UINT8 ubNumGroupsInSector;
UINT8 ubGroupIndex; UINT8 ubGroupIndex;
GROUP *pGroup; GROUP *pGroup;
@@ -1758,18 +1834,25 @@ void AddPossiblePendingEnemiesToBattle()
//return; //return;
} }
if ( pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps ) if ( pSector->ubNumRobots + pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps )
{ {
ubNumElites = ubNumTroops = ubNumAdmins = ubNumTanks = ubNumJeeps = 0; ubNumRobots = ubNumElites = ubNumTroops = ubNumAdmins = ubNumTanks = ubNumJeeps = 0;
ubNumAvailable = pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps ubNumAvailable = pSector->ubNumRobots + pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps
- pSector->ubElitesInBattle - pSector->ubTroopsInBattle - pSector->ubAdminsInBattle - pSector->ubTanksInBattle - pSector->ubJeepsInBattle; - pSector->ubRobotsInBattle - 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?
//This group has enemies waiting for a chance to enter the battle. //This group has enemies waiting for a chance to enter the battle.
if( pSector->ubElitesInBattle < pSector->ubNumElites ) if( pSector->ubRobotsInBattle < pSector->ubNumRobots )
{ //Add a robot
pSector->ubRobotsInBattle++;
ubNumAvailable--;
ubSlots--;
ubNumRobots++;
}
else if( pSector->ubElitesInBattle < pSector->ubNumElites )
{ //Add an elite troop { //Add an elite troop
pSector->ubElitesInBattle++; pSector->ubElitesInBattle++;
ubNumAvailable--; ubNumAvailable--;
@@ -1812,7 +1895,7 @@ void AddPossiblePendingEnemiesToBattle()
} }
if ( ubNumAdmins || ubNumTroops || ubNumElites || ubNumTanks || ubNumJeeps ) if ( ubNumAdmins || ubNumTroops || ubNumElites || ubNumRobots || 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;
@@ -1853,7 +1936,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, ubNumJeeps, FALSE ); AddEnemiesToBattle( 0, ubStrategicInsertionCode, ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, ubNumTanks, ubNumJeeps, FALSE );
gfPendingNonPlayerTeam[ENEMY_TEAM] = TRUE; gfPendingNonPlayerTeam[ENEMY_TEAM] = TRUE;
} }
} }
@@ -1884,7 +1967,7 @@ void AddPossiblePendingEnemiesToBattle()
// Flugente fix: check for underflow... // Flugente fix: check for underflow...
UINT8 currentgroupsize = pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle UINT8 currentgroupsize = pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle
+ pGroup->pEnemyGroup->ubTanksInBattle + pGroup->pEnemyGroup->ubJeepsInBattle; + pGroup->pEnemyGroup->ubRobotsInBattle + pGroup->pEnemyGroup->ubTanksInBattle + pGroup->pEnemyGroup->ubJeepsInBattle;
if ( currentgroupsize > pGroup->ubGroupSize ) if ( currentgroupsize > pGroup->ubGroupSize )
ubNumAvailable = 0; ubNumAvailable = 0;
else else
@@ -1949,32 +2032,37 @@ 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, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 1, 0, 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, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 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, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 1, 0, 0, 0, 0, 0, FALSE );
}
else if( pGroup->pEnemyGroup->ubRobotsInBattle < pGroup->pEnemyGroup->ubNumRobots)
{ //Add a robot
pGroup->pEnemyGroup->ubRobotsInBattle++;
ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 1, 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, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 0, 1, 0, FALSE );
} }
else if ( pGroup->pEnemyGroup->ubJeepsInBattle < pGroup->pEnemyGroup->ubNumJeeps ) else if ( pGroup->pEnemyGroup->ubJeepsInBattle < pGroup->pEnemyGroup->ubNumJeeps )
{ { //Add a jeep
//Add a jeep
pGroup->pEnemyGroup->ubJeepsInBattle++; pGroup->pEnemyGroup->ubJeepsInBattle++;
ubSlots--; ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 0, 1, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 0, 0, 0, 0, 1, FALSE );
} }
else else
{ {
@@ -1983,7 +2071,7 @@ void AddPossiblePendingEnemiesToBattle()
pGroup->pEnemyGroup->ubTroopsInBattle++; pGroup->pEnemyGroup->ubTroopsInBattle++;
ubSlots--; ubSlots--;
AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, 0, FALSE ); AddEnemiesToBattle( pGroup, ubInsertionCode, 0, 1, 0, 0, 0, 0, FALSE );
} }
} }
@@ -2053,7 +2141,7 @@ void NotifyPlayersOfNewEnemies()
} }
} }
void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumTanks, UINT8 ubNumJeeps, BOOLEAN fMagicallyAppeared ) void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumRobots, UINT8 ubNumTanks, UINT8 ubNumJeeps, BOOLEAN fMagicallyAppeared )
{ {
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
MAPEDGEPOINTINFO MapEdgepointInfo; MAPEDGEPOINTINFO MapEdgepointInfo;
@@ -2078,13 +2166,15 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
if( !gbWorldSectorZ ) if( !gbWorldSectorZ )
{ {
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ]; SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
pSector->ubNumAdmins += ubNumAdmins; pSector->ubNumAdmins += ubNumAdmins;
pSector->ubAdminsInBattle += ubNumAdmins; pSector->ubAdminsInBattle += ubNumAdmins;
pSector->ubNumTroops += ubNumTroops; pSector->ubNumTroops += ubNumTroops;
pSector->ubTroopsInBattle += ubNumTroops; pSector->ubTroopsInBattle += ubNumTroops;
pSector->ubNumElites += ubNumElites; pSector->ubNumElites += ubNumElites;
pSector->ubElitesInBattle += ubNumElites; pSector->ubElitesInBattle += ubNumElites;
pSector->ubNumTanks += ubNumTanks; pSector->ubNumRobots += ubNumRobots;
pSector->ubRobotsInBattle += ubNumRobots;
pSector->ubNumTanks += ubNumTanks;
pSector->ubTanksInBattle += ubNumTanks; pSector->ubTanksInBattle += ubNumTanks;
pSector->ubNumJeeps += ubNumJeeps; pSector->ubNumJeeps += ubNumJeeps;
pSector->ubJeepsInBattle += ubNumJeeps; pSector->ubJeepsInBattle += ubNumJeeps;
@@ -2094,13 +2184,15 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
if( pSector ) if( pSector )
{ {
pSector->ubNumAdmins += ubNumAdmins; pSector->ubNumAdmins += ubNumAdmins;
pSector->ubAdminsInBattle += ubNumAdmins; pSector->ubAdminsInBattle += ubNumAdmins;
pSector->ubNumTroops += ubNumTroops; pSector->ubNumTroops += ubNumTroops;
pSector->ubTroopsInBattle += ubNumTroops; pSector->ubTroopsInBattle += ubNumTroops;
pSector->ubNumElites += ubNumElites; pSector->ubNumElites += ubNumElites;
pSector->ubElitesInBattle += ubNumElites; pSector->ubElitesInBattle += ubNumElites;
pSector->ubNumTanks += ubNumTanks; pSector->ubNumRobots += ubNumRobots;
pSector->ubRobotsInBattle += ubNumRobots;
pSector->ubNumTanks += ubNumTanks;
pSector->ubTanksInBattle += ubNumTanks; pSector->ubTanksInBattle += ubNumTanks;
pSector->ubNumJeeps += ubNumJeeps; pSector->ubNumJeeps += ubNumJeeps;
pSector->ubJeepsInBattle += ubNumJeeps; pSector->ubJeepsInBattle += ubNumJeeps;
@@ -2110,7 +2202,7 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
NotifyPlayersOfNewEnemies(); NotifyPlayersOfNewEnemies();
} }
ubTotalSoldiers = ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps; ubTotalSoldiers = ubNumAdmins + ubNumTroops + ubNumElites + ubNumRobots + ubNumTanks + ubNumJeeps;
#ifdef JA2UB #ifdef JA2UB
if( gsGridNoForMapEdgePointInfo != -1 ) if( gsGridNoForMapEdgePointInfo != -1 )
@@ -2232,7 +2324,30 @@ void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ub
} }
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 ); UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 );
} }
else if( ubNumTanks && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks) && ubNumberOfVehicles < 9 ) else if( ubNumRobots && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumTroops + ubNumAdmins + ubNumRobots) )
{
ubNumRobots--;
ubTotalSoldiers--;
Assert(pSoldier = TacticalCreateEnemyRobot());
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 );
}
else if( ubNumTanks && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumTroops + ubNumAdmins + ubNumRobots + ubNumTanks) && ubNumberOfVehicles < 9 )
{ {
ubNumTanks--; ubNumTanks--;
ubTotalSoldiers--; ubTotalSoldiers--;
@@ -2255,7 +2370,7 @@ 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 ) else if ( ubNumJeeps && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumTroops + ubNumAdmins + ubNumRobots + ubNumTanks + ubNumJeeps) && ubNumberOfVehicles < 9 )
{ {
ubNumJeeps--; ubNumJeeps--;
ubTotalSoldiers--; ubTotalSoldiers--;
@@ -2972,8 +3087,8 @@ BOOLEAN CheckPendingNonPlayerTeam( UINT8 usTeam )
if ( usTeam == ENEMY_TEAM ) if ( usTeam == ENEMY_TEAM )
{ {
if ( (pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps) > if ( (pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins + pSector->ubNumTanks + pSector->ubNumJeeps + pSector->ubNumRobots) >
(pSector->ubElitesInBattle + pSector->ubTroopsInBattle + pSector->ubAdminsInBattle + pSector->ubTanksInBattle + pSector->ubJeepsInBattle) ) (pSector->ubElitesInBattle + pSector->ubTroopsInBattle + pSector->ubAdminsInBattle + pSector->ubTanksInBattle + pSector->ubJeepsInBattle + pSector->ubRobotsInBattle) )
return TRUE; return TRUE;
} }
@@ -2987,7 +3102,7 @@ BOOLEAN CheckPendingNonPlayerTeam( UINT8 usTeam )
if ( usTeam == ENEMY_TEAM ) if ( usTeam == ENEMY_TEAM )
{ {
if ( pGroup->ubGroupSize > pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle if ( pGroup->ubGroupSize > pGroup->pEnemyGroup->ubElitesInBattle + pGroup->pEnemyGroup->ubTroopsInBattle + pGroup->pEnemyGroup->ubAdminsInBattle
+ pGroup->pEnemyGroup->ubTanksInBattle + pGroup->pEnemyGroup->ubJeepsInBattle ) + pGroup->pEnemyGroup->ubTanksInBattle + pGroup->pEnemyGroup->ubJeepsInBattle + pGroup->pEnemyGroup->ubRobotsInBattle )
return TRUE; return TRUE;
} }
else if ( usTeam == MILITIA_TEAM ) else if ( usTeam == MILITIA_TEAM )
+5 -5
View File
@@ -28,10 +28,10 @@ UINT16 NumPlayerTeamMembersInSector( INT16 sSectorX, INT16 sSectorY, INT8 sSecto
UINT16 NumEnemyArmedVehiclesInSector( 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, UINT8 *pubNumJeeps ); void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 usTeam, 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 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumTanks, UINT8 *pubNumJeeps ); void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
void GetNumberOfEnemiesInSector( 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 *pubNumRobots, 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
@@ -39,7 +39,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, UINT8 abNumJeeps, BOOLEAN fMagicallyAppeared ); void AddEnemiesToBattle( GROUP *pGroup, UINT8 ubStrategicInsertionCode, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumRobots, 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();
+31 -17
View File
@@ -33,19 +33,20 @@
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, UINT8 *pubNumJeeps ) void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps; UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, 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, pubNumJeeps ); GetNumberOfStationaryEnemiesInSector( sSectorX, sSectorY, pubNumAdmins, pubNumTroops, pubNumElites, pubNumRobots, pubNumTanks, pubNumJeeps );
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps ); GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( sSectorX, sSectorY, ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumRobots, &ubNumTanks, &ubNumJeeps );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites; *pubNumElites += ubNumElites;
*pubNumRobots += ubNumRobots;
*pubNumTanks += ubNumTanks; *pubNumTanks += ubNumTanks;
*pubNumJeeps += ubNumJeeps; *pubNumJeeps += ubNumJeeps;
@@ -59,11 +60,16 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
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, &ubNumJeeps ); GetNumberOfStationaryEnemiesInSector( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumRobots, &ubNumTanks, &ubNumJeeps );
while ( ubNumElites + ubNumTroops + ubNumAdmins + ubNumTanks + ubNumJeeps > gubReinforcementMinEnemyStaticGroupSize ) //count how many of static group will reinforce the battle, but leave minimal group size to guard while ( ubNumRobots + 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 ( ubNumRobots )
{
*pubNumRobots += 1;
ubNumRobots--;
}
else if( ubNumElites )
{ {
*pubNumElites += 1; *pubNumElites += 1;
ubNumElites--; ubNumElites--;
@@ -90,11 +96,12 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
} }
} }
GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps ); GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( SECTORX( pusMoveDir[ubIndex][0] ), SECTORY( pusMoveDir[ubIndex][0] ), ENEMY_TEAM, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumRobots, &ubNumTanks, &ubNumJeeps );
*pubNumAdmins += ubNumAdmins; *pubNumAdmins += ubNumAdmins;
*pubNumTroops += ubNumTroops; *pubNumTroops += ubNumTroops;
*pubNumElites += ubNumElites; *pubNumElites += ubNumElites;
*pubNumRobots += ubNumRobots;
*pubNumTanks += ubNumTanks; *pubNumTanks += ubNumTanks;
*pubNumJeeps += ubNumJeeps; *pubNumJeeps += ubNumJeeps;
} }
@@ -102,11 +109,11 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
UINT8 NumEnemiesInFiveSectors( INT16 sMapX, INT16 sMapY ) UINT8 NumEnemiesInFiveSectors( INT16 sMapX, INT16 sMapY )
{ {
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps; UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, ubNumTanks, ubNumJeeps;
GetNumberOfEnemiesInFiveSectors( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumTanks, &ubNumJeeps ); GetNumberOfEnemiesInFiveSectors( sMapX, sMapY, &ubNumAdmins, &ubNumTroops, &ubNumElites, &ubNumRobots, &ubNumTanks, &ubNumJeeps );
return ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps; return ubNumAdmins + ubNumTroops + ubNumElites + ubNumRobots + ubNumTanks + ubNumJeeps;
} }
BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY ) BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY )
@@ -256,40 +263,47 @@ UINT8 DoReinforcementAsPendingNonPlayer( INT16 sMapX, INT16 sMapY, UINT8 usTeam
{ {
pSector = &SectorInfo[ pusMoveDir[ ubIndex ][ 0 ] ]; pSector = &SectorInfo[ pusMoveDir[ ubIndex ][ 0 ] ];
if( pSector->ubNumElites ) if( pSector->ubNumRobots )
{
(pThisSector->ubNumRobots)++;
(pSector->ubNumRobots)--;
(pThisSector->ubRobotsInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 0, 1, 0, 0, FALSE );
}
else if( pSector->ubNumElites )
{ {
(pThisSector->ubNumElites)++; (pThisSector->ubNumElites)++;
(pSector->ubNumElites)--; (pSector->ubNumElites)--;
(pThisSector->ubElitesInBattle)++; (pThisSector->ubElitesInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 1, 0, 0, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 1, 0, 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, 0, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 1, 0, 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, 0, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 1, 0, 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, 0, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 0, 0, 0, 1, 0, FALSE );
} }
else if ( pSector->ubNumJeeps ) else if ( pSector->ubNumJeeps )
{ {
(pThisSector->ubNumJeeps)++; (pThisSector->ubNumJeeps)++;
(pSector->ubNumJeeps)--; (pSector->ubNumJeeps)--;
(pThisSector->ubJeepsInBattle)++; (pThisSector->ubJeepsInBattle)++;
AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ubIndex][2], 0, 0, 0, 0, 1, FALSE ); AddEnemiesToBattle( NULL, (UINT8)pusMoveDir[ ubIndex ][ 2 ], 0, 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, UINT8 *pubNumJeeps ); void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumRobots, 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);
+239 -446
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -75,7 +75,13 @@ void TagSAIGroupWithGracePeriod( GROUP *pGroup );
BOOLEAN PermittedToFillPatrolGroup( INT32 iPatrolID ); BOOLEAN PermittedToFillPatrolGroup( INT32 iPatrolID );
enum GROUP_TYPE
{
GROUP_TYPE_ATTACK,
GROUP_TYPE_PATROL
};
void InitializeGroup(const GROUP_TYPE groupType, const UINT8 groupSize, UINT8 &troopCount, UINT8 &eliteCount, UINT8 &robotCount, UINT8 &jeepCount, UINT8 &tankCount, const BOOLEAN asdUpgrade);
extern BOOLEAN gfDisplayStrategicAILogs; extern BOOLEAN gfDisplayStrategicAILogs;
extern BOOLEAN gfFirstBattleMeanwhileScenePending; extern BOOLEAN gfFirstBattleMeanwhileScenePending;
+8 -3
View File
@@ -706,7 +706,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, UINT8 ubNumJeeps ) GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumRobots, 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 ) );
@@ -717,7 +717,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 + ubNumJeeps > gGameExternalOptions.iMaxEnemyGroupSize ) while ( ubNumAdmins + ubNumTroops + ubNumElites + ubNumRobots + ubNumTanks + ubNumJeeps > gGameExternalOptions.iMaxEnemyGroupSize )
{ {
if (ubNumTroops) if (ubNumTroops)
{ {
@@ -731,6 +731,10 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
{ {
ubNumElites--; ubNumElites--;
} }
else if (ubNumRobots)
{
ubNumRobots--;
}
else if (ubNumTanks) else if (ubNumTanks)
{ {
ubNumTanks--; ubNumTanks--;
@@ -752,9 +756,10 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
pNew->pEnemyGroup->ubNumAdmins = ubNumAdmins; pNew->pEnemyGroup->ubNumAdmins = ubNumAdmins;
pNew->pEnemyGroup->ubNumTroops = ubNumTroops; pNew->pEnemyGroup->ubNumTroops = ubNumTroops;
pNew->pEnemyGroup->ubNumElites = ubNumElites; pNew->pEnemyGroup->ubNumElites = ubNumElites;
pNew->pEnemyGroup->ubNumRobots = ubNumRobots;
pNew->pEnemyGroup->ubNumTanks = ubNumTanks; pNew->pEnemyGroup->ubNumTanks = ubNumTanks;
pNew->pEnemyGroup->ubNumJeeps = ubNumJeeps; pNew->pEnemyGroup->ubNumJeeps = ubNumJeeps;
pNew->ubGroupSize = (UINT8)(ubNumAdmins + ubNumTroops + ubNumElites + ubNumTanks + ubNumJeeps); pNew->ubGroupSize = (UINT8)(ubNumAdmins + ubNumTroops + ubNumElites + ubNumRobots + ubNumTanks + ubNumJeeps);
pNew->ubTransportationMask = FOOT; pNew->ubTransportationMask = FOOT;
pNew->fVehicle = FALSE; pNew->fVehicle = FALSE;
pNew->ubCreatedSectorID = pNew->ubOriginalSector; pNew->ubCreatedSectorID = pNew->ubOriginalSector;
+3 -1
View File
@@ -64,12 +64,14 @@ typedef struct ENEMYGROUP
UINT8 ubNumTroops; //number of regular troops in the group UINT8 ubNumTroops; //number of regular troops in the group
UINT8 ubNumElites; //number of elite troops in the group UINT8 ubNumElites; //number of elite troops in the group
UINT8 ubNumAdmins; //number of administrators in the group UINT8 ubNumAdmins; //number of administrators in the group
UINT8 ubNumRobots; //number of enemy robots in the group
UINT8 ubLeaderProfileID; //could be Mike, maybe the warden... someone new, but likely nobody. UINT8 ubLeaderProfileID; //could be Mike, maybe the warden... someone new, but likely nobody.
UINT8 ubPendingReinforcements;//This group is waiting for reinforcements before attacking or attempting to fortify newly aquired sector. UINT8 ubPendingReinforcements;//This group is waiting for reinforcements before attacking or attempting to fortify newly aquired sector.
UINT8 ubAdminsInBattle; //number of administrators in currently in battle. UINT8 ubAdminsInBattle; //number of administrators in currently in battle.
UINT8 ubIntention; //the type of group this is: patrol, assault, spies, etc. UINT8 ubIntention; //the type of group this is: patrol, assault, spies, etc.
UINT8 ubTroopsInBattle; //number of soldiers currently in battle. UINT8 ubTroopsInBattle; //number of soldiers currently in battle.
UINT8 ubElitesInBattle; //number of elite soldiers currently in battle. UINT8 ubElitesInBattle; //number of elite soldiers currently in battle.
UINT8 ubRobotsInBattle; //number of enemy robots currently in battle.
// WDS - New AI // WDS - New AI
UINT8 ubNumTanks; UINT8 ubNumTanks;
UINT8 ubTanksInBattle; UINT8 ubTanksInBattle;
@@ -196,7 +198,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 ubNumTanksm, UINT8 ubNumJeeps ); GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmins, UINT8 ubNumTroops, UINT8 ubNumElites, UINT8 ubNumRobots, UINT8 ubNumTanks, UINT8 ubNumJeeps );
GROUP* CreateNewMilitiaGroupDepartingFromSector( UINT32 uiSector, UINT8& arusNumAdmins, UINT8& arusNumTroops, UINT8& arusNumElites ); GROUP* CreateNewMilitiaGroupDepartingFromSector( UINT32 uiSector, UINT8& arusNumAdmins, UINT8& arusNumTroops, UINT8& arusNumElites );
+1
View File
@@ -428,6 +428,7 @@ INT8 SoldierClassToRankIndex( UINT8 ubSoldierClass )
case SOLDIER_CLASS_BANDIT: bRankIndex = 0; break; case SOLDIER_CLASS_BANDIT: bRankIndex = 0; break;
case SOLDIER_CLASS_ELITE: bRankIndex = 2; break; case SOLDIER_CLASS_ELITE: bRankIndex = 2; break;
case SOLDIER_CLASS_ARMY: bRankIndex = 1; break; case SOLDIER_CLASS_ARMY: bRankIndex = 1; break;
case SOLDIER_CLASS_ROBOT: bRankIndex = 2; break;
default: default:
// this happens when an NPC joins the enemy team (e.g. Conrad, Iggy, Mike) // this happens when an NPC joins the enemy team (e.g. Conrad, Iggy, Mike)
+2
View File
@@ -90,6 +90,7 @@ BOOLEAN LuaUnderground::InitializeSectorList()
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("numJeeps", s->ubNumJeeps );
sectorData.getValue("numRobots", s->ubNumRobots);
sectorData.getValue("numBloodcats", s->ubNumBloodcats); sectorData.getValue("numBloodcats", s->ubNumBloodcats);
sectorData.getValue("numCreatures", s->ubNumCreatures); sectorData.getValue("numCreatures", s->ubNumCreatures);
@@ -108,6 +109,7 @@ BOOLEAN LuaUnderground::InitializeSectorList()
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\tJeeps: " << static_cast<int>(s->ubNumJeeps) << LF;
m_log << "\t\tRobots: " << static_cast<int>(s->ubNumRobots) << 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;
+1
View File
@@ -318,6 +318,7 @@ void DoneFadeOutKilledQueen( void )
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubAdminsInBattle = 0; SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubAdminsInBattle = 0;
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 ) ].ubRobotsInBattle = 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; SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubJeepsInBattle = 0;
+48 -16
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, UINT8 *pubNumJeeps ); BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumRobots, 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, ubNumJeeps = 0; UINT8 ubNumRobots = 0, ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0, ubNumJeeps = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps; UINT8 ubStrategicRobots, ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps;
gfRestoringEnemySoldiersFromTempFile = TRUE; gfRestoringEnemySoldiersFromTempFile = TRUE;
@@ -256,6 +256,7 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
ubStrategicAdmins = pSector->ubNumAdmins; ubStrategicAdmins = pSector->ubNumAdmins;
ubStrategicTanks = pSector->ubNumTanks; ubStrategicTanks = pSector->ubNumTanks;
ubStrategicJeeps = pSector->ubNumJeeps; ubStrategicJeeps = pSector->ubNumJeeps;
ubStrategicRobots = pSector->ubNumRobots;
ubStrategicCreatures = pSector->ubNumCreatures; ubStrategicCreatures = pSector->ubNumCreatures;
} }
else else
@@ -263,7 +264,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, &ubStrategicJeeps ); GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicRobots, &ubStrategicTanks, &ubStrategicJeeps );
} }
for( i = 0; i < slots; i++ ) for( i = 0; i < slots; i++ )
@@ -370,6 +371,16 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
} }
} }
break; break;
case SOLDIER_CLASS_ROBOT:
if (ENEMYROBOT(curr->pBasicPlacement))
{
ubNumRobots++;
if (ubNumRobots < ubStrategicRobots)
{
AddPlacementToWorld(curr);
}
}
break;
} }
break; break;
} }
@@ -397,14 +408,15 @@ 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 || ubStrategicJeeps > ubNumJeeps ) if ( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicRobots > ubNumRobots || 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;
ubStrategicRobots = ( ubStrategicRobots > ubNumRobots ) ? ubStrategicRobots - ubNumRobots : 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;
ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0; ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks, ubStrategicJeeps ); AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicRobots, ubStrategicTanks, ubStrategicJeeps );
} }
if( ubStrategicCreatures > ubNumCreatures ) if( ubStrategicCreatures > ubNumCreatures )
@@ -688,8 +700,8 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
#endif #endif
INT8 bSectorZ; INT8 bSectorZ;
UINT8 ubSectorID; UINT8 ubSectorID;
UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0, ubNumJeeps = 0; UINT8 ubNumRobots = 0, ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0, ubNumJeeps = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps; UINT8 ubStrategicRobots = 0, ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps;
gfRestoringEnemySoldiersFromTempFile = TRUE; gfRestoringEnemySoldiersFromTempFile = TRUE;
@@ -730,16 +742,17 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
ubNumAdmins = pSector->ubNumAdmins; ubNumAdmins = pSector->ubNumAdmins;
ubNumTanks = pSector->ubNumTanks; ubNumTanks = pSector->ubNumTanks;
ubNumJeeps = pSector->ubNumJeeps; ubNumJeeps = pSector->ubNumJeeps;
ubNumRobots = pSector->ubNumRobots;
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, &ubStrategicJeeps ); CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( &ubStrategicRobots, &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 || ubStrategicJeeps != ubNumJeeps ) if ( ubStrategicRobots != ubNumRobots || 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 );
@@ -748,7 +761,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
} }
//reset //reset
ubNumElites = ubNumTroops = ubNumAdmins = ubNumCreatures = ubNumTanks = ubNumJeeps = 0; ubNumElites = ubNumTroops = ubNumAdmins = ubNumCreatures = ubNumTanks = ubNumJeeps = ubNumRobots = 0;
//Open the file for reading //Open the file for reading
@@ -888,6 +901,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
ubStrategicElites = pSector->ubNumElites; ubStrategicElites = pSector->ubNumElites;
ubStrategicTroops = pSector->ubNumTroops; ubStrategicTroops = pSector->ubNumTroops;
ubStrategicAdmins = pSector->ubNumAdmins; ubStrategicAdmins = pSector->ubNumAdmins;
ubStrategicRobots = pSector->ubNumRobots;
ubStrategicTanks = pSector->ubNumTanks; ubStrategicTanks = pSector->ubNumTanks;
ubStrategicJeeps = pSector->ubNumJeeps; ubStrategicJeeps = pSector->ubNumJeeps;
ubStrategicCreatures = pSector->ubNumCreatures; ubStrategicCreatures = pSector->ubNumCreatures;
@@ -897,7 +911,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, &ubStrategicJeeps ); GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicRobots, &ubStrategicTanks, &ubStrategicJeeps );
} }
for( i = 0; i < slots; i++ ) for( i = 0; i < slots; i++ )
@@ -990,7 +1004,17 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
++ubNumJeeps; ++ubNumJeeps;
if ( ubNumJeeps <= ubStrategicJeeps ) if ( ubNumJeeps <= ubStrategicJeeps )
{ {
//def: AddPlacementToWorld( curr ); //def: AddPlacementToWorld( curr );
}
}
break;
case SOLDIER_CLASS_ROBOT:
if ( ENEMYROBOT( curr->pBasicPlacement ) )
{
ubNumRobots++;
if (ubNumRobots <= ubStrategicRobots)
{
//def: AddPlacementToWorld( curr );
} }
} }
break; break;
@@ -1019,14 +1043,15 @@ 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 || ubStrategicJeeps > ubNumJeeps ) if ( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicRobots > ubNumRobots || 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;
ubStrategicRobots = ( ubStrategicRobots > ubNumRobots ) ? ubStrategicRobots - ubNumRobots : 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;
ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0; ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks, ubStrategicJeeps ); AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicRobots, ubStrategicTanks, ubStrategicJeeps );
} }
if( ubStrategicCreatures > ubNumCreatures ) if( ubStrategicCreatures > ubNumCreatures )
@@ -1618,7 +1643,7 @@ BOOLEAN NewWayOfSavingEnemyAndCivliansToTempFile( INT16 sSectorX, INT16 sSectorY
BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks, UINT8 *pubNumJeeps ) BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumRobots, UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{ {
// SOLDIERINITNODE *curr; // SOLDIERINITNODE *curr;
SOLDIERCREATE_STRUCT tempDetailedPlacement; SOLDIERCREATE_STRUCT tempDetailedPlacement;
@@ -1638,6 +1663,7 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
// UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures; // UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures;
//make sure the variables are initialized //make sure the variables are initialized
*pubNumRobots = 0;
*pubNumElites = 0; *pubNumElites = 0;
*pubNumRegulars = 0; *pubNumRegulars = 0;
*pubNumAdmins = 0; *pubNumAdmins = 0;
@@ -1817,6 +1843,12 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
(*pubNumJeeps)++; (*pubNumJeeps)++;
} }
break; break;
case SOLDIER_CLASS_ROBOT:
if ( ENEMYROBOT( (&tempDetailedPlacement) ) )
{
(*pubNumRobots)++;
}
break;
} }
/* /*
while( curr ) while( curr )
+12 -11
View File
@@ -1195,17 +1195,16 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
return( GAME_SCREEN ); return( GAME_SCREEN );
} }
usRandom = 12;// (UINT16)Random( 20 ); usRandom = 1;// (UINT16)Random( 6 );
if( usRandom < 5 ) switch (usRandom)
pSoldier = TacticalCreateAdministrator(); {
else if( usRandom < 15 ) case 0: pSoldier = TacticalCreateAdministrator(); break;
pSoldier = TacticalCreateArmyTroop(); case 1: pSoldier = TacticalCreateArmyTroop(); break;
else if ( usRandom < 12 ) case 2: pSoldier = TacticalCreateEliteEnemy(); break;
pSoldier = TacticalCreateEnemyTank( ); case 3: pSoldier = TacticalCreateEnemyTank(); break;
else if ( usRandom < 15 ) case 4: pSoldier = TacticalCreateEnemyJeep(); break;
pSoldier = TacticalCreateEnemyJeep( ); case 5: pSoldier = TacticalCreateEnemyRobot(); break;
else }
pSoldier = TacticalCreateEliteEnemy( );
//Add soldier strategic info, so it doesn't break the counters! //Add soldier strategic info, so it doesn't break the counters!
if( pSoldier ) if( pSoldier )
@@ -1218,6 +1217,7 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break; case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
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_ROBOT: pSector->ubNumRobots++; pSector->ubRobotsInBattle++; 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; case SOLDIER_CLASS_JEEP: pSector->ubNumJeeps++; pSector->ubJeepsInBattle++; break;
} }
@@ -1232,6 +1232,7 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break; case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
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_ROBOT: pSector->ubNumRobots++; pSector->ubRobotsInBattle++; 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; case SOLDIER_CLASS_JEEP: pSector->ubNumJeeps++; pSector->ubJeepsInBattle++; break;
} }
+14 -7
View File
@@ -88,7 +88,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 EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp, BOOLEAN fTank = TRUE ); void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp );
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 );
@@ -248,13 +248,14 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
return; return;
} }
if ( ARMED_VEHICLE( pp ) ) if ( ARMED_VEHICLE( pp ) || ENEMYROBOT( pp ) )
{ {
EquipArmouredVehicle( pp, TANK( pp ) ); EquipArmouredVehicle( pp );
return; return;
} }
Assert( (bSoldierClass >= SOLDIER_CLASS_NONE) && (bSoldierClass <= SOLDIER_CLASS_ELITE_MILITIA) || bSoldierClass == SOLDIER_CLASS_TANK || bSoldierClass == SOLDIER_CLASS_JEEP ); // rftr: enemy tanks, jeeps, and robots would have early exited above
Assert( (bSoldierClass >= SOLDIER_CLASS_NONE) && (bSoldierClass <= SOLDIER_CLASS_ELITE_MILITIA) );
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
@@ -3253,12 +3254,12 @@ UINT16 SelectStandardArmyGun( UINT8 uiGunLevel, INT8 bSoldierClass )
void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp, BOOLEAN fTank ) void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp )
{ {
// 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)
// tanks get a main cannon and a MG, other vehicles just get the MG // tanks get a main cannon and a MG, other vehicles just get the MG
if ( fTank ) if ( TANK(pp) )
{ {
CreateItem( TANK_CANNON, ( INT8 )( 80 + Random( 21 ) ), &( pp->Inv[ HANDPOS ]) ); CreateItem( TANK_CANNON, ( INT8 )( 80 + Random( 21 ) ), &( pp->Inv[ HANDPOS ]) );
pp->Inv[ HANDPOS ].fFlags |= OBJECT_UNDROPPABLE; pp->Inv[ HANDPOS ].fFlags |= OBJECT_UNDROPPABLE;
@@ -3278,7 +3279,13 @@ void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp, BOOLEAN fTank )
gTempObject.fFlags |= OBJECT_UNDROPPABLE; gTempObject.fFlags |= OBJECT_UNDROPPABLE;
PlaceObjectInSoldierCreateStruct( pp, &gTempObject ); PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
} }
else else if ( COMBAT_JEEP(pp) )
{
// machine gun
CreateItems( MINIMI, (INT8)(80 + Random( 21 )), 1, &(pp->Inv[HANDPOS]) );
pp->Inv[HANDPOS].fFlags |= OBJECT_UNDROPPABLE;
}
else if ( ENEMYROBOT(pp) )
{ {
// machine gun // machine gun
CreateItems( MINIMI, (INT8)(80 + Random( 21 )), 1, &(pp->Inv[HANDPOS]) ); CreateItems( MINIMI, (INT8)(80 + Random( 21 )), 1, &(pp->Inv[HANDPOS]) );
+2 -2
View File
@@ -3243,7 +3243,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 && !ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813 for current tank don't go further as it lead to invalid animation if ( fPermanent && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( 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);
@@ -9078,7 +9078,7 @@ void CheckEquipmentForDamage( SOLDIERTYPE *pSoldier, INT32 iDamage )
BOOLEAN fBlowsUp; BOOLEAN fBlowsUp;
UINT8 ubNumberOfObjects; UINT8 ubNumberOfObjects;
if ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
return; return;
} }
+1 -1
View File
@@ -2049,7 +2049,7 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p
ubPosType = TORSO_TARGET_POS; ubPosType = TORSO_TARGET_POS;
} }
} }
else if ( ARMED_VEHICLE( pSoldier ) ) else if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
// high up! // high up!
//ubPosType = HEAD_TARGET_POS; //ubPosType = HEAD_TARGET_POS;
+2 -1
View File
@@ -350,7 +350,8 @@ namespace LogicalBodyTypes {
SOLDIER_CLASS_ZOMBIE, SOLDIER_CLASS_ZOMBIE,
SOLDIER_CLASS_TANK, SOLDIER_CLASS_TANK,
SOLDIER_CLASS_JEEP, SOLDIER_CLASS_JEEP,
SOLDIER_CLASS_BANDIT SOLDIER_CLASS_BANDIT,
SOLDIER_CLASS_ROBOT
); );
/***************************************** /*****************************************
+5 -5
View File
@@ -7265,16 +7265,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 = pSectorInfo->ubNumJeeps = 0; pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = pSectorInfo->ubNumJeeps = pSectorInfo->ubNumRobots = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = 0; pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = pSectorInfo->ubRobotsInBattle = 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 = pSectorInfo->ubNumJeeps = 0; pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = pSectorInfo->ubNumJeeps = pSectorInfo->ubNumRobots = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = 0; pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = pSectorInfo->ubRobotsInBattle = 0;
} }
} }
@@ -10941,7 +10941,7 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
{ {
enemysidestrength += pSoldier->GetSurrenderStrength(); enemysidestrength += pSoldier->GetSurrenderStrength();
if ( pSoldier->ubProfile != NO_PROFILE || ARMED_VEHICLE(pSoldier) ) if ( pSoldier->ubProfile != NO_PROFILE || ARMED_VEHICLE(pSoldier) || ENEMYROBOT(pSoldier) )
fNoSurrender = TRUE; fNoSurrender = TRUE;
} }
} }
+4 -4
View File
@@ -2594,7 +2594,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime,
} }
} }
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 if ( AM_A_ROBOT( pSoldier ) || ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( 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;
} }
@@ -2968,7 +2968,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 ( ARMED_VEHICLE( pSoldier ) && !Item[pObj->usItem].cannon ) if ( (ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier )) && !Item[pObj->usItem].cannon )
return; return;
if ( Item[pObj->usItem].cannon ) if ( Item[pObj->usItem].cannon )
@@ -4432,7 +4432,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 ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) || ENEMYROBOT( 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)
@@ -4573,7 +4573,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 ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) || ENEMYROBOT( pSoldier ) )
return 0; return 0;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// THE GUN RECOIL KICK ENERGY COST // THE GUN RECOIL KICK ENERGY COST
+3
View File
@@ -4004,6 +4004,9 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
// SANDRO - experimental - more specific statistics of mercs // SANDRO - experimental - more specific statistics of mercs
switch(pSoldier->ubSoldierClass) switch(pSoldier->ubSoldierClass)
{ {
case SOLDIER_CLASS_ROBOT:
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsOthers++;
break;
case SOLDIER_CLASS_ELITE : case SOLDIER_CLASS_ELITE :
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsElites++; gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsElites++;
break; break;
+11 -7
View File
@@ -16670,7 +16670,7 @@ UINT32 SOLDIERTYPE::GetSurrenderStrength( )
value = value * (5 + sqrt( (double)max( 1, this->aiData.bMorale ) )) / 15; value = value * (5 + sqrt( (double)max( 1, this->aiData.bMorale ) )) / 15;
// adjust for type of soldier // adjust for type of soldier
if ( this->ubSoldierClass == SOLDIER_CLASS_ELITE || this->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA ) if ( this->ubSoldierClass == SOLDIER_CLASS_ELITE || this->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA || this->ubSoldierClass == SOLDIER_CLASS_ROBOT )
value *= 1.5f; value *= 1.5f;
else if ( this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || this->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA || this->ubSoldierClass == SOLDIER_CLASS_BANDIT ) else if ( this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || this->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA || this->ubSoldierClass == SOLDIER_CLASS_BANDIT )
value *= 0.75f; value *= 0.75f;
@@ -16720,8 +16720,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 )
{ {
// armed vehicles cannot be captured // armed vehicles and robots cannot be captured
if ( ARMED_VEHICLE(this) ) if ( ARMED_VEHICLE(this) || ENEMYROBOT(this) )
return FALSE; return FALSE;
// enemies can be captured // enemies can be captured
@@ -19346,7 +19346,7 @@ BOOLEAN SOLDIERTYPE::CanMedicAI( )
return FALSE; return FALSE;
// this is not for tanks // this is not for tanks
if ( ARMED_VEHICLE( this ) ) if ( ARMED_VEHICLE( this ) || ENEMYROBOT( this ) )
return FALSE; return FALSE;
if ( HAS_SKILL_TRAIT( this, DOCTOR_NT ) ) if ( HAS_SKILL_TRAIT( this, DOCTOR_NT ) )
@@ -19378,7 +19378,7 @@ BOOLEAN SOLDIERTYPE::AIDoctorFriend( )
return FALSE; return FALSE;
// this is not for tanks // this is not for tanks
if ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( 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)
@@ -21389,6 +21389,10 @@ UINT8 SOLDIERTYPE::GetTurncoatConvinctionChance( UINT16 usID, INT16 sApproach )
|| pSoldier->bTeam != ENEMY_TEAM ) || pSoldier->bTeam != ENEMY_TEAM )
return 0; return 0;
// enemy robots can't be turncoats
if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ROBOT)
return 0;
if ( this->stats.bLife < OKLIFE ) if ( this->stats.bLife < OKLIFE )
return 0; return 0;
@@ -23363,7 +23367,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 ) || ARMED_VEHICLE( this ) )//dnl ch64 300813 if ( AM_A_ROBOT( this ) || ARMED_VEHICLE( this ) || ENEMYROBOT( this ) )//dnl ch64 300813
{ {
return(FALSE); return(FALSE);
} }
@@ -23415,7 +23419,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 ) || ARMED_VEHICLE( this ) )//dnl ch64 300813 if ( AM_A_ROBOT( this ) || ARMED_VEHICLE( this ) || ENEMYROBOT( this ) )//dnl ch64 300813
{ {
return(FALSE); return(FALSE);
} }
+1
View File
@@ -337,6 +337,7 @@ enum
SOLDIER_CLASS_TANK, SOLDIER_CLASS_TANK,
SOLDIER_CLASS_JEEP, SOLDIER_CLASS_JEEP,
SOLDIER_CLASS_BANDIT, SOLDIER_CLASS_BANDIT,
SOLDIER_CLASS_ROBOT,
SOLDIER_CLASS_MAX, SOLDIER_CLASS_MAX,
}; };
+53 -4
View File
@@ -613,9 +613,9 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
pCreateStruct->fPlayerPlan = 0; pCreateStruct->fPlayerPlan = 0;
} }
if ( is_networked && ARMED_VEHICLE( pCreateStruct ) ) if ( is_networked && (ARMED_VEHICLE( pCreateStruct ) || ENEMYROBOT( pCreateStruct )) )
{ {
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank"); ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank/jeep/robot");
return NULL; return NULL;
} }
} }
@@ -730,6 +730,13 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
break; break;
} }
// enemy robot special case
if (pCreateStruct->ubBodyType == ROBOTNOWEAPON && pCreateStruct->ubSoldierClass == SOLDIER_CLASS_ROBOT)
{
Soldier.bTeam = ENEMY_TEAM;
}
} }
} }
else else
@@ -826,7 +833,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
// Flugente: disease can affect a soldier's health // Flugente: disease can affect a soldier's health
// not for us, and not for individual militia (their health is affected by their hourly healing instead) // not for us, and not for individual militia (their health is affected by their hourly healing instead)
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && !ARMED_VEHICLE((&Soldier)) && if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && !ARMED_VEHICLE((&Soldier)) && !ENEMYROBOT((&Soldier)) &&
!( Soldier.bTeam == MILITIA_TEAM && gGameExternalOptions.fIndividualMilitia && gGameExternalOptions.fIndividualMilitia_ManageHealth ) ) !( Soldier.bTeam == MILITIA_TEAM && gGameExternalOptions.fIndividualMilitia && gGameExternalOptions.fIndividualMilitia_ManageHealth ) )
{ {
UINT8 sector = SECTOR( Soldier.sSectorX, Soldier.sSectorY ); UINT8 sector = SECTOR( Soldier.sSectorX, Soldier.sSectorY );
@@ -1756,7 +1763,7 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
// Flugente: soldier profiles // Flugente: soldier profiles
// silversurfer: Don't replace tanks! // silversurfer: Don't replace tanks!
if ( !ARMED_VEHICLE( pCreateStruct ) ) if ( !ARMED_VEHICLE( pCreateStruct ) && !ENEMYROBOT( pCreateStruct ) )
{ {
MILITIA militia; MILITIA militia;
if ( GetMilitia( pSoldier->usIndividualMilitiaID, &militia ) ) if ( GetMilitia( pSoldier->usIndividualMilitiaID, &militia ) )
@@ -2556,6 +2563,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
} }
break; break;
case SOLDIER_CLASS_ROBOT:
case SOLDIER_CLASS_TANK: case SOLDIER_CLASS_TANK:
case SOLDIER_CLASS_JEEP: case SOLDIER_CLASS_JEEP:
pp->bExpLevel = bp->bRelativeAttributeLevel; pp->bExpLevel = bp->bRelativeAttributeLevel;
@@ -3241,6 +3249,47 @@ SOLDIERTYPE* TacticalCreateEnemyJeep( )
return(pSoldier); return(pSoldier);
} }
// rftr: enemy robots
SOLDIERTYPE* TacticalCreateEnemyRobot()
{
BASIC_SOLDIERCREATE_STRUCT bp;
SOLDIERCREATE_STRUCT pp;
UINT8 ubID;
SOLDIERTYPE * pSoldier;
if ( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI )
{
pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ROBOT );
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 = AGGRESSIVE;
bp.ubBodyType = ROBOTNOWEAPON;
bp.ubSoldierClass = SOLDIER_CLASS_ROBOT;
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;
pSoldier->stats.bLifeMax = 80;
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
}
return(pSoldier);
}
//USED BY STRATEGIC AI and AUTORESOLVE //USED BY STRATEGIC AI and AUTORESOLVE
SOLDIERTYPE* TacticalCreateZombie() SOLDIERTYPE* TacticalCreateZombie()
{ {
+1
View File
@@ -471,6 +471,7 @@ SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass, INT16 sX, INT16 sY );
SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType ); SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType );
SOLDIERTYPE* TacticalCreateEnemyTank(); SOLDIERTYPE* TacticalCreateEnemyTank();
SOLDIERTYPE* TacticalCreateEnemyJeep( ); SOLDIERTYPE* TacticalCreateEnemyJeep( );
SOLDIERTYPE* TacticalCreateEnemyRobot();
// Flugente: create an armed civilian // Flugente: create an armed civilian
SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass = SOLDIER_CLASS_ARMY ); SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass = SOLDIER_CLASS_ARMY );
+48 -6
View File
@@ -1050,12 +1050,13 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
return ubNumAdded; return ubNumAdded;
} }
void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks, UINT8 ubTotalJeeps ) void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalRobots, UINT8 ubTotalTanks, UINT8 ubTotalJeeps )
{ {
SOLDIERINITNODE *mark; SOLDIERINITNODE *mark;
SOLDIERINITNODE *curr; SOLDIERINITNODE *curr;
INT32 iRandom; INT32 iRandom;
UINT8 ubMaxNum; UINT8 ubMaxNum;
UINT8 ubRobotPDSlots = 0, ubRobotDSlots = 0, ubRobotPSlots = 0, ubRobotBSlots = 0;
UINT8 ubElitePDSlots = 0, ubEliteDSlots = 0, ubElitePSlots = 0, ubEliteBSlots = 0; UINT8 ubElitePDSlots = 0, ubEliteDSlots = 0, ubElitePSlots = 0, ubEliteBSlots = 0;
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;
@@ -1078,7 +1079,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 + ubTotalJeeps; ubMaxNum = ubTotalAdmin + ubTotalTroops + ubTotalElite + ubTotalRobots + ubTotalTanks + ubTotalJeeps;
AssertLE (ubMaxNum, gGameExternalOptions.ubGameMaximumNumberOfEnemies); AssertLE (ubMaxNum, gGameExternalOptions.ubGameMaximumNumberOfEnemies);
@@ -1141,6 +1142,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
else else
ubJeepBSlots++; ubJeepBSlots++;
} }
break;
case SOLDIER_CLASS_TANK: case SOLDIER_CLASS_TANK:
if ( TANK( curr->pDetailedPlacement ) ) if ( TANK( curr->pDetailedPlacement ) )
{ {
@@ -1154,6 +1156,16 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
ubTankBSlots++; ubTankBSlots++;
} }
break; break;
case SOLDIER_CLASS_ROBOT:
if ( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement )
ubRobotPDSlots++;
else if ( curr->pBasicPlacement->fPriorityExistance )
ubRobotPSlots++;
else if ( curr->pDetailedPlacement )
ubRobotDSlots++;
else
ubRobotBSlots++;
break;
} }
} }
curr = curr->next; curr = curr->next;
@@ -1162,7 +1174,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 + 2; ++ubCurrClass ) for( ubCurrClass = SOLDIER_CLASS_ADMINISTRATOR; ubCurrClass <= SOLDIER_CLASS_ARMY + 3; ++ubCurrClass )
{ {
//First, prepare the counters. //First, prepare the counters.
switch( ubCurrClass ) switch( ubCurrClass )
@@ -1190,6 +1202,11 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
pCurrSlots = &ubJeepPDSlots; pCurrSlots = &ubJeepPDSlots;
pCurrTotal = &ubTotalJeeps; pCurrTotal = &ubTotalJeeps;
break; break;
case SOLDIER_CLASS_ROBOT + 3: // SOLDIER_CLASS_ROBOT
ubCurrClass = SOLDIER_CLASS_ROBOT;
pCurrSlots = &ubRobotPDSlots;
pCurrTotal = &ubTotalRobots;
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;
@@ -1370,16 +1387,22 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
} }
else if( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks ) else if( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks )
{ {
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK; curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK;
curr->pBasicPlacement->ubBodyType = TANK_NW; curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--; ubTotalTanks--;
} }
else if ( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps ) else if( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps )
{ {
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP; curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP; curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--; ubTotalJeeps--;
} }
else if( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps + ubTotalRobots )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_ROBOT;
curr->pBasicPlacement->ubBodyType = ROBOTNOWEAPON;
ubTotalRobots--;
}
else else
Assert(0); Assert(0);
if( AddPlacementToWorld( curr ) ) if( AddPlacementToWorld( curr ) )
@@ -1494,6 +1517,19 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
return; return;
ubFreeSlots--; ubFreeSlots--;
} }
else if ( ubTotalRobots )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_ROBOT;
curr->pBasicPlacement->ubBodyType = ROBOTNOWEAPON;
ubTotalRobots--;
if ( AddPlacementToWorld( curr ) )
{
ubMaxNum--;
}
else
return;
ubFreeSlots--;
}
} }
curr = curr->next; curr = curr->next;
} }
@@ -1532,12 +1568,18 @@ 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 ) else if( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps )
{ {
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP; curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP; curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--; ubTotalJeeps--;
} }
else if( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps + ubTotalRobots )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_ROBOT;
curr->pBasicPlacement->ubBodyType = ROBOTNOWEAPON;
ubTotalRobots--;
}
else else
Assert(0); Assert(0);
/* DISABLE THE OVERRIDE FOR NOW... /* DISABLE THE OVERRIDE FOR NOW...
+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, UINT8 ubTotalJeeps ); void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalRobots, 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
@@ -12,6 +12,7 @@
#define AM_AN_EPC( p ) ( ( p->ubProfile == NO_PROFILE ) ? FALSE : ( gMercProfiles[ p->ubProfile ].ubMiscFlags & PROFILE_MISC_FLAG_EPCACTIVE ) ) #define AM_AN_EPC( p ) ( ( p->ubProfile == NO_PROFILE ) ? FALSE : ( gMercProfiles[ p->ubProfile ].ubMiscFlags & PROFILE_MISC_FLAG_EPCACTIVE ) )
// rftr - this is for madlab's robot, since it has a profile
#define AM_A_ROBOT( p ) ( ( p->ubProfile == NO_PROFILE ) ? FALSE : ( gMercProfiles[ p->ubProfile ].ubBodyType == ROBOTNOWEAPON ) ) #define AM_A_ROBOT( p ) ( ( p->ubProfile == NO_PROFILE ) ? FALSE : ( gMercProfiles[ p->ubProfile ].ubBodyType == ROBOTNOWEAPON ) )
@@ -34,6 +35,7 @@
#define COMBAT_JEEP( p ) ( p->ubBodyType == COMBAT_JEEP ) #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 ENEMYROBOT( p ) (p->ubBodyType == ROBOTNOWEAPON && p->bTeam == ENEMY_TEAM)
#define ARMED_VEHICLE( p ) ( TANK( p ) || COMBAT_JEEP(p) ) #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 )
+2 -2
View File
@@ -54,7 +54,7 @@ STR16 gStrAlertStatus[] = { L"Green", L"Yellow", L"Red", L"Black" };
STR16 gStrAttitude[] = { L"DEFENSIVE", L"BRAVESOLO", L"BRAVEAID", L"CUNNINGSOLO", L"CUNNINGAID", L"AGGRESSIVE", L"MAXATTITUDES", L"ATTACKSLAYONLY" }; STR16 gStrAttitude[] = { L"DEFENSIVE", L"BRAVESOLO", L"BRAVEAID", L"CUNNINGSOLO", L"CUNNINGAID", L"AGGRESSIVE", L"MAXATTITUDES", L"ATTACKSLAYONLY" };
STR16 gStrOrders[] = { L"STATIONARY", L"ONGUARD", L"CLOSEPATROL", L"FARPATROL", L"POINTPATROL", L"ONCALL", L"SEEKENEMY", L"RNDPTPATROL", L"SNIPER" }; STR16 gStrOrders[] = { L"STATIONARY", L"ONGUARD", L"CLOSEPATROL", L"FARPATROL", L"POINTPATROL", L"ONCALL", L"SEEKENEMY", L"RNDPTPATROL", L"SNIPER" };
STR16 gStrTeam[] = { L"OUR_TEAM", L"ENEMY_TEAM", L"CREATURE_TEAM", L"MILITIA_TEAM", L"CIV_TEAM", L"LAST_TEAM", L"PLAYER_PLAN", L"LAN_TEAM_ONE", L"LAN_TEAM_TWO", L"LAN_TEAM_THREE", L"LAN_TEAM_FOUR" }; STR16 gStrTeam[] = { L"OUR_TEAM", L"ENEMY_TEAM", L"CREATURE_TEAM", L"MILITIA_TEAM", L"CIV_TEAM", L"LAST_TEAM", L"PLAYER_PLAN", L"LAN_TEAM_ONE", L"LAN_TEAM_TWO", L"LAN_TEAM_THREE", L"LAN_TEAM_FOUR" };
STR16 gStrClass[] = { L"SOLDIER_CLASS_NONE", L"SOLDIER_CLASS_ADMINISTRATOR", L"SOLDIER_CLASS_ELITE", L"SOLDIER_CLASS_ARMY", L"SOLDIER_CLASS_GREEN_MILITIA", L"SOLDIER_CLASS_REG_MILITIA", L"SOLDIER_CLASS_ELITE_MILITIA", L"SOLDIER_CLASS_CREATURE", L"SOLDIER_CLASS_MINER", L"SOLDIER_CLASS_ZOMBIE", L"SOLDIER_CLASS_TANK", L"SOLDIER_CLASS_JEEP", L"SOLDIER_CLASS_BANDIT"}; STR16 gStrClass[] = { L"SOLDIER_CLASS_NONE", L"SOLDIER_CLASS_ADMINISTRATOR", L"SOLDIER_CLASS_ELITE", L"SOLDIER_CLASS_ARMY", L"SOLDIER_CLASS_GREEN_MILITIA", L"SOLDIER_CLASS_REG_MILITIA", L"SOLDIER_CLASS_ELITE_MILITIA", L"SOLDIER_CLASS_CREATURE", L"SOLDIER_CLASS_MINER", L"SOLDIER_CLASS_ZOMBIE", L"SOLDIER_CLASS_TANK", L"SOLDIER_CLASS_JEEP", L"SOLDIER_CLASS_BANDIT", L"SOLDIER_CLASS_ROBOT" };
STR16 SeenStr(INT32 value) STR16 SeenStr(INT32 value)
{ {
@@ -95,7 +95,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
// WANNE: No tooltips on bloodcats, bugs, tanks, robots // WANNE: No tooltips on bloodcats, bugs, tanks, robots
// sevenfm: allow tooltip in debug mode // sevenfm: allow tooltip in debug mode
if (gGameExternalOptions.ubSoldierTooltipDetailLevel < 4 && if (gGameExternalOptions.ubSoldierTooltipDetailLevel < 4 &&
(CREATURE_OR_BLOODCAT( pSoldier ) || ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier))) (CREATURE_OR_BLOODCAT( pSoldier ) || ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier) || ENEMYROBOT( pSoldier )))
{ {
return; return;
} }
+1 -1
View File
@@ -2015,7 +2015,7 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
} }
} }
if ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
// reduce interrupt possibilities for tanks! // reduce interrupt possibilities for tanks!
iPoints /= 2; iPoints /= 2;
+17 -17
View File
@@ -4091,7 +4091,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{ {
iHitChance = 100; iHitChance = 100;
} }
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 else if ( AM_A_ROBOT( pTargetSoldier ) || ENEMYROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) || CREATURE_OR_BLOODCAT( pTargetSoldier ) || (SOLDIER_CLASS_MILITIA( pTargetSoldier->ubSoldierClass ) && (gGameExternalOptions.ubMilitiaDropEquipment != 2)) ) // added militia here - SANDRO
{ {
iHitChance = 0; iHitChance = 0;
} }
@@ -4450,7 +4450,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 ) && !ARMED_VEHICLE( pTargetSoldier ) ) if ( iHitChance > 0 && pSoldier->bTeam == gbPlayerNum && pTargetSoldier->bTeam != gbPlayerNum && !(pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( pTargetSoldier ) && !ARMED_VEHICLE( pTargetSoldier ) && !ENEMYROBOT( pTargetSoldier ) )
{ {
if (fFailure == FALSE) if (fFailure == FALSE)
{ {
@@ -4582,7 +4582,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
} }
} }
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) ) if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) || ENEMYROBOT( pTargetSoldier ) )
{ {
ubExpGain = 0; ubExpGain = 0;
} }
@@ -4632,7 +4632,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
} }
} }
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) ) if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) || ENEMYROBOT( pTargetSoldier ) )
{ {
ubExpGain = 0; ubExpGain = 0;
} }
@@ -6870,7 +6870,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 && !ARMED_VEHICLE( pTarget ) && !(pSoldier->ubBodyType != QUEENMONSTER) ) if ( pTarget->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY && !ARMED_VEHICLE( pTarget ) && !ENEMYROBOT( 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 )
@@ -6885,7 +6885,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 ( ARMED_VEHICLE( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) ) if ( ARMED_VEHICLE( pTarget ) || ENEMYROBOT( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) )
{ {
// reduce ability to track shots // reduce ability to track shots
iBonus = iBonus / 2; iBonus = iBonus / 2;
@@ -7455,7 +7455,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 ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
// allow absolute minimums // allow absolute minimums
iChance = 0; iChance = 0;
@@ -7683,7 +7683,7 @@ INT32 ArmourProtection( SOLDIERTYPE * pTarget, UINT16 ubArmourType, INT16 * pbSt
iCoverage = Armour [ ubArmourType ].ubCoverage; iCoverage = Armour [ ubArmourType ].ubCoverage;
if ( *plateHit ) iCoverage = 100; if ( *plateHit ) iCoverage = 100;
if ( !AM_A_ROBOT( pTarget ) ) if ( !(AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget )) )
{ {
// check for the bullet missing armor due to coverage // check for the bullet missing armor due to coverage
iFailure = PreRandom( 100 ) + 1 - iCoverage; iFailure = PreRandom( 100 ) + 1 - iCoverage;
@@ -7758,7 +7758,7 @@ INT32 ArmourProtection( SOLDIERTYPE * pTarget, UINT16 ubArmourType, INT16 * pbSt
} }
} }
if ( !AM_A_ROBOT( pTarget ) ) if ( !(AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget )) )
{ {
*pbStatus -= (iAppliedProtection * Armour[ubArmourType].ubDegradePercent) / 100; *pbStatus -= (iAppliedProtection * Armour[ubArmourType].ubDegradePercent) / 100;
} }
@@ -7978,9 +7978,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
{ {
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierZombie; damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierZombie;
} }
else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE ) else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE || pTarget->flags.uiStatusFlags & SOLDIER_ROBOT )
{ {
if ( COMBAT_JEEP( pTarget ) || AM_A_ROBOT( pTarget ) ) if ( COMBAT_JEEP( pTarget ) || AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget ))
{ {
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierArmouredVehicle; damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierArmouredVehicle;
} }
@@ -8078,7 +8078,7 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
ShutupaYoFace( pTarget->iFaceIndex ); ShutupaYoFace( pTarget->iFaceIndex );
} }
if ( iImpact > 0 && !ARMED_VEHICLE( pTarget ) ) if ( iImpact > 0 && !ARMED_VEHICLE( pTarget ) && !ENEMYROBOT( 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 )
@@ -8236,7 +8236,7 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
} }
} }
if ( AM_A_ROBOT( pTarget ) ) if ( AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget ) )
{ {
iImpactForCrits = 0; iImpactForCrits = 0;
} }
@@ -8591,7 +8591,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
iImpact += EffectiveStrength( pSoldier, FALSE ) / 20; // 0 to 5 for strength, adjusted by damage taken iImpact += EffectiveStrength( pSoldier, FALSE ) / 20; // 0 to 5 for strength, adjusted by damage taken
if ( AM_A_ROBOT( pTarget ) ) if ( AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget) )
{ {
iImpact /= 4; iImpact /= 4;
} }
@@ -8608,7 +8608,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
{ {
iImpact += GetDamage(&pSoldier->inv[HANDPOS]); iImpact += GetDamage(&pSoldier->inv[HANDPOS]);
if ( AM_A_ROBOT( pTarget ) ) if ( AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget ) )
{ {
iImpact /= 2; iImpact /= 2;
} }
@@ -8619,7 +8619,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
{ {
iImpact += GetDamage(&pSoldier->inv[HANDPOS]); iImpact += GetDamage(&pSoldier->inv[HANDPOS]);
} }
if ( AM_A_ROBOT( pTarget ) ) if ( AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget ) )
{ {
iImpact /= 2; iImpact /= 2;
} }
@@ -8643,7 +8643,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
// only the item impact is multiplied, not the level and strength bonus, but here it does // only the item impact is multiplied, not the level and strength bonus, but here it does
iImpact = (INT32)(iImpact * gGameExternalOptions.iMeleeDamageModifier / 100 ); iImpact = (INT32)(iImpact * gGameExternalOptions.iMeleeDamageModifier / 100 );
if ( AM_A_ROBOT( pTarget ) ) if ( AM_A_ROBOT( pTarget ) || ENEMYROBOT( pTarget ) )
{ {
iImpact = 0; iImpact = 0;
} }
+2 -1
View File
@@ -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 ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
return( -5 ); return( -5 );
} }
@@ -4885,6 +4885,7 @@ void DebugSoldierPage4( )
case SOLDIER_CLASS_MINER: gprintf( 320, LINE_HEIGHT * ubLine, L"(Miner)" ); break; case SOLDIER_CLASS_MINER: gprintf( 320, LINE_HEIGHT * ubLine, L"(Miner)" ); break;
case SOLDIER_CLASS_ZOMBIE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Zombie)" ); break; case SOLDIER_CLASS_ZOMBIE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Zombie)" ); break;
case SOLDIER_CLASS_BANDIT: gprintf( 320, LINE_HEIGHT * ubLine, L"(Bandit)" ); break; case SOLDIER_CLASS_BANDIT: gprintf( 320, LINE_HEIGHT * ubLine, L"(Bandit)" ); break;
case SOLDIER_CLASS_ROBOT: gprintf( 320, LINE_HEIGHT * ubLine, L"(Army Robot)" ); break;
default: break; //don't care (don't write anything) default: break; //don't care (don't write anything)
} }
+7 -2
View File
@@ -1451,7 +1451,7 @@ void CancelAIAction(SOLDIERTYPE *pSoldier, UINT8 ubForce)
DebugAI(AI_MSG_INFO, pSoldier, String("CancelAIAction")); DebugAI(AI_MSG_INFO, pSoldier, String("CancelAIAction"));
// 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 || !ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813 if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !ARMED_VEHICLE( pSoldier ) || !ENEMYROBOT( 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!
@@ -1861,7 +1861,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 || !ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813 if ( gGameExternalOptions.fEnemyTanksCanMoveInTactical || !ARMED_VEHICLE( pSoldier ) || !ENEMYROBOT( pSoldier ) )//dnl ch64 290813
SkipCoverCheck = FALSE; SkipCoverCheck = FALSE;
// reset this field, too // reset this field, too
@@ -2945,6 +2945,11 @@ void HandleAITacticalTraversal( SOLDIERTYPE * pSoldier )
++pSectorInfo->ubNumAdmins; ++pSectorInfo->ubNumAdmins;
break; break;
case SOLDIER_CLASS_ROBOT:
if (ENEMYROBOT(pSoldier))
++pSectorInfo->ubNumRobots;
break;
case SOLDIER_CLASS_TANK: case SOLDIER_CLASS_TANK:
if( TANK(pSoldier) ) if( TANK(pSoldier) )
++pSectorInfo->ubNumTanks; ++pSectorInfo->ubNumTanks;
+8 -6
View File
@@ -1237,8 +1237,8 @@ INT32 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, BOOLEAN * pfChangeLevel
continue; continue;
} }
// sevenfm: zombies do not attack vehicles // sevenfm: zombies do not attack vehicles (rftr: or robots)
if (pSoldier->IsZombie() && (ARMED_VEHICLE(pOpponent) || (pOpponent->flags.uiStatusFlags & SOLDIER_VEHICLE))) if (pSoldier->IsZombie() && (AM_A_ROBOT(pOpponent) || ENEMYROBOT(pOpponent) || ARMED_VEHICLE(pOpponent) || (pOpponent->flags.uiStatusFlags & SOLDIER_VEHICLE)))
{ {
continue; continue;
} }
@@ -3031,6 +3031,7 @@ UINT8 SoldierDifficultyLevel( SOLDIERTYPE * pSoldier )
bDifficulty = bDifficultyBase; bDifficulty = bDifficultyBase;
break; break;
case SOLDIER_CLASS_ROBOT:
case SOLDIER_CLASS_ELITE: case SOLDIER_CLASS_ELITE:
bDifficulty = bDifficultyBase + 1; bDifficulty = bDifficultyBase + 1;
break; break;
@@ -3476,7 +3477,7 @@ UINT8 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 au
continue; continue;
// this is not for tanks // this is not for tanks
if ( ARMED_VEHICLE( pFriend ) ) if ( ARMED_VEHICLE( pFriend ) || ENEMYROBOT( pFriend ))
continue; continue;
// skip if this guy is dead // skip if this guy is dead
@@ -3529,7 +3530,7 @@ UINT8 GetClosestWoundedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 au
continue; continue;
// this is not for tanks // this is not for tanks
if ( ARMED_VEHICLE( pFriend ) ) if ( ARMED_VEHICLE( pFriend ) || ENEMYROBOT( pFriend ) )
continue; continue;
// skip if this guy is dead, or not wounded (enough) // skip if this guy is dead, or not wounded (enough)
@@ -3578,7 +3579,7 @@ UINT8 GetClosestMedicSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTe
continue; continue;
// this is not for tanks // this is not for tanks
if ( ARMED_VEHICLE( pFriend ) ) if ( ARMED_VEHICLE( pFriend ) || ENEMYROBOT( pFriend ) )
continue; continue;
// skip this guy if he is dead or unconscious // skip this guy if he is dead or unconscious
@@ -4907,7 +4908,8 @@ BOOLEAN SoldierAI(SOLDIERTYPE *pSoldier)
pSoldier->flags.uiStatusFlags & SOLDIER_BOXER || pSoldier->flags.uiStatusFlags & SOLDIER_BOXER ||
ARMED_VEHICLE(pSoldier) || ARMED_VEHICLE(pSoldier) ||
pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ||
AM_A_ROBOT(pSoldier)) AM_A_ROBOT(pSoldier) ||
ENEMYROBOT(pSoldier))
return FALSE; return FALSE;
return TRUE; return TRUE;
+3 -3
View File
@@ -117,7 +117,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 ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
// don't remove ammo // don't remove ammo
gTempObject = pSoldier->inv[bPayloadPocket]; gTempObject = pSoldier->inv[bPayloadPocket];
@@ -514,7 +514,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot)
} }
// no crouched/prone if we are tank/using throwing knife/hip firing // no crouched/prone if we are tank/using throwing knife/hip firing
if ( pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD || ARMED_VEHICLE( pSoldier ) || (Item[pSoldier->usAttackingWeapon].usItemClass & IC_THROWING_KNIFE) ) if ( pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD || ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) || (Item[pSoldier->usAttackingWeapon].usItemClass & IC_THROWING_KNIFE) )
continue; continue;
// --------- Crouched --------- // --------- Crouched ---------
@@ -1159,7 +1159,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS && Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_CREATUREGAS &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS && Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_BURNABLEGAS &&
Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_SMOKE && Explosive[Item[usGrenade].ubClassIndex].ubType != EXPLOSV_SMOKE &&
(ARMED_VEHICLE(pOpponent) || pOpponent->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT(pOpponent))) (ARMED_VEHICLE(pOpponent) || ENEMYROBOT(pOpponent) || pOpponent->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT(pOpponent)))
{ {
continue; continue;
} }
+22 -19
View File
@@ -71,7 +71,7 @@ STR8 gStr8AlertStatus[] = { "Green", "Yellow", "Red", "Black" };
STR8 gStr8Attitude[] = { "DEFENSIVE", "BRAVESOLO", "BRAVEAID", "CUNNINGSOLO", "CUNNINGAID", "AGGRESSIVE", "MAXATTITUDES", "ATTACKSLAYONLY" }; STR8 gStr8Attitude[] = { "DEFENSIVE", "BRAVESOLO", "BRAVEAID", "CUNNINGSOLO", "CUNNINGAID", "AGGRESSIVE", "MAXATTITUDES", "ATTACKSLAYONLY" };
STR8 gStr8Orders[] = { "STATIONARY", "ONGUARD", "CLOSEPATROL", "FARPATROL", "POINTPATROL", "ONCALL", "SEEKENEMY", "RNDPTPATROL", "SNIPER" }; STR8 gStr8Orders[] = { "STATIONARY", "ONGUARD", "CLOSEPATROL", "FARPATROL", "POINTPATROL", "ONCALL", "SEEKENEMY", "RNDPTPATROL", "SNIPER" };
STR8 gStr8Team[] = { "OUR_TEAM", "ENEMY_TEAM", "CREATURE_TEAM", "MILITIA_TEAM", "CIV_TEAM", "LAST_TEAM", "PLAYER_PLAN", "LAN_TEAM_ONE", "LAN_TEAM_TWO", "LAN_TEAM_THREE", "LAN_TEAM_FOUR" }; STR8 gStr8Team[] = { "OUR_TEAM", "ENEMY_TEAM", "CREATURE_TEAM", "MILITIA_TEAM", "CIV_TEAM", "LAST_TEAM", "PLAYER_PLAN", "LAN_TEAM_ONE", "LAN_TEAM_TWO", "LAN_TEAM_THREE", "LAN_TEAM_FOUR" };
STR8 gStr8Class[] = { "SOLDIER_CLASS_NONE", "SOLDIER_CLASS_ADMINISTRATOR", "SOLDIER_CLASS_ELITE", "SOLDIER_CLASS_ARMY", "SOLDIER_CLASS_GREEN_MILITIA", "SOLDIER_CLASS_REG_MILITIA", "SOLDIER_CLASS_ELITE_MILITIA", "SOLDIER_CLASS_CREATURE", "SOLDIER_CLASS_MINER", "SOLDIER_CLASS_ZOMBIE", "SOLDIER_CLASS_TANK", "SOLDIER_CLASS_JEEP", "SOLDIER_CLASS_BANDIT" }; STR8 gStr8Class[] = { "SOLDIER_CLASS_NONE", "SOLDIER_CLASS_ADMINISTRATOR", "SOLDIER_CLASS_ELITE", "SOLDIER_CLASS_ARMY", "SOLDIER_CLASS_GREEN_MILITIA", "SOLDIER_CLASS_REG_MILITIA", "SOLDIER_CLASS_ELITE_MILITIA", "SOLDIER_CLASS_CREATURE", "SOLDIER_CLASS_MINER", "SOLDIER_CLASS_ZOMBIE", "SOLDIER_CLASS_TANK", "SOLDIER_CLASS_JEEP", "SOLDIER_CLASS_BANDIT", "SOLDIER_CLASS_ROBOT" };
STR8 gStr8Knowledge[] = { "HEARD_3_TURNS_AGO", "HEARD_2_TURNS_AGO", "HEARD_LAST_TURN", "HEARD_THIS_TURN", "NOT_HEARD_OR_SEEN", "SEEN_CURRENTLY", "SEEN_THIS_TURN", "SEEN_LAST_TURN", "SEEN_2_TURNS_AGO", "SEEN_3_TURNS_AGO" }; STR8 gStr8Knowledge[] = { "HEARD_3_TURNS_AGO", "HEARD_2_TURNS_AGO", "HEARD_LAST_TURN", "HEARD_THIS_TURN", "NOT_HEARD_OR_SEEN", "SEEN_CURRENTLY", "SEEN_THIS_TURN", "SEEN_LAST_TURN", "SEEN_2_TURNS_AGO", "SEEN_3_TURNS_AGO" };
void DoneScheduleAction( SOLDIERTYPE * pSoldier ) void DoneScheduleAction( SOLDIERTYPE * pSoldier )
@@ -812,7 +812,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo );
// Flugente: tanks do not care about gas // Flugente: tanks do not care about gas
if ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
bInGas = FALSE; bInGas = FALSE;
} }
@@ -1135,6 +1135,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
pSoldier->aiData.bLastAction != AI_ACTION_CLIMB_ROOF && pSoldier->aiData.bLastAction != AI_ACTION_CLIMB_ROOF &&
pSoldier->aiData.bOrders != STATIONARY && pSoldier->aiData.bOrders != STATIONARY &&
pSoldier->pathing.bLevel == 0 && pSoldier->pathing.bLevel == 0 &&
!ENEMYROBOT(pSoldier) &&
!is_networked) !is_networked)
{ {
iChance = 10 + pSoldier->aiData.bBypassToGreen; iChance = 10 + pSoldier->aiData.bBypassToGreen;
@@ -2099,7 +2100,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
AIPopMessage(tempstr); AIPopMessage(tempstr);
#endif #endif
if ( fClimb )//&& pSoldier->aiData.usActionData == sNoiseGridNo) if ( !ENEMYROBOT(pSoldier) && fClimb )//&& pSoldier->aiData.usActionData == sNoiseGridNo)
{ {
// need to climb AND have enough APs to get there this turn // need to climb AND have enough APs to get there this turn
BOOLEAN fUp = TRUE; BOOLEAN fUp = TRUE;
@@ -2258,7 +2259,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
AIPopMessage(tempstr); AIPopMessage(tempstr);
#endif #endif
if ( fClimb )//&& pSoldier->aiData.usActionData == sClosestFriend) if ( !ENEMYROBOT(pSoldier) && fClimb )//&& pSoldier->aiData.usActionData == sClosestFriend)
{ {
// need to climb AND have enough APs to get there this turn // need to climb AND have enough APs to get there this turn
BOOLEAN fUp = TRUE; BOOLEAN fUp = TRUE;
@@ -2593,7 +2594,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo );
// Flugente: tanks do not care about gas // Flugente: tanks do not care about gas
if ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
bInGas = FALSE; bInGas = FALSE;
} }
@@ -3047,6 +3048,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
(fAnyCover || // safe position (fAnyCover || // safe position
!fCanBeSeen && NightLight() && CountFriendsFlankSameSpot(pSoldier, sClosestOpponent) && Chance(50) || !fCanBeSeen && NightLight() && CountFriendsFlankSameSpot(pSoldier, sClosestOpponent) && Chance(50) ||
ARMED_VEHICLE(pSoldier) || // tanks don't need cover ARMED_VEHICLE(pSoldier) || // tanks don't need cover
ENEMYROBOT(pSoldier) || // robots don't try to be in cover
pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || MercPtrs[BestShot.ubOpponent]->sLastTarget == pSoldier->sGridNo) || // return fire pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || MercPtrs[BestShot.ubOpponent]->sLastTarget == pSoldier->sGridNo) || // return fire
Chance((BestShot.ubChanceToReallyHit + 100) / 2) || // 50% chance to fire without cover Chance((BestShot.ubChanceToReallyHit + 100) / 2) || // 50% chance to fire without cover
//SoldierToSoldierLineOfSightTest(pSoldier, MercPtrs[BestShot.ubOpponent], TRUE, CALC_FROM_ALL_DIRS)) && // can see target after turning //SoldierToSoldierLineOfSightTest(pSoldier, MercPtrs[BestShot.ubOpponent], TRUE, CALC_FROM_ALL_DIRS)) && // can see target after turning
@@ -3054,6 +3056,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
// reduce chance to shoot if target is beyond weapon range // reduce chance to shoot if target is beyond weapon range
(AICheckIsMachinegunner(pSoldier) || (AICheckIsMachinegunner(pSoldier) ||
ARMED_VEHICLE(pSoldier) || ARMED_VEHICLE(pSoldier) ||
ENEMYROBOT(pSoldier) ||
AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) || AnyCoverAtSpot(pSoldier, pSoldier->sGridNo) ||
pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || MercPtrs[BestShot.ubOpponent]->sLastTarget == pSoldier->sGridNo) || // return fire pSoldier->aiData.bUnderFire && (pSoldier->ubPreviousAttackerID == BestShot.ubOpponent || pSoldier->ubNextToPreviousAttackerID == BestShot.ubOpponent || MercPtrs[BestShot.ubOpponent]->sLastTarget == pSoldier->sGridNo) || // return fire
Chance(100 * (GunRange(&pSoldier->inv[BestShot.bWeaponIn], pSoldier) / CELL_X_SIZE) / PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget))) && Chance(100 * (GunRange(&pSoldier->inv[BestShot.bWeaponIn], pSoldier) / CELL_X_SIZE) / PythSpacesAway(pSoldier->sGridNo, BestShot.sTarget))) &&
@@ -4025,7 +4028,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
AIPopMessage(tempstr); AIPopMessage(tempstr);
#endif #endif
if (fClimb)//&& pSoldier->aiData.usActionData == sClosestDisturbance) if (!ENEMYROBOT(pSoldier) && fClimb)//&& pSoldier->aiData.usActionData == sClosestDisturbance)
{ {
// need to climb AND have enough APs to get there this turn // need to climb AND have enough APs to get there this turn
BOOLEAN fUp = TRUE; BOOLEAN fUp = TRUE;
@@ -4297,7 +4300,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier)
AIPopMessage(tempstr); AIPopMessage(tempstr);
#endif #endif
if ( fClimb )//&& pSoldier->aiData.usActionData == sClosestFriend) if ( !ENEMYROBOT(pSoldier) && fClimb )//&& pSoldier->aiData.usActionData == sClosestFriend)
{ {
// need to climb AND have enough APs to get there this turn // need to climb AND have enough APs to get there this turn
BOOLEAN fUp = TRUE; BOOLEAN fUp = TRUE;
@@ -5039,7 +5042,7 @@ INT16 ubMinAPCost;
bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo );
// Flugente: tanks do not care about gas // Flugente: tanks do not care about gas
if ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
bInGas = FALSE; bInGas = FALSE;
} }
@@ -5162,7 +5165,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 && !ARMED_VEHICLE( pSoldier ) ) if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( 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 )
{ {
@@ -5553,7 +5556,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 && !ARMED_VEHICLE( pSoldier ) && !(pSoldier->flags.uiStatusFlags & (SOLDIER_DRIVER | SOLDIER_PASSENGER)) ) if ( bWeaponIn != NO_SLOT && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( 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;
@@ -5641,7 +5644,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 ( !ARMED_VEHICLE( pSoldier ) && !(pSoldier->flags.uiStatusFlags & (SOLDIER_DRIVER | SOLDIER_PASSENGER)) ) else if ( !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( 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
@@ -5860,7 +5863,7 @@ INT16 ubMinAPCost;
} }
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
} }
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 if ( BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE)) && !((ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( 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;
DebugAI(AI_MSG_INFO, pSoldier, String("best action = throw something, iAttackValue = %d", BestThrow.iAttackValue)); DebugAI(AI_MSG_INFO, pSoldier, String("best action = throw something, iAttackValue = %d", BestThrow.iAttackValue));
@@ -6310,7 +6313,7 @@ INT16 ubMinAPCost;
if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimAP + ubBurstAPs ) if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimAP + 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 ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
iChance = 100; iChance = 100;
} }
@@ -6427,7 +6430,7 @@ L_NEWAIM:
if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimAP + ubBurstAPs ) if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimAP + 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 ( ARMED_VEHICLE( pSoldier ) ) if ( ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
iChance = 100; iChance = 100;
} }
@@ -6765,7 +6768,7 @@ L_NEWAIM:
pSoldier->aiData.usActionData = GoAsFarAsPossibleTowards(pSoldier,sClosestOpponent,AI_ACTION_GET_CLOSER); pSoldier->aiData.usActionData = GoAsFarAsPossibleTowards(pSoldier,sClosestOpponent,AI_ACTION_GET_CLOSER);
// Flugente: if on the same level and there is a jumpable window here, jump through it // Flugente: if on the same level and there is a jumpable window here, jump through it
if ( gGameExternalOptions.fCanJumpThroughWindows ) if ( gGameExternalOptions.fCanJumpThroughWindows && !ENEMYROBOT(pSoldier) )
{ {
// determine if there is a jumpable window in the direction to our target // determine if there is a jumpable window in the direction to our target
// if yes, and we are not facing it, face it now // if yes, and we are not facing it, face it now
@@ -6813,14 +6816,14 @@ L_NEWAIM:
if (pSoldier->pathing.bLevel > 0 ) if (pSoldier->pathing.bLevel > 0 )
fUp = FALSE; fUp = FALSE;
if ( pSoldier->bActionPoints > GetAPsToClimbRoof ( pSoldier, fUp ) ) if ( !ENEMYROBOT(pSoldier) && (pSoldier->bActionPoints > GetAPsToClimbRoof ( pSoldier, fUp )) )
{ {
pSoldier->aiData.usActionData = targetGridNo;//FindClosestClimbPoint(pSoldier, fUp ); pSoldier->aiData.usActionData = targetGridNo;//FindClosestClimbPoint(pSoldier, fUp );
// Necessary test: can we climb up at this position? It might happen that our target is directly above us, then we'll have to move // Necessary test: can we climb up at this position? It might happen that our target is directly above us, then we'll have to move
INT8 newdirection; INT8 newdirection;
if ( ( fUp && FindHeigherLevel( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &newdirection ) ) || ( !fUp && FindLowerLevel( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &newdirection ) ) ) if ( ( fUp && FindHeigherLevel( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &newdirection ) ) || ( !fUp && FindLowerLevel( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &newdirection ) ) )
{ {
return( AI_ACTION_CLIMB_ROOF ); return( AI_ACTION_CLIMB_ROOF );
} }
else else
@@ -9586,7 +9589,7 @@ INT8 ArmedVehicleDecideActionBlack( SOLDIERTYPE *pSoldier )
// 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 && !ARMED_VEHICLE( pSoldier ) ) if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( 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 )
{ {
@@ -9859,7 +9862,7 @@ INT8 ArmedVehicleDecideActionBlack( SOLDIERTYPE *pSoldier )
BestAttack.iAttackValue = 0; BestAttack.iAttackValue = 0;
} }
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 if ( BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE)) && !((ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( 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" );
+4 -4
View File
@@ -1621,7 +1621,7 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
sNewWoundAmt = (INT16)(sNewWoundAmt * (100 + gSkillTraitValues.ubDEDamageOfBombsAndMines) / 100.0f + 0.5f); sNewWoundAmt = (INT16)(sNewWoundAmt * (100 + gSkillTraitValues.ubDEDamageOfBombsAndMines) / 100.0f + 0.5f);
} }
// Heavy Weapons trait bonus damage to tanks // Heavy Weapons trait bonus damage to tanks
if ( HAS_SKILL_TRAIT( MercPtrs[ubOwner], HEAVY_WEAPONS_NT ) && ARMED_VEHICLE( pSoldier ) && if ( HAS_SKILL_TRAIT( MercPtrs[ubOwner], HEAVY_WEAPONS_NT ) && (ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( 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.0f + 0.5f); // +30% sNewWoundAmt = (INT16)(sNewWoundAmt * (100 + gSkillTraitValues.ubHWDamageTanksBonusPercent * NUM_SKILL_TRAITS( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT )) / 100.0f + 0.5f); // +30%
@@ -1656,7 +1656,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) && !ARMED_VEHICLE( pSoldier ) && !AM_A_ROBOT( pSoldier ) && !(pSoldier->flags.uiStatusFlags & SOLDIER_MONSTER) && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( pSoldier ) &&
sNewWoundAmt > 2 && sNewWoundAmt < pSoldier->stats.bLife ) sNewWoundAmt > 2 && sNewWoundAmt < pSoldier->stats.bLife )
{ {
if ( PreRandom( sNewWoundAmt ) > gSkillTraitValues.ubDamageNeededToLoseStats ) if ( PreRandom( sNewWoundAmt ) > gSkillTraitValues.ubDamageNeededToLoseStats )
@@ -1923,7 +1923,7 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
FLOAT fGasBreathDamageModifier = 1.0; FLOAT fGasBreathDamageModifier = 1.0;
INT8 bPosOfMask = NO_SLOT; INT8 bPosOfMask = NO_SLOT;
if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->stats.bLife || AM_A_ROBOT( pSoldier ) ) if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->stats.bLife || AM_A_ROBOT( pSoldier ) || ENEMYROBOT( pSoldier ) )
{ {
return( fRecompileMovementCosts ); return( fRecompileMovementCosts );
} }
@@ -4732,7 +4732,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] ) && !ARMED_VEHICLE( MercPtrs[ubID] ) ) if ( !(MercPtrs[ubID]->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( MercPtrs[ubID] ) && !ARMED_VEHICLE( MercPtrs[ubID] ) && !ENEMYROBOT( MercPtrs[ubID] ) )
continue; continue;
} }
+1 -1
View File
@@ -4,7 +4,7 @@
//#include "Soldier Control.h" //#include "Soldier Control.h"
//#include "mousesystem.h" //#include "mousesystem.h"
typedef struct _MOUSE_REGION MOUSE_REGION; typedef struct _MOUSE_REGION MOUSE_REGION;
extern class SOLDIERTYPE; class SOLDIERTYPE;
void InitTacticalPlacementGUI(); void InitTacticalPlacementGUI();
void KillTacticalPlacementGUI(); void KillTacticalPlacementGUI();
+1
View File
@@ -1885,6 +1885,7 @@ enum
STR_MILITIAMOVEMENT_NO_LIMITEDROAMING, STR_MILITIAMOVEMENT_NO_LIMITEDROAMING,
STR_MILITIAMOVEMENT_NO_STAFF_ABORT, STR_MILITIAMOVEMENT_NO_STAFF_ABORT,
STR_AR_ROBOT_NAME,
STR_AR_TANK_NAME, STR_AR_TANK_NAME,
STR_AR_JEEP_NAME, STR_AR_JEEP_NAME,
+1
View File
@@ -3524,6 +3524,7 @@ STR16 gpStrategicString[] =
L"民兵无法移动到这。(RESTRICT_ROAMING = TRUE", //L"Militia cannot move here (RESTRICT_ROAMING = TRUE).", L"民兵无法移动到这。(RESTRICT_ROAMING = TRUE", //L"Militia cannot move here (RESTRICT_ROAMING = TRUE).",
L"战术中心无人兼职,民兵移动失败!", //L"War room isn't staffed - militia move aborted!", L"战术中心无人兼职,民兵移动失败!", //L"War room isn't staffed - militia move aborted!",
L"Robot", //STR_AR_ROBOT_NAME, TODO: translate
L"坦克", //STR_AR_TANK_NAME, L"坦克", //STR_AR_TANK_NAME,
L"吉普", // L"Jeep", STR_AR_JEEP_NAME L"吉普", // L"Jeep", STR_AR_JEEP_NAME
+1
View File
@@ -3524,6 +3524,7 @@ STR16 gpStrategicString[] =
L"Militia cannot move here (RESTRICT_ROAMING = TRUE).", L"Militia cannot move here (RESTRICT_ROAMING = TRUE).",
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Robot", //STR_AR_ROBOT_NAME, TODO: translate
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
+1
View File
@@ -3537,6 +3537,7 @@ STR16 gpStrategicString[] =
L"Militia cannot move here (RESTRICT_ROAMING = TRUE).", L"Militia cannot move here (RESTRICT_ROAMING = TRUE).",
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Robot", //STR_AR_ROBOT_NAME,
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME, L"Jeep", //STR_AR_JEEP_NAME,
+1
View File
@@ -3532,6 +3532,7 @@ STR16 gpStrategicString[] =
L"La milice ne peut pas se déplacer (RESTRICT_ROAMING = TRUE).", L"La milice ne peut pas se déplacer (RESTRICT_ROAMING = TRUE).",
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"Robot", //STR_AR_ROBOT_NAME, // TODO: translate
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"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
+1
View File
@@ -3561,6 +3561,7 @@ STR16 gpStrategicString[] =
L"Militia cannot move here (RESTRICT_ROAMING = TRUE).", L"Militia cannot move here (RESTRICT_ROAMING = TRUE).",
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Robot", //STR_AR_ROBOT_NAME, // TODO: translate
L"Panzer", //STR_AR_TANK_NAME, L"Panzer", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
+1
View File
@@ -3519,6 +3519,7 @@ STR16 gpStrategicString[] =
L"Militia cannot move here (RESTRICT_ROAMING = TRUE).", L"Militia cannot move here (RESTRICT_ROAMING = TRUE).",
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Robot", //STR_AR_ROBOT_NAME, TODO: translate
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
+1
View File
@@ -3530,6 +3530,7 @@ STR16 gpStrategicString[] =
L"Militia cannot move here (RESTRICT_ROAMING = TRUE).", L"Militia cannot move here (RESTRICT_ROAMING = TRUE).",
L"War room isn't staffed - militia move aborted!", L"War room isn't staffed - militia move aborted!",
L"Robot", //STR_AR_ROBOT_NAME, // TODO: translate
L"Tank", //STR_AR_TANK_NAME, L"Tank", //STR_AR_TANK_NAME,
L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate L"Jeep", //STR_AR_JEEP_NAME // TODO.Translate
+1
View File
@@ -3524,6 +3524,7 @@ STR16 gpStrategicString[] =
L"Ополчение не может быть сюда перемещено (RESTRICT_ROAMING = TRUE).", L"Ополчение не может быть сюда перемещено (RESTRICT_ROAMING = TRUE).",
L"War room isn't staffed - militia move aborted!", // TODO.Translate L"War room isn't staffed - militia move aborted!", // TODO.Translate
L"Робот", //STR_AR_ROBOT_NAME, TODO: translate
L"Танк", //STR_AR_TANK_NAME, L"Танк", //STR_AR_TANK_NAME,
L"Джип", //STR_AR_JEEP_NAME L"Джип", //STR_AR_JEEP_NAME
+2 -1
View File
@@ -159,8 +159,9 @@ static int LuaGroupCreate( lua_State *L )
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 ); UINT8 NumJeeps = (UINT8)luaL_checkinteger( L, 6 );
UINT8 NumRobots = (UINT8)luaL_checkinteger( L, 7);
GROUP *pGroup = CreateNewEnemyGroupDepartingFromSector( Sector, NumAdmins, NumTroops, NumElites, NumTanks, NumJeeps ); GROUP *pGroup = CreateNewEnemyGroupDepartingFromSector( Sector, NumAdmins, NumTroops, NumElites, NumRobots, NumTanks, NumJeeps );
if (pGroup) if (pGroup)
{ {
+11 -10
View File
@@ -107,6 +107,7 @@ void RandomAddEnemy( UINT8 SectorX, UINT8 SectorY, UINT8 Level )
UINT8 ubNumElites = 0; UINT8 ubNumElites = 0;
UINT8 ubNumTanks = 0; UINT8 ubNumTanks = 0;
UINT8 ubNumJeeps = 0; UINT8 ubNumJeeps = 0;
UINT8 ubNumRobots = 0;
if ( Level != 0 ) if ( Level != 0 )
{ {
@@ -121,31 +122,31 @@ void RandomAddEnemy( UINT8 SectorX, UINT8 SectorY, UINT8 Level )
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
break; break;
case DIF_LEVEL_HARD: case DIF_LEVEL_HARD:
ubNumAdmins = Random( 0 ); ubNumAdmins = Random( 0 );
ubNumTroops = 20 + Random( 7 ); ubNumTroops = 20 + Random( 7 );
ubNumElites = 2 + Random( 2 ); ubNumElites = 2 + Random( 2 );
SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
break; break;
} }
} }
@@ -161,31 +162,31 @@ void RandomAddEnemy( UINT8 SectorX, UINT8 SectorY, UINT8 Level )
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
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, ubNumJeeps ); SetNumberJa25EnemiesInSector( SectorX, SectorY, Level, ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks, ubNumJeeps, ubNumRobots );
break; break;
} }
} }