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

This is savegame compatible. GameDir >= r2305 required.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8114 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2016-03-20 18:45:51 +00:00
parent b8c0036396
commit 9e97538d89
75 changed files with 1614 additions and 772 deletions
+36 -4
View File
@@ -1118,6 +1118,7 @@ ANI_SPEED_DEF gubAnimWalkSpeeds[ TOTALBODYTYPES ] =
-10, (FLOAT)4.0, //ELDORADO
-10, (FLOAT)4.0, //ICECREAMTRUCK
-10, (FLOAT)4.0, //JEEP
-10, (FLOAT)4.0, //COMBAT_JEEP
};
extern INT16 gubMaxActionPoints[TOTALBODYTYPES] = {0};
@@ -3592,7 +3593,10 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ TANK_NW ][ TANK_SHOOT ] = TANKNW_SHOOT;
gubAnimSurfaceIndex[ TANK_NW ][ TANK_BURST ] = TANKNW_SHOOT;
gubAnimSurfaceIndex[ TANK_NW ][ VEHICLE_DIE ] = TANKNW_DIE;
gubAnimSurfaceCorpseID[ TANK_NW ][ STANDING ] = TANK1_DEAD;
gubAnimSurfaceCorpseID[TANK_NW][STANDING] = TANK1_DEAD;
gubAnimSurfaceCorpseID[TANK_NW][WALKING] = TANK1_DEAD;
gubAnimSurfaceCorpseID[TANK_NW][RUNNING] = TANK1_DEAD;
gubAnimSurfaceCorpseID[TANK_NW][WALK_BACKWARDS] = TANK1_DEAD;
// TANK
gubAnimSurfaceIndex[ TANK_NE ][ STANDING ] = TANKNE_READY;
@@ -3603,6 +3607,9 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ TANK_NE ][ TANK_BURST ] = TANKNE_SHOOT;
gubAnimSurfaceIndex[ TANK_NE ][ VEHICLE_DIE ] = TANKNE_DIE;
gubAnimSurfaceCorpseID[ TANK_NE ][ STANDING ] = TANK2_DEAD;
gubAnimSurfaceCorpseID[ TANK_NE ][WALKING] = TANK2_DEAD;
gubAnimSurfaceCorpseID[ TANK_NE ][RUNNING] = TANK2_DEAD;
gubAnimSurfaceCorpseID[ TANK_NE ][WALK_BACKWARDS] = TANK2_DEAD;
// ELDORADO
gubAnimSurfaceIndex[ ELDORADO ][ STANDING ] = ELDORADO_BASIC;
@@ -3610,21 +3617,45 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ ELDORADO ][ RUNNING ] = ELDORADO_BASIC;
gubAnimSurfaceIndex[ ELDORADO ][ WALK_BACKWARDS ] = ELDORADO_BASIC;
gubAnimSurfaceIndex[ ELDORADO ][ VEHICLE_DIE ] = ELDORADO_DIE;
gubAnimSurfaceCorpseID[ELDORADO][STANDING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ELDORADO][WALKING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ELDORADO][RUNNING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ELDORADO][WALK_BACKWARDS] = ICECREAM_DEAD;
// ICECREAMTRUCK
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ STANDING ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ WALKING ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ RUNNING ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ WALK_BACKWARDS ] = ICECREAMTRUCK_BASIC;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ VEHICLE_DIE ] = HUMVEE_DIE;
gubAnimSurfaceCorpseID[ ICECREAMTRUCK ][ STANDING ] = ICECREAM_DEAD;
gubAnimSurfaceIndex[ ICECREAMTRUCK ][ VEHICLE_DIE ] = HUMVEE_DIE;
gubAnimSurfaceCorpseID[ICECREAMTRUCK][STANDING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ICECREAMTRUCK][WALKING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ICECREAMTRUCK][RUNNING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[ICECREAMTRUCK][WALK_BACKWARDS] = ICECREAM_DEAD;
// JEEP
gubAnimSurfaceIndex[ JEEP ][ STANDING ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ WALKING ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ RUNNING ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ WALK_BACKWARDS ] = JEEP_BASIC;
gubAnimSurfaceIndex[ JEEP ][ VEHICLE_DIE ] = JEEP_DIE;
gubAnimSurfaceIndex[ JEEP ][ VEHICLE_DIE ] = JEEP_DIE;
gubAnimSurfaceCorpseID[JEEP][STANDING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[JEEP][WALKING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[JEEP][RUNNING] = ICECREAM_DEAD;
gubAnimSurfaceCorpseID[JEEP][WALK_BACKWARDS] = ICECREAM_DEAD;
// COMBAT_JEEP
gubAnimSurfaceIndex[COMBAT_JEEP][STANDING] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][WALKING] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][RUNNING] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][WALK_BACKWARDS] = ARMED_CAR_READY;
gubAnimSurfaceIndex[COMBAT_JEEP][TANK_SHOOT] = ARMED_CAR_SHOOT;
gubAnimSurfaceIndex[COMBAT_JEEP][TANK_BURST] = ARMED_CAR_SHOOT;
gubAnimSurfaceIndex[COMBAT_JEEP][VEHICLE_DIE] = ARMED_CAR_DIE;
gubAnimSurfaceCorpseID[COMBAT_JEEP][STANDING] = HUMMER_DEAD;
gubAnimSurfaceCorpseID[COMBAT_JEEP][WALKING] = HUMMER_DEAD;
gubAnimSurfaceCorpseID[COMBAT_JEEP][RUNNING] = HUMMER_DEAD;
gubAnimSurfaceCorpseID[COMBAT_JEEP][WALK_BACKWARDS] = HUMMER_DEAD;
}
BOOLEAN LoadAnimationStateInstructions( )
@@ -3991,6 +4022,7 @@ INT8 GetBodyTypePaletteSubstitutionCode( SOLDIERTYPE *pSoldier, UINT8 ubBodyType
case ROBOTNOWEAPON:
case TANK_NW:
case TANK_NE:
case COMBAT_JEEP:
return( 0 );
}
+11
View File
@@ -472,6 +472,10 @@ AnimationSurfaceType gAnimSurfaceDatabase[ NUMANIMATIONSURFACETYPES ] =
JEEP_BASIC, "ANIMS\\VEHICLES\\JEEP.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
JEEP_DIE, "ANIMS\\VEHICLES\\HM_WREK.STI", NO_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1,
ARMED_CAR_READY, "ANIMS\\VEHICLES\\LATV_ROT.STI", S_STRUCT, ANIM_DATA_FLAG_NOFRAMES, 32, TO_INIT, NULL, NULL, 0, -1,
ARMED_CAR_SHOOT, "ANIMS\\VEHICLES\\LATV_SHT.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
ARMED_CAR_DIE, "ANIMS\\VEHICLES\\LATV_DIE.STI", S_STRUCT, 0, 2, TO_INIT, NULL, NULL, 0, -1,
BODYEXPLODE, "ANIMS\\S_MERC\\BOD_BLOW.STI", NO_STRUCT, 0, 1, TO_INIT, NULL, NULL, 0, -1,
//<SB> crouch throwing
@@ -802,6 +806,13 @@ AnimationStructureType gAnimStructureDatabase[ TOTALBODYTYPES ][ NUM_STRUCT_IDS
"ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
//COMBAT_JEEP
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
};
+5
View File
@@ -66,6 +66,7 @@ enum SoldierBodyTypes
ELDORADO,
ICECREAMTRUCK,
JEEP,
COMBAT_JEEP, // Flugente, smeagol & DepressivesBrot: lightly armored tactical vehicle
TOTALBODYTYPES
@@ -503,6 +504,10 @@ typedef enum
JEEP_BASIC,
JEEP_DIE,
ARMED_CAR_READY,
ARMED_CAR_SHOOT,
ARMED_CAR_DIE,
BODYEXPLODE,
//<SB> crouch throwing
+1
View File
@@ -321,6 +321,7 @@ void DoneFadeOutKilledQueen( void )
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubTroopsInBattle = 0;
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubElitesInBattle = 0;
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubTanksInBattle = 0;
SectorInfo[ SECTOR( VICTORY_X, VICTORY_Y ) ].ubJeepsInBattle = 0;
// ATE: banish elliot... dead or alive
gMercProfiles[ ELLIOT ].sSectorX = 0;
+49 -17
View File
@@ -44,7 +44,7 @@ int gCivPreservedTempFileVersion[256];
BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *pNode, GROUP *pGroup = NULL );
BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks );
BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
BOOLEAN gfRestoringEnemySoldiersFromTempFile = FALSE;
BOOLEAN gfRestoringCiviliansFromTempFile = FALSE;
@@ -105,8 +105,8 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
#endif
INT8 bSectorZ;
UINT8 ubSectorID;
UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks;
UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0, ubNumJeeps = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps;
gfRestoringEnemySoldiersFromTempFile = TRUE;
@@ -255,6 +255,7 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
ubStrategicTroops = pSector->ubNumTroops;
ubStrategicAdmins = pSector->ubNumAdmins;
ubStrategicTanks = pSector->ubNumTanks;
ubStrategicJeeps = pSector->ubNumJeeps;
ubStrategicCreatures = pSector->ubNumCreatures;
}
else
@@ -262,7 +263,7 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
SECTORINFO *pSector;
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubStrategicCreatures = pSector->ubNumCreatures;
GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks );
GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks, &ubStrategicJeeps );
}
for( i = 0; i < slots; i++ )
@@ -359,6 +360,16 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
}
}
break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( curr->pBasicPlacement ) )
{
++ubNumJeeps;
if ( ubNumJeeps < ubStrategicJeeps )
{
AddPlacementToWorld( curr );
}
}
break;
}
break;
}
@@ -386,14 +397,16 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
}
//now add any extra enemies that have arrived since the temp file was made.
if( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks )
if ( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks || ubStrategicJeeps > ubNumJeeps )
{
ubStrategicTroops = ( ubStrategicTroops > ubNumTroops ) ? ubStrategicTroops - ubNumTroops : 0;
ubStrategicElites = ( ubStrategicElites > ubNumElites ) ? ubStrategicElites - ubNumElites : 0;
ubStrategicAdmins = ( ubStrategicAdmins > ubNumAdmins ) ? ubStrategicAdmins - ubNumAdmins : 0;
ubStrategicTanks = ( ubStrategicTanks > ubNumTanks ) ? ubStrategicTanks - ubNumTanks : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks );
ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks, ubStrategicJeeps );
}
if( ubStrategicCreatures > ubNumCreatures )
{
ubStrategicCreatures; //not sure if this wil ever happen. If so, needs to be handled.
@@ -675,8 +688,8 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
#endif
INT8 bSectorZ;
UINT8 ubSectorID;
UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks;
UINT8 ubNumElites = 0, ubNumTroops = 0, ubNumAdmins = 0, ubNumCreatures = 0, ubNumTanks = 0, ubNumJeeps = 0;
UINT8 ubStrategicElites, ubStrategicTroops, ubStrategicAdmins, ubStrategicCreatures, ubStrategicTanks, ubStrategicJeeps;
gfRestoringEnemySoldiersFromTempFile = TRUE;
@@ -716,16 +729,17 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
ubNumTroops = pSector->ubNumTroops;
ubNumAdmins = pSector->ubNumAdmins;
ubNumTanks = pSector->ubNumTanks;
ubNumJeeps = pSector->ubNumJeeps;
ubNumCreatures = pSector->ubNumCreatures;
}
if( !( gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{
// Get the number of enemies form the temp file
CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( &ubStrategicElites, &ubStrategicTroops, &ubStrategicAdmins, &ubStrategicCreatures, &ubStrategicTanks );
CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( &ubStrategicElites, &ubStrategicTroops, &ubStrategicAdmins, &ubStrategicCreatures, &ubStrategicTanks, &ubStrategicJeeps );
//If any of the counts differ from what is in memory
if( ubStrategicElites != ubNumElites || ubStrategicTroops != ubNumTroops || ubStrategicAdmins != ubNumAdmins || ubStrategicCreatures != ubNumCreatures || ubStrategicTanks != ubNumTanks )
if ( ubStrategicElites != ubNumElites || ubStrategicTroops != ubNumTroops || ubStrategicAdmins != ubNumAdmins || ubStrategicCreatures != ubNumCreatures || ubStrategicTanks != ubNumTanks || ubStrategicJeeps != ubNumJeeps )
{
//remove the file
RemoveEnemySoldierTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
@@ -734,7 +748,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
}
//reset
ubNumElites = ubNumTroops = ubNumAdmins = ubNumCreatures = ubNumTanks = 0;
ubNumElites = ubNumTroops = ubNumAdmins = ubNumCreatures = ubNumTanks = ubNumJeeps = 0;
//Open the file for reading
@@ -875,6 +889,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
ubStrategicTroops = pSector->ubNumTroops;
ubStrategicAdmins = pSector->ubNumAdmins;
ubStrategicTanks = pSector->ubNumTanks;
ubStrategicJeeps = pSector->ubNumJeeps;
ubStrategicCreatures = pSector->ubNumCreatures;
}
else
@@ -882,7 +897,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
SECTORINFO *pSector;
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubStrategicCreatures = pSector->ubNumCreatures;
GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks );
GetNumberOfEnemiesInSector( sSectorX, sSectorY, &ubStrategicAdmins, &ubStrategicTroops, &ubStrategicElites, &ubStrategicTanks, &ubStrategicJeeps );
}
for( i = 0; i < slots; i++ )
@@ -969,6 +984,16 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
}
}
break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( curr->pBasicPlacement ) )
{
++ubNumJeeps;
if ( ubNumJeeps <= ubStrategicJeeps )
{
//def: AddPlacementToWorld( curr );
}
}
break;
}
break;
}
@@ -994,21 +1019,21 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
}
//now add any extra enemies that have arrived since the temp file was made.
if( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks )
if ( ubStrategicTroops > ubNumTroops || ubStrategicElites > ubNumElites || ubStrategicAdmins > ubNumAdmins || ubStrategicTanks > ubNumTanks || ubStrategicJeeps > ubNumJeeps )
{
ubStrategicTroops = ( ubStrategicTroops > ubNumTroops ) ? ubStrategicTroops - ubNumTroops : 0;
ubStrategicElites = ( ubStrategicElites > ubNumElites ) ? ubStrategicElites - ubNumElites : 0;
ubStrategicAdmins = ( ubStrategicAdmins > ubNumAdmins ) ? ubStrategicAdmins - ubNumAdmins : 0;
ubStrategicTanks = ( ubStrategicTanks > ubNumTanks ) ? ubStrategicTanks - ubNumTanks : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks );
ubStrategicJeeps = (ubStrategicJeeps > ubNumJeeps) ? ubStrategicJeeps - ubNumJeeps : 0;
AddSoldierInitListEnemyDefenceSoldiers( ubStrategicAdmins, ubStrategicTroops, ubStrategicElites, ubStrategicTanks, ubStrategicJeeps );
}
if( ubStrategicCreatures > ubNumCreatures )
{
ubStrategicCreatures; //not sure if this wil ever happen. If so, needs to be handled.
}
//set the number of enemies in the sector
if( bSectorZ )
{
@@ -1593,7 +1618,7 @@ BOOLEAN NewWayOfSavingEnemyAndCivliansToTempFile( INT16 sSectorX, INT16 sSectorY
BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks )
BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile( UINT8 *pubNumElites, UINT8 *pubNumRegulars, UINT8 *pubNumAdmins, UINT8 *pubNumCreatures, UINT8 *pubNumTanks, UINT8 *pubNumJeeps )
{
// SOLDIERINITNODE *curr;
SOLDIERCREATE_STRUCT tempDetailedPlacement;
@@ -1617,6 +1642,7 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
*pubNumRegulars = 0;
*pubNumAdmins = 0;
*pubNumTanks = 0;
*pubNumJeeps = 0;
*pubNumCreatures = 0;
//STEP ONE: Set up the temp file to read from.
@@ -1785,6 +1811,12 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
(*pubNumTanks)++;
}
break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( (&tempDetailedPlacement) ) )
{
(*pubNumJeeps)++;
}
break;
}
/*
while( curr )
+3
View File
@@ -5315,6 +5315,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
}
}
#include "Strategic AI.h"
// Flugente: callback after deciding what tactical function to use
void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue )
{
@@ -5356,6 +5357,8 @@ void TacticalFunctionSelectionMessageBoxCallBack( UINT8 ubExitValue )
break;
case 8:
ExecuteStrategicAIAction( NPC_ACTION_SEND_SOLDIERS_TO_DRASSEN, 0, 0 );
break;
default:
break;
}
+79 -4
View File
@@ -1156,13 +1156,21 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
return( GAME_SCREEN );
}
usRandom = (UINT16)Random( 12 );
if( usRandom < 3 )
// Flugente hack
/*if ( Water(usMapPos) )
pSoldier = TacticalCreateEnemyBoat( );
else
pSoldier = TacticalCreateEnemyJeep( );*/
usRandom = (UINT16)Random( 20 );
if( usRandom < 5 )
pSoldier = TacticalCreateAdministrator();
else if( usRandom < 6 )
else if( usRandom < 10 )
pSoldier = TacticalCreateArmyTroop();
else if ( usRandom < 9 )
else if ( usRandom < 12 )
pSoldier = TacticalCreateEnemyTank( );
else if ( usRandom < 15 )
pSoldier = TacticalCreateEnemyJeep( );
else
pSoldier = TacticalCreateEliteEnemy( );
@@ -1178,6 +1186,7 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
case SOLDIER_CLASS_TANK: pSector->ubNumTanks++; pSector->ubTanksInBattle++; break;
case SOLDIER_CLASS_JEEP: pSector->ubNumJeeps++; pSector->ubJeepsInBattle++; break;
}
}
else
@@ -1191,6 +1200,7 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
case SOLDIER_CLASS_TANK: pSector->ubNumTanks++; pSector->ubTanksInBattle++; break;
case SOLDIER_CLASS_JEEP: pSector->ubNumJeeps++; pSector->ubJeepsInBattle++; break;
}
}
}
@@ -1205,6 +1215,71 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
return( GAME_SCREEN );
}
/*void TankBattlefun()
{
int teamsize = 1;
for ( int i = 0; i < teamsize; ++i)
{
{
SOLDIERTYPE *pSoldier = TacticalCreateTankFuntime(ENEMY_TEAM);
if( pSoldier )
{
if( !gbWorldSectorZ )
{
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
switch( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
}
}
else
{
UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
if( pSector )
{
switch( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
}
}
}
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
//pSoldier->usStrategicInsertionData = gMapInformation.sSouthGridNo;
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
AllTeamsLookForAll( NO_INTERRUPTS );
}
}
{
SOLDIERTYPE *pSoldier = TacticalCreateTankFuntime(MILITIA_TEAM);
if( pSoldier )
{
pSoldier->ubSoldierClass = SOLDIER_CLASS_ELITE_MILITIA;
if( !gbWorldSectorZ )
{
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
pSector->ubNumberOfCivsAtLevel[ELITE_MILITIA]++;
}
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_SOUTH;
//pSoldier->usStrategicInsertionData = gMapInformation.sSouthGridNo;
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
AllTeamsLookForAll( NO_INTERRUPTS );
}
}
}
}*/
UINT32 UIHandleEnterEditMode( UI_EVENT *pUIEvent )
{
+3 -3
View File
@@ -2365,7 +2365,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
/////////////////// ANTI-TANK AMMO
if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank )
if ( AmmoTypes[Magazine[Item[gpItemDescObject->usItem].ubClassIndex].ubAmmoType].dDamageModifierTank >= 0.1f )
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 1 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 1 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -5946,8 +5946,8 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
}
/////////////////// ANTI-TANK AMMO
if ( ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank && !fComparisonMode ) ||
( fComparisonMode && AmmoTypes[Magazine[Item[ gpComparedItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank ) )
if ( (AmmoTypes[Magazine[Item[gpItemDescObject->usItem].ubClassIndex].ubAmmoType].dDamageModifierTank >= 0.1f && !fComparisonMode) ||
(fComparisonMode && AmmoTypes[Magazine[Item[gpComparedItemDescObject->usItem].ubClassIndex].ubAmmoType].dDamageModifierTank >= 0.1f ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 1, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
+1 -1
View File
@@ -2024,7 +2024,7 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
swprintf( NameStr, zGrod[0] );
}
//Legion
else if ( TANK( pSoldier ) )
else if ( ARMED_VEHICLE( pSoldier ) )
{
swprintf( NameStr, gNewVehicle[164].NewVehicleStrings );
}
+26 -18
View File
@@ -91,7 +91,7 @@ ARMY_GUN_CHOICE_TYPE gExtendedArmyGunChoices[SOLDIER_GUN_CHOICE_SELECTIONS][ARMY
ARMY_GUN_CHOICE_TYPE gArmyItemChoices[SOLDIER_GUN_CHOICE_SELECTIONS][MAX_ITEM_TYPES];
void RandomlyChooseWhichItemsAreDroppable( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass );
void EquipTank( SOLDIERCREATE_STRUCT *pp );
void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp, BOOLEAN fTank = TRUE );
void ChooseKitsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bKitClass );
void ChooseMiscGearForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bMiscClass );
@@ -251,13 +251,13 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
return;
}
if ( TANK( pp ) )
if ( ARMED_VEHICLE( pp ) )
{
EquipTank( pp );
EquipArmouredVehicle( pp, TANK( pp ) );
return;
}
Assert( ( bSoldierClass >= SOLDIER_CLASS_NONE ) && ( bSoldierClass <= SOLDIER_CLASS_ELITE_MILITIA ) || bSoldierClass == SOLDIER_CLASS_TANK );
Assert( (bSoldierClass >= SOLDIER_CLASS_NONE) && (bSoldierClass <= SOLDIER_CLASS_ELITE_MILITIA) || bSoldierClass == SOLDIER_CLASS_TANK || bSoldierClass == SOLDIER_CLASS_JEEP );
Assert( ( bEquipmentRating >= 0 ) && ( bEquipmentRating <= 4 ) );
// equipment level is modified by 1/10 of the difficulty percentage, -5, so it's between -5 to +5
@@ -3406,24 +3406,33 @@ UINT16 SelectStandardArmyGun( UINT8 uiGunLevel, INT8 bSoldierClass )
void EquipTank( SOLDIERCREATE_STRUCT *pp )
void EquipArmouredVehicle( SOLDIERCREATE_STRUCT *pp, BOOLEAN fTank )
{
// tanks get special equipment, and they drop nothing (MGs are hard-mounted & non-removable)
// main cannon
CreateItem( TANK_CANNON, ( INT8 )( 80 + Random( 21 ) ), &( pp->Inv[ HANDPOS ]) );
pp->Inv[ HANDPOS ].fFlags |= OBJECT_UNDROPPABLE;
// tanks get a main cannon and a MG, other vehicles just get the MG
if ( fTank )
{
CreateItem( TANK_CANNON, ( INT8 )( 80 + Random( 21 ) ), &( pp->Inv[ HANDPOS ]) );
pp->Inv[ HANDPOS ].fFlags |= OBJECT_UNDROPPABLE;
// machine gun
CreateItems( MINIMI, ( INT8 )( 80 + Random( 21 ) ), 1, &gTempObject );
gTempObject.fFlags |= OBJECT_UNDROPPABLE;
PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
// tanks don't deplete shells or ammo...
CreateItems( TANK_SHELL, 100, 1, &gTempObject );
gTempObject.fFlags |= OBJECT_UNDROPPABLE;
PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
// tanks don't deplete shells or ammo...
CreateItems( TANK_SHELL, 100, 1, &gTempObject );
gTempObject.fFlags |= OBJECT_UNDROPPABLE;
PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
// machine gun
CreateItems( MINIMI, (INT8)(80 + Random( 21 )), 1, &gTempObject );
gTempObject.fFlags |= OBJECT_UNDROPPABLE;
PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
}
else
{
// machine gun
CreateItems( MINIMI, (INT8)(80 + Random( 21 )), 1, &(pp->Inv[HANDPOS]) );
pp->Inv[HANDPOS].fFlags |= OBJECT_UNDROPPABLE;
}
// armour equal to spectra all over (for vs explosives)
CreateItem( SPECTRA_VEST, 100, &(pp->Inv[ VESTPOS ]) );
pp->Inv[ VESTPOS ].fFlags |= OBJECT_UNDROPPABLE;
@@ -3431,7 +3440,6 @@ void EquipTank( SOLDIERCREATE_STRUCT *pp )
pp->Inv[ HELMETPOS ].fFlags |= OBJECT_UNDROPPABLE;
CreateItem( SPECTRA_LEGGINGS, 100, &(pp->Inv[ LEGPOS ]) );
pp->Inv[ LEGPOS ].fFlags |= OBJECT_UNDROPPABLE;
}
+2 -2
View File
@@ -3229,7 +3229,7 @@ void SwapObjs(SOLDIERTYPE* pSoldier, int leftSlot, int rightSlot, BOOLEAN fPerma
{
SwapObjs(&pSoldier->inv[ leftSlot ], &pSoldier->inv[ rightSlot ]);
if(fPermanent && !TANK(pSoldier))//dnl ch64 290813 for current tank don't go further as it lead to invalid animation
if ( fPermanent && !ARMED_VEHICLE( pSoldier ) )//dnl ch64 290813 for current tank don't go further as it lead to invalid animation
{
//old usItem for the left slot is now stored in the right slot, and vice versa
HandleTacticalEffectsOfEquipmentChange(pSoldier, leftSlot, pSoldier->inv[ rightSlot ].usItem, pSoldier->inv[ leftSlot ].usItem);
@@ -8953,7 +8953,7 @@ void CheckEquipmentForDamage( SOLDIERTYPE *pSoldier, INT32 iDamage )
BOOLEAN fBlowsUp;
UINT8 ubNumberOfObjects;
if ( TANK( pSoldier ) )
if ( ARMED_VEHICLE( pSoldier ) )
{
return;
}
+7 -7
View File
@@ -2047,7 +2047,7 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p
ubPosType = TORSO_TARGET_POS;
}
}
else if ( TANK( pSoldier ) )
else if ( ARMED_VEHICLE( pSoldier ) )
{
// high up!
//ubPosType = HEAD_TARGET_POS;
@@ -2184,7 +2184,7 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p
// robot is 1/3 the height of regular people
*pdZPos = *pdZPos / 3;
}
else if ( TANK ( pSoldier ) )
else if ( ARMED_VEHICLE( pSoldier ) )
{
*pdZPos = (*pdZPos * 4) / 3;
}
@@ -2311,7 +2311,7 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
fSmell = HasThermalOptics( pStartSoldier);
}
if ( TANK( pStartSoldier ) )
if ( ARMED_VEHICLE( pStartSoldier ) )
{
INT16 sDistance;
@@ -2352,7 +2352,7 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
// anv: special check for vehicles - since they're no longer transparent, we need to check for visibility
// of all substructures, also vehicle will be noticed even if just part of it is sticking around the corner
if( pEndSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && ( !TANK( pEndSoldier ) || gGameExternalOptions.fEnemyTanksAnyPartVisible ) )
if ( pEndSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && (!ARMED_VEHICLE( pEndSoldier ) || gGameExternalOptions.fEnemyTanksAnyPartVisible) )
{
STRUCTURE *pBase = pEndSoldier->pLevelNode->pStructureData;
if( pBase == NULL )
@@ -2917,7 +2917,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
{
usExpGain /= 2;
}
else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTarget ) || TANK( pTarget ) )
else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTarget ) || ARMED_VEHICLE( pTarget ) )
{
// no exp from shooting a vehicle that you can't damage and can't move!
usExpGain = 0;
@@ -3305,7 +3305,7 @@ INT32 HandleBulletStructureInteraction( BULLET * pBullet, STRUCTURE * pStructure
//else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE )
//{
// stops if using HE ammo
else if ( AmmoTypes[ubAmmoType].highExplosive && !AmmoTypes[ubAmmoType].antiTank )
else if ( AmmoTypes[ubAmmoType].highExplosive && AmmoTypes[ubAmmoType].dDamageModifierTank < 0.1f )
{
*pfHit = TRUE;
return( 0 );
@@ -3457,7 +3457,7 @@ INT32 CTGTHandleBulletStructureInteraction( BULLET * pBullet, STRUCTURE * pStruc
//else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE )
//{
// stops if using HE ammo
else if ( AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ][0]->data.gun.ubGunAmmoType].highExplosive && !AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ][0]->data.gun.ubGunAmmoType].antiTank )
else if ( AmmoTypes[pBullet->pFirer->inv[pBullet->pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType].highExplosive && AmmoTypes[pBullet->pFirer->inv[pBullet->pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType].dDamageModifierTank < 0.1f )
{
return( pBullet->iImpact );
}
+6 -6
View File
@@ -3585,7 +3585,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
//
gMercProfiles[ pSoldierOld->ubProfile ].bLife = 0;
if ( !(pSoldierOld->flags.uiStatusFlags & SOLDIER_VEHICLE) && !TANK( pSoldierOld) )
if ( !(pSoldierOld->flags.uiStatusFlags & SOLDIER_VEHICLE) && !ARMED_VEHICLE( pSoldierOld ) )
{
if ( pSoldierOld->ubAttackerID != NOBODY )
{
@@ -7021,16 +7021,16 @@ void RemoveStaticEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
SECTORINFO *pSectorInfo = &(SectorInfo[SECTOR( sMapX, sMapY )]);
pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = 0;
pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = pSectorInfo->ubNumJeeps = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = 0;
}
else
{
UNDERGROUND_SECTORINFO *pSectorInfo;
pSectorInfo = FindUnderGroundSector( sMapX, sMapY, bMapZ );
pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = 0;
pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = pSectorInfo->ubNumTanks = pSectorInfo->ubNumJeeps = 0;
pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = pSectorInfo->ubTanksInBattle = pSectorInfo->ubJeepsInBattle = 0;
}
}
@@ -10485,7 +10485,7 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
{
enemysidestrength += pSoldier->GetSurrenderStrength();
if ( pSoldier->ubProfile != NO_PROFILE || TANK(pSoldier) )
if ( pSoldier->ubProfile != NO_PROFILE || ARMED_VEHICLE(pSoldier) )
fNoSurrender = TRUE;
}
}
+10 -7
View File
@@ -2621,7 +2621,10 @@ if(!GridNoOnVisibleWorldTile(iDestination))
fPathingForPlayer = ( (s->bTeam == gbPlayerNum) && (!gTacticalStatus.fAutoBandageMode) && !(s->flags.uiStatusFlags & SOLDIER_PCUNDERAICONTROL) );
fNonFenceJumper = !( IS_MERC_BODY_TYPE( s ) ) || (UsingNewInventorySystem() == true && FindBackpackOnSoldier( s ) != ITEM_NOT_FOUND);//Moa: added backpack check
fNonSwimmer = !( IS_MERC_BODY_TYPE( s ) );
// Flugente: nonswimmers are those who are not mercs and not boats
fNonSwimmer = !(IS_MERC_BODY_TYPE( s ) );
if ( fNonSwimmer )
{
if ( Water( sDestination, ubLevel ) )
@@ -2638,13 +2641,13 @@ if(!GridNoOnVisibleWorldTile(iDestination))
fVehicleIgnoreObstacles = TRUE;
}
// AI can't press shift, let's assume only tanks ram through (we wouldn't want AI cars to get destroyed kamikazing through walls, no matter how funny that would be)
else if( !fPathingForPlayer && TANK(s) )
else if ( !fPathingForPlayer && ARMED_VEHICLE( s ) )
{
fVehicleIgnoreObstacles = TRUE;
}
if( fVehicleIgnoreObstacles &&
( ( gGameExternalOptions.fAllowCarsDrivingOverPeople && !TANK(s) ) ||
( gGameExternalOptions.fAllowTanksDrivingOverPeople && TANK(s) ) ) )
((gGameExternalOptions.fAllowCarsDrivingOverPeople && !ARMED_VEHICLE( s )) ||
(gGameExternalOptions.fAllowTanksDrivingOverPeople && ARMED_VEHICLE( s ))) )
{
fPathAroundPeople = FALSE;
}
@@ -2846,9 +2849,9 @@ if(!GridNoOnVisibleWorldTile(iDestination))
else
{
if (ISWATER(gubWorldMovementCosts[iOrigination][0][ubLevel]) && ISWATER(gubWorldMovementCosts[iDestination][0][ubLevel]))
iWaterToWater = 1;
iWaterToWater = 1;
else
iWaterToWater = 0;
iWaterToWater = 0;
}
//setup Q and first path record
@@ -4617,7 +4620,7 @@ INT32 PlotPath( SOLDIERTYPE *pSold, INT32 sDestGridNo, INT8 bCopyRoute, INT8 bPl
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_RUN];
break;
case WALKING:
if (!(pSold->MercInWater()) && ( (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIRE ) ))
if ( 0 && !(pSold->MercInWater()) && ( (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIRE ) ))
{
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY];
}
+18 -16
View File
@@ -57,17 +57,17 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState );
INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8 bLevel )
{
// SANDRO - Note: this procedure was changed a bit
INT16 sAPCost = 0;
INT16 sAPCost = 0;
INT16 sSwitchValue;
BOOLEAN fHiddenStructVisible; // Used for hidden struct visiblity
BOOLEAN fHiddenStructVisible; // Used for hidden struct visiblity
// SANDRO - removed AP cost of moving stealthy or reversed outside this procedure
//if (GridCost[gridno] == NPCMINECOST)
// switchValue = BackupGridCost[gridno];
//else
sSwitchValue = gubWorldMovementCosts[sGridNo][bDir][ bLevel ];
sSwitchValue = gubWorldMovementCosts[sGridNo][bDir][ bLevel ];
// Check reality vs what the player knows....
if ( pSoldier->bTeam == gbPlayerNum )
@@ -83,15 +83,16 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8
}
}
}
//ddd window
if ( sSwitchValue == TRAVELCOST_JUMPABLEWINDOW
|| sSwitchValue == TRAVELCOST_JUMPABLEWINDOW_N
|| sSwitchValue == TRAVELCOST_JUMPABLEWINDOW_W)
{
if (bDir & 1)
return -1;
return -1;
}
//ddd if we don't check this condition, then when we approach to the tile with a window, when the distance to that tile will be 1
//we'll get nice message, that the way is blocked
if ( sSwitchValue == TRAVELCOST_NOT_STANDING)// || sSwitchValue == TRAVELCOST_JUMPABLEWINDOW)
@@ -106,6 +107,7 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8
{
return -1;
}
sSwitchValue = DoorTravelCost( pSoldier, sGridNo, (UINT8) sSwitchValue, (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), NULL );
}
else if (gfPlotPathToExitGrid && sSwitchValue == TRAVELCOST_EXITGRID)
@@ -138,20 +140,20 @@ INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, INT8
case TRAVELCOST_DEBRIS : sAPCost += APBPConstants[AP_MOVEMENT_RUBBLE];
break;
case TRAVELCOST_SHORE : sAPCost += APBPConstants[AP_MOVEMENT_SHORE]; // wading shallow water
if (!IS_MERC_BODY_TYPE( pSoldier ))
if ( !IS_MERC_BODY_TYPE( pSoldier ) )
{
return -1;
}
break;
case TRAVELCOST_KNEEDEEP : sAPCost += APBPConstants[AP_MOVEMENT_LAKE]; // wading waist/chest deep - very slow
if (!IS_MERC_BODY_TYPE( pSoldier ))
if ( !IS_MERC_BODY_TYPE( pSoldier ) )
{
return -1;
}
break;
case TRAVELCOST_DEEPWATER: sAPCost += APBPConstants[AP_MOVEMENT_OCEAN]; // can swim, so it's faster than wading
if (!IS_MERC_BODY_TYPE( pSoldier ))
if ( !IS_MERC_BODY_TYPE( pSoldier ) )
{
return -1;
}
@@ -1474,7 +1476,7 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
sBreathPerAP = APBPConstants[BP_PER_AP_MIN_EFFORT];
// OK, check if we are in water and are waling/standing
if ( pSoldier->MercInWater( ) )
if ( 0 && pSoldier->MercInWater( ) )
{
switch( usAnimState )
{
@@ -2481,7 +2483,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime,
}
}
if ( AM_A_ROBOT( pSoldier ) || TANK( pSoldier ) || ubForceRaiseGunCost == 2 )//dnl ch64 300813 robots and tanks cannot do this //dnl ch69 150913 need option to override raise gun cost
if ( AM_A_ROBOT( pSoldier ) || ARMED_VEHICLE( pSoldier ) || ubForceRaiseGunCost == 2 )//dnl ch64 300813 robots and tanks cannot do this //dnl ch69 150913 need option to override raise gun cost
{
fAddingRaiseGunCost = FALSE;
}
@@ -2632,7 +2634,7 @@ INT16 MinPtsToMove(SOLDIERTYPE *pSoldier)
INT16 sCost;
INT32 sGridNo;
if ( TANK( pSoldier ) && !gGameExternalOptions.fEnemyTanksCanMoveInTactical )
if ( ARMED_VEHICLE( pSoldier ) && !gGameExternalOptions.fEnemyTanksCanMoveInTactical )
{
return(sLowest);//dnl ch64 290813 100AP made INT8 return obsolete
}
@@ -2837,7 +2839,7 @@ void DeductAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE* pObj )
{
// tanks never run out of MG ammo!
// unlimited cannon ammo is handled in AI
if ( TANK( pSoldier ) && !Item[pObj->usItem].cannon )
if ( ARMED_VEHICLE( pSoldier ) && !Item[pObj->usItem].cannon )
return;
if ( Item[pObj->usItem].cannon )
@@ -4031,7 +4033,7 @@ INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAim
Assert(pSoldier != NULL);
Assert(&pSoldier->inv[HANDPOS] != NULL);
#ifndef dnlCALCBESTSHOT//dnl ch69 150913 if this is turn on we get incorrect APs as MinAPsToShootOrStab always include raise gun cost
if (!TANK(pSoldier) && !( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_FIREREADY | ANIM_FIRE )))//dnl ch64 310813
if (!ARMED_VEHICLE(pSoldier) && !( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_FIREREADY | ANIM_FIRE )))//dnl ch64 310813
{
// Weapon not ready, check aiming from hip, else add raise gun cost
//if (!pSoldier->IsValidShotFromHip(bAimTime,sTargetGridNo))
@@ -4238,7 +4240,7 @@ INT32 GetBPCostPer10APsForGunHolding( SOLDIERTYPE * pSoldier, BOOLEAN fEstimate
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
return 0;
if ( TANK( pSoldier ) || AM_A_ROBOT( pSoldier ) )
if ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) )
return 0;
//////////////////////////////////////////////////////////////////////////////
// THE BASIC COST FOR HOLDING THE GUN RAISED (per AP)
@@ -4379,7 +4381,7 @@ INT32 GetBPCostForRecoilkick( SOLDIERTYPE * pSoldier )
return 0;
if ( Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usItemClass != IC_GUN && Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usItemClass != IC_LAUNCHER )
return 0;
if ( TANK( pSoldier ) || AM_A_ROBOT( pSoldier ) )
if ( ARMED_VEHICLE( pSoldier ) || AM_A_ROBOT( pSoldier ) )
return 0;
//////////////////////////////////////////////////////////////////////////////
// THE GUN RECOIL KICK ENERGY COST
+2 -1
View File
@@ -3949,7 +3949,7 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
default :
if ( CREATURE_OR_BLOODCAT( pSoldier ) )
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++;
else if ( TANK( pSoldier ) )
else if ( ARMED_VEHICLE( pSoldier ) )
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsTanks++;
else if ( pSoldier->bTeam == CIV_TEAM && !pSoldier->aiData.bNeutral && pSoldier->bSide != gbPlayerNum )
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsHostiles++;
@@ -4209,6 +4209,7 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier )
case QUEENMONSTER:
case TANK_NW:
case TANK_NE:
case COMBAT_JEEP:
pSoldier->stats.bLife = 0;
break;
+20 -19
View File
@@ -5122,7 +5122,7 @@ UINT16 SelectFireAnimation( SOLDIERTYPE *pSoldier, UINT8 ubHeight )
return(TANK_SHOOT);
}
if ( TANK(pSoldier) )
if ( ARMED_VEHICLE( pSoldier ) )
{
return(TANK_BURST);
}
@@ -5474,7 +5474,7 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady, BOOL
return(INVALID_ANIMATION);
}
if ( TANK(pSoldier) )
if ( ARMED_VEHICLE( pSoldier ) )
{
return(INVALID_ANIMATION);
}
@@ -8095,7 +8095,7 @@ void SOLDIERTYPE::TurnSoldier( void )
if ( ((gAnimControl[this->usAnimState].uiFlags & ANIM_FIREREADY) &&
this->flags.bTurningFromPronePosition == TURNING_FROM_PRONE_OFF) ||
this->ubBodyType == ROBOTNOWEAPON ||
TANK(this) )
ARMED_VEHICLE( this ) )
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "TurnSoldier: EVENT_InitNewSoldierAnim" ) );
this->EVENT_InitNewSoldierAnim( SelectFireAnimation( this, gAnimControl[this->usAnimState].ubEndHeight ), 0, FALSE );
@@ -8175,7 +8175,7 @@ void SOLDIERTYPE::TurnSoldier( void )
// Don't do anything if we are at dest direction!
if ( this->ubDirection == this->pathing.bDesiredDirection )
{
if ( TANK(this) )
if ( ARMED_VEHICLE( this ) )
{
if ( this->iTuringSoundID != NO_SAMPLE )
{
@@ -8324,7 +8324,7 @@ void SOLDIERTYPE::TurnSoldier( void )
}
}
if ( TANK(this) )
if ( ARMED_VEHICLE( this ) )
{
if ( this->iTuringSoundID == NO_SAMPLE )
{
@@ -9871,22 +9871,23 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
// OK, If we are a vehicle.... damage vehicle...( people inside... )
if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
if ( TANK( this ) )
if ( ubReason == TAKE_DAMAGE_GUNFIRE )
{
//sLifeDeduct = (sLifeDeduct * 2) / 3;
;
}
else if ( ubReason == TAKE_DAMAGE_EXPLOSION )
{
if ( ARMED_VEHICLE( this ) )
;
else
{
if ( ubReason == TAKE_DAMAGE_GUNFIRE )
if ( sLifeDeduct > 50 )
{
sLifeDeduct /= 3;
}
else if ( ubReason == TAKE_DAMAGE_EXPLOSION && sLifeDeduct > 50 )
{
// boom!
sLifeDeduct *= 2;
}
}
}
VehicleTakeDamage( this->bVehicleID, ubReason, sLifeDeduct, this->sGridNo, ubAttacker );
HandleTakeDamageDeath( this, bOldLife, ubReason );
@@ -15992,7 +15993,7 @@ UINT32 SOLDIERTYPE::GetSurrenderStrength( )
value *= 0.75f;
// tanks won't surrender that easy
if ( TANK( this ) )
if ( ARMED_VEHICLE( this ) )
value *= 10;
return value;
@@ -16036,8 +16037,8 @@ BOOLEAN SOLDIERTYPE::CanBeCaptured( )
// if this guy is not already handcuffed, and is not an NPC
if ( !(this->usSoldierFlagMask & SOLDIER_POW) && this->ubProfile == NO_PROFILE )
{
// tanks cannot be captured
if ( this->ubSoldierClass == SOLDIER_CLASS_TANK )
// armed vehicles cannot be captured
if ( ARMED_VEHICLE(this) )
return FALSE;
// enemies can be captured
@@ -18241,7 +18242,7 @@ BOOLEAN SOLDIERTYPE::CanMedicAI( )
return FALSE;
// this is not for tanks
if ( TANK( this ) )
if ( ARMED_VEHICLE( this ) )
return FALSE;
if ( HAS_SKILL_TRAIT( this, DOCTOR_NT ) )
@@ -18273,7 +18274,7 @@ BOOLEAN SOLDIERTYPE::AIDoctorFriend( )
return FALSE;
// this is not for tanks
if ( TANK( pSoldier ) )
if ( ARMED_VEHICLE( pSoldier ) )
return FALSE;
// if this guy is wounded, heal him (should always be the case, otherwise this function was called needlessly)
@@ -20504,7 +20505,7 @@ BOOLEAN SOLDIERTYPE::IsValidShotFromHip( INT16 bAimTime, INT32 iTrgGridNo )
return(FALSE);
}
// robots and tanks cannot do this
if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813
if ( AM_A_ROBOT( this ) || ARMED_VEHICLE( this ) )//dnl ch64 300813
{
return(FALSE);
}
@@ -20556,7 +20557,7 @@ BOOLEAN SOLDIERTYPE::IsValidPistolFastShot( INT16 bAimTime, INT32 iTrgGridNo )
return(FALSE);
}
// robots and tanks cannot do this
if ( AM_A_ROBOT( this ) || TANK( this ) )//dnl ch64 300813
if ( AM_A_ROBOT( this ) || ARMED_VEHICLE( this ) )//dnl ch64 300813
{
return(FALSE);
}
+1
View File
@@ -332,6 +332,7 @@ enum
SOLDIER_CLASS_MINER,
SOLDIER_CLASS_ZOMBIE,
SOLDIER_CLASS_TANK,
SOLDIER_CLASS_JEEP,
SOLDIER_CLASS_MAX,
};
+46 -3
View File
@@ -606,7 +606,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
pCreateStruct->fPlayerPlan = 0;
}
if ( is_networked && TANK( pCreateStruct ) )
if ( is_networked && ARMED_VEHICLE( pCreateStruct ) )
{
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank");
return NULL;
@@ -802,7 +802,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
Soldier.bOldLife = Soldier.stats.bLifeMax;
// Flugente: disease can affect a soldier's health
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && Soldier.ubSoldierClass != SOLDIER_CLASS_TANK )
if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && !ARMED_VEHICLE((&Soldier)) )
{
UINT8 sector = SECTOR( Soldier.sSectorX, Soldier.sSectorY );
UINT16 population = GetSectorPopulation( Soldier.sSectorX, Soldier.sSectorY );
@@ -1073,6 +1073,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
case JEEP:
case TANK_NW:
case TANK_NE:
case COMBAT_JEEP:
Soldier.flags.uiStatusFlags |= SOLDIER_VEHICLE;
@@ -1115,6 +1116,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
*/
case TANK_NW:
case TANK_NE:
case COMBAT_JEEP:
ubVehicleID = TANK_CAR;
break;
@@ -1704,7 +1706,7 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
// Flugente: soldier profiles
// silversurfer: Don't replace tanks!
if ( !TANK( pCreateStruct ) )
if ( !ARMED_VEHICLE( pCreateStruct ) )
{
// We have a function for this
INT8 type = pSoldier->GetSoldierProfileType( pCreateStruct->bTeam );
@@ -2476,6 +2478,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
break;
case SOLDIER_CLASS_TANK:
case SOLDIER_CLASS_JEEP:
pp->bExpLevel = bp->bRelativeAttributeLevel;
break;
@@ -3127,6 +3130,46 @@ SOLDIERTYPE* TacticalCreateEnemyTank()
return( pSoldier );
}
SOLDIERTYPE* TacticalCreateEnemyJeep( )
{
BASIC_SOLDIERCREATE_STRUCT bp;
SOLDIERCREATE_STRUCT pp;
UINT8 ubID;
SOLDIERTYPE * pSoldier;
if ( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI )
{
pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_JEEP );
if ( pSoldier )
return pSoldier;
}
memset( &bp, 0, sizeof(BASIC_SOLDIERCREATE_STRUCT) );
RandomizeRelativeLevel( &(bp.bRelativeAttributeLevel), SOLDIER_CLASS_ELITE );
RandomizeRelativeLevel( &(bp.bRelativeEquipmentLevel), SOLDIER_CLASS_ELITE );
bp.bTeam = ENEMY_TEAM;
bp.bOrders = SEEKENEMY;
bp.bAttitude = (INT8)Random( MAXATTITUDES );
bp.ubBodyType = COMBAT_JEEP;
bp.ubSoldierClass = SOLDIER_CLASS_JEEP;
CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp );
pSoldier = TacticalCreateSoldier( &pp, &ubID );
if ( pSoldier )
{
// send soldier to centre of map, roughly
pSoldier->aiData.sNoiseGridno = (CENTRAL_GRIDNO + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) * WORLD_COLS);
pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION;
// Flugente: why would a vehicle's armour depend on game progress? Always give them 100 HP
pSoldier->stats.bLifeMax = 100;
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
}
return(pSoldier);
}
//USED BY STRATEGIC AI and AUTORESOLVE
// should to be succeeded by TacticalCreateArmyTroop/EliteEnemy and AddSoldierToVehicle
SOLDIERTYPE* TacticalCreateJeep()
+1
View File
@@ -443,6 +443,7 @@ SOLDIERTYPE* TacticalCreateZombie(); // Flugente Zombies
SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass, INT16 sX, INT16 sY ); // Flugente: added sector coordinates
SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType );
SOLDIERTYPE* TacticalCreateEnemyTank();
SOLDIERTYPE* TacticalCreateEnemyJeep( );
SOLDIERTYPE* TacticalCreateJeep();
// Flugente: create an armed civilian
+72 -20
View File
@@ -591,7 +591,7 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
// First check if this guy has a profile and if so check his location such that it matches!
// Get profile from placement info
if ( TANK( curr->pBasicPlacement ) )
if ( ARMED_VEHICLE( curr->pBasicPlacement ) )
{
while (1)
{
@@ -804,7 +804,7 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld: create soldier"));
if ( is_networked && ( TANK( (&tempDetailedPlacement) ) || tempDetailedPlacement.fOnRoof ) )
if ( is_networked && (ARMED_VEHICLE( (&tempDetailedPlacement) ) || tempDetailedPlacement.fOnRoof) )
return TRUE;
pSoldier = TacticalCreateSoldier( &tempDetailedPlacement, &ubID );
@@ -1019,7 +1019,7 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
return ubNumAdded;
}
void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks )
void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks, UINT8 ubTotalJeeps )
{
SOLDIERINITNODE *mark;
SOLDIERINITNODE *curr;
@@ -1029,6 +1029,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
UINT8 ubTroopPDSlots = 0, ubTroopDSlots = 0, ubTroopPSlots = 0, ubTroopBSlots = 0;
UINT8 ubAdminPDSlots = 0, ubAdminDSlots = 0, ubAdminPSlots = 0, ubAdminBSlots = 0;
UINT8 ubTankPDSlots = 0, ubTankDSlots = 0, ubTankPSlots = 0, ubTankBSlots = 0;
UINT8 ubJeepPDSlots = 0, ubJeepDSlots = 0, ubJeepPSlots = 0, ubJeepBSlots = 0;
UINT8 ubFreeSlots;
UINT8 *pCurrSlots=NULL;
UINT8 *pCurrTotal=NULL;
@@ -1046,7 +1047,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//of each type of enemy may not be the same. Elites will choose the best placements, then army, then
//administrators.
ubMaxNum = ubTotalAdmin + ubTotalTroops + ubTotalElite + ubTotalTanks;
ubMaxNum = ubTotalAdmin + ubTotalTroops + ubTotalElite + ubTotalTanks + ubTotalJeeps;
AssertLE (ubMaxNum, gGameExternalOptions.ubGameMaximumNumberOfEnemies);
@@ -1096,6 +1097,18 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
else
ubTroopBSlots++;
break;
case SOLDIER_CLASS_JEEP:
if ( COMBAT_JEEP( curr->pDetailedPlacement ) )
{
if ( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement )
ubJeepPDSlots++;
else if ( curr->pBasicPlacement->fPriorityExistance )
ubJeepPSlots++;
else if ( curr->pDetailedPlacement )
ubJeepDSlots++;
else
ubJeepBSlots++;
}
case SOLDIER_CLASS_TANK:
if ( TANK( curr->pDetailedPlacement ) )
{
@@ -1117,7 +1130,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
//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
//and randomly choose some (or all) of the matching slots to fill. This is done randomly.
for( ubCurrClass = SOLDIER_CLASS_ADMINISTRATOR; ubCurrClass <= SOLDIER_CLASS_ARMY + 1; ubCurrClass++ )
for( ubCurrClass = SOLDIER_CLASS_ADMINISTRATOR; ubCurrClass <= SOLDIER_CLASS_ARMY + 2; ++ubCurrClass )
{
//First, prepare the counters.
switch( ubCurrClass )
@@ -1139,6 +1152,11 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
pCurrSlots = &ubTankPDSlots;
pCurrTotal = &ubTotalTanks;
break;
case SOLDIER_CLASS_ARMY + 2:// SOLDIER_CLASS_JEEP
ubCurrClass = SOLDIER_CLASS_JEEP;
pCurrSlots = &ubJeepPDSlots;
pCurrTotal = &ubTotalJeeps;
break;
}
//Now, loop through the priority existance and detailed placement section of the list.
curr = gSoldierInitHead;
@@ -1317,10 +1335,16 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
}
else if( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK;
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK;
curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--;
}
else if ( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--;
}
else
Assert(0);
if( AddPlacementToWorld( curr ) )
@@ -1406,18 +1430,34 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
curr = gSoldierInitHead;
while( curr && ubFreeSlots && ubMaxNum )
{
if( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM && ubTotalTanks && !GridNoIndoors( curr->pBasicPlacement->usStartingGridNo ))
if ( !curr->pSoldier && curr->pBasicPlacement->bTeam == ENEMY_TEAM && !GridNoIndoors( curr->pBasicPlacement->usStartingGridNo ) && (ubTotalTanks || ubTotalJeeps) )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK;
curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--;
if( AddPlacementToWorld( curr ) )
if ( ubTotalJeeps )
{
ubMaxNum--;
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--;
if( AddPlacementToWorld( curr ) )
{
ubMaxNum--;
}
else
return;
ubFreeSlots--;
}
else if ( ubTotalTanks )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_TANK;
curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--;
if ( AddPlacementToWorld( curr ) )
{
ubMaxNum--;
}
else
return;
ubFreeSlots--;
}
else
return;
ubFreeSlots--;
}
curr = curr->next;
}
@@ -1456,6 +1496,12 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
curr->pBasicPlacement->ubBodyType = TANK_NW;
ubTotalTanks--;
}
else if ( iRandom < ubTotalElite + ubTotalTroops + ubTotalAdmin + ubTotalTanks + ubTotalJeeps )
{
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_JEEP;
curr->pBasicPlacement->ubBodyType = COMBAT_JEEP;
ubTotalJeeps--;
}
else
Assert(0);
/* DISABLE THE OVERRIDE FOR NOW...
@@ -1546,7 +1592,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
// silversurfer: Replace body type. Militia tanks are not allowed.
if( curr->pBasicPlacement->fDetailedPlacement )
{
if ( TANK( curr->pDetailedPlacement ) )
if ( ARMED_VEHICLE( curr->pDetailedPlacement ) )
{
curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank
@@ -1555,7 +1601,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr->pBasicPlacement->usStartingGridNo = iNewSpot;
}
}
else if ( TANK( curr->pBasicPlacement ) )
else if ( ARMED_VEHICLE( curr->pBasicPlacement ) )
{
curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank
@@ -1563,14 +1609,17 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
if( iNewSpot != NOWHERE)
curr->pBasicPlacement->usStartingGridNo = iNewSpot;
}
if( curr->pDetailedPlacement )
{ //delete the detailed placement information.
{
//delete the detailed placement information.
delete( curr->pDetailedPlacement );
curr->pDetailedPlacement = NULL;
curr->pBasicPlacement->fDetailedPlacement = FALSE;
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeAttributeLevel ), curr->pBasicPlacement->ubSoldierClass );
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeEquipmentLevel ), curr->pBasicPlacement->ubSoldierClass );
}
if( AddPlacementToWorld( curr ) )
{
ubMaxNum--;
@@ -1726,7 +1775,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
curr->pBasicPlacement->bAttitude = (INT8) Random( MAXATTITUDES );
// silversurfer: Replace body type. Militia tanks are not allowed.
if ( TANK(curr->pBasicPlacement) )
if ( ARMED_VEHICLE( curr->pBasicPlacement ) )
{
curr->pBasicPlacement->ubBodyType = PreRandom( REGFEMALE + 1 );
// check for better spot next to the tank so the militia doesn't get stuck in the tank
@@ -1734,14 +1783,17 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
if( iNewSpot != NOWHERE)
curr->pBasicPlacement->usStartingGridNo = iNewSpot;
}
if( curr->pDetailedPlacement )
{ //delete the detailed placement information.
{
//delete the detailed placement information.
delete( curr->pDetailedPlacement );
curr->pDetailedPlacement = NULL;
curr->pBasicPlacement->fDetailedPlacement = FALSE;
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeAttributeLevel), curr->pBasicPlacement->ubSoldierClass );
RandomizeRelativeLevel( &( curr->pBasicPlacement->bRelativeEquipmentLevel), curr->pBasicPlacement->ubSoldierClass );
}
if( AddPlacementToWorld( curr ) )
{
ubMaxNum--;
+1 -1
View File
@@ -40,7 +40,7 @@ void RemoveSoldierNodeFromInitList( SOLDIERINITNODE *pNode );
SOLDIERINITNODE* FindSoldierInitNodeWithID( UINT16 usID );
UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum );
void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks );
void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTroops, UINT8 ubTotalElite, UINT8 ubTotalTanks, UINT8 ubTotalJeeps );
void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNumInfants,
UINT8 ubNumYoungMales, UINT8 ubNumYoungFemales, UINT8 ubNumAdultMales,
UINT8 ubNumAdultFemales );
+2
View File
@@ -1024,6 +1024,7 @@ BOOLEAN LoadMercProfiles(void)
case ELDORADO:
case ICECREAMTRUCK:
case JEEP:
case COMBAT_JEEP:
gProfilesVehicle[uiLoop].ProfilId = uiLoop;
break;
// Make it an RPC
@@ -1051,6 +1052,7 @@ BOOLEAN LoadMercProfiles(void)
case ELDORADO:
case ICECREAMTRUCK:
case JEEP:
case COMBAT_JEEP:
gProfilesVehicle[uiLoop].ProfilId = uiLoop;
break;
// RPC or NPC
+2 -2
View File
@@ -224,11 +224,11 @@ INT8 TileIsClear( SOLDIERTYPE *pSoldier, INT8 bDirection, INT32 sGridNo, INT8 b
}
// anv: vehicles can ram people
if ( !TANK(pSoldier) && gGameExternalOptions.fAllowCarsDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && pSoldier->usSoldierFlagMask2 & SOLDIER_RAM_THROUGH_OBSTACLES )
if ( !ARMED_VEHICLE( pSoldier ) && gGameExternalOptions.fAllowCarsDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && pSoldier->usSoldierFlagMask2 & SOLDIER_RAM_THROUGH_OBSTACLES )
{
return( MOVE_TILE_CLEAR );
}
else if( TANK(pSoldier) && gGameExternalOptions.fAllowTanksDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
else if ( ARMED_VEHICLE( pSoldier ) && gGameExternalOptions.fAllowTanksDrivingOverPeople && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
return( MOVE_TILE_CLEAR );
}
+3 -1
View File
@@ -32,9 +32,11 @@
#define CREATURE_OR_BLOODCAT( p ) ( (p->flags.uiStatusFlags & SOLDIER_MONSTER) || p->ubBodyType == BLOODCAT )
#define COMBAT_JEEP( p ) ( p->ubBodyType == COMBAT_JEEP )
#define TANK( p ) (p->ubBodyType == TANK_NE || p->ubBodyType == TANK_NW )
#define 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->flags.uiStatusFlags & SOLDIER_ENEMY) ) && p->stats.bLife >= OKLIFE )
#define OK_ENTERABLE_VEHICLE( p ) ( ( p->flags.uiStatusFlags & SOLDIER_VEHICLE ) && (!ARMED_VEHICLE( p ) || !(p->flags.uiStatusFlags & SOLDIER_ENEMY) ) && p->stats.bLife >= OKLIFE )
#endif
+1 -1
View File
@@ -60,7 +60,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
return;
// WANNE: No tooltips on bloodcats, bugs, tanks, roboter
if ( CREATURE_OR_BLOODCAT( pSoldier ) || TANK ( pSoldier ) ||
if ( CREATURE_OR_BLOODCAT( pSoldier ) || ARMED_VEHICLE( pSoldier ) ||
AM_A_ROBOT( pSoldier))
{
return;
+1 -1
View File
@@ -1969,7 +1969,7 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
}
}
if ( TANK( pSoldier ) )
if ( ARMED_VEHICLE( pSoldier ) )
{
// reduce interrupt possibilities for tanks!
iPoints /= 2;
+1
View File
@@ -4962,6 +4962,7 @@ void ChangeSoldiersBodyType( UINT8 ubBodyType, BOOLEAN fCreateNewPalette )
case TANK_NW:
case TANK_NE:
case COMBAT_JEEP:
pSoldier->flags.uiStatusFlags |= SOLDIER_VEHICLE;
//pSoldier->inv[ HANDPOS ].usItem = TANK_CANNON;
+37 -24
View File
@@ -3320,7 +3320,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{
iHitChance = 100;
}
else if ( AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) || CREATURE_OR_BLOODCAT( pTargetSoldier ) || (SOLDIER_CLASS_MILITIA(pTargetSoldier->ubSoldierClass) && (gGameExternalOptions.ubMilitiaDropEquipment != 2)) ) // added militia here - SANDRO
else if ( AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) || CREATURE_OR_BLOODCAT( pTargetSoldier ) || (SOLDIER_CLASS_MILITIA( pTargetSoldier->ubSoldierClass ) && (gGameExternalOptions.ubMilitiaDropEquipment != 2)) ) // added militia here - SANDRO
{
iHitChance = 0;
}
@@ -3653,7 +3653,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
}
// Give some experience
if ( iHitChance > 0 && pSoldier->bTeam == gbPlayerNum && pTargetSoldier->bTeam != gbPlayerNum && !(pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( pTargetSoldier ) && !TANK( pTargetSoldier ) )
if ( iHitChance > 0 && pSoldier->bTeam == gbPlayerNum && pTargetSoldier->bTeam != gbPlayerNum && !(pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( pTargetSoldier ) && !ARMED_VEHICLE( pTargetSoldier ) )
{
if (fFailure == FALSE)
{
@@ -3778,7 +3778,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
}
}
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) )
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) )
{
ubExpGain = 0;
}
@@ -3828,7 +3828,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
}
}
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) )
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || ARMED_VEHICLE( pTargetSoldier ) )
{
ubExpGain = 0;
}
@@ -6996,7 +6996,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
iPenalty = ((iMaxRange - (iRange-iAccRangeMod) * 3) * 10) / (17 * CELL_X_SIZE);
if ( iPenalty < 0 )
iChance += iPenalty;
if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) )
if ( ARMED_VEHICLE( pSoldier ) && (iRange / CELL_X_SIZE < MaxNormalDistanceVisible( )) )
iChance -= 2 * ( MaxNormalDistanceVisible() - (iRange / CELL_X_SIZE) );
// Like the above modifier, only this applies to long range weapons trying to be used in close quater. Penalty will result when within 10% of max range
iPenalty = (((iRange - iMinRange - iAccRangeMod) * 12) * 10) / (17 * CELL_X_SIZE);
@@ -7005,7 +7005,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// Effects of visual range
// From for JA2.5: 3% bonus/penalty for each tile different from range NORMAL_RANGE.
if (!TANK(pSoldier)) // WANNE: No penalty on the tank
if ( !ARMED_VEHICLE( pSoldier ) ) // WANNE: No penalty on the tank
iPenalty = 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE;
if ( fCantSeeTarget ){
// CHRISL: There are conditions where iSightRange can still return 0. If that happens, the result is that "impossible" shots are actually easier then
@@ -7043,7 +7043,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
switch( gAnimControl[ pTarget->usAnimState ].ubHeight )
{
case ANIM_CROUCH:
if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
if ( ARMED_VEHICLE( pSoldier ) && iRange < MIN_TANK_RANGE )
{
// 13% penalty per tile closer than min range
iChance -= (INT32)(13 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ));
@@ -7063,7 +7063,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
}
break;
case ANIM_PRONE:
if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
if ( ARMED_VEHICLE( pSoldier ) && iRange < MIN_TANK_RANGE )
{
// 25% penalty per tile closer than min range
iChance -= (INT32)(25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE ) * iPenalty);
@@ -7204,7 +7204,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// if target sees us, he may have a chance to dodge before the gun goes off
// but ability to dodge is reduced if crouched or prone!
if (pTarget->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY && !TANK( pTarget ) && !(pSoldier->ubBodyType != QUEENMONSTER) )
if ( pTarget->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY && !ARMED_VEHICLE( pTarget ) && !(pSoldier->ubBodyType != QUEENMONSTER) )
{
iPenalty = ( EffectiveAgility( pTarget, FALSE ) / 5 + EffectiveExpLevel( pTarget ) * 2);
switch( gAnimControl[ pTarget->usAnimState ].ubHeight )
@@ -7219,7 +7219,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// reduce dodge ability by the attacker's stats
iBonus = ( EffectiveDexterity( pSoldier, FALSE ) / 5 + EffectiveExpLevel( pSoldier ) * 2);
if ( TANK( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) )
if ( ARMED_VEHICLE( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) )
{
// reduce ability to track shots
iBonus = iBonus / 2;
@@ -7235,7 +7235,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
iChance -= iPenalty;
}
}
else if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
else if ( ARMED_VEHICLE( pSoldier ) && iRange < MIN_TANK_RANGE )
{
// 25% penalty per tile closer than min range
iChance -= 25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
@@ -7802,7 +7802,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// be an effective CTH of only 1/5000 (50 chances to get a 1 out of 100 CTH, hehehe)
if (iChance <= gGameExternalOptions.ubMinimumCTH)
{
if ( TANK( pSoldier ) )
if ( ARMED_VEHICLE( pSoldier ) )
{
// allow absolute minimums
iChance = 0;
@@ -8626,12 +8626,12 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
if ( iPenalty < 0 )
{
// No penalty on tanks
//if (!TANK(pSoldier))
//if (!ARMED_VEHICLE(pSoldier))
iChance += iPenalty;
}
//iChance -= 20 * iRange / iMaxRange;
if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) )
if ( ARMED_VEHICLE( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) )
{
// tank; penalize at close range!
// 2 percent per tile closer than max visible distance
@@ -8655,7 +8655,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// range less penalized, and longer range more penalized
// WANNE: No penalty on the tank
if (!TANK(pSoldier))
if (!ARMED_VEHICLE(pSoldier))
iChance += 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE;
// if aiming at the head, reduce chance to hit
if (ubAimPos == AIM_SHOT_HEAD)
@@ -9567,15 +9567,31 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
ubAmmoType = Explosive[Item[usAttackingWeapon].ubClassIndex].ubFragType;
}
if ( TANK( pTarget ) )
// Flugente: ammotype can alter the damage dealt
FLOAT damagefactor = AmmoTypes[ubAmmoType].dDamageModifierLife;
if ( pTarget->IsZombie( ) )
{
if ( !AmmoTypes[ubAmmoType].antiTank )
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierZombie;
}
else if ( pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
if ( COMBAT_JEEP( pTarget ) || AM_A_ROBOT( pTarget ) )
{
// ping!
return( 0 );
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierArmouredVehicle;
}
else if ( TANK( pTarget ) )
{
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierTank;
}
else
{
damagefactor *= AmmoTypes[ubAmmoType].dDamageModifierCivilianVehicle;
}
}
iOrigImpact = iOrigImpact * damagefactor;
// plus/minus up to 25% due to "random" factors (major organs hit or missed,
// lucky lighter in breast pocket, divine intervention on behalf of "Rev"...)
iFluke = PreRandom(51) - 25; // gives (0 to 50 -25)->-25% to +25%
@@ -9622,9 +9638,6 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
pTarget->iLastArmourProtection += iTotalArmourProtection;
}
// Flugente: ammotype can alter the damage dealt
iImpact *= AmmoTypes[ubAmmoType].dDamageModifierLife;
// calc minimum damage
if ( AmmoTypes[ubAmmoType].zeroMinimumDamage )
{
@@ -9654,14 +9667,14 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
}
// Flugente: if this is cryo ammo, freeze target.
if ( !TANK( pTarget ) && !(pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE) && AmmoTypes[ubAmmoType].ammoflag & AMMO_CRYO )
if ( !ARMED_VEHICLE( pTarget ) && !(pTarget->flags.uiStatusFlags & SOLDIER_VEHICLE) && AmmoTypes[ubAmmoType].ammoflag & AMMO_CRYO )
{
pTarget->usSkillCooldown[SOLDIER_COOLDOWN_CRYO] += 2;
ShutupaYoFace( pTarget->iFaceIndex );
}
if ( iImpact > 0 && !TANK( pTarget ) )
if ( iImpact > 0 && !ARMED_VEHICLE( pTarget ) )
{
// Flugente: any bullet can have drug effects it set so in the magazine item
if ( ammoitem != NOTHING )
+5 -2
View File
@@ -252,7 +252,6 @@ typedef struct
INT32 multipleBulletDamageDivisor;
UINT16 highExplosive;
UINT8 explosionSize; //0=none, 1=small, 2=medium, 3=large
BOOLEAN antiTank;
BOOLEAN dart;
BOOLEAN knife;
UINT16 monsterSpit;
@@ -272,7 +271,11 @@ typedef struct
// Flugente: modifiers for life and breath damage, 1.0 being the unmodified value
FLOAT dDamageModifierLife;
FLOAT dDamageModifierBreath;
FLOAT dDamageModifierTank;
FLOAT dDamageModifierArmouredVehicle;
FLOAT dDamageModifierCivilianVehicle;
FLOAT dDamageModifierZombie;
} AMMOTYPE;
enum
+42 -9
View File
@@ -71,7 +71,6 @@ ammotypeStartElementHandle(void *userData, const XML_Char *name, const XML_Char
strcmp(name, "spreadPattern") == 0 ||
strcmp(name, "highExplosive") == 0 ||
strcmp(name, "explosionSize") == 0 ||
strcmp(name, "antiTank") == 0 ||
strcmp(name, "dart") == 0 ||
strcmp(name, "knife") == 0 ||
strcmp(name, "ignoreArmour") == 0 ||
@@ -83,7 +82,11 @@ ammotypeStartElementHandle(void *userData, const XML_Char *name, const XML_Char
strcmp(name, "dirtModificator") == 0 ||
strcmp(name, "ammoflag" ) == 0 ||
strcmp(name, "dDamageModifierLife" ) == 0 ||
strcmp(name, "dDamageModifierBreath") == 0 ))
strcmp(name, "dDamageModifierBreath" ) == 0 ||
strcmp(name, "dDamageModifierTank" ) == 0 ||
strcmp(name, "dDamageModifierArmouredVehicle" ) == 0 ||
strcmp(name, "dDamageModifierCivilianVehicle" ) == 0 ||
strcmp(name, "dDamageModifierZombie") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
@@ -246,11 +249,6 @@ ammotypeEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curAmmoType.explosionSize = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "antiTank") == 0)
{
pData->curElement = ELEMENT;
pData->curAmmoType.antiTank = (BOOLEAN) atol(pData->szCharData);
}
else if(strcmp(name, "dart") == 0)
{
pData->curElement = ELEMENT;
@@ -312,7 +310,39 @@ ammotypeEndElementHandle(void *userData, const XML_Char *name)
// reasonable values only
pData->curAmmoType.dDamageModifierBreath = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierBreath ) );
}
else if ( strcmp( name, "dDamageModifierTank" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierTank = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierTank = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierTank ) );
}
else if ( strcmp( name, "dDamageModifierArmouredVehicle" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierArmouredVehicle = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierArmouredVehicle = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierArmouredVehicle ) );
}
else if ( strcmp( name, "dDamageModifierCivilianVehicle" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierCivilianVehicle = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierCivilianVehicle = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierCivilianVehicle ) );
}
else if ( strcmp( name, "dDamageModifierZombie" ) == 0 )
{
pData->curElement = ELEMENT;
pData->curAmmoType.dDamageModifierZombie = (FLOAT)atof( pData->szCharData );
// reasonable values only
pData->curAmmoType.dDamageModifierZombie = min( 100.0f, max( 0.0f, pData->curAmmoType.dDamageModifierZombie ) );
}
pData->maxReadDepth--;
}
@@ -425,7 +455,6 @@ BOOLEAN WriteAmmoTypeStats()
FilePrintf(hFile,"\t\t<multipleBulletDamageDivisor>%d</multipleBulletDamageDivisor>\r\n", AmmoTypes[cnt].multipleBulletDamageDivisor );
FilePrintf(hFile,"\t\t<highExplosive>%d</highExplosive>\r\n", AmmoTypes[cnt].highExplosive );
FilePrintf(hFile,"\t\t<explosionSize>%d</explosionSize>\r\n", AmmoTypes[cnt].explosionSize );
FilePrintf(hFile,"\t\t<antiTank>%d</antiTank>\r\n", AmmoTypes[cnt].antiTank );
FilePrintf(hFile,"\t\t<dart>%d</dart>\r\n", AmmoTypes[cnt].dart );
FilePrintf(hFile,"\t\t<knife>%d</knife>\r\n", AmmoTypes[cnt].knife );
FilePrintf(hFile,"\t\t<monsterSpit>%d</monsterSpit>\r\n", AmmoTypes[cnt].monsterSpit );
@@ -438,7 +467,11 @@ BOOLEAN WriteAmmoTypeStats()
FilePrintf(hFile,"\t\t<ammoflag>%d</ammoflag>\r\n", AmmoTypes[cnt].ammoflag );
FilePrintf(hFile,"\t\t<dDamageModifierLife>%4.2f</dDamageModifierLife>\r\n", AmmoTypes[cnt].dDamageModifierLife );
FilePrintf(hFile,"\t\t<dDamageModifierBreath>%4.2f</dDamageModifierBreath>\r\n", AmmoTypes[cnt].dDamageModifierBreath );
FilePrintf(hFile,"\t\t<dDamageModifierTank>%4.2f</dDamageModifierTank>\r\n", AmmoTypes[cnt].dDamageModifierTank );
FilePrintf(hFile,"\t\t<dDamageModifierArmouredVehicle>%4.2f</dDamageModifierArmouredVehicle>\r\n", AmmoTypes[cnt].dDamageModifierArmouredVehicle );
FilePrintf(hFile,"\t\t<dDamageModifierCivilianVehicle>%4.2f</dDamageModifierCivilianVehicle>\r\n", AmmoTypes[cnt].dDamageModifierCivilianVehicle );
FilePrintf(hFile,"\t\t<dDamageModifierZombie>%4.2f</dDamageModifierZombie>\r\n", AmmoTypes[cnt].dDamageModifierZombie );
FilePrintf(hFile,"\t</AMMOTYPE>\r\n");
}
FilePrintf(hFile,"</AMMOTYPELIST>\r\n");
+6 -6
View File
@@ -1233,7 +1233,7 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
}
}
if ( bFacingDir == DIRECTION_IRRELEVANT && TANK( pSoldier ) )
if ( bFacingDir == DIRECTION_IRRELEVANT && ARMED_VEHICLE( pSoldier ) )
{
// always calculate direction for tanks so we have something to work with
bFacingDir = pSoldier->pathing.bDesiredDirection;
@@ -1241,7 +1241,7 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
//bSubjectDir = atan8(pSoldier->sX,pSoldier->sY,pOpponent->sX,pOpponent->sY);
}
if ( !TANK( pSoldier ) && ( bFacingDir == DIRECTION_IRRELEVANT || (pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT) || (pSubject && pSubject->flags.fMuzzleFlash) ) )
if ( !ARMED_VEHICLE( pSoldier ) && (bFacingDir == DIRECTION_IRRELEVANT || (pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT) || (pSubject && pSubject->flags.fMuzzleFlash)) )
{
sDistVisible = MaxNormalDistanceVisible();
}
@@ -1385,10 +1385,10 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
}
// let tanks see and be seen further (at night)
if ( (TANK( pSoldier ) && sDistVisible > 0) || (pSubject && TANK( pSubject ) ) )
if ( (ARMED_VEHICLE( pSoldier ) && sDistVisible > 0) || (pSubject && ARMED_VEHICLE( pSubject )) )
{
#if 0
if ( TANK(pSoldier) && sDistVisible > 0 && pSubject)
if ( ARMED_VEHICLE(pSoldier) && sDistVisible > 0 && pSubject)
{
sDistVisible = __max( sDistVisible + 5, pSubject->GetMaxDistanceVisible(pSoldier->sGridNo, pSoldier->pathing.bLevel) );
}
@@ -1561,7 +1561,7 @@ INT8 DecideHearing( SOLDIERTYPE * pSoldier )
// calculate the hearing value for the merc...
INT8 bHearing;
if ( TANK( pSoldier ) )
if ( ARMED_VEHICLE( pSoldier ) )
{
return( -5 );
}
@@ -6443,7 +6443,7 @@ void HearNoise(SOLDIERTYPE *pSoldier, UINT8 ubNoiseMaker, INT32 sGridNo, INT8 bL
// (taking into account we are definitely aware of this guy now)
// skip LOS check if we had to turn and we're a tank. sorry Mr Tank, no looking out of the sides for you!
if ( !( bHadToTurn && TANK( pSoldier ) ) )
if ( !(bHadToTurn && ARMED_VEHICLE( pSoldier )) )
{
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, bLevel, 0, TRUE, sDistVisible ) )
{