mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- 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
222 lines
7.2 KiB
C++
222 lines
7.2 KiB
C++
// 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);
|
|
} |