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:
Wanne
2014-05-18 15:26:15 +00:00
parent cf1b9982ba
commit bbff053fc5
35 changed files with 1209 additions and 144 deletions
+6 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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 )
+1
View File
@@ -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 );
+40 -32
View File
@@ -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
View File
@@ -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 );
+37
View File
@@ -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
View File
@@ -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
+23 -1
View File
@@ -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;
+8 -2
View File
@@ -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 );
} }
} }
+1 -1
View File
@@ -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 );
+8
View File
@@ -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"
> >
+8
View File
@@ -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"
> >
+1
View File
@@ -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" />
+3
View File
@@ -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>
+2
View File
@@ -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" />
+6
View File
@@ -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>
+84 -13
View File
@@ -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;
+222
View File
@@ -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);
}
+85
View File
@@ -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
View File
@@ -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
View File
@@ -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 );
+102
View File
@@ -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) );
} }
} }
+34
View File
@@ -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
+1
View File
@@ -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);
+1
View File
@@ -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
+5
View File
@@ -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
+5
View File
@@ -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
+5
View File
@@ -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
+5
View File
@@ -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
+6
View File
@@ -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 ] =
{ {
+5
View File
@@ -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
+5
View File
@@ -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
+5
View File
@@ -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
+5
View File
@@ -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