diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp
index 0f30eb19..48cc43f1 100644
--- a/Strategic/Assignments.cpp
+++ b/Strategic/Assignments.cpp
@@ -16750,7 +16750,12 @@ SOLDIERTYPE *GetSelectedAssignSoldier( BOOLEAN fNullOK )
{
// better be an active person, not a vehicle
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 );
diff --git a/Tactical/Animation Data.cpp b/Tactical/Animation Data.cpp
index cd628244..cf94ae25 100644
--- a/Tactical/Animation Data.cpp
+++ b/Tactical/Animation Data.cpp
@@ -777,27 +777,27 @@ AnimationStructureType gAnimStructureDatabase[ TOTALBODYTYPES ][ NUM_STRUCT_IDS
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD", NULL, // default
//ELDORADO
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ELDRDO.JSD", NULL,
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
//ICECREAMTRUCK
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\ICECREAM.JSD", NULL,
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
//JEEP
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
- "ANIMS\\STRUCTDATA\\HMMV.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
+ "ANIMS\\STRUCTDATA\\JEEP.JSD", NULL,
"ANIMS\\STRUCTDATA\\M_CROUCH.JSD",NULL, // default
};
diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp
index 7fa53aa8..c1b7e66d 100644
--- a/Tactical/Handle UI.cpp
+++ b/Tactical/Handle UI.cpp
@@ -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 ( ( pSoldier->flags.uiStatusFlags & ( SOLDIER_PASSENGER )) )
{
if ( !UIHandleOnMerc( TRUE ) )
{
- guiNewUICursor = FLOATING_X_UICURSOR;
+ guiNewUICursor = INVALID_ACTION_UICURSOR;
return( GAME_SCREEN );
}
}
@@ -3219,16 +3219,6 @@ UINT32 UIHandleHCOnTerrain( UI_EVENT *pUIEvent )
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 ( pSoldier->bBreath < OKBREATH && pSoldier->bCollapsed )
{
@@ -3445,6 +3435,20 @@ BOOLEAN UIHandleOnMerc( BOOLEAN fMovementMode )
// Check if this guy is on the enemy team....
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;
guiPendingOverrideEvent = M_CHANGE_TO_ACTION;
@@ -3531,7 +3535,7 @@ void UIHandleSoldierStanceChange( UINT8 ubSoldierID, INT8 bNewStance )
{
SOLDIERTYPE *pSoldier = MercPtrs[ ubSoldierID ];
- if( pSoldier->flags.uiStatusFlags & SOLDIER_DRIVER )
+ if( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
{
pSoldier = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
}
@@ -6371,11 +6375,30 @@ INT8 UIHandleInteractiveTilesAndItemsOnTerrain( SOLDIERTYPE *pSoldier, INT32 usM
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 )
{
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
if ( fItemsOnlyIfOnIntTiles )
diff --git a/Tactical/Handle UI.h b/Tactical/Handle UI.h
index db0ec0b6..af02cca1 100644
--- a/Tactical/Handle UI.h
+++ b/Tactical/Handle UI.h
@@ -343,6 +343,7 @@ UINT32 UIHandleLUIEndLock( UI_EVENT *pUIEvent );
void BeginDisplayTimedCursor( UINT32 uiCursorID, UINT32 uiDelay );
void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent );
+void HandleHandCursorRightClick( INT32 usMapPos, UINT32 *puiNewEvent );
INT8 HandleMoveModeInteractiveClick( INT32 usMapPos, UINT32 *puiNewEvent );
BOOLEAN HandleUIReloading( SOLDIERTYPE *pSoldier );
diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp
index 0d87ae66..7c3518da 100644
--- a/Tactical/Interface Panels.cpp
+++ b/Tactical/Interface Panels.cpp
@@ -5693,6 +5693,13 @@ void RenderTEAMPanel( BOOLEAN fDirty )
// clear pStr value
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
{
UINT8 ubTempSkillArray[30];
@@ -5716,7 +5723,8 @@ void RenderTEAMPanel( BOOLEAN fDirty )
if ( bNumSkillTraits == 0 )
{
- swprintf( pStr, L"%s", pPersonnelScreenStrings[ PRSNL_TXT_NOSKILLS ] );
+ swprintf( sTemp, L"%s", pPersonnelScreenStrings[ PRSNL_TXT_NOSKILLS ] );
+ wcscat( pStr, sTemp );
}
else
{
@@ -6974,8 +6982,8 @@ void AddPlayerToInterfaceTeamSlot( UINT8 ubID )
return;
}
- //if ( !( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
- //{
+ if ( !( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) )
+ {
if ( !PlayerExistsInSlot( ubID ) )
{
// Find a free slot
@@ -6999,38 +7007,38 @@ void AddPlayerToInterfaceTeamSlot( UINT8 ubID )
}
}
}
- //}
- //else
- //{
- // // anv: for passengers, position on team panel will be linked with seat in vehicle
- // if ( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
- // {
- // SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( MercPtrs[ ubID ]->iVehicleId );
- // if( pVehicle != NULL )
- // {
- // for( UINT8 iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
- // {
- // SOLDIERTYPE *pPassenger = pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].pPassengers[ iCounter ];
- // if( pPassenger != NULL && pPassenger->ubID == ubID )
- // {
- // gTeamPanel[ iCounter ].fOccupied = TRUE;
- // gTeamPanel[ iCounter ].ubID = ubID;
+ }
+ else
+ {
+ // anv: for passengers, position on team panel will be linked with seat in vehicle
+ if ( MercPtrs[ ubID ]->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
+ {
+ SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( MercPtrs[ ubID ]->iVehicleId );
+ if( pVehicle != NULL )
+ {
+ for( UINT8 iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
+ {
+ SOLDIERTYPE *pPassenger = pVehicleList[ MercPtrs[ ubID ]->iVehicleId ].pPassengers[ iCounter ];
+ if( pPassenger != NULL && pPassenger->ubID == ubID )
+ {
+ gTeamPanel[ iCounter ].fOccupied = TRUE;
+ gTeamPanel[ iCounter ].ubID = ubID;
- // MSYS_SetRegionUserData( &gTEAM_FirstHandInv[ iCounter ], 0, iCounter );
- // MSYS_SetRegionUserData( &gTEAM_FaceRegions[ iCounter ], 0, iCounter );
+ MSYS_SetRegionUserData( &gTEAM_FirstHandInv[ iCounter ], 0, iCounter );
+ MSYS_SetRegionUserData( &gTEAM_FaceRegions[ iCounter ], 0, iCounter );
- // // DIRTY INTERFACE
- // fInterfacePanelDirty = DIRTYLEVEL2;
+ // DIRTY INTERFACE
+ fInterfacePanelDirty = DIRTYLEVEL2;
- // // Set ID to do open anim
- // MercPtrs[ ubID ]->flags.fUInewMerc = TRUE;
- //
- // return;
- // }
- // }
- // }
- // }
- //}
+ // Set ID to do open anim
+ MercPtrs[ ubID ]->flags.fUInewMerc = TRUE;
+
+ return;
+ }
+ }
+ }
+ }
+ }
}
BOOLEAN InitTEAMSlots( )
diff --git a/Tactical/Interface.cpp b/Tactical/Interface.cpp
index 072c4ad6..b4d17797 100644
--- a/Tactical/Interface.cpp
+++ b/Tactical/Interface.cpp
@@ -1083,6 +1083,17 @@ void PopupMovementMenu( UI_EVENT *pUIEvent )
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 ),
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)BtnMovementCallback );
@@ -1776,7 +1787,16 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
//if ( pSoldier->flags.fShowLocator )
{
// 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!
sXPos += 25;
@@ -1833,7 +1853,16 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
if ( gGameExternalOptions.ubShowHealthBarsOnHead )
{
// 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!
sXPos += 25;
@@ -1901,7 +1930,16 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
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
SetFont( TINYFONT1 );
diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp
index 6de372a4..bc70ebc2 100644
--- a/Tactical/LOS.cpp
+++ b/Tactical/LOS.cpp
@@ -43,6 +43,7 @@
#include "Quests.h"
#include "items.h"
#include "Item Types.h"
+#include "Vehicles.h"
#endif
#include "fresh_header.h"
#include "WorldDat.h"
@@ -902,6 +903,16 @@ INT16 GetSightAdjustment( SOLDIERTYPE* pSoldier, INT32 sGridNo, INT16 bLevel, IN
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);
}
@@ -2316,6 +2327,32 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
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 ) );
}
diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp
index 0f38ebc8..7c927af4 100644
--- a/Tactical/Overhead.cpp
+++ b/Tactical/Overhead.cpp
@@ -1512,7 +1512,7 @@ BOOLEAN ExecuteOverhead( )
}
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;
continue;
}
@@ -3104,8 +3104,15 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF
if( ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
{
- pSoldier = GetDriver( pSoldier->iVehicleId );
- usSoldierID = pSoldier->ubID;
+ pSoldier = GetDriver( pSoldier->bVehicleID );
+ if( pSoldier == NULL )
+ {
+ return;
+ }
+ else
+ {
+ usSoldierID = pSoldier->ubID;
+ }
}
// If we are dead, ignore
diff --git a/Tactical/Real Time Input.cpp b/Tactical/Real Time Input.cpp
index fe35385d..9fe82c0d 100644
--- a/Tactical/Real Time Input.cpp
+++ b/Tactical/Real Time Input.cpp
@@ -62,6 +62,7 @@
#include "SkillMenu.h" // sevenfm: need this for TraitsMenu
#include "Vehicles.h" // anv: for switching from soldier to vehicle
+#include "VehicleMenu.h"
#endif
@@ -1249,6 +1250,16 @@ void QueryRTRightButton( UINT32 *puiNewEvent )
break;
}
}
+ // anv: CTRL+RMB - VehicleMenu
+ else if(_KeyDown(CTRL))
+ {
+ switch( gCurrentUIMode )
+ {
+ case HANDCURSOR_MODE:
+ HandleHandCursorRightClick( usMapPos, puiNewEvent );
+ break;
+ }
+ }
else
{
// Switch on UI mode
@@ -1261,7 +1272,18 @@ void QueryRTRightButton( UINT32 *puiNewEvent )
case CONFIRM_MOVE_MODE:
case MOVE_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
*puiNewEvent = M_CHANGE_TO_ACTION;
fClickIntercepted = TRUE;
diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp
index 7cf2070b..261a1483 100644
--- a/Tactical/Soldier Control.cpp
+++ b/Tactical/Soldier Control.cpp
@@ -1097,6 +1097,7 @@ void SOLDIERTYPE::initialize()
memset( this, 0, SIZEOF_SOLDIERTYPE_POD);
inv.clear();
ai_masterplan_ = 0;
+ this->iVehicleId = (-1);
memset( &aiData, 0, sizeof(STRUCT_AIData) );
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 );
}
}
+ UpdateAllVehiclePassengersGridNo( this );
}
// 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;
UINT32 uiMercFlags;
@@ -12654,7 +12656,7 @@ void SOLDIERTYPE::EVENT_SoldierEnterVehicle( INT32 sGridNo, UINT8 ubDirection )
pTSoldier = MercPtrs[ usSoldierIndex ];
// Enter vehicle...
- EnterVehicle( pTSoldier, this );
+ EnterVehicle( pTSoldier, this, ubSeatIndex );
}
UnSetUIBusy( this->ubID );
@@ -20497,6 +20499,10 @@ void InternalPlaySoldierFootstepSound( SOLDIERTYPE * pSoldier )
{
// anv: vehicle sounds
//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 );
}
}
diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h
index cc731130..2f1f4aaf 100644
--- a/Tactical/Soldier Control.h
+++ b/Tactical/Soldier Control.h
@@ -1546,7 +1546,7 @@ public:
void EVENT_SoldierBeginUseDetonator( void );
void EVENT_SoldierBeginDropBomb( );
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_SetSoldierPositionAndMaybeFinalDest( FLOAT dNewXPos, FLOAT dNewYPos, BOOLEAN fUpdateFinalDest );
void EVENT_SetSoldierPositionForceDelete( FLOAT dNewXPos, FLOAT dNewYPos );
diff --git a/Tactical/Tactical_VS2005.vcproj b/Tactical/Tactical_VS2005.vcproj
index f3f745e3..732cff86 100644
--- a/Tactical/Tactical_VS2005.vcproj
+++ b/Tactical/Tactical_VS2005.vcproj
@@ -666,6 +666,10 @@
RelativePath=".\Vehicles.h"
>
+
+
@@ -992,6 +996,10 @@
RelativePath=".\Vehicles.cpp"
>
+
+
diff --git a/Tactical/Tactical_VS2008.vcproj b/Tactical/Tactical_VS2008.vcproj
index e8869040..2e584bf0 100644
--- a/Tactical/Tactical_VS2008.vcproj
+++ b/Tactical/Tactical_VS2008.vcproj
@@ -670,6 +670,10 @@
RelativePath="Vehicles.h"
>
+
+
@@ -994,6 +998,10 @@
RelativePath="Vehicles.cpp"
>
+
+
diff --git a/Tactical/Tactical_VS2010.vcxproj b/Tactical/Tactical_VS2010.vcxproj
index 10fc0d52..d1c3a9da 100644
--- a/Tactical/Tactical_VS2010.vcxproj
+++ b/Tactical/Tactical_VS2010.vcxproj
@@ -186,6 +186,7 @@
+
diff --git a/Tactical/Tactical_VS2010.vcxproj.filters b/Tactical/Tactical_VS2010.vcxproj.filters
index b92577d8..ed9dc3a4 100644
--- a/Tactical/Tactical_VS2010.vcxproj.filters
+++ b/Tactical/Tactical_VS2010.vcxproj.filters
@@ -668,5 +668,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/Tactical/Tactical_VS2013.vcxproj b/Tactical/Tactical_VS2013.vcxproj
index ecbfab1f..b0f77f76 100644
--- a/Tactical/Tactical_VS2013.vcxproj
+++ b/Tactical/Tactical_VS2013.vcxproj
@@ -105,6 +105,7 @@
+
@@ -187,6 +188,7 @@
+
diff --git a/Tactical/Tactical_VS2013.vcxproj.filters b/Tactical/Tactical_VS2013.vcxproj.filters
index cea304fe..ec81aea1 100644
--- a/Tactical/Tactical_VS2013.vcxproj.filters
+++ b/Tactical/Tactical_VS2013.vcxproj.filters
@@ -245,6 +245,9 @@
Header Files
+
+
+ Header Files
Header Files
@@ -484,6 +487,9 @@
Source Files
+
+
+ Source Files
Source Files
diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp
index 394977f0..94d333f2 100644
--- a/Tactical/Turn Based Input.cpp
+++ b/Tactical/Turn Based Input.cpp
@@ -107,6 +107,7 @@
#include "Militia Control.h"
#include "Ambient Control.h"
#include "Strategic AI.h"
+#include "VehicleMenu.h"
#endif
#include "Quest Debug System.h"
@@ -1012,6 +1013,16 @@ void QueryTBRightButton( UINT32 *puiNewEvent )
break;
}
}
+ // anv: CTRL+RMB - VehicleMenu
+ else if(_KeyDown(CTRL))
+ {
+ switch( gCurrentUIMode )
+ {
+ case HANDCURSOR_MODE:
+ HandleHandCursorRightClick( usMapPos, puiNewEvent );
+ break;
+ }
+ }
else
{
// Switch on UI mode
@@ -1022,7 +1033,18 @@ void QueryTBRightButton( UINT32 *puiNewEvent )
break;
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
*puiNewEvent = M_CHANGE_TO_ACTION;
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
INT32 sActionGridNo;
@@ -5320,7 +5342,9 @@ INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT
{
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 )
{
@@ -5344,6 +5368,7 @@ INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT
pSoldier->aiData.ubPendingAction = MERC_ENTER_VEHICLE;
pSoldier->aiData.sPendingActionData2 = pTSoldier->sGridNo;
pSoldier->aiData.bPendingActionData3 = ubDirection;
+ pSoldier->aiData.uiPendingActionData4 = ubSeatIndex;
pSoldier->aiData.ubPendingActionAnimCount = 0;
// WALK UP TO DEST FIRST
@@ -5351,7 +5376,7 @@ INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT
}
else
{
- pSoldier->EVENT_SoldierEnterVehicle( pTSoldier->sGridNo, ubDirection );
+ pSoldier->EVENT_SoldierEnterVehicle( pTSoldier->sGridNo, ubDirection, ubSeatIndex );
}
// OK, set UI
@@ -5390,7 +5415,7 @@ void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent )
return;
}
- if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, FALSE ) == -1 )
+ if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, FALSE, 0 ) == -1 )
{
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 );
@@ -5596,7 +5656,7 @@ INT8 HandleMoveModeInteractiveClick( INT32 usMapPos, UINT32 *puiNewEvent )
}
// 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 );
}
@@ -6744,6 +6804,24 @@ void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection )
INT8 bNewPosition = bOldPosition + bDirection;
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
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
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
fCharacterInfoPanelDirty = TRUE;
fTeamPanelDirty = TRUE;
diff --git a/Tactical/VehicleMenu.cpp b/Tactical/VehicleMenu.cpp
new file mode 100644
index 00000000..072baa63
--- /dev/null
+++ b/Tactical/VehicleMenu.cpp
@@ -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( &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( &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( &Popup_VehicleMenuOptionOff, NULL ));
+ }
+ else
+ {
+ // keep, but colour in yellow
+ pOption->color_foreground = FONT_YELLOW;
+ }
+ }
+ else
+ {
+ // Set this option off.
+ pOption->setAvail(new popupCallbackFunction( &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( &Popup_VehicleMenuOptionOff, NULL ));
+ }
+ }
+ }
+
+ GetPopup()->addOption( *pOption );
+ }
+
+ // cancel option
+ swprintf( pStr, pSkillMenuStrings[SKILLMENU_CANCEL] );
+ pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction( &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);
+}
\ No newline at end of file
diff --git a/Tactical/VehicleMenu.h b/Tactical/VehicleMenu.h
new file mode 100644
index 00000000..7d5a418c
--- /dev/null
+++ b/Tactical/VehicleMenu.h
@@ -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
\ No newline at end of file
diff --git a/Tactical/Vehicles.cpp b/Tactical/Vehicles.cpp
index bffd894a..6b07c5c3 100644
--- a/Tactical/Vehicles.cpp
+++ b/Tactical/Vehicles.cpp
@@ -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;
UINT32 vCount = 0;
+ UINT8 ubFinalSeatIndex = 0;
+ BOOLEAN fFoundPlace = FALSE;
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 ) );
}
- 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
- 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
- pVehicleList[ iId ].pPassengers[ iCounter ] = pSoldier;
+ pVehicleList[ iId ].pPassengers[ ubFinalSeatIndex ] = pSoldier;
if( pSoldier->bAssignment == VEHICLE )
{
@@ -624,17 +648,27 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecific
}
// 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 );
-
}
else
{
- // Set as driver...
pSoldier->flags.uiStatusFlags |= SOLDIER_PASSENGER;
}
@@ -643,8 +677,16 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecific
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.....
- pSoldier->EVENT_SetSoldierPosition( pVehicleSoldier->dXPos, pVehicleSoldier->dYPos );
+ //pSoldier->EVENT_SetSoldierPosition( pVehicleSoldier->dXPos, pVehicleSoldier->dYPos );
+ UpdateAllVehiclePassengersGridNo( pVehicleSoldier );
// Stop from any movement.....
pSoldier->EVENT_StopMerc( pSoldier->sGridNo, pSoldier->ubDirection );
@@ -754,6 +796,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
if( pSoldier->flags.uiStatusFlags & SOLDIER_DRIVER )
{
fNewDriverNeeded = TRUE;
+ pVehicleList[ iId ].ubDriver = NOBODY;
}
pSoldier->flags.uiStatusFlags &= ( ~( SOLDIER_DRIVER | SOLDIER_PASSENGER ) );
@@ -765,14 +808,14 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
fSoldierLeft = TRUE;
- if( fNewDriverNeeded )
- {
- SOLDIERTYPE* pNewDriver = pVehicleList[ iId ].pPassengers[ iCounter ];
- pNewDriver->flags.uiStatusFlags |= SOLDIER_DRIVER;
- pNewDriver->flags.uiStatusFlags &= ~(SOLDIER_PASSENGER);
- SetDriver( iId, pNewDriver->ubID );
- fNewDriverNeeded = FALSE;
- }
+ //if( fNewDriverNeeded )
+ //{
+ // SOLDIERTYPE* pNewDriver = pVehicleList[ iId ].pPassengers[ iCounter ];
+ // pNewDriver->flags.uiStatusFlags |= SOLDIER_DRIVER;
+ // pNewDriver->flags.uiStatusFlags &= ~(SOLDIER_PASSENGER);
+ // SetDriver( iId, pNewDriver->ubID );
+ // fNewDriverNeeded = FALSE;
+ //}
}
}
@@ -1526,12 +1569,46 @@ BOOLEAN AnyAccessibleVehiclesInSoldiersSector( SOLDIERTYPE *pSoldier )
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 )
{
+ // 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;
}
@@ -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...
@@ -1621,13 +1698,9 @@ BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpe
if ( IsEnoughSpaceInVehicle( pVehicle->bVehicleID ) )
{
// anv: check if preferred seat is already taken, if so automatically choose another
- if( fSpecificSeat )
+ if ( pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] != NULL )
{
- if ( pVehicleList[ pVehicle->bVehicleID ].pPassengers[ubSeatIndex] != NULL )
- {
- fSpecificSeat = FALSE;
- ubSeatIndex = 0;
- }
+ ubSeatIndex = 0;
}
INT16 sAPCost = APBPConstants[AP_ENTER_VEHICLE];
@@ -1640,16 +1713,8 @@ BOOLEAN EnterVehicle( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, BOOLEAN fSpe
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....
- AddSoldierToVehicle( pSoldier, pVehicle->bVehicleID, fSpecificSeat, ubSeatIndex );
+ AddSoldierToVehicle( pSoldier, pVehicle->bVehicleID, ubSeatIndex );
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
// namely, back to standing, because we set them to crouching when entering
SendChangeSoldierStanceEvent( pSoldier, ANIM_STAND );
+ pSoldier->EVENT_SetSoldierDesiredDirection( pSoldier->ubDirection );
// Update visiblity.....
HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO );
@@ -1783,6 +1849,138 @@ BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier )
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 )
{
@@ -2009,6 +2207,11 @@ INT16 GetOrigInternalArmorValueForVehicleInLocation( UINT8 ubID, UINT8 ubLocatio
SOLDIERTYPE * GetSoldierStructureForVehicle( INT32 iId )
{
+ if( iId == (-1) )
+ {
+ return( 0 );
+ }
+
for( INT32 iCounter = 0; iCounter < TOTAL_SOLDIERS; iCounter++ )
{
SOLDIERTYPE *pSoldier = &Menptr[ iCounter ];
@@ -2357,8 +2560,88 @@ void UpdateAllVehiclePassengersGridNo( SOLDIERTYPE *pSoldier )
{
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.....
- 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);
}
+ // 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
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 )
{
// WDS - make number of mercenaries, etc. be configurable
diff --git a/Tactical/Vehicles.h b/Tactical/Vehicles.h
index f77db1a4..f5ceed94 100644
--- a/Tactical/Vehicles.h
+++ b/Tactical/Vehicles.h
@@ -11,6 +11,25 @@
extern std::vector gubVehicleMovementGroups;
#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
{
UINT8 uiIndex;
@@ -30,27 +49,10 @@ typedef struct
CHAR16 NewShortVehicleStrings[128];
INT32 NewCarPortraits;
BOOLEAN NewUsed;
+ VEHICLE_SEAT VehicleSeats[10];
} NEW_CAR;
-typedef struct
-{
- UINT8 ubSeatIndex; // index inside a vehicle (corresponding to .pPassengers[counter])
- CHAR16 zSeatName[16]; // name (to display on entering menu and on team panel)
- BOOLEAN fDriver; // seat has to be taken to steer the vehicle
- BOOLEAN fView; // can look out of vehicle
- BOOLEAN fDriveBy; // can shoot from this seat
- BOOLEAN fSeatBelt; // for collisions
- BOOLEAN fHidden; // merc on this seat is invisible from outside - spy as a driver smuggling in others?
- UINT8 ubRotation; // rotation in relation to vehicle
- UINT8 ubTunnelVision; // tunnel vision (small windows, etc.)
- UINT8 ubProtection; // influence probability vehicle will be hit instead of passenger
- UINT8 ubCompartment; // passenger can switch to another seat in the same compartment without exiting vehicle
- UINT8 ubStructureLink; // link to physical part of structure (for hit calculations)
- UINT32 usMountedGun; // passenger on this seat will use this gun instead of his own, link to Items.xml
-
-} VEHICLE_SEAT;
-
extern NEW_CAR gNewVehicle[NUM_PROFILES];
extern BOOLEAN LoadNewVehiclesToSaveGameFile( HWFILE hFile );
@@ -331,7 +333,7 @@ BOOLEAN AnyAccessibleVehiclesInSoldiersSector( SOLDIERTYPE *pSoldier );
BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId );
// 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
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 :-)
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 );
@@ -395,6 +397,9 @@ void SetVehicleName( SOLDIERTYPE *pVehicle );
BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier );
+BOOLEAN ChangeVehicleSeat( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex );
+BOOLEAN SwapVehicleSeat( SOLDIERTYPE *pVehicle, SOLDIERTYPE *pSoldier, UINT8 ubSeatIndex );
+
void AddPassangersToTeamPanel( INT32 iId );
@@ -456,6 +461,8 @@ BOOLEAN IsEnoughSpaceInVehicle( INT32 iID );
BOOLEAN IsSoldierInThisVehicleSquad( SOLDIERTYPE *pSoldier, INT8 bSquadNumber );
+INT8 GetSeatIndexFromSoldier( SOLDIERTYPE *pSoldier );
+
SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier );
BOOLEAN DoesVehicleHaveAnyPassengers( INT32 iVehicleID );
diff --git a/Tactical/XML_Vehicles.cpp b/Tactical/XML_Vehicles.cpp
index 66c112b3..fd4b4127 100644
--- a/Tactical/XML_Vehicles.cpp
+++ b/Tactical/XML_Vehicles.cpp
@@ -19,6 +19,7 @@ struct
UINT32 maxArraySize;
UINT32 curIndex;
+ UINT32 curSeatIndex;
UINT32 currentDepth;
UINT32 maxReadDepth;
}
@@ -65,6 +66,28 @@ newCarStartElementHandle(void *userData, const XML_Char *name, const XML_Char **
pData->curElement = ELEMENT_PROPERTY;
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';
}
@@ -121,13 +144,16 @@ newCarEndElementHandle(void *userData, const XML_Char *name)
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleName, pData->curNewCar.NewVehicleName);
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewShortVehicleStrings, pData->curNewCar.NewShortVehicleStrings);
gNewVehicle[ pData->curNewCar.uiIndex ].NewUsed = FALSE;
+ memcpy( gNewVehicle[ pData->curNewCar.uiIndex ].VehicleSeats, pData->curNewCar.VehicleSeats, sizeof(pData->curNewCar.VehicleSeats) );
+
}
else
{
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleStrings, pData->curNewCar.NewVehicleStrings);
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)
{
@@ -213,6 +239,81 @@ newCarEndElementHandle(void *userData, const XML_Char *name)
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--;
@@ -301,6 +402,7 @@ void InitNewVehicles ()
gNewVehicle[ iCount ].NewVehicleName[127] = '\0';
gNewVehicle[ iCount ].NewShortVehicleStrings[127] = '\0';
gNewVehicle[ iCount ].NewUsed = FALSE;
+ memset( &gNewVehicle[ iCount ].VehicleSeats, 0, sizeof(gNewVehicle[ iCount ].VehicleSeats) );
}
}
diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp
index 6f241116..9f3e38da 100644
--- a/Tactical/opplist.cpp
+++ b/Tactical/opplist.cpp
@@ -48,6 +48,7 @@
#include "drugs and alcohol.h"
#include "Interface.h"
#include "Explosion Control.h"//dnl ch40 200909
+ #include "Vehicles.h"
#endif
#ifdef JA2UB
@@ -1217,6 +1218,18 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
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 ) )
{
// always calculate direction for tanks so we have something to work with
@@ -5296,6 +5309,8 @@ void DebugSoldierPage4( )
//
#define MAX_MOVEMENT_NOISE 9
+#define VEHICLE_FAST_MOVEMENT_NOISE 25
+#define VEHICLE_NORMAL_MOVEMENT_NOISE 15
UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
{
@@ -5303,6 +5318,25 @@ UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
UINT8 ubMaxVolume, ubVolume, ubBandaged, ubEffLife;
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
// modify amount of noise and stealth difficulty depending on surface type
diff --git a/Utils/ExportStrings.cpp b/Utils/ExportStrings.cpp
index 7b02a982..643dba84 100644
--- a/Utils/ExportStrings.cpp
+++ b/Utils/ExportStrings.cpp
@@ -177,6 +177,7 @@ bool Loc::ExportStrings()
ExportSection(props, L"Vehicle", Loc::pVehicleStrings, 0, 6);
ExportSection(props, L"ShortVehicle", Loc::pShortVehicleStrings, 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"ExitingSectorHelp", Loc::pExitingSectorHelpText, 0, TEXT_NUM_EXIT_GUI);
diff --git a/Utils/Text.h b/Utils/Text.h
index a3a41c9d..e89daec8 100644
--- a/Utils/Text.h
+++ b/Utils/Text.h
@@ -740,6 +740,7 @@ extern STR16 sKeyDescriptionStrings[2];
extern CHAR16 zHealthStr[][13];
extern STR16 gzHiddenHitCountStr[1];
extern STR16 zVehicleName[ 6 ];
+extern STR16 pVehicleSeatsStrings[ 2 ] ;
// Flugente: externalised texts for some features
enum
diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp
index 5fa315d0..e2ca5ea3 100644
--- a/Utils/_ChineseText.cpp
+++ b/Utils/_ChineseText.cpp
@@ -3072,6 +3072,11 @@ STR16 zVehicleName[] =
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
diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp
index 5690fcb3..b29f6e5f 100644
--- a/Utils/_DutchText.cpp
+++ b/Utils/_DutchText.cpp
@@ -3070,6 +3070,11 @@ STR16 zVehicleName[] =
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
diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp
index af7ce5d2..13984f08 100644
--- a/Utils/_EnglishText.cpp
+++ b/Utils/_EnglishText.cpp
@@ -3072,6 +3072,11 @@ STR16 zVehicleName[] =
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
diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp
index fe116fec..07449292 100644
--- a/Utils/_FrenchText.cpp
+++ b/Utils/_FrenchText.cpp
@@ -3074,6 +3074,11 @@ STR16 zVehicleName[] =
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
diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp
index 0499f1c5..93bc94e3 100644
--- a/Utils/_GermanText.cpp
+++ b/Utils/_GermanText.cpp
@@ -3075,6 +3075,12 @@ STR16 zVehicleName[] =
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
CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
{
diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp
index f3369609..9aaa3c66 100644
--- a/Utils/_ItalianText.cpp
+++ b/Utils/_ItalianText.cpp
@@ -3066,6 +3066,11 @@ STR16 zVehicleName[] =
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
diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp
index 2624b457..9b691c04 100644
--- a/Utils/_PolishText.cpp
+++ b/Utils/_PolishText.cpp
@@ -3079,6 +3079,11 @@ STR16 zVehicleName[] =
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
diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp
index f30569f6..04d2d6d4 100644
--- a/Utils/_RussianText.cpp
+++ b/Utils/_RussianText.cpp
@@ -3072,6 +3072,11 @@ STR16 zVehicleName[] =
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
diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp
index ef210299..4f7f54b4 100644
--- a/Utils/_TaiwaneseText.cpp
+++ b/Utils/_TaiwaneseText.cpp
@@ -3075,6 +3075,11 @@ STR16 zVehicleName[] =
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