mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Driveable vehicle Update: Externalized vehicle seats (by anv)
- externalised vehicle seats (TableData\Vehicles.xml) influence position of passenger, field of view, ability to shoot and being hidden, - seat can chosen by using ctrl+RMB on vehicle (ctrl + LMB just takes the first visible seat) - seats can be changed or swapped while inside vehicle, - remade JSD files for cars, - vehicles aren't transparent anymore, - vehicles are louder than people, depending how fast they move. see: http://www.bears-pit.com/board/ubbthreads.php/topics/332790/5.html git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7212 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -16750,7 +16750,12 @@ SOLDIERTYPE *GetSelectedAssignSoldier( BOOLEAN fNullOK )
|
||||
{
|
||||
// better be an active person, not a vehicle
|
||||
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 );
|
||||
|
||||
+15
-15
@@ -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
|
||||
|
||||
};
|
||||
|
||||
+37
-14
@@ -1491,14 +1491,14 @@ UINT32 UIHandleMOnTerrain( UI_EVENT *pUIEvent )
|
||||
}
|
||||
}
|
||||
|
||||
// If we are a passenger or driver just show an X
|
||||
// If we are a passenger or driver just show ?
|
||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||
{
|
||||
if ( ( 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 )
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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( )
|
||||
|
||||
+41
-3
@@ -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 );
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -666,6 +666,10 @@
|
||||
RelativePath=".\Vehicles.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VehicleMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Weapons.h"
|
||||
>
|
||||
@@ -992,6 +996,10 @@
|
||||
RelativePath=".\Vehicles.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VehicleMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Weapons.cpp"
|
||||
>
|
||||
|
||||
@@ -670,6 +670,10 @@
|
||||
RelativePath="Vehicles.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="VehicleMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Weapons.h"
|
||||
>
|
||||
@@ -994,6 +998,10 @@
|
||||
RelativePath="Vehicles.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="VehicleMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Weapons.cpp"
|
||||
>
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
<ClCompile Include="TeamTurns.cpp" />
|
||||
<ClCompile Include="Turn Based Input.cpp" />
|
||||
<ClCompile Include="UI Cursors.cpp" />
|
||||
<ClCompile Include="VehicleMenu.cpp" />
|
||||
<ClCompile Include="Vehicles.cpp" />
|
||||
<ClCompile Include="Weapons.cpp" />
|
||||
<ClCompile Include="World Items.cpp" />
|
||||
|
||||
@@ -668,5 +668,8 @@
|
||||
<ClCompile Include="XML_Keys.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VehicleMenu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -105,6 +105,7 @@
|
||||
<ClInclude Include="TeamTurns.h" />
|
||||
<ClInclude Include="UI Cursors.h" />
|
||||
<ClInclude Include="Vehicles.h" />
|
||||
<ClInclude Include="VehicleMenu.h" />
|
||||
<ClInclude Include="Weapons.h" />
|
||||
<ClInclude Include="World Items.h" />
|
||||
<ClInclude Include="XML.h" />
|
||||
@@ -187,6 +188,7 @@
|
||||
<ClCompile Include="Turn Based Input.cpp" />
|
||||
<ClCompile Include="UI Cursors.cpp" />
|
||||
<ClCompile Include="Vehicles.cpp" />
|
||||
<ClCompile Include="VehicleMenu.cpp" />
|
||||
<ClCompile Include="Weapons.cpp" />
|
||||
<ClCompile Include="World Items.cpp" />
|
||||
<ClCompile Include="XML_AmmoStrings.cpp" />
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="Vehicles.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VehicleMenu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Weapons.h">
|
||||
<Filter>Header Files</Filter>
|
||||
@@ -484,6 +487,9 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="Vehicles.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VehicleMenu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Weapons.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
// anv: totally not a copy of SkillMenu.cpp
|
||||
|
||||
#include "VehicleMenu.h"
|
||||
#include "Soldier Profile Type.h"
|
||||
#include "Overhead.h"
|
||||
#include "Text.h"
|
||||
#include "Isometric Utils.h"
|
||||
#include "DisplayCover.h"
|
||||
#include "worldman.h"
|
||||
#include "Vehicles.h"
|
||||
#include "soldier macros.h"
|
||||
#include "Soldier Add.h"
|
||||
#include "PATHAI.h"
|
||||
#include "Points.h"
|
||||
#include "Handle UI.h"
|
||||
#include "Squads.h"
|
||||
#include "Font Control.h"
|
||||
|
||||
// sevenfm: need this for correct calculation of vehicle menu position
|
||||
extern INT16 gsInterfaceLevel;
|
||||
|
||||
UINT16 usVehicleMenuPosX = 0;
|
||||
UINT16 usVehicleMenuPosY = 0;
|
||||
|
||||
INT32 sVehicleMenuTargetGridNo = NOWHERE;
|
||||
|
||||
SOLDIERTYPE *pCurrentSoldier = NULL;
|
||||
SOLDIERTYPE *pCurrentVehicle = NULL;
|
||||
|
||||
void HideVehicleMenu( void )
|
||||
{
|
||||
// Dirty!
|
||||
fMapPanelDirty = TRUE;
|
||||
}
|
||||
|
||||
// Turns an option off by always returning FALSE
|
||||
BOOLEAN Popup_VehicleMenuOptionOff( void ) { return FALSE; }
|
||||
|
||||
void
|
||||
VehicleMenuItem::SetupPopup(CHAR* name)
|
||||
{
|
||||
// create a popup
|
||||
gPopup = new POPUP(name);
|
||||
|
||||
// add a callback that lets the keyboard handler know we're done (and ready to pop up again)
|
||||
gPopup->setCallback(POPUP_CALLBACK_HIDE, new popupCallbackFunction<void, void>( &HideVehicleMenu ) );
|
||||
}
|
||||
|
||||
// Different VehicleItem classes. We need wrappers for each one, as we cannot pass a pointer to a member function (we need a concrete object)
|
||||
|
||||
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||
VehicleSelection gVehicleSelection;
|
||||
|
||||
void Wrapper_Function_VehicleSelection( UINT32 aVal ) { gVehicleSelection.Functions(aVal); }
|
||||
void Wrapper_Setup_VehicleSelection( UINT32 aVal ) { gVehicleSelection.Setup(aVal); }
|
||||
void Wrapper_Cancel_VehicleSelection( UINT32 aVal ) { gVehicleSelection.Cancel(); }
|
||||
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||
void
|
||||
VehicleSelection::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if ( pCurrentSoldier == NULL )
|
||||
return;
|
||||
|
||||
if ( pCurrentVehicle == NULL )
|
||||
return;
|
||||
|
||||
SetupPopup("VehicleSelection");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
// create entries for each vehicle seat
|
||||
INT8 bVehicleID = pCurrentVehicle->bVehicleID;
|
||||
INT8 bSeatIndex = GetSeatIndexFromSoldier( pCurrentSoldier );
|
||||
INT32 iSeatingCapacity = gNewVehicle[ pVehicleList[ bVehicleID ].ubVehicleType ].iNewSeatingCapacities;
|
||||
|
||||
for ( int i = 0; i < iSeatingCapacity; ++i)
|
||||
{
|
||||
swprintf( pStr, gNewVehicle[ pVehicleList[ bVehicleID ].ubVehicleType ].VehicleSeats[i].zSeatName );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Function_VehicleSelection, i ));
|
||||
|
||||
// if seat is already taken, grey it out
|
||||
if ( pVehicleList[ bVehicleID ].pPassengers[ i ] != NULL )
|
||||
{
|
||||
if( pCurrentSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
||||
{
|
||||
if( pVehicleList[ bVehicleID ].pPassengers[ i ] == pCurrentSoldier )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_VehicleMenuOptionOff, NULL ));
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep, but colour in yellow
|
||||
pOption->color_foreground = FONT_YELLOW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_VehicleMenuOptionOff, NULL ));
|
||||
}
|
||||
}
|
||||
|
||||
// block swapping between different compartments
|
||||
if( gTacticalStatus.uiFlags & INCOMBAT )
|
||||
{
|
||||
if( bSeatIndex != (-1) )
|
||||
{
|
||||
if( gNewVehicle[pVehicleList[ pCurrentVehicle->bVehicleID ].ubVehicleType].VehicleSeats[bSeatIndex].ubCompartment !=
|
||||
gNewVehicle[pVehicleList[ pCurrentVehicle->bVehicleID ].ubVehicleType].VehicleSeats[i].ubCompartment )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_VehicleMenuOptionOff, NULL ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, pSkillMenuStrings[SKILLMENU_CANCEL] );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_VehicleSelection, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// grab soldier's x,y screen position
|
||||
INT16 sX, sY;
|
||||
GetGridNoScreenPos( sVehicleMenuTargetGridNo, gsInterfaceLevel, &sX, &sY );
|
||||
|
||||
if( sX < 0 ) sX = 0;
|
||||
if( sY < 0 ) sY = 0;
|
||||
|
||||
usVehicleMenuPosX = sX + 30;
|
||||
usVehicleMenuPosY = sY;
|
||||
|
||||
if ( ( usVehicleMenuPosX + 200 ) > SCREEN_WIDTH )
|
||||
usVehicleMenuPosX = SCREEN_WIDTH - 200;
|
||||
|
||||
if ( ( usVehicleMenuPosY + 130 ) > SCREEN_HEIGHT )
|
||||
usVehicleMenuPosY = SCREEN_HEIGHT - 190;
|
||||
|
||||
SetPos(usVehicleMenuPosX, usVehicleMenuPosY);
|
||||
}
|
||||
|
||||
void
|
||||
VehicleSelection::Functions( UINT32 aVal )
|
||||
{
|
||||
INT32 sActionGridNo;
|
||||
UINT8 ubDirection;
|
||||
INT16 sAPCost = 0;
|
||||
INT32 sTempSelectedSoldier;
|
||||
|
||||
Cancel();
|
||||
|
||||
if( pCurrentSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) && pCurrentSoldier->iVehicleId == pCurrentVehicle->bVehicleID )
|
||||
{
|
||||
if( SwapVehicleSeat( pCurrentVehicle, pCurrentSoldier, aVal ) )
|
||||
{
|
||||
sTempSelectedSoldier = gusSelectedSoldier;
|
||||
SetCurrentSquad( CurrentSquad(), TRUE );
|
||||
gusSelectedSoldier = sTempSelectedSoldier;
|
||||
}
|
||||
}
|
||||
else if ( OK_ENTERABLE_VEHICLE( pCurrentVehicle ) && pCurrentVehicle->bVisible != -1 && OKUseVehicle( pCurrentVehicle->ubProfile ) )
|
||||
{
|
||||
// Find a gridno closest to sweetspot...
|
||||
sActionGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pCurrentSoldier, pCurrentSoldier->usUIMovementMode, 5, &ubDirection, 0, pCurrentVehicle, TRUE );
|
||||
|
||||
if (!TileIsOutOfBounds(sActionGridNo))
|
||||
{
|
||||
// Calculate AP costs...
|
||||
//sAPCost = GetAPsToBeginFirstAid( pSoldier );
|
||||
sAPCost += PlotPath( pCurrentSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pCurrentSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pCurrentSoldier->bActionPoints);
|
||||
|
||||
if ( EnoughPoints( pCurrentSoldier, sAPCost, 0, TRUE ) )
|
||||
{
|
||||
pCurrentSoldier->DoMercBattleSound( BATTLE_SOUND_OK1 );
|
||||
|
||||
// CHECK IF WE ARE AT THIS GRIDNO NOW
|
||||
if ( pCurrentSoldier->sGridNo != sActionGridNo )
|
||||
{
|
||||
// SEND PENDING ACTION
|
||||
pCurrentSoldier->aiData.ubPendingAction = MERC_ENTER_VEHICLE;
|
||||
pCurrentSoldier->aiData.sPendingActionData2 = pCurrentVehicle->sGridNo;
|
||||
pCurrentSoldier->aiData.bPendingActionData3 = ubDirection;
|
||||
pCurrentSoldier->aiData.uiPendingActionData4 = aVal;
|
||||
pCurrentSoldier->aiData.ubPendingActionAnimCount = 0;
|
||||
|
||||
// WALK UP TO DEST FIRST
|
||||
pCurrentSoldier->EVENT_InternalGetNewSoldierPath( sActionGridNo, pCurrentSoldier->usUIMovementMode, 3 , pCurrentSoldier->flags.fNoAPToFinishMove );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCurrentSoldier->EVENT_SoldierEnterVehicle( pCurrentVehicle->sGridNo, ubDirection, aVal );
|
||||
}
|
||||
|
||||
// OK, set UI
|
||||
SetUIBusy( pCurrentSoldier->ubID );
|
||||
//guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cancel();
|
||||
gVehicleSelection.Cancel();
|
||||
}
|
||||
/////////////////////////////// Vehicle Selection ////////////////////////////////////////////
|
||||
|
||||
void VehicleMenu( INT32 usMapPos, SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVehicle )
|
||||
{
|
||||
sVehicleMenuTargetGridNo = usMapPos;
|
||||
pCurrentSoldier = pSoldier;
|
||||
pCurrentVehicle = pVehicle;
|
||||
gVehicleSelection.Setup(0);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef _VEHICLE_MENU_
|
||||
#define _VEHICLE_MENU_
|
||||
|
||||
#include "popup_class.h"
|
||||
#include "Soldier Profile.h"
|
||||
|
||||
class VehicleMenuItem
|
||||
{
|
||||
public:
|
||||
VehicleMenuItem() :
|
||||
fInitialized(FALSE), usPosX(0), gPopup(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Cancel()
|
||||
{
|
||||
// Hide the Filter Menu pop-up.
|
||||
if (gPopup != NULL && fInitialized )
|
||||
{
|
||||
gPopup->hide();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Destroy()
|
||||
{
|
||||
// If we already have a popup, destroy it first. This ensures we get a fresh menu each time.
|
||||
if ( fInitialized )
|
||||
{
|
||||
delete(gPopup);
|
||||
gPopup = NULL;
|
||||
fInitialized = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
UINT16 GetMaxPosX()
|
||||
{
|
||||
if ( gPopup )
|
||||
return (usPosX + gPopup->getBoxDimensions().iRight);
|
||||
|
||||
return usPosX;
|
||||
}
|
||||
|
||||
virtual void SetPos(UINT16 usX, UINT16 usY)
|
||||
{
|
||||
// same y, different x
|
||||
usPosX = usX;
|
||||
gPopup->setPosition( usPosX, usY );
|
||||
|
||||
fInitialized = TRUE;
|
||||
gPopup->show();
|
||||
}
|
||||
|
||||
void SetupPopup(CHAR* name);
|
||||
|
||||
POPUP* GetPopup()
|
||||
{
|
||||
return gPopup;
|
||||
}
|
||||
|
||||
virtual void Setup( UINT32 aVal ) {}
|
||||
virtual void Functions( UINT32 aVal ) {}
|
||||
|
||||
private:
|
||||
BOOLEAN fInitialized;
|
||||
UINT16 usPosX;
|
||||
POPUP* gPopup;
|
||||
};
|
||||
|
||||
// select a vehicle seat (and possibly other options)
|
||||
class VehicleSelection : public VehicleMenuItem
|
||||
{
|
||||
public:
|
||||
VehicleSelection() : usSector(0) {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
void Functions( UINT32 aVal );
|
||||
|
||||
private:
|
||||
UINT32 usSector;
|
||||
};
|
||||
|
||||
|
||||
void VehicleMenu( INT32 usMapPos, SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVehicle );
|
||||
|
||||
#endif
|
||||
+358
-37
@@ -475,10 +475,12 @@ BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId )
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, BOOLEAN fSpecificSeat, UINT8 ubSeatIndex )
|
||||
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId, UINT8 ubSeatIndex )
|
||||
{
|
||||
INT32 iCounter = 0;
|
||||
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
|
||||
|
||||
+27
-20
@@ -11,6 +11,25 @@
|
||||
extern std::vector<INT8> 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 );
|
||||
|
||||
+104
-2
@@ -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) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 ] =
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user