mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
New Feature: Allow driving vehicles in tactical (by anv)
- To control vehicle, click on it or on the steering wheel in team panel under driver's portrait.
- Vehicles have two gears - slow drive and fast drive, switchable just like walking and running ('S', 'R', double-click).
- Vehicles working: Ice Cream Van, Hummer, Jeep, El Dorado and, potentially, tanks.
- Passengers can be selected and ordered to open fire from the inside
- You can also open inventory screen for passengers, pass or throw items, etc.
Normally vehicle is treated as any other merc and has its own APs. It has obvious disadvantages - it's possible to drive in the middle of the enemy group using vehicle's 100AP,
and then use all your mercs inside vehicle with their still full APs to kill everything that moves at point blank range - with even the driver participating!
- To prevent that you can set Tactical Gameplay Settings > AP_SHARED_AMONG_PASSENGERS_AND_VEHICLE_MODE with following calculation methods
more infos: http://www.bears-pit.com/board/ubbthreads.php/topics/332208/1.html
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7193 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -1381,6 +1381,9 @@ void LoadGameExternalOptions()
|
||||
else
|
||||
gGameExternalOptions.fSoldierProfiles_Militia = FALSE;
|
||||
|
||||
gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleMode = iniReader.ReadInteger("Tactical Gameplay Settings","AP_SHARED_AMONG_PASSENGERS_AND_VEHICLE_MODE", 3, 0, 3);
|
||||
gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleScale = iniReader.ReadInteger("Tactical Gameplay Settings","AP_SHARED_AMONG_PASSENGERS_AND_VEHICLE_SCALE", 100, 0, 200);
|
||||
|
||||
// *** ddd - BEGIN
|
||||
gGameExternalOptions.fExtMouseKeyEnabled = iniReader.ReadBoolean("Tactical Interface Settings", "ENABLE_EXT_MOUSE_KEYS", FALSE);
|
||||
|
||||
@@ -3159,6 +3162,10 @@ void LoadGameAPBPConstants()
|
||||
APBPConstants[AP_APPLYITEM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_APPLYITEM",50),50);
|
||||
APBPConstants[AP_INVENTORY_ARM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_INVENTORY_ARM",50),50);
|
||||
APBPConstants[AP_SPOTTER] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_SPOTTER",20),20);
|
||||
|
||||
APBPConstants[AP_ENTER_VEHICLE] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_ENTER_VEHICLE",30),30);
|
||||
APBPConstants[AP_EXIT_VEHICLE] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_EXIT_VEHICLE",30),30);
|
||||
APBPConstants[AP_CHANGE_SEAT_VEHICLE] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_CHANGE_SEAT_VEHICLE",20),20);
|
||||
|
||||
APBPConstants[DEFAULT_APS] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","DEFAULT_APS",80),80);
|
||||
APBPConstants[DEFAULT_AIMSKILL] = iniReader.ReadInteger("APConstants","DEFAULT_AIMSKILL",80);
|
||||
|
||||
@@ -1451,6 +1451,9 @@ typedef struct
|
||||
UINT8 ubExtremeIronManSavingTimeNotification;
|
||||
UINT8 ubExtremeIronManSavingHour;
|
||||
|
||||
UINT8 ubAPSharedAmongPassengersAndVehicleMode;
|
||||
UINT8 ubAPSharedAmongPassengersAndVehicleScale;
|
||||
|
||||
} GAME_EXTERNAL_OPTIONS;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -156,6 +156,10 @@ AP_APPLYITEM,
|
||||
AP_INVENTORY_ARM,
|
||||
AP_SPOTTER,
|
||||
|
||||
AP_ENTER_VEHICLE,
|
||||
AP_EXIT_VEHICLE,
|
||||
AP_CHANGE_SEAT_VEHICLE,
|
||||
|
||||
DEFAULT_APS,
|
||||
DEFAULT_AIMSKILL,
|
||||
BP_RATIO_RED_PTS_TO_NORMAL,
|
||||
|
||||
@@ -3496,12 +3496,15 @@ void InitAnimationSurfacesPerBodytype( )
|
||||
// HUMVEE
|
||||
gubAnimSurfaceIndex[ HUMVEE ][ STANDING ] = HUMVEE_BASIC;
|
||||
gubAnimSurfaceIndex[ HUMVEE ][ WALKING ] = HUMVEE_BASIC;
|
||||
gubAnimSurfaceIndex[ HUMVEE ][ RUNNING ] = HUMVEE_BASIC;
|
||||
gubAnimSurfaceIndex[ HUMVEE ][ WALK_BACKWARDS ] = HUMVEE_BASIC;
|
||||
gubAnimSurfaceIndex[ HUMVEE ][ VEHICLE_DIE ] = HUMVEE_DIE;
|
||||
gubAnimSurfaceCorpseID[ HUMVEE ][ STANDING ] = HUMMER_DEAD;
|
||||
|
||||
// TANK
|
||||
gubAnimSurfaceIndex[ TANK_NW ][ STANDING ] = TANKNW_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NW ][ WALKING ] = TANKNW_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NW ][ WALKING ] = TANKNW_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NW ][ WALK_BACKWARDS ] = TANKNW_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NW ][ TANK_SHOOT ] = TANKNW_SHOOT;
|
||||
gubAnimSurfaceIndex[ TANK_NW ][ TANK_BURST ] = TANKNW_SHOOT;
|
||||
gubAnimSurfaceIndex[ TANK_NW ][ VEHICLE_DIE ] = TANKNW_DIE;
|
||||
@@ -3509,7 +3512,8 @@ void InitAnimationSurfacesPerBodytype( )
|
||||
|
||||
// TANK
|
||||
gubAnimSurfaceIndex[ TANK_NE ][ STANDING ] = TANKNE_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NE ][ WALKING ] = TANKNE_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NE ][ WALKING ] = TANKNE_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NE ][ WALK_BACKWARDS ] = TANKNE_READY;
|
||||
gubAnimSurfaceIndex[ TANK_NE ][ TANK_SHOOT ] = TANKNE_SHOOT;
|
||||
gubAnimSurfaceIndex[ TANK_NE ][ TANK_BURST ] = TANKNE_SHOOT;
|
||||
gubAnimSurfaceIndex[ TANK_NE ][ VEHICLE_DIE ] = TANKNE_DIE;
|
||||
@@ -3518,17 +3522,23 @@ void InitAnimationSurfacesPerBodytype( )
|
||||
// ELDORADO
|
||||
gubAnimSurfaceIndex[ ELDORADO ][ STANDING ] = ELDORADO_BASIC;
|
||||
gubAnimSurfaceIndex[ ELDORADO ][ WALKING ] = ELDORADO_BASIC;
|
||||
gubAnimSurfaceIndex[ ELDORADO ][ RUNNING ] = ELDORADO_BASIC;
|
||||
gubAnimSurfaceIndex[ ELDORADO ][ WALK_BACKWARDS ] = ELDORADO_BASIC;
|
||||
gubAnimSurfaceIndex[ ELDORADO ][ VEHICLE_DIE ] = ELDORADO_DIE;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -1477,9 +1477,22 @@ UINT32 UIHandleMOnTerrain( UI_EVENT *pUIEvent )
|
||||
gUIActionModeChangeDueToMouseOver = FALSE;
|
||||
|
||||
// If we are a vehicle..... just show an X
|
||||
//if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||
//{
|
||||
// if ( ( OK_ENTERABLE_VEHICLE( pSoldier ) ) )
|
||||
// {
|
||||
// if ( !UIHandleOnMerc( TRUE ) )
|
||||
// {
|
||||
// guiNewUICursor = FLOATING_X_UICURSOR;
|
||||
// return( GAME_SCREEN );
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
// If we are a passenger or driver just show an X
|
||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||
{
|
||||
if ( ( OK_ENTERABLE_VEHICLE( pSoldier ) ) )
|
||||
if ( ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER )) )
|
||||
{
|
||||
if ( !UIHandleOnMerc( TRUE ) )
|
||||
{
|
||||
|
||||
@@ -6287,13 +6287,14 @@ void MercFacePanelCallback( MOUSE_REGION * pRegion, INT32 iReason )
|
||||
{
|
||||
if ( !gfInItemPickupMenu && gpItemPointer == NULL )
|
||||
{
|
||||
if ( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||
{
|
||||
pVehicle = GetSoldierStructureForVehicle( MercPtrs[ ubSoldierID ]->iVehicleId );
|
||||
//if ( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||
//if ( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER ) )
|
||||
//{
|
||||
// pVehicle = GetSoldierStructureForVehicle( MercPtrs[ ubSoldierID ]->iVehicleId );
|
||||
|
||||
HandleLocateSelectMerc( pVehicle->ubID, 0 );
|
||||
}
|
||||
else
|
||||
// HandleLocateSelectMerc( pVehicle->ubID, 0 );
|
||||
//}
|
||||
//else
|
||||
{
|
||||
if ( !InOverheadMap( ) )
|
||||
{
|
||||
@@ -6350,7 +6351,8 @@ void MercFacePanelCallback( MOUSE_REGION * pRegion, INT32 iReason )
|
||||
if ( !InOverheadMap( ) )
|
||||
{
|
||||
// Only if guy is not dead!
|
||||
if ( !( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & SOLDIER_DEAD ) && !AM_AN_EPC( MercPtrs[ ubSoldierID ] ) && !( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
|
||||
//if ( !( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & SOLDIER_DEAD ) && !AM_AN_EPC( MercPtrs[ ubSoldierID ] ) && !( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
|
||||
if ( !( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & SOLDIER_DEAD ) && !AM_AN_EPC( MercPtrs[ ubSoldierID ] ) )
|
||||
{
|
||||
gfSwitchPanel = TRUE;
|
||||
gbNewPanel = SM_PANEL;
|
||||
@@ -6846,8 +6848,17 @@ void TMClickFirstHandInvCallback( MOUSE_REGION * pRegion, INT32 iReason )
|
||||
|
||||
if (iReason == MSYS_CALLBACK_REASON_LBUTTON_UP )
|
||||
{
|
||||
// Change to use cursor mode...
|
||||
guiPendingOverrideEvent = A_ON_TERRAIN;
|
||||
// anv: select vehicle by clicking on the steering wheel
|
||||
if ( MercPtrs[ ubSoldierID ]->flags.uiStatusFlags & SOLDIER_DRIVER )
|
||||
{
|
||||
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( MercPtrs[ ubSoldierID ]->iVehicleId );
|
||||
HandleLocateSelectMerc( pVehicle->ubID, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Change to use cursor mode...
|
||||
guiPendingOverrideEvent = A_ON_TERRAIN;
|
||||
}
|
||||
}
|
||||
|
||||
if (iReason == MSYS_CALLBACK_REASON_RBUTTON_UP )
|
||||
|
||||
@@ -916,7 +916,7 @@ void PopupMovementMenu( UI_EVENT *pUIEvent )
|
||||
//SetButtonSavedRect( iActionIcons[ RUN_ICON ] );
|
||||
ButtonList[ iActionIcons[ RUN_ICON ] ]->UserData[0] = (UINT32)pUIEvent;
|
||||
|
||||
if ( pSoldier->MercInWater( ) || ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) || ( pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT ) )
|
||||
if ( pSoldier->MercInWater( ) || ( pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT ) )
|
||||
{
|
||||
DisableButton( iActionIcons[ RUN_ICON ] );
|
||||
}
|
||||
|
||||
+39
-4
@@ -2504,6 +2504,41 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
|
||||
{
|
||||
// Adjust AP/Breathing points to move
|
||||
DeductPoints( pSoldier, sAPCost, sBPCost, MOVEMENT_INTERRUPT );
|
||||
|
||||
// anv: deduct points from vehicle passengers to prevent time travel paradoxes... yeah yeah, you get the idea
|
||||
if ( gTacticalStatus.uiFlags & TURNBASED && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleMode )
|
||||
{
|
||||
INT32 iId = pSoldier->bVehicleID;
|
||||
// Loop through passengers and update each guy's AP
|
||||
for( INT32 iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
||||
{
|
||||
SOLDIERTYPE *pPassenger = pVehicleList[ iId ].pPassengers[ iCounter ];
|
||||
if( pPassenger != NULL )
|
||||
{
|
||||
//INT16 sPassengerAPCost = pPassenger->bInitialActionPoints * sAPCost / max(1, pSoldier->bInitialActionPoints) * gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleScale / 100;
|
||||
INT16 sPassengerAPCost = 0;
|
||||
switch( gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleMode )
|
||||
{
|
||||
case 1:
|
||||
sPassengerAPCost = sAPCost;
|
||||
break;
|
||||
case 2:
|
||||
sPassengerAPCost = pPassenger->bInitialActionPoints * sAPCost / max(1, pSoldier->bInitialActionPoints);
|
||||
break;
|
||||
case 3:
|
||||
INT16 sPassengerAPTreshold = pPassenger->bInitialActionPoints * ( pSoldier->bActionPoints - sAPCost ) / max(1, pSoldier->bInitialActionPoints);
|
||||
sPassengerAPCost = pPassenger->bInitialActionPoints * sAPCost / max(1, pSoldier->bInitialActionPoints) ;
|
||||
if( pPassenger->bActionPoints - sPassengerAPCost > sPassengerAPTreshold )
|
||||
sPassengerAPCost = max( sPassengerAPCost, ( pPassenger->bActionPoints - sPassengerAPCost ) - sPassengerAPTreshold );
|
||||
else
|
||||
sPassengerAPCost = 0;
|
||||
break;
|
||||
}
|
||||
sPassengerAPCost = sPassengerAPCost * gGameExternalOptions.ubAPSharedAmongPassengersAndVehicleScale / 100;
|
||||
DeductPoints( pPassenger, sPassengerAPCost, 0, MOVEMENT_INTERRUPT );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OK, let's check for monsters....
|
||||
@@ -4449,7 +4484,7 @@ UINT8 FindNextActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL
|
||||
|
||||
if ( fGoodForLessOKLife )
|
||||
{
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && pTeamSoldier->bAssignment < ON_DUTY && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && ( pTeamSoldier->bAssignment < ON_DUTY || pTeamSoldier->bAssignment == VEHICLE ) && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
{
|
||||
return( (UINT8)cnt );
|
||||
}
|
||||
@@ -4480,7 +4515,7 @@ UINT8 FindNextActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL
|
||||
|
||||
if ( fGoodForLessOKLife )
|
||||
{
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && pTeamSoldier->bAssignment < ON_DUTY && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && ( pTeamSoldier->bAssignment < ON_DUTY || pTeamSoldier->bAssignment == VEHICLE ) && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
{
|
||||
return( (UINT8)cnt );
|
||||
}
|
||||
@@ -4559,7 +4594,7 @@ UINT8 FindPrevActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL
|
||||
if ( fGoodForLessOKLife )
|
||||
{
|
||||
// Check for bLife > 0
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && pTeamSoldier->bAssignment < ON_DUTY && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && ( pTeamSoldier->bAssignment < ON_DUTY || pTeamSoldier->bAssignment == VEHICLE ) && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
{
|
||||
return( (UINT8)cnt );
|
||||
}
|
||||
@@ -4589,7 +4624,7 @@ UINT8 FindPrevActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL
|
||||
|
||||
if ( fGoodForLessOKLife )
|
||||
{
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && pTeamSoldier->bAssignment < ON_DUTY && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
if ( pTeamSoldier->stats.bLife > 0 && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == gbPlayerNum && ( pTeamSoldier->bAssignment < ON_DUTY || pTeamSoldier->bAssignment == VEHICLE ) && OK_INTERRUPT_MERC( pTeamSoldier ) && pSoldier->bAssignment == pTeamSoldier->bAssignment )
|
||||
{
|
||||
return( (UINT8)cnt );
|
||||
}
|
||||
|
||||
+13
-13
@@ -4849,19 +4849,19 @@ INT32 PlotPath( SOLDIERTYPE *pSold, INT32 sDestGridNo, INT8 bCopyRoute, INT8 bPl
|
||||
}
|
||||
|
||||
// Are we a vehicle?
|
||||
if ( pSold->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
// did we exceed WALK cost?
|
||||
if ( sPointsSwat > sAPBudget)
|
||||
{
|
||||
sFootOrderIndex = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
sFootOrderIndex = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
//if ( pSold->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
//{
|
||||
// // did we exceed WALK cost?
|
||||
// if ( sPointsSwat > sAPBudget)
|
||||
// {
|
||||
// sFootOrderIndex = 4;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// sFootOrderIndex = 3;
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
{
|
||||
// did we exceed CRAWL cost?
|
||||
if (sFootOrderIndex == 0 && sPointsCrawl > sAPBudget)
|
||||
|
||||
@@ -880,6 +880,12 @@ void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, UINT8 ub
|
||||
sAPCost = 0;
|
||||
}
|
||||
|
||||
// anv: there were weird things going on here, deducting fuel for strategic travel happens elsewhere anyway
|
||||
if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
iBPCost = 0;
|
||||
}
|
||||
|
||||
// Get New points
|
||||
sNewAP = pSoldier->bActionPoints - sAPCost;
|
||||
|
||||
|
||||
@@ -1728,7 +1728,8 @@ void HandleVehicleMovementSound( SOLDIERTYPE *pSoldier, BOOLEAN fOn )
|
||||
{
|
||||
if ( pVehicle->iMovementSoundID == NO_SAMPLE )
|
||||
{
|
||||
pVehicle->iMovementSoundID = PlayJA2Sample( pVehicle->iMoveSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
// anv: will be played in InternalPlaySoldierFootstepSound
|
||||
//pVehicle->iMovementSoundID = PlayJA2Sample( pVehicle->iMoveSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3384,7 +3385,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
|
||||
|| usNewState == SWATTING_WK)
|
||||
{
|
||||
// CHECK FOR SIDEWAYS!
|
||||
if ( this->ubDirection == gPurpendicularDirection[ this->ubDirection ][ this->pathing.usPathingData[ this->pathing.usPathIndex ] ] )
|
||||
if ( !( this->flags.uiStatusFlags & SOLDIER_VEHICLE ) && this->ubDirection == gPurpendicularDirection[ this->ubDirection ][ this->pathing.usPathingData[ this->pathing.usPathIndex ] ] )
|
||||
{
|
||||
// We are perpendicular!
|
||||
// SANDRO - wait wait wait!!! We need to determine if gonna sidestep with weapon raised
|
||||
@@ -5289,9 +5290,10 @@ UINT16 SOLDIERTYPE::GetMoveStateBasedOnStance( UINT8 ubStanceHeight )
|
||||
switch ( ubStanceHeight )
|
||||
{
|
||||
case ANIM_STAND:
|
||||
if ( this->flags.fUIMovementFast && !( this->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
||||
//if ( this->flags.fUIMovementFast && !( this->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
||||
if ( this->flags.fUIMovementFast )
|
||||
{
|
||||
return( RUNNING );
|
||||
return( RUNNING );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7876,14 +7878,29 @@ void SOLDIERTYPE::TurnSoldier( void )
|
||||
INT32 cnt;
|
||||
|
||||
// If we are a vehicle... DON'T TURN!
|
||||
// anv: YES PLIZ DO
|
||||
if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
if ( this->ubBodyType != TANK_NW && this->ubBodyType != TANK_NE )
|
||||
//if ( this->ubBodyType != TANK_NW && this->ubBodyType != TANK_NE )
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
// need to turn around passengers inside
|
||||
INT32 iId = this->bVehicleID;
|
||||
|
||||
// Loop through passengers and update each guy's rotation
|
||||
for( INT32 iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
||||
{
|
||||
return;
|
||||
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
|
||||
{
|
||||
pVehicleList[ iId ].pPassengers[ iCounter ]->flags.fDontChargeTurningAPs = TRUE;
|
||||
pVehicleList[ iId ].pPassengers[ iCounter ]->EVENT_SetSoldierDesiredDirection( this->pathing.bDesiredDirection );
|
||||
//pVehicleList[ iId ].pPassengers[ iCounter ]->pathing.bDesiredDirection = this->pathing.bDesiredDirection;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Lesh: patch for "Bug: Enemy turns around in turn based mode!"
|
||||
//else // Lesh: patch for "Bug: Enemy turns around in turn based mode!"
|
||||
{
|
||||
// in case of errors in turning tasks
|
||||
if ( this->pathing.bDesiredDirection > 7 || this->pathing.bDesiredDirection < 0)
|
||||
@@ -8549,8 +8566,8 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier
|
||||
UINT32 uiTerrainDelay;
|
||||
UINT32 uiSpeed = 0;
|
||||
|
||||
INT8 bBreathDef, bLifeDef;
|
||||
INT16 bAgilDef;
|
||||
INT8 bBreathDef = 0, bLifeDef = 0;
|
||||
INT16 bAgilDef = 0;
|
||||
INT8 bAdditional = 0;
|
||||
|
||||
// for those animations which have a speed of zero, we have to calculate it
|
||||
@@ -8675,13 +8692,29 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier
|
||||
uiTerrainDelay = 40; // standing still
|
||||
}
|
||||
|
||||
bBreathDef = 50 - ( pStatsSoldier->bBreath / 2 );
|
||||
if( !(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) )
|
||||
{
|
||||
bBreathDef = 50 - ( pStatsSoldier->bBreath / 2 );
|
||||
|
||||
if ( bBreathDef > 30 )
|
||||
bBreathDef = 30;
|
||||
if ( bBreathDef > 30 )
|
||||
bBreathDef = 30;
|
||||
|
||||
bAgilDef = 50 - ( EffectiveAgility( pStatsSoldier, FALSE ) / 4 );
|
||||
bLifeDef = 50 - ( pStatsSoldier->stats.bLife / 2 );
|
||||
bAgilDef = 50 - ( EffectiveAgility( pStatsSoldier, FALSE ) / 4 );
|
||||
bLifeDef = 50 - ( pStatsSoldier->stats.bLife / 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// anv: vehicles have no agility and making them slower with less fuel would make no sense
|
||||
// instead take gear into consideration here
|
||||
if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE && pSoldier->usAnimState == RUNNING )
|
||||
{
|
||||
bAgilDef = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
bAgilDef = 30;
|
||||
}
|
||||
}
|
||||
|
||||
uiTerrainDelay += ( bLifeDef + bBreathDef + bAgilDef + bAdditional );
|
||||
|
||||
@@ -10237,7 +10270,9 @@ BOOLEAN SOLDIERTYPE::InternalDoMercBattleSound( UINT8 ubBattleSoundID, INT8 bSpe
|
||||
if ( ( this->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
||||
{
|
||||
// Pick a passenger from vehicle....
|
||||
pSoldier = PickRandomPassengerFromVehicle( this );
|
||||
//pSoldier = PickRandomPassengerFromVehicle( this );
|
||||
// anv: as vehicles can be controlled, get a driver
|
||||
pSoldier = GetDriver(this->bVehicleID);
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
{
|
||||
@@ -20453,6 +20488,12 @@ void InternalPlaySoldierFootstepSound( SOLDIERTYPE * pSoldier )
|
||||
PlaySoldierJA2Sample( pSoldier->ubID, ubSoundBase + pSoldier->ubLastFootPrintSound, RATE_11025, SoundVolume( bVolume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// anv: vehicle sounds
|
||||
//PlaySoldierJA2Sample( pSoldier->ubID, S_VECH1_MOVE, RATE_11025, SoundVolume( bVolume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE );
|
||||
PlaySoldierJA2Sample( pSoldier->ubID, pVehicleList[ pSoldier->bVehicleID ].iMoveSound, RATE_11025, SoundVolume( bVolume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
void PlaySoldierFootstepSound( SOLDIERTYPE *pSoldier )
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
#define OK_ENEMY_MERC( p ) ( !p->aiData.bNeutral && (p->bSide != gbPlayerNum ) && p->stats.bLife >= OKLIFE && (p->bTeam < 5 ))
|
||||
|
||||
// Checks if our guy can be controllable .... checks bInSector, team, on duty, etc...
|
||||
#define OK_CONTROLLABLE_MERC( p ) ( p->stats.bLife >= OKLIFE && p->bActive && p->bInSector && p->bTeam == gbPlayerNum && p->bAssignment < ON_DUTY )
|
||||
//#define OK_CONTROLLABLE_MERC( p ) ( p->stats.bLife >= OKLIFE && p->bActive && p->bInSector && p->bTeam == gbPlayerNum && p->bAssignment < ON_DUTY )
|
||||
#define OK_CONTROLLABLE_MERC( p ) ( p->stats.bLife >= OKLIFE && p->bActive && p->bInSector && p->bTeam == gbPlayerNum && ( p->bAssignment < ON_DUTY || p->bAssignment == VEHICLE ) )
|
||||
|
||||
// Checks if our guy can be controllable .... checks bInSector, team, on duty, etc...
|
||||
#define OK_INSECTOR_MERC( p ) ( p->stats.bLife >= OKLIFE && p->bActive && p->bInSector && p->bTeam == gbPlayerNum && p->bAssignment < ON_DUTY )
|
||||
|
||||
@@ -5565,7 +5565,15 @@ INT8 HandleMoveModeInteractiveClick( INT32 usMapPos, UINT32 *puiNewEvent )
|
||||
// ATE: If we are a vehicle, no moving!
|
||||
if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ VEHICLE_CANT_MOVE_IN_TACTICAL ] );
|
||||
// anv: yes moving
|
||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ VEHICLE_CANT_MOVE_IN_TACTICAL ] );
|
||||
//return( -3 );
|
||||
}
|
||||
|
||||
if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||
{
|
||||
// anv: there's some weird bug with moving invisible passengers after loading game, that should solve it
|
||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ VEHICLE_CANT_MOVE_IN_TACTICAL ] );
|
||||
return( -3 );
|
||||
}
|
||||
|
||||
@@ -5923,7 +5931,12 @@ void ToggleStealthMode( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
||||
if ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ giSMStealthButton ]->uiFlags & BUTTON_ENABLED ) )
|
||||
{
|
||||
{
|
||||
if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// ATE: Toggle stealth
|
||||
if ( gpSMCurrentMerc != NULL && pSoldier->ubID == gpSMCurrentMerc->ubID )
|
||||
{
|
||||
|
||||
+67
-4
@@ -41,6 +41,9 @@
|
||||
#include "Queen Command.h"
|
||||
#endif
|
||||
|
||||
#include "Points.h"
|
||||
#include "Init.h"
|
||||
|
||||
//INT8 gubVehicleMovementGroups[ MAX_VEHICLES ];
|
||||
std::vector<INT8> gubVehicleMovementGroups (MAX_VEHICLES, 0);
|
||||
|
||||
@@ -472,7 +475,7 @@ BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecificSeat, UINT8 ubSeatIndex )
|
||||
{
|
||||
INT32 iCounter = 0;
|
||||
UINT32 vCount = 0;
|
||||
@@ -556,8 +559,11 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
|
||||
if ( pVehicleSoldier )
|
||||
{
|
||||
// anv: when we enter vehicle in battle, we need to unbusy soldier BEFORE we change selected soldier or else we'll get lock
|
||||
UnSetUIBusy( pSoldier->ubID );
|
||||
|
||||
// can't call SelectSoldier in mapscreen, that will initialize interface panels!!!
|
||||
if ( guiCurrentScreen == GAME_SCREEN )
|
||||
if ( guiCurrentScreen == GAME_SCREEN )
|
||||
{
|
||||
SelectSoldier( pVehicleSoldier->ubID, FALSE, TRUE );
|
||||
}
|
||||
@@ -713,6 +719,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
INT32 iCounter = 0;
|
||||
BOOLEAN fSoldierLeft = FALSE;
|
||||
BOOLEAN fSoldierFound = FALSE;
|
||||
BOOLEAN fNewDriverNeeded = FALSE;
|
||||
SOLDIERTYPE *pVehicleSoldier;
|
||||
UINT8 iOldGroupID=0;
|
||||
|
||||
@@ -743,6 +750,12 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
pVehicleList[ iId ].pPassengers[ iCounter ] = NULL;
|
||||
|
||||
|
||||
// anv: make sure someone else becomes driver if he was the previous one
|
||||
if( pSoldier->flags.uiStatusFlags & SOLDIER_DRIVER )
|
||||
{
|
||||
fNewDriverNeeded = TRUE;
|
||||
}
|
||||
|
||||
pSoldier->flags.uiStatusFlags &= ( ~( SOLDIER_DRIVER | SOLDIER_PASSENGER ) );
|
||||
|
||||
// check if anyone left in vehicle
|
||||
@@ -752,6 +765,14 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
|
||||
{
|
||||
fSoldierLeft = TRUE;
|
||||
if( fNewDriverNeeded )
|
||||
{
|
||||
SOLDIERTYPE* pNewDriver = pVehicleList[ iId ].pPassengers[ iCounter ];
|
||||
pNewDriver->flags.uiStatusFlags |= SOLDIER_DRIVER;
|
||||
pNewDriver->flags.uiStatusFlags &= ~(SOLDIER_PASSENGER);
|
||||
pVehicleList[ iId ].ubDriver = pNewDriver->ubID;
|
||||
fNewDriverNeeded = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -801,6 +822,8 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
CancelPathForVehicle( &( pVehicleList[ iId ] ), FALSE );
|
||||
}
|
||||
|
||||
pVehicleSoldier->EVENT_StopMerc( pVehicleSoldier->sGridNo, pVehicleSoldier->ubDirection );
|
||||
|
||||
// if the vehicle was abandoned between sectors
|
||||
if ( pVehicleList[ iId ].fBetweenSectors )
|
||||
{
|
||||
@@ -1588,16 +1611,42 @@ BOOLEAN TakeSoldierOutOfVehicle( SOLDIERTYPE *pSoldier )
|
||||
|
||||
|
||||
|
||||
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier )
|
||||
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpecificSeat, UINT8 ubSeatIndex )
|
||||
{
|
||||
|
||||
// TEST IF IT'S VALID...
|
||||
if ( pVehicle->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
// Is there room...
|
||||
if ( IsEnoughSpaceInVehicle( pVehicle->bVehicleID ) )
|
||||
{
|
||||
// anv: check if preferred seat is already taken, if so automatically choose another
|
||||
if( fSpecificSeat )
|
||||
{
|
||||
if ( pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] != NULL )
|
||||
{
|
||||
fSpecificSeat = FALSE;
|
||||
ubSeatIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
INT16 sAPCost = APBPConstants[AP_ENTER_VEHICLE];
|
||||
//Are we currently in combat?
|
||||
if(gTacticalStatus.uiFlags & INCOMBAT)
|
||||
{
|
||||
if(EnoughPoints(pSoldier, sAPCost, 0, TRUE))
|
||||
DeductPoints(pSoldier, sAPCost, 0);
|
||||
else
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
// anv: since now they can shoot it's important to set passenger to proper stance
|
||||
SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH );
|
||||
// bInitialActionPoints - point in time where soldier and vehicle start sharing timeline
|
||||
pSoldier->bInitialActionPoints = pSoldier->bActionPoints;
|
||||
|
||||
// OK, add....
|
||||
AddSoldierToVehicle( pSoldier, pVehicle->bVehicleID );
|
||||
AddSoldierToVehicle( pSoldier, pVehicle->bVehicleID, fSpecificSeat, ubSeatIndex );
|
||||
|
||||
if ( !(guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
|
||||
{
|
||||
@@ -1651,6 +1700,16 @@ BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
INT16 sAPCost = APBPConstants[AP_EXIT_VEHICLE];
|
||||
//Are we currently in combat?
|
||||
if(gTacticalStatus.uiFlags & INCOMBAT)
|
||||
{
|
||||
if(EnoughPoints(pSoldier, sAPCost, 0, TRUE))
|
||||
DeductPoints(pSoldier, sAPCost, 0);
|
||||
else
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
// TEST IF IT'S VALID...
|
||||
if ( pVehicle->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||
{
|
||||
@@ -1677,6 +1736,10 @@ BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier )
|
||||
// Add to sector....
|
||||
pSoldier->EVENT_SetSoldierPosition( CenterX( sGridNo ), CenterY( sGridNo ) );
|
||||
|
||||
// anv: since now they can shoot it's important to set passenger to proper stance
|
||||
// namely, back to standing, because we set them to crouching when entering
|
||||
SendChangeSoldierStanceEvent( pSoldier, ANIM_STAND );
|
||||
|
||||
// Update visiblity.....
|
||||
HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO );
|
||||
|
||||
|
||||
+20
-2
@@ -33,6 +33,24 @@ typedef struct
|
||||
|
||||
} NEW_CAR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 ubSeatIndex; // index inside a vehicle (corresponding to .pPassengers[counter])
|
||||
CHAR16 zSeatName[16]; // name (to display on entering menu and on team panel)
|
||||
BOOLEAN fDriver; // seat has to be taken to steer the vehicle
|
||||
BOOLEAN fView; // can look out of vehicle
|
||||
BOOLEAN fDriveBy; // can shoot from this seat
|
||||
BOOLEAN fSeatBelt; // for collisions
|
||||
BOOLEAN fHidden; // merc on this seat is invisible from outside - spy as a driver smuggling in others?
|
||||
UINT8 ubRotation; // rotation in relation to vehicle
|
||||
UINT8 ubTunnelVision; // tunnel vision (small windows, etc.)
|
||||
UINT8 ubProtection; // influence probability vehicle will be hit instead of passenger
|
||||
UINT8 ubCompartment; // passenger can switch to another seat in the same compartment without exiting vehicle
|
||||
UINT8 ubStructureLink; // link to physical part of structure (for hit calculations)
|
||||
UINT32 usMountedGun; // passenger on this seat will use this gun instead of his own, link to Items.xml
|
||||
|
||||
} VEHICLE_SEAT;
|
||||
|
||||
extern NEW_CAR gNewVehicle[NUM_PROFILES];
|
||||
|
||||
extern BOOLEAN LoadNewVehiclesToSaveGameFile( HWFILE hFile );
|
||||
@@ -313,7 +331,7 @@ BOOLEAN AnyAccessibleVehiclesInSoldiersSector( SOLDIERTYPE *pSoldier );
|
||||
BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId );
|
||||
|
||||
// add soldier to Vehicle
|
||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId );
|
||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecificSeat = FALSE, UINT8 ubSeatIndex = 0 );
|
||||
|
||||
// remove soldier from vehicle
|
||||
BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId );
|
||||
@@ -369,7 +387,7 @@ INT32 GetNumberInVehicle( INT32 iId );
|
||||
// grab # in vehicle skipping EPCs (who aren't allowed to drive :-)
|
||||
INT32 GetNumberOfNonEPCsInVehicle( INT32 iId );
|
||||
|
||||
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier );
|
||||
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpecificSeat = FALSE, UINT8 ubSeatIndex = 0 );
|
||||
|
||||
SOLDIERTYPE *GetDriver( INT32 iID );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user