mirror of
https://github.com/1dot13/source.git
synced 2026-09-09 14:46:05 +02:00
Driveable vehicle Update: Externalized vehicle seats (by anv)
- externalised vehicle seats (TableData\Vehicles.xml) influence position of passenger, field of view, ability to shoot and being hidden, - seat can chosen by using ctrl+RMB on vehicle (ctrl + LMB just takes the first visible seat) - seats can be changed or swapped while inside vehicle, - remade JSD files for cars, - vehicles aren't transparent anymore, - vehicles are louder than people, depending how fast they move. see: http://www.bears-pit.com/board/ubbthreads.php/topics/332790/5.html git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7212 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -16750,7 +16750,12 @@ SOLDIERTYPE *GetSelectedAssignSoldier( BOOLEAN fNullOK )
|
|||||||
{
|
{
|
||||||
// better be an active person, not a vehicle
|
// better be an active person, not a vehicle
|
||||||
Assert( pSoldier->bActive );
|
Assert( pSoldier->bActive );
|
||||||
Assert( !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) );
|
// anv: don't assert, handle...
|
||||||
|
//Assert( !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) );
|
||||||
|
if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||||
|
{
|
||||||
|
pSoldier = GetDriver( pSoldier->iVehicleId );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return( pSoldier );
|
return( pSoldier );
|
||||||
|
|||||||
+15
-15
@@ -777,27 +777,27 @@ AnimationStructureType gAnimStructureDatabase[ TOTALBODYTYPES ][ NUM_STRUCT_IDS
|
|||||||
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD", NULL, // default
|
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD", NULL, // default
|
||||||
|
|
||||||
//ELDORADO
|
//ELDORADO
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
|
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
|
||||||
|
|
||||||
//ICECREAMTRUCK
|
//ICECREAMTRUCK
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
|
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
|
||||||
|
|
||||||
//JEEP
|
//JEEP
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
|
"ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
|
||||||
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
|
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
+37
-14
@@ -1491,14 +1491,14 @@ UINT32 UIHandleMOnTerrain( UI_EVENT *pUIEvent )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are a passenger or driver just show an X
|
// If we are a passenger or driver just show ?
|
||||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||||
{
|
{
|
||||||
if ( ( pSoldier->flags.uiStatusFlags & ( SOLDIER_PASSENGER )) )
|
if ( ( pSoldier->flags.uiStatusFlags & ( SOLDIER_PASSENGER )) )
|
||||||
{
|
{
|
||||||
if ( !UIHandleOnMerc( TRUE ) )
|
if ( !UIHandleOnMerc( TRUE ) )
|
||||||
{
|
{
|
||||||
guiNewUICursor = FLOATING_X_UICURSOR;
|
guiNewUICursor = INVALID_ACTION_UICURSOR;
|
||||||
return( GAME_SCREEN );
|
return( GAME_SCREEN );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3219,16 +3219,6 @@ UINT32 UIHandleHCOnTerrain( UI_EVENT *pUIEvent )
|
|||||||
return( GAME_SCREEN );
|
return( GAME_SCREEN );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are a passenger or driver just show an ?
|
|
||||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
||||||
{
|
|
||||||
if ( ( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_DRIVER | SOLDIER_PASSENGER )) )
|
|
||||||
{
|
|
||||||
guiNewUICursor = INVALID_ACTION_UICURSOR;
|
|
||||||
return( GAME_SCREEN );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are out of breath, no cursor...
|
// If we are out of breath, no cursor...
|
||||||
if ( pSoldier->bBreath < OKBREATH && pSoldier->bCollapsed )
|
if ( pSoldier->bBreath < OKBREATH && pSoldier->bCollapsed )
|
||||||
{
|
{
|
||||||
@@ -3445,6 +3435,20 @@ BOOLEAN UIHandleOnMerc( BOOLEAN fMovementMode )
|
|||||||
// Check if this guy is on the enemy team....
|
// Check if this guy is on the enemy team....
|
||||||
if ( !pSoldier->aiData.bNeutral && (pSoldier->bSide != gbPlayerNum ) )
|
if ( !pSoldier->aiData.bNeutral && (pSoldier->bSide != gbPlayerNum ) )
|
||||||
{
|
{
|
||||||
|
// anv: don't switch if passengers are blocked from attacking
|
||||||
|
if( gusSelectedSoldier != NOBODY )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pSelectedSoldier = MercPtrs[gusSelectedSoldier];
|
||||||
|
if( pSelectedSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSelectedSoldier->iVehicleId );
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSelectedSoldier );
|
||||||
|
if( gNewVehicle[ pVehicleList[ pSelectedSoldier->iVehicleId ].ubVehicleType ].VehicleSeats[bSeatIndex].fBlockedShots == TRUE )
|
||||||
|
{
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
gUIActionModeChangeDueToMouseOver = TRUE;
|
gUIActionModeChangeDueToMouseOver = TRUE;
|
||||||
|
|
||||||
guiPendingOverrideEvent = M_CHANGE_TO_ACTION;
|
guiPendingOverrideEvent = M_CHANGE_TO_ACTION;
|
||||||
@@ -3531,7 +3535,7 @@ void UIHandleSoldierStanceChange( UINT8 ubSoldierID, INT8 bNewStance )
|
|||||||
{
|
{
|
||||||
SOLDIERTYPE *pSoldier = MercPtrs[ ubSoldierID ];
|
SOLDIERTYPE *pSoldier = MercPtrs[ ubSoldierID ];
|
||||||
|
|
||||||
if( pSoldier->flags.uiStatusFlags & SOLDIER_DRIVER )
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
{
|
{
|
||||||
pSoldier = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
pSoldier = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
}
|
}
|
||||||
@@ -6371,11 +6375,30 @@ INT8 UIHandleInteractiveTilesAndItemsOnTerrain( SOLDIERTYPE *pSoldier, INT32 usM
|
|||||||
|
|
||||||
gfBeginVehicleCursor = FALSE;
|
gfBeginVehicleCursor = FALSE;
|
||||||
|
|
||||||
|
// If we are a passenger or driver just show an ?
|
||||||
|
if ( ( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_DRIVER | SOLDIER_PASSENGER )) )
|
||||||
|
{
|
||||||
|
// unless we are over our own vehicle, then we can call vehicle menu
|
||||||
|
if( gfUIFullTargetFound )
|
||||||
|
{
|
||||||
|
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
||||||
|
if( pSoldier->iVehicleId == pTSoldier->bVehicleID )
|
||||||
|
{
|
||||||
|
guiNewUICursor = ENTER_VEHICLE_UICURSOR;
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guiNewUICursor = INVALID_ACTION_UICURSOR;
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
if ( gfUIFullTargetFound )
|
if ( gfUIFullTargetFound )
|
||||||
{
|
{
|
||||||
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
||||||
|
|
||||||
if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 )
|
// anv: added condition - make sure we won't put vehicle in another vehicle
|
||||||
|
if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 && !( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER | SOLDIER_VEHICLE ) ) )
|
||||||
|
//if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 )
|
||||||
{
|
{
|
||||||
// grab number of occupants in vehicles
|
// grab number of occupants in vehicles
|
||||||
if ( fItemsOnlyIfOnIntTiles )
|
if ( fItemsOnlyIfOnIntTiles )
|
||||||
|
|||||||
@@ -343,6 +343,7 @@ UINT32 UIHandleLUIEndLock( UI_EVENT *pUIEvent );
|
|||||||
void BeginDisplayTimedCursor( UINT32 uiCursorID, UINT32 uiDelay );
|
void BeginDisplayTimedCursor( UINT32 uiCursorID, UINT32 uiDelay );
|
||||||
|
|
||||||
void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent );
|
void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent );
|
||||||
|
void HandleHandCursorRightClick( INT32 usMapPos, UINT32 *puiNewEvent );
|
||||||
INT8 HandleMoveModeInteractiveClick( INT32 usMapPos, UINT32 *puiNewEvent );
|
INT8 HandleMoveModeInteractiveClick( INT32 usMapPos, UINT32 *puiNewEvent );
|
||||||
|
|
||||||
BOOLEAN HandleUIReloading( SOLDIERTYPE *pSoldier );
|
BOOLEAN HandleUIReloading( SOLDIERTYPE *pSoldier );
|
||||||
|
|||||||
@@ -5693,6 +5693,13 @@ void RenderTEAMPanel( BOOLEAN fDirty )
|
|||||||
// clear pStr value
|
// clear pStr value
|
||||||
swprintf( pStr, L"");
|
swprintf( pStr, L"");
|
||||||
|
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( bSeatIndex != (-1) )
|
||||||
|
{
|
||||||
|
swprintf( sTemp, L"%s\n", gNewVehicle[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ].VehicleSeats[ bSeatIndex ].zSeatName );
|
||||||
|
wcscat( pStr, sTemp );
|
||||||
|
}
|
||||||
|
|
||||||
if (gGameOptions.fNewTraitSystem) // SANDRO - old/new traits check
|
if (gGameOptions.fNewTraitSystem) // SANDRO - old/new traits check
|
||||||
{
|
{
|
||||||
UINT8 ubTempSkillArray[30];
|
UINT8 ubTempSkillArray[30];
|
||||||
@@ -5716,7 +5723,8 @@ void RenderTEAMPanel( BOOLEAN fDirty )
|
|||||||
|
|
||||||
if ( bNumSkillTraits == 0 )
|
if ( bNumSkillTraits == 0 )
|
||||||
{
|
{
|
||||||
swprintf( pStr, L"%s", pPersonnelScreenStrings[ PRSNL_TXT_NOSKILLS ] );
|
swprintf( sTemp, L"%s", pPersonnelScreenStrings[ PRSNL_TXT_NOSKILLS ] );
|
||||||
|
wcscat( pStr, sTemp );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -6974,8 +6982,8 @@ void AddPlayerToInterfaceTeamSlot( UINT8 ubID )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if ( !( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
|
if ( !( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
|
||||||
//{
|
{
|
||||||
if ( !PlayerExistsInSlot( ubID ) )
|
if ( !PlayerExistsInSlot( ubID ) )
|
||||||
{
|
{
|
||||||
// Find a free slot
|
// Find a free slot
|
||||||
@@ -6999,38 +7007,38 @@ void AddPlayerToInterfaceTeamSlot( UINT8 ubID )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//}
|
}
|
||||||
//else
|
else
|
||||||
//{
|
{
|
||||||
// // anv: for passengers, position on team panel will be linked with seat in vehicle
|
// anv: for passengers, position on team panel will be linked with seat in vehicle
|
||||||
// if ( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
if ( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
// {
|
{
|
||||||
// SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( MercPtrs[ ubID ]->iVehicleId );
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( MercPtrs[ ubID ]->iVehicleId );
|
||||||
// if( pVehicle != NULL )
|
if( pVehicle != NULL )
|
||||||
// {
|
{
|
||||||
// for( UINT8 iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
for( UINT8 iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
||||||
// {
|
{
|
||||||
// SOLDIERTYPE *pPassenger = pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].pPassengers[ iCounter ];
|
SOLDIERTYPE *pPassenger = pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].pPassengers[ iCounter ];
|
||||||
// if( pPassenger != NULL && pPassenger->ubID == ubID )
|
if( pPassenger != NULL && pPassenger->ubID == ubID )
|
||||||
// {
|
{
|
||||||
// gTeamPanel[ iCounter ].fOccupied = TRUE;
|
gTeamPanel[ iCounter ].fOccupied = TRUE;
|
||||||
// gTeamPanel[ iCounter ].ubID = ubID;
|
gTeamPanel[ iCounter ].ubID = ubID;
|
||||||
|
|
||||||
// MSYS_SetRegionUserData( &gTEAM_FirstHandInv[ iCounter ], 0, iCounter );
|
MSYS_SetRegionUserData( &gTEAM_FirstHandInv[ iCounter ], 0, iCounter );
|
||||||
// MSYS_SetRegionUserData( &gTEAM_FaceRegions[ iCounter ], 0, iCounter );
|
MSYS_SetRegionUserData( &gTEAM_FaceRegions[ iCounter ], 0, iCounter );
|
||||||
|
|
||||||
// // DIRTY INTERFACE
|
// DIRTY INTERFACE
|
||||||
// fInterfacePanelDirty = DIRTYLEVEL2;
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||||
|
|
||||||
// // Set ID to do open anim
|
// Set ID to do open anim
|
||||||
// MercPtrs[ ubID ]->flags.fUInewMerc = TRUE;
|
MercPtrs[ ubID ]->flags.fUInewMerc = TRUE;
|
||||||
//
|
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN InitTEAMSlots( )
|
BOOLEAN InitTEAMSlots( )
|
||||||
|
|||||||
+41
-3
@@ -1083,6 +1083,17 @@ void PopupMovementMenu( UI_EVENT *pUIEvent )
|
|||||||
fDisableAction = TRUE;
|
fDisableAction = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anv: don't switch if passengers are blocked from attacking
|
||||||
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( gNewVehicle[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ].VehicleSeats[bSeatIndex].fBlockedShots == TRUE )
|
||||||
|
{
|
||||||
|
fDisableAction = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iActionIcons[ ACTIONC_ICON ] = QuickCreateButton( iIconImages[ uiActionImages ], (INT16)(iMenuAnchorX ), (INT16)(iMenuAnchorY + 20 ),
|
iActionIcons[ ACTIONC_ICON ] = QuickCreateButton( iIconImages[ uiActionImages ], (INT16)(iMenuAnchorX ), (INT16)(iMenuAnchorY + 20 ),
|
||||||
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
|
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
|
||||||
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)BtnMovementCallback );
|
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)BtnMovementCallback );
|
||||||
@@ -1776,7 +1787,16 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
|||||||
//if ( pSoldier->flags.fShowLocator )
|
//if ( pSoldier->flags.fShowLocator )
|
||||||
{
|
{
|
||||||
// Render the beastie
|
// Render the beastie
|
||||||
GetSoldierAboveGuyPositions( pSoldier, &sXPos, &sYPos, TRUE );
|
// anv: if soldier is in vehicle, draw above middle of the vehicle
|
||||||
|
if( !(pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
|
||||||
|
{
|
||||||
|
GetSoldierAboveGuyPositions( pSoldier, &sXPos, &sYPos, TRUE );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
|
GetSoldierAboveGuyPositions( pVehicle, &sXPos, &sYPos, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust for bars!
|
// Adjust for bars!
|
||||||
sXPos += 25;
|
sXPos += 25;
|
||||||
@@ -1833,7 +1853,16 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
|||||||
if ( gGameExternalOptions.ubShowHealthBarsOnHead )
|
if ( gGameExternalOptions.ubShowHealthBarsOnHead )
|
||||||
{
|
{
|
||||||
// Render the beastie
|
// Render the beastie
|
||||||
GetSoldierAboveGuyPositions( pSoldier, &sXPos, &sYPos, TRUE );
|
// anv: if soldier is in vehicle, draw above middle of the vehicle
|
||||||
|
if( !(pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
|
||||||
|
{
|
||||||
|
GetSoldierAboveGuyPositions( pSoldier, &sXPos, &sYPos, TRUE );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
|
GetSoldierAboveGuyPositions( pVehicle, &sXPos, &sYPos, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust for bars!
|
// Adjust for bars!
|
||||||
sXPos += 25;
|
sXPos += 25;
|
||||||
@@ -1901,7 +1930,16 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetSoldierAboveGuyPositions( pSoldier, &sXPos, &sYPos, FALSE );
|
// anv: if soldier is in vehicle, draw above middle of the vehicle
|
||||||
|
if( !(pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
|
||||||
|
{
|
||||||
|
GetSoldierAboveGuyPositions( pSoldier, &sXPos, &sYPos, FALSE );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
|
GetSoldierAboveGuyPositions( pVehicle, &sXPos, &sYPos, FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
// Display name
|
// Display name
|
||||||
SetFont( TINYFONT1 );
|
SetFont( TINYFONT1 );
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "Quests.h"
|
#include "Quests.h"
|
||||||
#include "items.h"
|
#include "items.h"
|
||||||
#include "Item Types.h"
|
#include "Item Types.h"
|
||||||
|
#include "Vehicles.h"
|
||||||
#endif
|
#endif
|
||||||
#include "fresh_header.h"
|
#include "fresh_header.h"
|
||||||
#include "WorldDat.h"
|
#include "WorldDat.h"
|
||||||
@@ -902,6 +903,16 @@ INT16 GetSightAdjustment( SOLDIERTYPE* pSoldier, INT32 sGridNo, INT16 bLevel, IN
|
|||||||
iSightAdjustment += GetSightAdjustmentCamouflageOnTerrain( pSoldier, bStance, ubTerrainType );
|
iSightAdjustment += GetSightAdjustmentCamouflageOnTerrain( pSoldier, bStance, ubTerrainType );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anv: some places in vehicle completely obscure passenger from outside
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( bSeatIndex != (-1) )
|
||||||
|
{
|
||||||
|
if( gNewVehicle[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ].VehicleSeats[ bSeatIndex ].fHidden )
|
||||||
|
{
|
||||||
|
iSightAdjustment = (-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return MINMAX100N(iSightAdjustment);
|
return MINMAX100N(iSightAdjustment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2316,6 +2327,32 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
|
|||||||
iTileSightLimit += iTileSightLimit * GetSightAdjustment(pEndSoldier) / 100;
|
iTileSightLimit += iTileSightLimit * GetSightAdjustment(pEndSoldier) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 ) )
|
||||||
|
{
|
||||||
|
STRUCTURE *pBase = pEndSoldier->pLevelNode->pStructureData;
|
||||||
|
if( pBase == NULL )
|
||||||
|
{
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
DB_STRUCTURE_TILE ** ppTile = pBase->pDBStructureRef->ppTile;
|
||||||
|
UINT8 ubNumberOfTiles = pBase->pDBStructureRef->pDBStructure->ubNumberOfTiles;
|
||||||
|
|
||||||
|
INT32 sStructGridNo;
|
||||||
|
|
||||||
|
// loop through all tiles
|
||||||
|
for (UINT8 ubLoop = BASE_TILE; ubLoop < ubNumberOfTiles; ubLoop++)
|
||||||
|
{
|
||||||
|
sStructGridNo = AddPosRelToBase(pBase->sGridNo, ppTile[ubLoop]);
|
||||||
|
if( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( sStructGridNo ), (FLOAT) CenterY( sStructGridNo ), dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight, cthCalc ) )
|
||||||
|
{
|
||||||
|
return( TRUE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight, cthCalc ) );
|
return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight, cthCalc ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -1512,7 +1512,7 @@ BOOLEAN ExecuteOverhead( )
|
|||||||
}
|
}
|
||||||
else if ( pSoldier->aiData.ubPendingAction == MERC_ENTER_VEHICLE )
|
else if ( pSoldier->aiData.ubPendingAction == MERC_ENTER_VEHICLE )
|
||||||
{
|
{
|
||||||
pSoldier->EVENT_SoldierEnterVehicle( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3 );
|
pSoldier->EVENT_SoldierEnterVehicle( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3, pSoldier->aiData.uiPendingActionData4 );
|
||||||
pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
|
pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3104,8 +3104,15 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF
|
|||||||
|
|
||||||
if( ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
if( ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
||||||
{
|
{
|
||||||
pSoldier = GetDriver( pSoldier->iVehicleId );
|
pSoldier = GetDriver( pSoldier->bVehicleID );
|
||||||
usSoldierID = pSoldier->ubID;
|
if( pSoldier == NULL )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usSoldierID = pSoldier->ubID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are dead, ignore
|
// If we are dead, ignore
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
#include "SkillMenu.h" // sevenfm: need this for TraitsMenu
|
#include "SkillMenu.h" // sevenfm: need this for TraitsMenu
|
||||||
|
|
||||||
#include "Vehicles.h" // anv: for switching from soldier to vehicle
|
#include "Vehicles.h" // anv: for switching from soldier to vehicle
|
||||||
|
#include "VehicleMenu.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1249,6 +1250,16 @@ void QueryRTRightButton( UINT32 *puiNewEvent )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// anv: CTRL+RMB - VehicleMenu
|
||||||
|
else if(_KeyDown(CTRL))
|
||||||
|
{
|
||||||
|
switch( gCurrentUIMode )
|
||||||
|
{
|
||||||
|
case HANDCURSOR_MODE:
|
||||||
|
HandleHandCursorRightClick( usMapPos, puiNewEvent );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Switch on UI mode
|
// Switch on UI mode
|
||||||
@@ -1261,7 +1272,18 @@ void QueryRTRightButton( UINT32 *puiNewEvent )
|
|||||||
case CONFIRM_MOVE_MODE:
|
case CONFIRM_MOVE_MODE:
|
||||||
case MOVE_MODE:
|
case MOVE_MODE:
|
||||||
case TALKCURSOR_MODE:
|
case TALKCURSOR_MODE:
|
||||||
|
// anv: don't switch if passengers are blocked from attacking
|
||||||
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
||||||
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( gNewVehicle[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ].VehicleSeats[bSeatIndex].fBlockedShots == TRUE )
|
||||||
|
{
|
||||||
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pVehicleSeatsStrings[0] );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// We have here a change to action mode
|
// We have here a change to action mode
|
||||||
*puiNewEvent = M_CHANGE_TO_ACTION;
|
*puiNewEvent = M_CHANGE_TO_ACTION;
|
||||||
fClickIntercepted = TRUE;
|
fClickIntercepted = TRUE;
|
||||||
|
|||||||
@@ -1097,6 +1097,7 @@ void SOLDIERTYPE::initialize()
|
|||||||
memset( this, 0, SIZEOF_SOLDIERTYPE_POD);
|
memset( this, 0, SIZEOF_SOLDIERTYPE_POD);
|
||||||
inv.clear();
|
inv.clear();
|
||||||
ai_masterplan_ = 0;
|
ai_masterplan_ = 0;
|
||||||
|
this->iVehicleId = (-1);
|
||||||
|
|
||||||
memset( &aiData, 0, sizeof(STRUCT_AIData) );
|
memset( &aiData, 0, sizeof(STRUCT_AIData) );
|
||||||
memset( &flags, 0, sizeof(STRUCT_Flags) );
|
memset( &flags, 0, sizeof(STRUCT_Flags) );
|
||||||
@@ -8210,6 +8211,7 @@ void SOLDIERTYPE::TurnSoldier( void )
|
|||||||
pVehicleList[ iId ].pPassengers[ iCounter ]->EVENT_SetSoldierDesiredDirection( ( pVehicleList[ iId ].pPassengers[ iCounter ]->pathing.bDesiredDirection + bDirectionChange + NUM_WORLD_DIRECTIONS ) % NUM_WORLD_DIRECTIONS );
|
pVehicleList[ iId ].pPassengers[ iCounter ]->EVENT_SetSoldierDesiredDirection( ( pVehicleList[ iId ].pPassengers[ iCounter ]->pathing.bDesiredDirection + bDirectionChange + NUM_WORLD_DIRECTIONS ) % NUM_WORLD_DIRECTIONS );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UpdateAllVehiclePassengersGridNo( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the soldier is not crawling or multi-tiled, he should be allowed to turn in place. Even if there is some
|
// If the soldier is not crawling or multi-tiled, he should be allowed to turn in place. Even if there is some
|
||||||
@@ -12643,7 +12645,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginFirstAid( INT32 sGridNo, UINT8 ubDirection )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SOLDIERTYPE::EVENT_SoldierEnterVehicle( INT32 sGridNo, UINT8 ubDirection )
|
void SOLDIERTYPE::EVENT_SoldierEnterVehicle( INT32 sGridNo, UINT8 ubDirection, UINT8 ubSeatIndex )
|
||||||
{
|
{
|
||||||
SOLDIERTYPE *pTSoldier;
|
SOLDIERTYPE *pTSoldier;
|
||||||
UINT32 uiMercFlags;
|
UINT32 uiMercFlags;
|
||||||
@@ -12654,7 +12656,7 @@ void SOLDIERTYPE::EVENT_SoldierEnterVehicle( INT32 sGridNo, UINT8 ubDirection )
|
|||||||
pTSoldier = MercPtrs[ usSoldierIndex ];
|
pTSoldier = MercPtrs[ usSoldierIndex ];
|
||||||
|
|
||||||
// Enter vehicle...
|
// Enter vehicle...
|
||||||
EnterVehicle( pTSoldier, this );
|
EnterVehicle( pTSoldier, this, ubSeatIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
UnSetUIBusy( this->ubID );
|
UnSetUIBusy( this->ubID );
|
||||||
@@ -20497,6 +20499,10 @@ void InternalPlaySoldierFootstepSound( SOLDIERTYPE * pSoldier )
|
|||||||
{
|
{
|
||||||
// anv: vehicle sounds
|
// anv: vehicle sounds
|
||||||
//PlaySoldierJA2Sample( pSoldier->ubID, S_VECH1_MOVE, RATE_11025, SoundVolume( bVolume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE );
|
//PlaySoldierJA2Sample( pSoldier->ubID, S_VECH1_MOVE, RATE_11025, SoundVolume( bVolume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE );
|
||||||
|
if ( pSoldier->usAnimState == RUNNING )
|
||||||
|
{
|
||||||
|
bVolume = HIGHVOLUME;
|
||||||
|
}
|
||||||
PlaySoldierJA2Sample( pSoldier->ubID, pVehicleList[ pSoldier->bVehicleID ].iMoveSound, 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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1546,7 +1546,7 @@ public:
|
|||||||
void EVENT_SoldierBeginUseDetonator( void );
|
void EVENT_SoldierBeginUseDetonator( void );
|
||||||
void EVENT_SoldierBeginDropBomb( );
|
void EVENT_SoldierBeginDropBomb( );
|
||||||
void EVENT_SoldierDefuseTripwire( INT32 sGridNo, INT32 sItem );
|
void EVENT_SoldierDefuseTripwire( INT32 sGridNo, INT32 sItem );
|
||||||
void EVENT_SoldierEnterVehicle( INT32 sGridNo, UINT8 ubDirection );
|
void EVENT_SoldierEnterVehicle( INT32 sGridNo, UINT8 ubDirection, UINT8 ubSeatIndex = 0 );
|
||||||
void EVENT_SoldierBeginGiveItem( void );
|
void EVENT_SoldierBeginGiveItem( void );
|
||||||
void EVENT_SetSoldierPositionAndMaybeFinalDest( FLOAT dNewXPos, FLOAT dNewYPos, BOOLEAN fUpdateFinalDest );
|
void EVENT_SetSoldierPositionAndMaybeFinalDest( FLOAT dNewXPos, FLOAT dNewYPos, BOOLEAN fUpdateFinalDest );
|
||||||
void EVENT_SetSoldierPositionForceDelete( FLOAT dNewXPos, FLOAT dNewYPos );
|
void EVENT_SetSoldierPositionForceDelete( FLOAT dNewXPos, FLOAT dNewYPos );
|
||||||
|
|||||||
@@ -666,6 +666,10 @@
|
|||||||
RelativePath=".\Vehicles.h"
|
RelativePath=".\Vehicles.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\VehicleMenu.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Weapons.h"
|
RelativePath=".\Weapons.h"
|
||||||
>
|
>
|
||||||
@@ -992,6 +996,10 @@
|
|||||||
RelativePath=".\Vehicles.cpp"
|
RelativePath=".\Vehicles.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\VehicleMenu.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Weapons.cpp"
|
RelativePath=".\Weapons.cpp"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -670,6 +670,10 @@
|
|||||||
RelativePath="Vehicles.h"
|
RelativePath="Vehicles.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="VehicleMenu.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="Weapons.h"
|
RelativePath="Weapons.h"
|
||||||
>
|
>
|
||||||
@@ -994,6 +998,10 @@
|
|||||||
RelativePath="Vehicles.cpp"
|
RelativePath="Vehicles.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="VehicleMenu.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="Weapons.cpp"
|
RelativePath="Weapons.cpp"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -186,6 +186,7 @@
|
|||||||
<ClCompile Include="TeamTurns.cpp" />
|
<ClCompile Include="TeamTurns.cpp" />
|
||||||
<ClCompile Include="Turn Based Input.cpp" />
|
<ClCompile Include="Turn Based Input.cpp" />
|
||||||
<ClCompile Include="UI Cursors.cpp" />
|
<ClCompile Include="UI Cursors.cpp" />
|
||||||
|
<ClCompile Include="VehicleMenu.cpp" />
|
||||||
<ClCompile Include="Vehicles.cpp" />
|
<ClCompile Include="Vehicles.cpp" />
|
||||||
<ClCompile Include="Weapons.cpp" />
|
<ClCompile Include="Weapons.cpp" />
|
||||||
<ClCompile Include="World Items.cpp" />
|
<ClCompile Include="World Items.cpp" />
|
||||||
|
|||||||
@@ -668,5 +668,8 @@
|
|||||||
<ClCompile Include="XML_Keys.cpp">
|
<ClCompile Include="XML_Keys.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="VehicleMenu.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -105,6 +105,7 @@
|
|||||||
<ClInclude Include="TeamTurns.h" />
|
<ClInclude Include="TeamTurns.h" />
|
||||||
<ClInclude Include="UI Cursors.h" />
|
<ClInclude Include="UI Cursors.h" />
|
||||||
<ClInclude Include="Vehicles.h" />
|
<ClInclude Include="Vehicles.h" />
|
||||||
|
<ClInclude Include="VehicleMenu.h" />
|
||||||
<ClInclude Include="Weapons.h" />
|
<ClInclude Include="Weapons.h" />
|
||||||
<ClInclude Include="World Items.h" />
|
<ClInclude Include="World Items.h" />
|
||||||
<ClInclude Include="XML.h" />
|
<ClInclude Include="XML.h" />
|
||||||
@@ -187,6 +188,7 @@
|
|||||||
<ClCompile Include="Turn Based Input.cpp" />
|
<ClCompile Include="Turn Based Input.cpp" />
|
||||||
<ClCompile Include="UI Cursors.cpp" />
|
<ClCompile Include="UI Cursors.cpp" />
|
||||||
<ClCompile Include="Vehicles.cpp" />
|
<ClCompile Include="Vehicles.cpp" />
|
||||||
|
<ClCompile Include="VehicleMenu.cpp" />
|
||||||
<ClCompile Include="Weapons.cpp" />
|
<ClCompile Include="Weapons.cpp" />
|
||||||
<ClCompile Include="World Items.cpp" />
|
<ClCompile Include="World Items.cpp" />
|
||||||
<ClCompile Include="XML_AmmoStrings.cpp" />
|
<ClCompile Include="XML_AmmoStrings.cpp" />
|
||||||
|
|||||||
@@ -245,6 +245,9 @@
|
|||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Vehicles.h">
|
<ClInclude Include="Vehicles.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="VehicleMenu.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Weapons.h">
|
<ClInclude Include="Weapons.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
@@ -484,6 +487,9 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Vehicles.cpp">
|
<ClCompile Include="Vehicles.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="VehicleMenu.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Weapons.cpp">
|
<ClCompile Include="Weapons.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
#include "Militia Control.h"
|
#include "Militia Control.h"
|
||||||
#include "Ambient Control.h"
|
#include "Ambient Control.h"
|
||||||
#include "Strategic AI.h"
|
#include "Strategic AI.h"
|
||||||
|
#include "VehicleMenu.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Quest Debug System.h"
|
#include "Quest Debug System.h"
|
||||||
@@ -1012,6 +1013,16 @@ void QueryTBRightButton( UINT32 *puiNewEvent )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// anv: CTRL+RMB - VehicleMenu
|
||||||
|
else if(_KeyDown(CTRL))
|
||||||
|
{
|
||||||
|
switch( gCurrentUIMode )
|
||||||
|
{
|
||||||
|
case HANDCURSOR_MODE:
|
||||||
|
HandleHandCursorRightClick( usMapPos, puiNewEvent );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Switch on UI mode
|
// Switch on UI mode
|
||||||
@@ -1022,7 +1033,18 @@ void QueryTBRightButton( UINT32 *puiNewEvent )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MOVE_MODE:
|
case MOVE_MODE:
|
||||||
|
// anv: don't switch if passengers are blocked from attacking
|
||||||
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
||||||
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( gNewVehicle[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ].VehicleSeats[bSeatIndex].fBlockedShots == TRUE )
|
||||||
|
{
|
||||||
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pVehicleSeatsStrings[0] );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// We have here a change to action mode
|
// We have here a change to action mode
|
||||||
*puiNewEvent = M_CHANGE_TO_ACTION;
|
*puiNewEvent = M_CHANGE_TO_ACTION;
|
||||||
fClickIntercepted = TRUE;
|
fClickIntercepted = TRUE;
|
||||||
@@ -5308,7 +5330,7 @@ void CreatePlayerControlledMonster()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT16 usMapPos, BOOLEAN fMovementMode )
|
INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT16 usMapPos, BOOLEAN fMovementMode, UINT8 ubSeatIndex )
|
||||||
{
|
{
|
||||||
// Look for an item pool
|
// Look for an item pool
|
||||||
INT32 sActionGridNo;
|
INT32 sActionGridNo;
|
||||||
@@ -5320,7 +5342,9 @@ INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT
|
|||||||
{
|
{
|
||||||
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
||||||
|
|
||||||
if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 && OKUseVehicle( pTSoldier->ubProfile ) )
|
// anv: added condition - make sure we won't put vehicle in another vehicle
|
||||||
|
if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 && OKUseVehicle( pTSoldier->ubProfile ) && !( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER | SOLDIER_VEHICLE ) ) )
|
||||||
|
//if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 && OKUseVehicle( pTSoldier->ubProfile ) )
|
||||||
{
|
{
|
||||||
if ( ( GetNumberInVehicle( pTSoldier->bVehicleID ) == 0 ) || !fMovementMode )
|
if ( ( GetNumberInVehicle( pTSoldier->bVehicleID ) == 0 ) || !fMovementMode )
|
||||||
{
|
{
|
||||||
@@ -5344,6 +5368,7 @@ INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT
|
|||||||
pSoldier->aiData.ubPendingAction = MERC_ENTER_VEHICLE;
|
pSoldier->aiData.ubPendingAction = MERC_ENTER_VEHICLE;
|
||||||
pSoldier->aiData.sPendingActionData2 = pTSoldier->sGridNo;
|
pSoldier->aiData.sPendingActionData2 = pTSoldier->sGridNo;
|
||||||
pSoldier->aiData.bPendingActionData3 = ubDirection;
|
pSoldier->aiData.bPendingActionData3 = ubDirection;
|
||||||
|
pSoldier->aiData.uiPendingActionData4 = ubSeatIndex;
|
||||||
pSoldier->aiData.ubPendingActionAnimCount = 0;
|
pSoldier->aiData.ubPendingActionAnimCount = 0;
|
||||||
|
|
||||||
// WALK UP TO DEST FIRST
|
// WALK UP TO DEST FIRST
|
||||||
@@ -5351,7 +5376,7 @@ INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pSoldier->EVENT_SoldierEnterVehicle( pTSoldier->sGridNo, ubDirection );
|
pSoldier->EVENT_SoldierEnterVehicle( pTSoldier->sGridNo, ubDirection, ubSeatIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK, set UI
|
// OK, set UI
|
||||||
@@ -5390,7 +5415,7 @@ void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, FALSE ) == -1 )
|
if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, FALSE, 0 ) == -1 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5531,6 +5556,41 @@ void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleHandCursorRightClick( INT32 usMapPos, UINT32 *puiNewEvent )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pSoldier;
|
||||||
|
SOLDIERTYPE *pTSoldier;
|
||||||
|
|
||||||
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||||
|
{
|
||||||
|
// If we are out of breath, no cursor...
|
||||||
|
if( pSoldier->bBreath < OKBREATH && pSoldier->bCollapsed )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( gfUIFullTargetFound )
|
||||||
|
{
|
||||||
|
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
||||||
|
if( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 && OKUseVehicle( pTSoldier->ubProfile ) )
|
||||||
|
{
|
||||||
|
// anv: if we are passengers, only show menu when clicking on vehicle we're in
|
||||||
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
if( pSoldier->iVehicleId == pTSoldier->bVehicleID )
|
||||||
|
{
|
||||||
|
VehicleMenu(usMapPos, pSoldier, pTSoldier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VehicleMenu(usMapPos, pSoldier, pTSoldier);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern BOOLEAN AnyItemsVisibleOnLevel( ITEM_POOL *pItemPool, INT8 bZLevel );
|
extern BOOLEAN AnyItemsVisibleOnLevel( ITEM_POOL *pItemPool, INT8 bZLevel );
|
||||||
|
|
||||||
@@ -5596,7 +5656,7 @@ INT8 HandleMoveModeInteractiveClick( INT32 usMapPos, UINT32 *puiNewEvent )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See if we are over a vehicle, and walk up to it and enter....
|
// See if we are over a vehicle, and walk up to it and enter....
|
||||||
if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, TRUE ) == -1 )
|
if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, TRUE, 0 ) == -1 )
|
||||||
{
|
{
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
@@ -6744,6 +6804,24 @@ void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection )
|
|||||||
INT8 bNewPosition = bOldPosition + bDirection;
|
INT8 bNewPosition = bOldPosition + bDirection;
|
||||||
SOLDIERTYPE TempMercPtr = *MercPtrs[ ubSourceMerc ];
|
SOLDIERTYPE TempMercPtr = *MercPtrs[ ubSourceMerc ];
|
||||||
|
|
||||||
|
// anv: vehicle passengers are swapped differently
|
||||||
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
||||||
|
if( pVehicle != NULL && bNewPosition < gNewVehicle[pVehicle->bVehicleID].iNewSeatingCapacities )
|
||||||
|
{
|
||||||
|
if( SwapVehicleSeat( pVehicle, pSoldier, bNewPosition ) )
|
||||||
|
{
|
||||||
|
RebuildCurrentSquad( );
|
||||||
|
// refresh interface
|
||||||
|
fCharacterInfoPanelDirty = TRUE;
|
||||||
|
fTeamPanelDirty = TRUE;
|
||||||
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check if new position is occupied by another merc? we won't replace an empty slot
|
// check if new position is occupied by another merc? we won't replace an empty slot
|
||||||
if ( gTeamPanel[ bNewPosition ].fOccupied && gTeamPanel[ bNewPosition ].ubID != NOBODY )
|
if ( gTeamPanel[ bNewPosition ].fOccupied && gTeamPanel[ bNewPosition ].ubID != NOBODY )
|
||||||
{
|
{
|
||||||
@@ -6786,13 +6864,6 @@ void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection )
|
|||||||
// don't forget to renew selection of merc
|
// don't forget to renew selection of merc
|
||||||
gusSelectedSoldier = ubTargetMerc;
|
gusSelectedSoldier = ubTargetMerc;
|
||||||
|
|
||||||
// anv: if swapped guy was a driver, make sure vehicle driver ubID gets updates
|
|
||||||
if( MercPtrs[ ubTargetMerc ]->flags.uiStatusFlags & SOLDIER_DRIVER )
|
|
||||||
{
|
|
||||||
pVehicleList[ pSoldier->iVehicleId ].ubDriver = MercPtrs[ ubTargetMerc ]->ubID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// refresh interface
|
// refresh interface
|
||||||
fCharacterInfoPanelDirty = TRUE;
|
fCharacterInfoPanelDirty = TRUE;
|
||||||
fTeamPanelDirty = TRUE;
|
fTeamPanelDirty = TRUE;
|
||||||
|
|||||||
@@ -0,0 +1,222 @@
|
|||||||
|
// anv: totally not a copy of SkillMenu.cpp
|
||||||
|
|
||||||
|
#include "VehicleMenu.h"
|
||||||
|
#include "Soldier Profile Type.h"
|
||||||
|
#include "Overhead.h"
|
||||||
|
#include "Text.h"
|
||||||
|
#include "Isometric Utils.h"
|
||||||
|
#include "DisplayCover.h"
|
||||||
|
#include "worldman.h"
|
||||||
|
#include "Vehicles.h"
|
||||||
|
#include "soldier macros.h"
|
||||||
|
#include "Soldier Add.h"
|
||||||
|
#include "PATHAI.h"
|
||||||
|
#include "Points.h"
|
||||||
|
#include "Handle UI.h"
|
||||||
|
#include "Squads.h"
|
||||||
|
#include "Font Control.h"
|
||||||
|
|
||||||
|
// sevenfm: need this for correct calculation of vehicle menu position
|
||||||
|
extern INT16 gsInterfaceLevel;
|
||||||
|
|
||||||
|
UINT16 usVehicleMenuPosX = 0;
|
||||||
|
UINT16 usVehicleMenuPosY = 0;
|
||||||
|
|
||||||
|
INT32 sVehicleMenuTargetGridNo = NOWHERE;
|
||||||
|
|
||||||
|
SOLDIERTYPE *pCurrentSoldier = NULL;
|
||||||
|
SOLDIERTYPE *pCurrentVehicle = NULL;
|
||||||
|
|
||||||
|
void HideVehicleMenu( void )
|
||||||
|
{
|
||||||
|
// Dirty!
|
||||||
|
fMapPanelDirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turns an option off by always returning FALSE
|
||||||
|
BOOLEAN Popup_VehicleMenuOptionOff( void ) { return FALSE; }
|
||||||
|
|
||||||
|
void
|
||||||
|
VehicleMenuItem::SetupPopup(CHAR* name)
|
||||||
|
{
|
||||||
|
// create a popup
|
||||||
|
gPopup = new POPUP(name);
|
||||||
|
|
||||||
|
// add a callback that lets the keyboard handler know we're done (and ready to pop up again)
|
||||||
|
gPopup->setCallback(POPUP_CALLBACK_HIDE, new popupCallbackFunction<void, void>( &HideVehicleMenu ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Different VehicleItem classes. We need wrappers for each one, as we cannot pass a pointer to a member function (we need a concrete object)
|
||||||
|
|
||||||
|
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||||
|
VehicleSelection gVehicleSelection;
|
||||||
|
|
||||||
|
void Wrapper_Function_VehicleSelection( UINT32 aVal ) { gVehicleSelection.Functions(aVal); }
|
||||||
|
void Wrapper_Setup_VehicleSelection( UINT32 aVal ) { gVehicleSelection.Setup(aVal); }
|
||||||
|
void Wrapper_Cancel_VehicleSelection( UINT32 aVal ) { gVehicleSelection.Cancel(); }
|
||||||
|
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||||
|
|
||||||
|
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
VehicleSelection::Setup( UINT32 aVal )
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
if ( pCurrentSoldier == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( pCurrentVehicle == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetupPopup("VehicleSelection");
|
||||||
|
|
||||||
|
POPUP_OPTION *pOption;
|
||||||
|
|
||||||
|
CHAR16 pStr[300];
|
||||||
|
|
||||||
|
// create entries for each vehicle seat
|
||||||
|
INT8 bVehicleID = pCurrentVehicle->bVehicleID;
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pCurrentSoldier );
|
||||||
|
INT32 iSeatingCapacity = gNewVehicle[ pVehicleList[ bVehicleID ].ubVehicleType ].iNewSeatingCapacities;
|
||||||
|
|
||||||
|
for ( int i = 0; i < iSeatingCapacity; ++i)
|
||||||
|
{
|
||||||
|
swprintf( pStr, gNewVehicle[ pVehicleList[ bVehicleID ].ubVehicleType ].VehicleSeats[i].zSeatName );
|
||||||
|
|
||||||
|
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Function_VehicleSelection, i ));
|
||||||
|
|
||||||
|
// if seat is already taken, grey it out
|
||||||
|
if ( pVehicleList[ bVehicleID ].pPassengers[ i ] != NULL )
|
||||||
|
{
|
||||||
|
if( pCurrentSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
if( pVehicleList[ bVehicleID ].pPassengers[ i ] == pCurrentSoldier )
|
||||||
|
{
|
||||||
|
// Set this option off.
|
||||||
|
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_VehicleMenuOptionOff, NULL ));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// keep, but colour in yellow
|
||||||
|
pOption->color_foreground = FONT_YELLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set this option off.
|
||||||
|
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_VehicleMenuOptionOff, NULL ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// block swapping between different compartments
|
||||||
|
if( gTacticalStatus.uiFlags & INCOMBAT )
|
||||||
|
{
|
||||||
|
if( bSeatIndex != (-1) )
|
||||||
|
{
|
||||||
|
if( gNewVehicle[pVehicleList[ pCurrentVehicle->bVehicleID ].ubVehicleType].VehicleSeats[bSeatIndex].ubCompartment !=
|
||||||
|
gNewVehicle[pVehicleList[ pCurrentVehicle->bVehicleID ].ubVehicleType].VehicleSeats[i].ubCompartment )
|
||||||
|
{
|
||||||
|
// Set this option off.
|
||||||
|
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_VehicleMenuOptionOff, NULL ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetPopup()->addOption( *pOption );
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel option
|
||||||
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_CANCEL] );
|
||||||
|
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_VehicleSelection, 0 ) );
|
||||||
|
GetPopup()->addOption( *pOption );
|
||||||
|
|
||||||
|
// grab soldier's x,y screen position
|
||||||
|
INT16 sX, sY;
|
||||||
|
GetGridNoScreenPos( sVehicleMenuTargetGridNo, gsInterfaceLevel, &sX, &sY );
|
||||||
|
|
||||||
|
if( sX < 0 ) sX = 0;
|
||||||
|
if( sY < 0 ) sY = 0;
|
||||||
|
|
||||||
|
usVehicleMenuPosX = sX + 30;
|
||||||
|
usVehicleMenuPosY = sY;
|
||||||
|
|
||||||
|
if ( ( usVehicleMenuPosX + 200 ) > SCREEN_WIDTH )
|
||||||
|
usVehicleMenuPosX = SCREEN_WIDTH - 200;
|
||||||
|
|
||||||
|
if ( ( usVehicleMenuPosY + 130 ) > SCREEN_HEIGHT )
|
||||||
|
usVehicleMenuPosY = SCREEN_HEIGHT - 190;
|
||||||
|
|
||||||
|
SetPos(usVehicleMenuPosX, usVehicleMenuPosY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
VehicleSelection::Functions( UINT32 aVal )
|
||||||
|
{
|
||||||
|
INT32 sActionGridNo;
|
||||||
|
UINT8 ubDirection;
|
||||||
|
INT16 sAPCost = 0;
|
||||||
|
INT32 sTempSelectedSoldier;
|
||||||
|
|
||||||
|
Cancel();
|
||||||
|
|
||||||
|
if( pCurrentSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) && pCurrentSoldier->iVehicleId == pCurrentVehicle->bVehicleID )
|
||||||
|
{
|
||||||
|
if( SwapVehicleSeat( pCurrentVehicle, pCurrentSoldier, aVal ) )
|
||||||
|
{
|
||||||
|
sTempSelectedSoldier = gusSelectedSoldier;
|
||||||
|
SetCurrentSquad( CurrentSquad(), TRUE );
|
||||||
|
gusSelectedSoldier = sTempSelectedSoldier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( OK_ENTERABLE_VEHICLE( pCurrentVehicle ) && pCurrentVehicle->bVisible != -1 && OKUseVehicle( pCurrentVehicle->ubProfile ) )
|
||||||
|
{
|
||||||
|
// Find a gridno closest to sweetspot...
|
||||||
|
sActionGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pCurrentSoldier, pCurrentSoldier->usUIMovementMode, 5, &ubDirection, 0, pCurrentVehicle, TRUE );
|
||||||
|
|
||||||
|
if (!TileIsOutOfBounds(sActionGridNo))
|
||||||
|
{
|
||||||
|
// Calculate AP costs...
|
||||||
|
//sAPCost = GetAPsToBeginFirstAid( pSoldier );
|
||||||
|
sAPCost += PlotPath( pCurrentSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pCurrentSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pCurrentSoldier->bActionPoints);
|
||||||
|
|
||||||
|
if ( EnoughPoints( pCurrentSoldier, sAPCost, 0, TRUE ) )
|
||||||
|
{
|
||||||
|
pCurrentSoldier->DoMercBattleSound( BATTLE_SOUND_OK1 );
|
||||||
|
|
||||||
|
// CHECK IF WE ARE AT THIS GRIDNO NOW
|
||||||
|
if ( pCurrentSoldier->sGridNo != sActionGridNo )
|
||||||
|
{
|
||||||
|
// SEND PENDING ACTION
|
||||||
|
pCurrentSoldier->aiData.ubPendingAction = MERC_ENTER_VEHICLE;
|
||||||
|
pCurrentSoldier->aiData.sPendingActionData2 = pCurrentVehicle->sGridNo;
|
||||||
|
pCurrentSoldier->aiData.bPendingActionData3 = ubDirection;
|
||||||
|
pCurrentSoldier->aiData.uiPendingActionData4 = aVal;
|
||||||
|
pCurrentSoldier->aiData.ubPendingActionAnimCount = 0;
|
||||||
|
|
||||||
|
// WALK UP TO DEST FIRST
|
||||||
|
pCurrentSoldier->EVENT_InternalGetNewSoldierPath( sActionGridNo, pCurrentSoldier->usUIMovementMode, 3 , pCurrentSoldier->flags.fNoAPToFinishMove );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pCurrentSoldier->EVENT_SoldierEnterVehicle( pCurrentVehicle->sGridNo, ubDirection, aVal );
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK, set UI
|
||||||
|
SetUIBusy( pCurrentSoldier->ubID );
|
||||||
|
//guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cancel();
|
||||||
|
gVehicleSelection.Cancel();
|
||||||
|
}
|
||||||
|
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||||
|
|
||||||
|
void VehicleMenu( INT32 usMapPos, SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVehicle )
|
||||||
|
{
|
||||||
|
sVehicleMenuTargetGridNo = usMapPos;
|
||||||
|
pCurrentSoldier = pSoldier;
|
||||||
|
pCurrentVehicle = pVehicle;
|
||||||
|
gVehicleSelection.Setup(0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#ifndef _VEHICLE_MENU_
|
||||||
|
#define _VEHICLE_MENU_
|
||||||
|
|
||||||
|
#include "popup_class.h"
|
||||||
|
#include "Soldier Profile.h"
|
||||||
|
|
||||||
|
class VehicleMenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VehicleMenuItem() :
|
||||||
|
fInitialized(FALSE), usPosX(0), gPopup(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Cancel()
|
||||||
|
{
|
||||||
|
// Hide the Filter Menu pop-up.
|
||||||
|
if (gPopup != NULL && fInitialized )
|
||||||
|
{
|
||||||
|
gPopup->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Destroy()
|
||||||
|
{
|
||||||
|
// If we already have a popup, destroy it first. This ensures we get a fresh menu each time.
|
||||||
|
if ( fInitialized )
|
||||||
|
{
|
||||||
|
delete(gPopup);
|
||||||
|
gPopup = NULL;
|
||||||
|
fInitialized = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT16 GetMaxPosX()
|
||||||
|
{
|
||||||
|
if ( gPopup )
|
||||||
|
return (usPosX + gPopup->getBoxDimensions().iRight);
|
||||||
|
|
||||||
|
return usPosX;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void SetPos(UINT16 usX, UINT16 usY)
|
||||||
|
{
|
||||||
|
// same y, different x
|
||||||
|
usPosX = usX;
|
||||||
|
gPopup->setPosition( usPosX, usY );
|
||||||
|
|
||||||
|
fInitialized = TRUE;
|
||||||
|
gPopup->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupPopup(CHAR* name);
|
||||||
|
|
||||||
|
POPUP* GetPopup()
|
||||||
|
{
|
||||||
|
return gPopup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Setup( UINT32 aVal ) {}
|
||||||
|
virtual void Functions( UINT32 aVal ) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BOOLEAN fInitialized;
|
||||||
|
UINT16 usPosX;
|
||||||
|
POPUP* gPopup;
|
||||||
|
};
|
||||||
|
|
||||||
|
// select a vehicle seat (and possibly other options)
|
||||||
|
class VehicleSelection : public VehicleMenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VehicleSelection() : usSector(0) {}
|
||||||
|
|
||||||
|
void Setup( UINT32 aVal );
|
||||||
|
void Functions( UINT32 aVal );
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT32 usSector;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void VehicleMenu( INT32 usMapPos, SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVehicle );
|
||||||
|
|
||||||
|
#endif
|
||||||
+358
-37
@@ -475,10 +475,12 @@ BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecificSeat, UINT8 ubSeatIndex )
|
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, UINT8 ubSeatIndex )
|
||||||
{
|
{
|
||||||
INT32 iCounter = 0;
|
INT32 iCounter = 0;
|
||||||
UINT32 vCount = 0;
|
UINT32 vCount = 0;
|
||||||
|
UINT8 ubFinalSeatIndex = 0;
|
||||||
|
BOOLEAN fFoundPlace = FALSE;
|
||||||
SOLDIERTYPE *pVehicleSoldier = NULL;
|
SOLDIERTYPE *pVehicleSoldier = NULL;
|
||||||
|
|
||||||
|
|
||||||
@@ -571,13 +573,35 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecific
|
|||||||
PlayJA2Sample( pVehicleList[ pVehicleSoldier->bVehicleID ].iOutOfSound, RATE_11025, SoundVolume( HIGHVOLUME, pVehicleSoldier->sGridNo ), 1, SoundDir( pVehicleSoldier->sGridNo ) );
|
PlayJA2Sample( pVehicleList[ pVehicleSoldier->bVehicleID ].iOutOfSound, RATE_11025, SoundVolume( HIGHVOLUME, pVehicleSoldier->sGridNo ), 1, SoundDir( pVehicleSoldier->sGridNo ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
|
||||||
|
if( pVehicleList[ iId ].pPassengers[ ubSeatIndex ] == NULL )
|
||||||
|
{
|
||||||
|
ubFinalSeatIndex = ubSeatIndex;
|
||||||
|
fFoundPlace = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( iCounter = 0; !fFoundPlace && iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
||||||
|
{
|
||||||
|
if( pVehicleList[ iId ].pPassengers[ iCounter ] == NULL )
|
||||||
|
{
|
||||||
|
ubFinalSeatIndex = iCounter;
|
||||||
|
fFoundPlace = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fFoundPlace )
|
||||||
{
|
{
|
||||||
// check if slot free
|
// check if slot free
|
||||||
if( pVehicleList[ iId ].pPassengers[ iCounter ] == NULL )
|
if( pVehicleList[ iId ].pPassengers[ ubFinalSeatIndex ] == NULL )
|
||||||
{
|
{
|
||||||
|
// anv: since now they can shoot it's important to set passenger to proper stance
|
||||||
|
SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH );
|
||||||
|
|
||||||
// add person in
|
// add person in
|
||||||
pVehicleList[ iId ].pPassengers[ iCounter ] = pSoldier;
|
pVehicleList[ iId ].pPassengers[ ubFinalSeatIndex ] = pSoldier;
|
||||||
|
|
||||||
if( pSoldier->bAssignment == VEHICLE )
|
if( pSoldier->bAssignment == VEHICLE )
|
||||||
{
|
{
|
||||||
@@ -624,17 +648,27 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecific
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Are we the first?
|
// Are we the first?
|
||||||
if ( GetNumberInVehicle( iId ) == 1 )
|
//if ( GetNumberInVehicle( iId ) == 1 )
|
||||||
|
//{
|
||||||
|
// // Set as driver...
|
||||||
|
// pSoldier->flags.uiStatusFlags |= SOLDIER_DRIVER;
|
||||||
|
|
||||||
|
// SetDriver( iId , pSoldier->ubID );
|
||||||
|
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// // Set as driver...
|
||||||
|
// pSoldier->flags.uiStatusFlags |= SOLDIER_PASSENGER;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// anv: are we taking driver's seat
|
||||||
|
if( gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].VehicleSeats[ubFinalSeatIndex].fDriver )
|
||||||
{
|
{
|
||||||
// Set as driver...
|
|
||||||
pSoldier->flags.uiStatusFlags |= SOLDIER_DRIVER;
|
|
||||||
|
|
||||||
SetDriver( iId , pSoldier->ubID );
|
SetDriver( iId , pSoldier->ubID );
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Set as driver...
|
|
||||||
pSoldier->flags.uiStatusFlags |= SOLDIER_PASSENGER;
|
pSoldier->flags.uiStatusFlags |= SOLDIER_PASSENGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,8 +677,16 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecific
|
|||||||
|
|
||||||
if ( pVehicleSoldier )
|
if ( pVehicleSoldier )
|
||||||
{
|
{
|
||||||
|
// bInitialActionPoints - point in time where soldier and vehicle start sharing timeline
|
||||||
|
pSoldier->bInitialActionPoints = pSoldier->bActionPoints;
|
||||||
|
// set proper initial rotation
|
||||||
|
UINT8 ubRotation = gNewVehicle[ pVehicleList[ pVehicleSoldier->bVehicleID ].ubVehicleType ].VehicleSeats[ ubSeatIndex ].ubRotation;
|
||||||
|
pSoldier->flags.fDontChargeTurningAPs = TRUE;
|
||||||
|
pSoldier->EVENT_SetSoldierDesiredDirection( ( pVehicleSoldier->pathing.bDesiredDirection + ubRotation ) % NUM_WORLD_DIRECTIONS );
|
||||||
|
|
||||||
// Set gridno for vehicle.....
|
// Set gridno for vehicle.....
|
||||||
pSoldier->EVENT_SetSoldierPosition( pVehicleSoldier->dXPos, pVehicleSoldier->dYPos );
|
//pSoldier->EVENT_SetSoldierPosition( pVehicleSoldier->dXPos, pVehicleSoldier->dYPos );
|
||||||
|
UpdateAllVehiclePassengersGridNo( pVehicleSoldier );
|
||||||
|
|
||||||
// Stop from any movement.....
|
// Stop from any movement.....
|
||||||
pSoldier->EVENT_StopMerc( pSoldier->sGridNo, pSoldier->ubDirection );
|
pSoldier->EVENT_StopMerc( pSoldier->sGridNo, pSoldier->ubDirection );
|
||||||
@@ -754,6 +796,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
|||||||
if( pSoldier->flags.uiStatusFlags & SOLDIER_DRIVER )
|
if( pSoldier->flags.uiStatusFlags & SOLDIER_DRIVER )
|
||||||
{
|
{
|
||||||
fNewDriverNeeded = TRUE;
|
fNewDriverNeeded = TRUE;
|
||||||
|
pVehicleList[ iId ].ubDriver = NOBODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSoldier->flags.uiStatusFlags &= ( ~( SOLDIER_DRIVER | SOLDIER_PASSENGER ) );
|
pSoldier->flags.uiStatusFlags &= ( ~( SOLDIER_DRIVER | SOLDIER_PASSENGER ) );
|
||||||
@@ -765,14 +808,14 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
|
|||||||
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
|
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
|
||||||
{
|
{
|
||||||
fSoldierLeft = TRUE;
|
fSoldierLeft = TRUE;
|
||||||
if( fNewDriverNeeded )
|
//if( fNewDriverNeeded )
|
||||||
{
|
//{
|
||||||
SOLDIERTYPE* pNewDriver = pVehicleList[ iId ].pPassengers[ iCounter ];
|
// SOLDIERTYPE* pNewDriver = pVehicleList[ iId ].pPassengers[ iCounter ];
|
||||||
pNewDriver->flags.uiStatusFlags |= SOLDIER_DRIVER;
|
// pNewDriver->flags.uiStatusFlags |= SOLDIER_DRIVER;
|
||||||
pNewDriver->flags.uiStatusFlags &= ~(SOLDIER_PASSENGER);
|
// pNewDriver->flags.uiStatusFlags &= ~(SOLDIER_PASSENGER);
|
||||||
SetDriver( iId, pNewDriver->ubID );
|
// SetDriver( iId, pNewDriver->ubID );
|
||||||
fNewDriverNeeded = FALSE;
|
// fNewDriverNeeded = FALSE;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1526,12 +1569,46 @@ BOOLEAN AnyAccessibleVehiclesInSoldiersSector( SOLDIERTYPE *pSoldier )
|
|||||||
|
|
||||||
SOLDIERTYPE *GetDriver( INT32 iID )
|
SOLDIERTYPE *GetDriver( INT32 iID )
|
||||||
{
|
{
|
||||||
return( MercPtrs[ pVehicleList[ iID ].ubDriver ] );
|
INT32 iCounter;
|
||||||
|
if( pVehicleList[ iID ].ubDriver != NOBODY )
|
||||||
|
{
|
||||||
|
return( MercPtrs[ pVehicleList[ iID ].ubDriver ] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// anv: if vehicle has no driver, return any passenger
|
||||||
|
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iID ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
||||||
|
{
|
||||||
|
if( pVehicleList[ iID ].pPassengers[ iCounter ] != NULL )
|
||||||
|
{
|
||||||
|
return( pVehicleList[ iID ].pPassengers[ iCounter ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetDriver( INT32 iID, UINT8 ubID )
|
void SetDriver( INT32 iID, UINT8 ubID )
|
||||||
{
|
{
|
||||||
|
// anv: first make sure previous driver won't be driver anymore
|
||||||
|
if( pVehicleList[ iID ].ubDriver != NOBODY )
|
||||||
|
{
|
||||||
|
if( MercPtrs[ pVehicleList[ iID ].ubDriver ] )
|
||||||
|
{
|
||||||
|
MercPtrs[ pVehicleList[ iID ].ubDriver ]->flags.uiStatusFlags &= ~(SOLDIER_DRIVER);
|
||||||
|
if( GetSeatIndexFromSoldier( MercPtrs[ pVehicleList[ iID ].ubDriver ] ) != (-1) )
|
||||||
|
{
|
||||||
|
MercPtrs[ pVehicleList[ iID ].ubDriver ]->flags.uiStatusFlags |= SOLDIER_PASSENGER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set proper flags
|
||||||
|
if( ubID != NOBODY )
|
||||||
|
{
|
||||||
|
MercPtrs[ ubID ]->flags.uiStatusFlags |= SOLDIER_DRIVER;
|
||||||
|
MercPtrs[ ubID ]->flags.uiStatusFlags &= ~(SOLDIER_PASSENGER);
|
||||||
|
}
|
||||||
pVehicleList[ iID ].ubDriver = ubID;
|
pVehicleList[ iID ].ubDriver = ubID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1611,7 +1688,7 @@ BOOLEAN TakeSoldierOutOfVehicle( SOLDIERTYPE *pSoldier )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpecificSeat, UINT8 ubSeatIndex )
|
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex )
|
||||||
{
|
{
|
||||||
|
|
||||||
// TEST IF IT'S VALID...
|
// TEST IF IT'S VALID...
|
||||||
@@ -1621,13 +1698,9 @@ BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpe
|
|||||||
if ( IsEnoughSpaceInVehicle( pVehicle->bVehicleID ) )
|
if ( IsEnoughSpaceInVehicle( pVehicle->bVehicleID ) )
|
||||||
{
|
{
|
||||||
// anv: check if preferred seat is already taken, if so automatically choose another
|
// anv: check if preferred seat is already taken, if so automatically choose another
|
||||||
if( fSpecificSeat )
|
if ( pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] != NULL )
|
||||||
{
|
{
|
||||||
if ( pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] != NULL )
|
ubSeatIndex = 0;
|
||||||
{
|
|
||||||
fSpecificSeat = FALSE;
|
|
||||||
ubSeatIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INT16 sAPCost = APBPConstants[AP_ENTER_VEHICLE];
|
INT16 sAPCost = APBPConstants[AP_ENTER_VEHICLE];
|
||||||
@@ -1640,16 +1713,8 @@ BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpe
|
|||||||
return( FALSE );
|
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;
|
|
||||||
// set proper rotation
|
|
||||||
pSoldier->flags.fDontChargeTurningAPs = TRUE;
|
|
||||||
pSoldier->EVENT_SetSoldierDesiredDirection( pVehicle->pathing.bDesiredDirection );
|
|
||||||
|
|
||||||
// OK, add....
|
// OK, add....
|
||||||
AddSoldierToVehicle( pSoldier, pVehicle->bVehicleID, fSpecificSeat, ubSeatIndex );
|
AddSoldierToVehicle( pSoldier, pVehicle->bVehicleID, ubSeatIndex );
|
||||||
|
|
||||||
if ( !(guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
|
if ( !(guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
|
||||||
{
|
{
|
||||||
@@ -1742,6 +1807,7 @@ BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier )
|
|||||||
// anv: since now they can shoot it's important to set passenger to proper stance
|
// 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
|
// namely, back to standing, because we set them to crouching when entering
|
||||||
SendChangeSoldierStanceEvent( pSoldier, ANIM_STAND );
|
SendChangeSoldierStanceEvent( pSoldier, ANIM_STAND );
|
||||||
|
pSoldier->EVENT_SetSoldierDesiredDirection( pSoldier->ubDirection );
|
||||||
|
|
||||||
// Update visiblity.....
|
// Update visiblity.....
|
||||||
HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO );
|
HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO );
|
||||||
@@ -1783,6 +1849,138 @@ BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier )
|
|||||||
return( FALSE );
|
return( FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN ChangeVehicleSeat( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex )
|
||||||
|
{
|
||||||
|
// TEST IF IT'S VALID...
|
||||||
|
if ( pVehicle->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||||
|
{
|
||||||
|
// anv: check if preferred seat is available
|
||||||
|
if ( pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] == NULL )
|
||||||
|
{
|
||||||
|
|
||||||
|
INT8 bCurrentSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( bCurrentSeatIndex == (-1) )
|
||||||
|
{
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
INT16 sAPCost = APBPConstants[AP_CHANGE_SEAT_VEHICLE];
|
||||||
|
|
||||||
|
//Are we currently in combat?
|
||||||
|
if(gTacticalStatus.uiFlags & INCOMBAT)
|
||||||
|
{
|
||||||
|
if( gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[bCurrentSeatIndex].ubCompartment !=
|
||||||
|
gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[ubSeatIndex].ubCompartment )
|
||||||
|
{
|
||||||
|
// different compartment!
|
||||||
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pVehicleSeatsStrings[1] );
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
if(EnoughPoints(pSoldier, sAPCost, 0, TRUE))
|
||||||
|
DeductPoints(pSoldier, sAPCost, 0);
|
||||||
|
else
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] = pSoldier;
|
||||||
|
pVehicleList[ pVehicle->bVehicleID ].pPassengers[bCurrentSeatIndex] = NULL;
|
||||||
|
|
||||||
|
if( gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[bCurrentSeatIndex].fDriver )
|
||||||
|
{
|
||||||
|
SetDriver( pVehicle->bVehicleID, NOBODY );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[ubSeatIndex].fDriver )
|
||||||
|
{
|
||||||
|
SetDriver( pVehicle->bVehicleID, pSoldier->ubID );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set proper initial rotation
|
||||||
|
UINT8 ubRotation = gNewVehicle[ pVehicleList[ pVehicle->bVehicleID ].ubVehicleType ].VehicleSeats[ ubSeatIndex ].ubRotation;
|
||||||
|
pSoldier->flags.fDontChargeTurningAPs = TRUE;
|
||||||
|
pSoldier->EVENT_SetSoldierDesiredDirection( ( pVehicle->pathing.bDesiredDirection + ubRotation ) % NUM_WORLD_DIRECTIONS );
|
||||||
|
|
||||||
|
UpdateAllVehiclePassengersGridNo( pVehicle );
|
||||||
|
|
||||||
|
return( TRUE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN SwapVehicleSeat( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex )
|
||||||
|
{
|
||||||
|
// TEST IF IT'S VALID...
|
||||||
|
if ( pVehicle->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pSoldier2 = pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex];
|
||||||
|
|
||||||
|
if ( pSoldier2 != NULL )
|
||||||
|
{
|
||||||
|
INT8 bCurrentSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( bCurrentSeatIndex == (-1) )
|
||||||
|
{
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
INT16 sAPCost = APBPConstants[AP_CHANGE_SEAT_VEHICLE];
|
||||||
|
|
||||||
|
//Are we currently in combat?
|
||||||
|
if(gTacticalStatus.uiFlags & INCOMBAT)
|
||||||
|
{
|
||||||
|
if( gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[bCurrentSeatIndex].ubCompartment !=
|
||||||
|
gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[ubSeatIndex].ubCompartment )
|
||||||
|
{
|
||||||
|
// different compartment!
|
||||||
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pVehicleSeatsStrings[1] );
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( EnoughPoints(pSoldier, sAPCost, 0, TRUE) && EnoughPoints(pSoldier2, sAPCost, 0, TRUE) )
|
||||||
|
{
|
||||||
|
DeductPoints(pSoldier, sAPCost, 0);
|
||||||
|
DeductPoints(pSoldier2, sAPCost, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] = pSoldier;
|
||||||
|
pVehicleList[ pVehicle->bVehicleID ].pPassengers[bCurrentSeatIndex] = pSoldier2;
|
||||||
|
|
||||||
|
if( gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[bCurrentSeatIndex].fDriver )
|
||||||
|
{
|
||||||
|
SetDriver( pVehicle->bVehicleID, pSoldier2->ubID );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( gNewVehicle[pVehicleList[ pVehicle->bVehicleID ].ubVehicleType].VehicleSeats[ubSeatIndex].fDriver )
|
||||||
|
{
|
||||||
|
SetDriver( pVehicle->bVehicleID, pSoldier->ubID );
|
||||||
|
}
|
||||||
|
|
||||||
|
// set proper initial rotations
|
||||||
|
UINT8 ubRotation = gNewVehicle[ pVehicleList[ pVehicle->bVehicleID ].ubVehicleType ].VehicleSeats[ ubSeatIndex ].ubRotation;
|
||||||
|
pSoldier->flags.fDontChargeTurningAPs = TRUE;
|
||||||
|
pSoldier->EVENT_SetSoldierDesiredDirection( ( pVehicle->pathing.bDesiredDirection + ubRotation ) % NUM_WORLD_DIRECTIONS );
|
||||||
|
|
||||||
|
ubRotation = gNewVehicle[ pVehicleList[ pVehicle->bVehicleID ].ubVehicleType ].VehicleSeats[ bCurrentSeatIndex ].ubRotation;
|
||||||
|
pSoldier2->flags.fDontChargeTurningAPs = TRUE;
|
||||||
|
pSoldier2->EVENT_SetSoldierDesiredDirection( ( pVehicle->pathing.bDesiredDirection + ubRotation ) % NUM_WORLD_DIRECTIONS );
|
||||||
|
|
||||||
|
UpdateAllVehiclePassengersGridNo( pVehicle );
|
||||||
|
|
||||||
|
return( TRUE );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return( ChangeVehicleSeat( pVehicle, pSoldier, ubSeatIndex ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
void AddPassangersToTeamPanel( INT32 iId )
|
void AddPassangersToTeamPanel( INT32 iId )
|
||||||
{
|
{
|
||||||
@@ -2009,6 +2207,11 @@ INT16 GetOrigInternalArmorValueForVehicleInLocation( UINT8 ubID, UINT8 ubLocatio
|
|||||||
|
|
||||||
SOLDIERTYPE * GetSoldierStructureForVehicle( INT32 iId )
|
SOLDIERTYPE * GetSoldierStructureForVehicle( INT32 iId )
|
||||||
{
|
{
|
||||||
|
if( iId == (-1) )
|
||||||
|
{
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
for( INT32 iCounter = 0; iCounter < TOTAL_SOLDIERS; iCounter++ )
|
for( INT32 iCounter = 0; iCounter < TOTAL_SOLDIERS; iCounter++ )
|
||||||
{
|
{
|
||||||
SOLDIERTYPE *pSoldier = &Menptr[ iCounter ];
|
SOLDIERTYPE *pSoldier = &Menptr[ iCounter ];
|
||||||
@@ -2357,8 +2560,88 @@ void UpdateAllVehiclePassengersGridNo( SOLDIERTYPE *pSoldier )
|
|||||||
{
|
{
|
||||||
pPassenger = pVehicleList[ iId ].pPassengers[ iCounter ];
|
pPassenger = pVehicleList[ iId ].pPassengers[ iCounter ];
|
||||||
|
|
||||||
|
INT8 bOffsetX = gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].VehicleSeats[ iCounter ].bOffsetX;
|
||||||
|
INT8 bOffsetY = gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].VehicleSeats[ iCounter ].bOffsetY;
|
||||||
|
|
||||||
|
FLOAT dXOffset = 0;
|
||||||
|
FLOAT dYOffset = 0;
|
||||||
|
INT8 dX, dY;
|
||||||
|
INT8 bDiagonalX = 0;
|
||||||
|
INT8 bDiagonalY = 0;
|
||||||
|
|
||||||
|
switch( pSoldier->ubBodyType )
|
||||||
|
{
|
||||||
|
case ELDORADO:
|
||||||
|
case HUMVEE:
|
||||||
|
case JEEP:
|
||||||
|
bDiagonalY = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( pSoldier->ubDirection )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
dYOffset = -10 * ( bOffsetY + bDiagonalY );
|
||||||
|
dXOffset = 10 * bOffsetX;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if( bOffsetX < 0 )
|
||||||
|
{
|
||||||
|
dXOffset = - 10 + 10 * bOffsetY;
|
||||||
|
dYOffset = - 10 * bOffsetY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dYOffset = 10 + - 10 * bOffsetY;
|
||||||
|
dXOffset = 10 * bOffsetY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dXOffset = 10 * ( bOffsetY + bDiagonalY);
|
||||||
|
dYOffset = 10 * bOffsetX;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
dX = bOffsetY;
|
||||||
|
dY = bOffsetY;
|
||||||
|
if( bOffsetX > 0 )
|
||||||
|
dX -= 1;
|
||||||
|
else if( bOffsetX < 0 )
|
||||||
|
dY -= 1;
|
||||||
|
dXOffset = 10 * dX;
|
||||||
|
dYOffset = 10 * dY;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
dYOffset = 10 * ( bOffsetY + bDiagonalY );
|
||||||
|
dXOffset = -10 * bOffsetX;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if( bOffsetX < 0 )
|
||||||
|
{
|
||||||
|
dXOffset = 10 + - 10 * bOffsetY;
|
||||||
|
dYOffset = 10 * bOffsetY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dYOffset = - 10 + 10 * bOffsetY;
|
||||||
|
dXOffset = - 10 * bOffsetY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
dXOffset = -10 * ( bOffsetY + bDiagonalY );
|
||||||
|
dYOffset = -10 * bOffsetX;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
dX = bOffsetY;
|
||||||
|
dY = bOffsetY;
|
||||||
|
if( bOffsetX > 0 )
|
||||||
|
dX -= 1;
|
||||||
|
else if( bOffsetX < 0 )
|
||||||
|
dY -= 1;
|
||||||
|
dXOffset = - 10 * dX;
|
||||||
|
dYOffset = - 10 * dY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Set gridno.....
|
// Set gridno.....
|
||||||
pPassenger->EVENT_SetSoldierPosition( pSoldier->dXPos, pSoldier->dYPos );
|
pPassenger->EVENT_SetSoldierPosition( pSoldier->dXPos + dXOffset, pSoldier->dYPos + dYOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2595,6 +2878,12 @@ BOOLEAN CanSoldierDriveVehicle( SOLDIERTYPE *pSoldier, INT32 iVehicleId, BOOLEAN
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anv: only driver on driver's seat can drive
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( bSeatIndex == (-1) || gNewVehicle[ pVehicleList[ iVehicleId ].ubVehicleType ].VehicleSeats[bSeatIndex].fDriver == FALSE )
|
||||||
|
{
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
// yup, he could drive this vehicle
|
// yup, he could drive this vehicle
|
||||||
return( TRUE );
|
return( TRUE );
|
||||||
@@ -2708,6 +2997,38 @@ BOOLEAN IsSoldierInThisVehicleSquad( SOLDIERTYPE *pSoldier, INT8 bSquadNumber )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INT8 GetSeatIndexFromSoldier( SOLDIERTYPE *pSoldier )
|
||||||
|
{
|
||||||
|
INT32 iVehicleId;
|
||||||
|
SOLDIERTYPE *pVehicleSoldier;
|
||||||
|
INT32 iCounter;
|
||||||
|
|
||||||
|
iVehicleId = pSoldier->iVehicleId;
|
||||||
|
|
||||||
|
if( iVehicleId == (-1) )
|
||||||
|
{
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
pVehicleSoldier = GetSoldierStructureForVehicle( iVehicleId );
|
||||||
|
|
||||||
|
if( pVehicleSoldier == NULL )
|
||||||
|
{
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through passengers
|
||||||
|
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iVehicleId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
|
||||||
|
{
|
||||||
|
if( pVehicleList[ iVehicleId ].pPassengers[ iCounter ] == pSoldier )
|
||||||
|
{
|
||||||
|
return( iCounter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier )
|
SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier )
|
||||||
{
|
{
|
||||||
// WDS - make number of mercenaries, etc. be configurable
|
// WDS - make number of mercenaries, etc. be configurable
|
||||||
|
|||||||
+27
-20
@@ -11,6 +11,25 @@
|
|||||||
extern std::vector<INT8> gubVehicleMovementGroups;
|
extern std::vector<INT8> gubVehicleMovementGroups;
|
||||||
|
|
||||||
#define MAX_MAIN_VEHICLE_CHARS 500
|
#define MAX_MAIN_VEHICLE_CHARS 500
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UINT8 ubSeatIndex; // index inside a vehicle (corresponding to .pPassengers[counter])
|
||||||
|
CHAR16 zSeatName[20]; // name (to display on entering menu and on team panel)
|
||||||
|
BOOLEAN fDriver; // seat has to be taken to steer the vehicle
|
||||||
|
BOOLEAN fBlockedView; // can't look out of vehicle
|
||||||
|
BOOLEAN fBlockedShots; // can't 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; // initial rotation in relation to vehicle
|
||||||
|
INT8 bOffsetX; // X offset of seat grid, relative to vehicle middle
|
||||||
|
INT8 bOffsetY; // Y offset of seat grid, relative to vehicle middle
|
||||||
|
UINT8 ubCoverage; // 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;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT8 uiIndex;
|
UINT8 uiIndex;
|
||||||
@@ -30,27 +49,10 @@ typedef struct
|
|||||||
CHAR16 NewShortVehicleStrings[128];
|
CHAR16 NewShortVehicleStrings[128];
|
||||||
INT32 NewCarPortraits;
|
INT32 NewCarPortraits;
|
||||||
BOOLEAN NewUsed;
|
BOOLEAN NewUsed;
|
||||||
|
VEHICLE_SEAT VehicleSeats[10];
|
||||||
|
|
||||||
} NEW_CAR;
|
} 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 NEW_CAR gNewVehicle[NUM_PROFILES];
|
||||||
|
|
||||||
extern BOOLEAN LoadNewVehiclesToSaveGameFile( HWFILE hFile );
|
extern BOOLEAN LoadNewVehiclesToSaveGameFile( HWFILE hFile );
|
||||||
@@ -331,7 +333,7 @@ BOOLEAN AnyAccessibleVehiclesInSoldiersSector( SOLDIERTYPE *pSoldier );
|
|||||||
BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId );
|
BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId );
|
||||||
|
|
||||||
// add soldier to Vehicle
|
// add soldier to Vehicle
|
||||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecificSeat = FALSE, UINT8 ubSeatIndex = 0 );
|
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, UINT8 ubSeatIndex = 0 );
|
||||||
|
|
||||||
// remove soldier from vehicle
|
// remove soldier from vehicle
|
||||||
BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId );
|
BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId );
|
||||||
@@ -387,7 +389,7 @@ INT32 GetNumberInVehicle( INT32 iId );
|
|||||||
// grab # in vehicle skipping EPCs (who aren't allowed to drive :-)
|
// grab # in vehicle skipping EPCs (who aren't allowed to drive :-)
|
||||||
INT32 GetNumberOfNonEPCsInVehicle( INT32 iId );
|
INT32 GetNumberOfNonEPCsInVehicle( INT32 iId );
|
||||||
|
|
||||||
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpecificSeat = FALSE, UINT8 ubSeatIndex = 0 );
|
BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex = 0 );
|
||||||
|
|
||||||
SOLDIERTYPE *GetDriver( INT32 iID );
|
SOLDIERTYPE *GetDriver( INT32 iID );
|
||||||
|
|
||||||
@@ -395,6 +397,9 @@ void SetVehicleName( SOLDIERTYPE *pVehicle );
|
|||||||
|
|
||||||
BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier );
|
BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier );
|
||||||
|
|
||||||
|
BOOLEAN ChangeVehicleSeat( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex );
|
||||||
|
BOOLEAN SwapVehicleSeat( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex );
|
||||||
|
|
||||||
void AddPassangersToTeamPanel( INT32 iId );
|
void AddPassangersToTeamPanel( INT32 iId );
|
||||||
|
|
||||||
|
|
||||||
@@ -456,6 +461,8 @@ BOOLEAN IsEnoughSpaceInVehicle( INT32 iID );
|
|||||||
|
|
||||||
BOOLEAN IsSoldierInThisVehicleSquad( SOLDIERTYPE *pSoldier, INT8 bSquadNumber );
|
BOOLEAN IsSoldierInThisVehicleSquad( SOLDIERTYPE *pSoldier, INT8 bSquadNumber );
|
||||||
|
|
||||||
|
INT8 GetSeatIndexFromSoldier( SOLDIERTYPE *pSoldier );
|
||||||
|
|
||||||
SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier );
|
SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier );
|
||||||
|
|
||||||
BOOLEAN DoesVehicleHaveAnyPassengers( INT32 iVehicleID );
|
BOOLEAN DoesVehicleHaveAnyPassengers( INT32 iVehicleID );
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ struct
|
|||||||
|
|
||||||
UINT32 maxArraySize;
|
UINT32 maxArraySize;
|
||||||
UINT32 curIndex;
|
UINT32 curIndex;
|
||||||
|
UINT32 curSeatIndex;
|
||||||
UINT32 currentDepth;
|
UINT32 currentDepth;
|
||||||
UINT32 maxReadDepth;
|
UINT32 maxReadDepth;
|
||||||
}
|
}
|
||||||
@@ -65,6 +66,28 @@ newCarStartElementHandle(void *userData, const XML_Char *name, const XML_Char **
|
|||||||
pData->curElement = ELEMENT_PROPERTY;
|
pData->curElement = ELEMENT_PROPERTY;
|
||||||
pData->maxReadDepth++;
|
pData->maxReadDepth++;
|
||||||
}
|
}
|
||||||
|
else if(strcmp(name, "SEAT") == 0 && pData->curElement == ELEMENT)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->maxReadDepth++;
|
||||||
|
}
|
||||||
|
else if(pData->curElement == ELEMENT_SUBLIST &&
|
||||||
|
(strcmp(name, "SeatIndex") == 0 ||
|
||||||
|
strcmp(name, "SeatName") == 0 ||
|
||||||
|
strcmp(name, "Driver") == 0 ||
|
||||||
|
strcmp(name, "Hidden") == 0 ||
|
||||||
|
strcmp(name, "BlockedView") == 0 ||
|
||||||
|
strcmp(name, "BlockedShots") == 0 ||
|
||||||
|
strcmp(name, "Rotation") == 0 ||
|
||||||
|
strcmp(name, "OffsetX") == 0 ||
|
||||||
|
strcmp(name, "OffsetY") == 0 ||
|
||||||
|
strcmp(name, "Coverage") == 0 ||
|
||||||
|
strcmp(name, "Compartment") == 0 ||
|
||||||
|
strcmp(name, "MountedGun") == 0 ))
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST_PROPERTY;
|
||||||
|
pData->maxReadDepth++; //we are not skipping this element
|
||||||
|
}
|
||||||
|
|
||||||
pData->szCharData[0] = '\0';
|
pData->szCharData[0] = '\0';
|
||||||
}
|
}
|
||||||
@@ -121,6 +144,8 @@ newCarEndElementHandle(void *userData, const XML_Char *name)
|
|||||||
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleName, pData->curNewCar.NewVehicleName);
|
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleName, pData->curNewCar.NewVehicleName);
|
||||||
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewShortVehicleStrings, pData->curNewCar.NewShortVehicleStrings);
|
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewShortVehicleStrings, pData->curNewCar.NewShortVehicleStrings);
|
||||||
gNewVehicle[ pData->curNewCar.uiIndex ].NewUsed = FALSE;
|
gNewVehicle[ pData->curNewCar.uiIndex ].NewUsed = FALSE;
|
||||||
|
memcpy( gNewVehicle[ pData->curNewCar.uiIndex ].VehicleSeats, pData->curNewCar.VehicleSeats, sizeof(pData->curNewCar.VehicleSeats) );
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -128,6 +153,7 @@ newCarEndElementHandle(void *userData, const XML_Char *name)
|
|||||||
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleName, pData->curNewCar.NewVehicleName);
|
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleName, pData->curNewCar.NewVehicleName);
|
||||||
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewShortVehicleStrings, pData->curNewCar.NewShortVehicleStrings);
|
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewShortVehicleStrings, pData->curNewCar.NewShortVehicleStrings);
|
||||||
}
|
}
|
||||||
|
memset( pData->curNewCar.VehicleSeats, 0, sizeof(pData->curNewCar.VehicleSeats) );
|
||||||
}
|
}
|
||||||
else if(strcmp(name, "uiIndex") == 0)
|
else if(strcmp(name, "uiIndex") == 0)
|
||||||
{
|
{
|
||||||
@@ -213,6 +239,81 @@ newCarEndElementHandle(void *userData, const XML_Char *name)
|
|||||||
pData->curNewCar.szIconFace[i] = temp;
|
pData->curNewCar.szIconFace[i] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(strcmp(name, "SEAT") == 0 )
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT;
|
||||||
|
|
||||||
|
if (!NewCar_TextOnly)
|
||||||
|
{
|
||||||
|
memcpy( gNewVehicle[pData->curNewCar.uiIndex].VehicleSeats, pData->curNewCar.VehicleSeats, sizeof(pData->curNewCar.VehicleSeats) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wcscpy( gNewVehicle[pData->curNewCar.uiIndex].VehicleSeats[pData->curSeatIndex].zSeatName, pData->curNewCar.VehicleSeats[pData->curSeatIndex].zSeatName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "SeatIndex") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curSeatIndex = (int) atol(pData->szCharData);
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].ubSeatIndex = pData->curSeatIndex;
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "SeatName") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curNewCar.VehicleSeats[pData->curSeatIndex].zSeatName, sizeof(pData->curNewCar.VehicleSeats[pData->curSeatIndex].zSeatName)/sizeof( pData->curNewCar.VehicleSeats[pData->curSeatIndex].zSeatName[0]) );
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].zSeatName[sizeof(pData->curNewCar.VehicleSeats[pData->curSeatIndex].zSeatName)/sizeof(pData->curNewCar.VehicleSeats[pData->curSeatIndex].zSeatName[0]) - 1] = '\0';
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "Driver") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].fDriver = (BOOLEAN) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "Hidden") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].fHidden = (BOOLEAN) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "BlockedView") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].fBlockedView = (BOOLEAN) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "BlockedShots") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].fBlockedShots = (BOOLEAN) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "Rotation") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].ubRotation = (UINT8) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "OffsetX") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].bOffsetX = (INT8) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "OffsetY") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].bOffsetY = (INT8) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "Coverage") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].ubCoverage = (UINT8) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "Compartment") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].ubCompartment = (UINT8) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "MountedGun") == 0)
|
||||||
|
{
|
||||||
|
pData->curElement = ELEMENT_SUBLIST;
|
||||||
|
pData->curNewCar.VehicleSeats[pData->curSeatIndex].usMountedGun = (UINT32) atol(pData->szCharData);
|
||||||
|
}
|
||||||
|
|
||||||
pData->maxReadDepth--;
|
pData->maxReadDepth--;
|
||||||
|
|
||||||
@@ -301,6 +402,7 @@ void InitNewVehicles ()
|
|||||||
gNewVehicle[ iCount ].NewVehicleName[127] = '\0';
|
gNewVehicle[ iCount ].NewVehicleName[127] = '\0';
|
||||||
gNewVehicle[ iCount ].NewShortVehicleStrings[127] = '\0';
|
gNewVehicle[ iCount ].NewShortVehicleStrings[127] = '\0';
|
||||||
gNewVehicle[ iCount ].NewUsed = FALSE;
|
gNewVehicle[ iCount ].NewUsed = FALSE;
|
||||||
|
memset( &gNewVehicle[ iCount ].VehicleSeats, 0, sizeof(gNewVehicle[ iCount ].VehicleSeats) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
#include "drugs and alcohol.h"
|
#include "drugs and alcohol.h"
|
||||||
#include "Interface.h"
|
#include "Interface.h"
|
||||||
#include "Explosion Control.h"//dnl ch40 200909
|
#include "Explosion Control.h"//dnl ch40 200909
|
||||||
|
#include "Vehicles.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JA2UB
|
#ifdef JA2UB
|
||||||
@@ -1217,6 +1218,18 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anv: some places in vehicle don't give passenger any view outside
|
||||||
|
INT8 bSeatIndex = GetSeatIndexFromSoldier( pSoldier );
|
||||||
|
if( bSeatIndex != (-1) )
|
||||||
|
{
|
||||||
|
SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier ->iVehicleId );
|
||||||
|
// need to check this even if bSubjectDir is DIRECTION_IRRELEVANT
|
||||||
|
if( gNewVehicle[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ].VehicleSeats[ bSeatIndex ].fBlockedView )
|
||||||
|
{
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( bFacingDir == DIRECTION_IRRELEVANT && TANK( pSoldier ) )
|
if ( bFacingDir == DIRECTION_IRRELEVANT && TANK( pSoldier ) )
|
||||||
{
|
{
|
||||||
// always calculate direction for tanks so we have something to work with
|
// always calculate direction for tanks so we have something to work with
|
||||||
@@ -5296,6 +5309,8 @@ void DebugSoldierPage4( )
|
|||||||
//
|
//
|
||||||
|
|
||||||
#define MAX_MOVEMENT_NOISE 9
|
#define MAX_MOVEMENT_NOISE 9
|
||||||
|
#define VEHICLE_FAST_MOVEMENT_NOISE 25
|
||||||
|
#define VEHICLE_NORMAL_MOVEMENT_NOISE 15
|
||||||
|
|
||||||
UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
|
UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
|
||||||
{
|
{
|
||||||
@@ -5303,6 +5318,25 @@ UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
|
|||||||
UINT8 ubMaxVolume, ubVolume, ubBandaged, ubEffLife;
|
UINT8 ubMaxVolume, ubVolume, ubBandaged, ubEffLife;
|
||||||
INT8 bInWater = FALSE;
|
INT8 bInWater = FALSE;
|
||||||
|
|
||||||
|
// anv: vehicle and passengers
|
||||||
|
if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||||
|
{
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
else if( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE ) )
|
||||||
|
{
|
||||||
|
if( pSoldier->usAnimState == RUNNING )
|
||||||
|
{
|
||||||
|
// driving fast makes engine work louder
|
||||||
|
return( VEHICLE_FAST_MOVEMENT_NOISE );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return( VEHICLE_NORMAL_MOVEMENT_NOISE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// anv: additional tile properties
|
// anv: additional tile properties
|
||||||
// modify amount of noise and stealth difficulty depending on surface type
|
// modify amount of noise and stealth difficulty depending on surface type
|
||||||
|
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ bool Loc::ExportStrings()
|
|||||||
ExportSection(props, L"Vehicle", Loc::pVehicleStrings, 0, 6);
|
ExportSection(props, L"Vehicle", Loc::pVehicleStrings, 0, 6);
|
||||||
ExportSection(props, L"ShortVehicle", Loc::pShortVehicleStrings, 0, 6);
|
ExportSection(props, L"ShortVehicle", Loc::pShortVehicleStrings, 0, 6);
|
||||||
ExportSection(props, L"VehicleName", Loc::zVehicleName, 0, 6);
|
ExportSection(props, L"VehicleName", Loc::zVehicleName, 0, 6);
|
||||||
|
ExportSection(props, L"VehicleSeatsStrings", Loc::pVehicleSeatsStrings, 0, 2);
|
||||||
|
|
||||||
ExportSection(props, L"Tactical", Loc::TacticalStr, 0, TEXT_NUM_TACTICAL_STR);
|
ExportSection(props, L"Tactical", Loc::TacticalStr, 0, TEXT_NUM_TACTICAL_STR);
|
||||||
ExportSection(props, L"ExitingSectorHelp", Loc::pExitingSectorHelpText, 0, TEXT_NUM_EXIT_GUI);
|
ExportSection(props, L"ExitingSectorHelp", Loc::pExitingSectorHelpText, 0, TEXT_NUM_EXIT_GUI);
|
||||||
|
|||||||
@@ -740,6 +740,7 @@ extern STR16 sKeyDescriptionStrings[2];
|
|||||||
extern CHAR16 zHealthStr[][13];
|
extern CHAR16 zHealthStr[][13];
|
||||||
extern STR16 gzHiddenHitCountStr[1];
|
extern STR16 gzHiddenHitCountStr[1];
|
||||||
extern STR16 zVehicleName[ 6 ];
|
extern STR16 zVehicleName[ 6 ];
|
||||||
|
extern STR16 pVehicleSeatsStrings[ 2 ] ;
|
||||||
|
|
||||||
// Flugente: externalised texts for some features
|
// Flugente: externalised texts for some features
|
||||||
enum
|
enum
|
||||||
|
|||||||
@@ -3072,6 +3072,11 @@ STR16 zVehicleName[] =
|
|||||||
L"直升飞机", //an abbreviation for Helicopter
|
L"直升飞机", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.", // TODO.Translate
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.", // TODO.Translate
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
@@ -3070,6 +3070,11 @@ STR16 zVehicleName[] =
|
|||||||
L"Heli", //an abbreviation for Helicopter
|
L"Heli", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.", // TODO.Translate
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.", // TODO.Translate
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
@@ -3072,6 +3072,11 @@ STR16 zVehicleName[] =
|
|||||||
L"Heli", //an abbreviation for Helicopter
|
L"Heli", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.",
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.",
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
@@ -3074,6 +3074,11 @@ STR16 zVehicleName[] =
|
|||||||
L"Hélico", //an abbreviation for Helicopter
|
L"Hélico", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.", // TODO.Translate
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.", // TODO.Translate
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
@@ -3075,6 +3075,12 @@ STR16 zVehicleName[] =
|
|||||||
L"Heli", //an abbreviation for Helicopter
|
L"Heli", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.", // TODO.Translate
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.", // TODO.Translate
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3066,6 +3066,11 @@ STR16 zVehicleName[] =
|
|||||||
L"Eli", //an abbreviation for Helicopter
|
L"Eli", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.", // TODO.Translate
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.", // TODO.Translate
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
@@ -3079,6 +3079,11 @@ STR16 zVehicleName[] =
|
|||||||
L"Heli.", //an abbreviation for Helicopter
|
L"Heli.", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"Nie jesteś w stanie strzelać z tego miejsca.",
|
||||||
|
L"Nie możesz sie przesiąść między tymi dwoma miejscami bez opuszczania pojazdu.",
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
@@ -3072,6 +3072,11 @@ STR16 zVehicleName[] =
|
|||||||
L"Вертолёт", //an abbreviation for Helicopter
|
L"Вертолёт", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.", // TODO.Translate
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.", // TODO.Translate
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
@@ -3075,6 +3075,11 @@ STR16 zVehicleName[] =
|
|||||||
L"Heli", //an abbreviation for Helicopter
|
L"Heli", //an abbreviation for Helicopter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STR16 pVehicleSeatsStrings[] =
|
||||||
|
{
|
||||||
|
L"You cannot shoot from this seat.", // TODO.Translate
|
||||||
|
L"You cannot swap those two seats in combat without exiting vehicle first.", // TODO.Translate
|
||||||
|
};
|
||||||
|
|
||||||
//These are messages Used in the Tactical Screen
|
//These are messages Used in the Tactical Screen
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user