mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9344 3b4a5df2-a311-0410-b5c6-a8a6f20db521
9637 lines
272 KiB
C++
9637 lines
272 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "Tactical All.h"
|
|
#include "Language Defines.h"
|
|
#include "HelpScreen.h"
|
|
#include "Prebattle Interface.h"
|
|
#include "ambient control.h"
|
|
#include "DisplayCover.h"
|
|
#include "_Ja25Englishtext.h"
|
|
#else
|
|
#include "builddefines.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "stdlib.h"
|
|
#include "debug.h"
|
|
#include "math.h"
|
|
#include "jascreens.h"
|
|
#include "pathai.h"
|
|
#include "Animation Control.h"
|
|
#include "Animation Data.h"
|
|
#include "Event Pump.h"
|
|
#include "Timer Control.h"
|
|
#include "Handle UI.h"
|
|
#include "Isometric Utils.h"
|
|
#include "input.h"
|
|
#include "overhead.h"
|
|
#include "Sys Globals.h"
|
|
#include "screenids.h"
|
|
#include "interface.h"
|
|
#include "cursor control.h"
|
|
#include "points.h"
|
|
#include "Interactive Tiles.h"
|
|
#include "interface cursors.h"
|
|
#include "weapons.h"
|
|
#include "lighting.h"
|
|
#include "sound control.h"
|
|
#include "environment.h"
|
|
#include "Music Control.h"
|
|
#include "ai.h"
|
|
#include "renderworld.h"
|
|
#include "font control.h"
|
|
#include "worldman.h"
|
|
#include "Handle UI Plan.h"
|
|
#include "message.h"
|
|
#ifdef NETWORKED
|
|
#include "Networking.h"
|
|
#include "Communication.h"
|
|
#endif
|
|
#include "overhead map.h"
|
|
#include "world items.h"
|
|
#include "Game Clock.h"
|
|
#include "interface items.h"
|
|
#include "physics.h"
|
|
#include "ui cursors.h"
|
|
#include "worldman.h"
|
|
#include "strategicmap.h"
|
|
#include "soldier profile.h"
|
|
#include "soldier create.h"
|
|
#include "soldier add.h"
|
|
#include "dialogue control.h"
|
|
#include "interface dialogue.h"
|
|
#include "opplist.h"
|
|
#include "interactive tiles.h"
|
|
#include "messageboxscreen.h"
|
|
#include "gameloop.h"
|
|
|
|
#include "spread burst.h"
|
|
#include "explosion control.h"
|
|
#include "QuestDebug.h"
|
|
#include "assignments.h"
|
|
#include "EditScreen.h"
|
|
#include "SaveLoadGame.h"
|
|
#include "los.h"
|
|
#include "Exit Grids.h"
|
|
#include "Strategic Exit GUI.h"
|
|
#include "auto bandage.h"
|
|
#include "Options Screen.h"
|
|
#include "squads.h"
|
|
#include "interface panels.h"
|
|
#include "soldier tile.h"
|
|
#include "Soldier functions.h"
|
|
#include "Game Events.h"
|
|
#include "english.h"
|
|
#include "Random.h"
|
|
#include "Assignments.h"
|
|
#include "Map Screen Interface.h"
|
|
#include "renderworld.h"
|
|
#include "Quest Debug System.h"
|
|
//#include "medical.h"
|
|
#include "Arms Dealer Init.h"
|
|
#include "ShopKeeper Interface.h"
|
|
#include "GameSettings.h"
|
|
#include "vehicles.h"
|
|
#include "SaveLoadScreen.h"
|
|
#include "Air raid.h"
|
|
#include "meanwhile.h"
|
|
#include "text.h"
|
|
#include "Inventory Choosing.h"
|
|
#include "soldier macros.h"
|
|
#include "HelpScreen.h"
|
|
#include "cheats.h"
|
|
#include "displaycover.h"
|
|
#include "Tactical Save.h"
|
|
#include "history.h"
|
|
#include "Queen Command.h"
|
|
#include "PreBattle Interface.h"
|
|
#include "_Ja25EnglishText.h"
|
|
#include "Militia Control.h"
|
|
#include "Ambient Control.h"
|
|
#include "Strategic AI.h"
|
|
#include "VehicleMenu.h"
|
|
#endif
|
|
|
|
#include "Quest Debug System.h"
|
|
#include "connect.h"
|
|
#include "fresh_header.h"
|
|
|
|
#include "IMP Skill Trait.h" // added by Flugente
|
|
#include "SkillMenu.h" // added by Flugente
|
|
#include "Map Screen Interface Map Inventory.h"//dnl ch75 021113
|
|
|
|
#include "DisplayCover.h" // added by Sevenfm
|
|
#include "InterfaceItemImages.h" // added by Sevenfm
|
|
#include "DynamicDialogueWidget.h" // added by Flugente for DelayBoxDestructionBy(...)
|
|
#include "Utilities.h" // added by Flugente
|
|
#include "AIInternals.h" // sevenfm
|
|
#include "Interface Cursors.h" // sevenfm
|
|
#include "strategic.h" // shadooow for CreateNewMerc
|
|
//forward declarations of common classes to eliminate includes
|
|
class OBJECTTYPE;
|
|
class SOLDIERTYPE;
|
|
|
|
extern UIKEYBOARD_HOOK gUIKeyboardHook;
|
|
extern BOOLEAN fRightButtonDown;
|
|
extern BOOLEAN fLeftButtonDown;
|
|
extern BOOLEAN fIgnoreLeftUp;
|
|
extern UINT32 guiCurrentEvent;
|
|
extern UINT8 gubIntTileCheckFlags;
|
|
extern UINT32 guiCurrentUICursor;
|
|
extern SOLDIERTYPE *gpSMCurrentMerc;
|
|
extern INT32 gsOverItemsGridNo;
|
|
extern INT16 gsOverItemsLevel;
|
|
extern BOOLEAN gfUIShowExitSouth;
|
|
extern BOOLEAN fMiddleButtonDown;
|
|
extern BOOLEAN fX1ButtonDown;
|
|
extern BOOLEAN fX2ButtonDown;
|
|
|
|
extern INT32 giStartingMemValue;
|
|
|
|
|
|
extern BOOLEAN gfBeginBurstSpreadTracking;
|
|
extern BOOLEAN gfRTClickLeftHoldIntercepted;
|
|
|
|
extern BOOLEAN gfReportHitChances;
|
|
|
|
BOOLEAN gfFirstCycleMovementStarted = FALSE;
|
|
|
|
extern UINT32 guiVObjectSize;
|
|
extern UINT32 guiVSurfaceSize;
|
|
|
|
extern BOOLEAN gfNextShotKills;
|
|
UINT32 guiSoldierFlags;
|
|
UINT32 guiUITargetSoldierId = NOBODY;
|
|
|
|
// sevenfm: for cover dialog
|
|
extern COVER_DRAW_MODE gubDrawMode;
|
|
|
|
extern TraitSelection gTraitSelection;
|
|
extern SkillSelection gSkillSelection;
|
|
extern ArtillerySector gArtillerySector;
|
|
extern ArtilleryTeam gArtilleryTeam;
|
|
extern ReinforcementSector gReinforcementSector;
|
|
extern ReinforcementNumber gReinforcementNumber;
|
|
extern SoldierSelection gSoldierSelection;
|
|
extern DragSelection gDragSelection;
|
|
|
|
extern MOUSE_REGION gMPanelRegion;
|
|
|
|
extern UINT32 guiNewUICursor;
|
|
extern SOLDIERTYPE *pTMilitiaSoldier;
|
|
|
|
void HandleTalkingMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent );
|
|
void HandleMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent );
|
|
void HandleItemMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent );
|
|
void HandleOpenDoorMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent );
|
|
void HandleSectorExitMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent );
|
|
void HandleStanceChangeFromUIKeys( UINT8 ubAnimHeight );
|
|
|
|
extern BOOLEAN ValidQuickExchangePosition( );
|
|
|
|
|
|
BOOLEAN HandleUIReloading( SOLDIERTYPE *pSoldier );
|
|
|
|
|
|
extern SOLDIERTYPE *FindNextActiveSquad( SOLDIERTYPE *pSoldier );
|
|
extern SOLDIERTYPE *FindPrevActiveSquad( SOLDIERTYPE *pSoldier );
|
|
extern void ToggleItemGlow( BOOLEAN fOn );
|
|
extern void HandleTalkingMenuBackspace( void );
|
|
extern void BeginKeyPanelFromKeyShortcut( );
|
|
|
|
|
|
|
|
extern INT32 iSMPanelButtons[ NUM_SM_BUTTONS ];
|
|
extern INT32 iTEAMPanelButtons[ NUM_TEAM_BUTTONS ];
|
|
extern INT32 giSMStealthButton;
|
|
|
|
SOLDIERTYPE *gpExchangeSoldier1;
|
|
SOLDIERTYPE *gpExchangeSoldier2;
|
|
|
|
// Flugente: fortification
|
|
INT16 gCurrentFortificationStructure = -1;
|
|
UINT8 gCurrentFortificationTileLibraryIndex = 0;
|
|
|
|
extern UINT32 guiMessageBoxImage;
|
|
extern UINT16 guiMessageBoxImageIndex;
|
|
|
|
BOOLEAN ConfirmActionCancel( INT32 usMapPos, INT32 usOldMapPos );
|
|
|
|
BOOLEAN gfNextFireJam = FALSE;
|
|
INT16 brstmode = 0; //dddd
|
|
extern INT16 ITEMDESC_START_X;
|
|
extern INT16 ITEMDESC_START_Y;
|
|
|
|
|
|
BOOLEAN gfMouseLockedOnBorder = FALSE;
|
|
extern int iWindowedMode;
|
|
|
|
extern OBJECTTYPE *gpItemDescObject;
|
|
extern BOOLEAN gfInItemStackPopup;
|
|
extern BOOLEAN gfInKeyRingPopup;
|
|
|
|
|
|
//Little functions called by keyboard input
|
|
void SwapGoggles(SOLDIERTYPE *pTeamSoldier);
|
|
// HEADROCK HAM B2.8: Function to switch team's goggles uniformly
|
|
void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision);
|
|
void SeperateItems();
|
|
void StackAndSort( BOOLEAN fRestrictToAmmo );
|
|
void CreateRandomItem();
|
|
void MakeSelectedSoldierTired();
|
|
void ToggleRealTime( UINT32 *puiNewEvent );
|
|
void ToggleViewAllMercs();
|
|
void ToggleViewAllItems();
|
|
void TestExplosion();
|
|
void CycleSelectedMercsItem();
|
|
void ToggleWireFrame();
|
|
void RefreshSoldier();
|
|
void ChangeSoldiersBodyType( UINT8 ubBodyType, BOOLEAN fCreateNewPalette );
|
|
void TeleportSelectedSoldier();
|
|
void ToggleTurnMode();// ary-05/05/2009 : add forced turn mode
|
|
void ToggleTreeTops();
|
|
void ToggleZBuffer();
|
|
void TogglePlanningMode();
|
|
void SetBurstMode();
|
|
void SetScopeMode( INT32 usMapPos );
|
|
void ObliterateSector();
|
|
void RandomizeMercProfile();
|
|
void CreateNextCivType();
|
|
void ToggleCliffDebug();
|
|
void CreateCow();
|
|
void CreateBloodCat();
|
|
void CreatePlayerControlledCow();
|
|
void ToggleRealTimeConfirm();
|
|
void TestMeanWhile( INT32 iID );
|
|
void CreatePlayerControlledMonster();
|
|
void ChangeCurrentSquad( INT32 iSquad );
|
|
void HandleSelectMercSlot( UINT8 ubPanelSlot, INT8 bCode );
|
|
void EscapeUILock( );
|
|
void TestCapture( );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
void ToggleMapEdgepoints();
|
|
#endif
|
|
#ifdef JA2TESTVERSION
|
|
void ToggleMercsNeverQuit();
|
|
#endif
|
|
#ifdef JA2TESTVERSION
|
|
void DumpSectorDifficultyInfo( void );
|
|
#endif
|
|
|
|
void HandleStealthChangeFromUIKeys( );
|
|
|
|
extern BOOLEAN CompatibleAmmoForGun( OBJECTTYPE *pTryObject, OBJECTTYPE *pTestObject );
|
|
extern void DetermineWhichAssignmentMenusCanBeShown( void );
|
|
extern void DetermineWhichMilitiaControlMenusCanBeShown( void ); //lalien
|
|
// The_Bob - real time sneaking, 01-06-09
|
|
extern BOOLEAN WeSeeNoOne(void); // Needed to control entering turn-based with ctrl-x
|
|
|
|
void QueryTBMButton( UINT32 *puiNewEvent );
|
|
void QueryTBWheel( UINT32 *puiNewEvent );
|
|
void QueryTBX1Button( UINT32 *puiNewEvent );
|
|
void QueryTBX2Button( UINT32 *puiNewEvent );
|
|
|
|
void MercCreationCallBack(UINT8 ubResult);
|
|
void ItemCreationCallBack( UINT8 ubResult );
|
|
void CheatCreateItem();
|
|
// silversurfer: added for merc portrait swapping in tactical
|
|
void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection );
|
|
extern INT8 GetTeamSlotFromPlayerID( UINT8 ubID );
|
|
extern FACETYPE *gpCurrentTalkingFace;
|
|
|
|
// Flugente: toggle display of enemy role indicators
|
|
extern BOOLEAN gDisplayEnemyRoles;
|
|
|
|
// sevenfm: new mouse commands
|
|
void HandleAltMouseTBWheel( void );
|
|
void HandleAltMouseTBMButton( UINT32 *puiNewEvent );
|
|
void HandleAltMouseTBX1Button( UINT32 *puiNewEvent );
|
|
void HandleAltMouseTBX2Button( UINT32 *puiNewEvent );
|
|
|
|
// sevenfm: original mouse commands functionality
|
|
void HandleMouseTBWheel( void );
|
|
void HandleMouseTBMButton( UINT32 *puiNewEvent );
|
|
void HandleMouseTBX1Button( UINT32 *puiNewEvent );
|
|
void HandleMouseTBX2Button( UINT32 *puiNewEvent );
|
|
|
|
// sevenfm: check availability for actions
|
|
BOOLEAN CheckAutoBandage(void);
|
|
|
|
// sevenfm: common functionality
|
|
void HandleTBSelectAllMercs( void );
|
|
void HandleTBToggleStealthAll( void );
|
|
void HandleTBToggleFireMode( void );
|
|
void HandleTBJumpThroughWindow( void );
|
|
void HandleTBJump( void );
|
|
void HandleTBLook( UINT32 *puiNewEvent );
|
|
void HandleTBSelectAllMercs( void );
|
|
void HandleTBCycleThroughKnownEnemies( void );
|
|
void HandleTBCycleThroughKnownEnemiesBackward( void );
|
|
void HandleTBCycleThroughVisibleEnemies( void );
|
|
void HandleTBCycleThroughVisibleEnemiesBackward( void );
|
|
void HandleTBLocateSoldier( void );
|
|
void HandleTBChangeLevel( void );
|
|
void HandleTBSwapHands( void );
|
|
void HandleTBSwapGunsling( void );
|
|
void HandleTBSwapKnife( void );
|
|
void HandleTBSwapSidearm( void );
|
|
void HandleTBSwapGoogles( void );
|
|
void HandleTBToggleFormation( void );
|
|
void HandleTBEnterTurnbased( void );
|
|
void HandleTBToggleSneak( void );
|
|
void HandleTBToggleStealth( void );
|
|
void HandleTBReload( void );
|
|
void HandleTBReloadAll( void );
|
|
void HandleTBShowCover( void );
|
|
void HandleTBShowMines( void );
|
|
void HandleTBShowLOS( void );
|
|
void HandleTBToggleTrapNetworkView( void );
|
|
void HandleTBGotoHigherStance(void);
|
|
void HandleTBGotoLowerStance(void);
|
|
void HandleTBLocateNextMerc( void );
|
|
void HandleTBLocatePrevMerc( void );
|
|
void HandleTBLevelDown(void);
|
|
void HandleTBLevelUp(void);
|
|
void HandleTBDropBackpacks( void );
|
|
void HandleTBPickUpBackpacks( void );
|
|
void HandleTBSoldierRun( void );
|
|
void HandleTBSkillsMenu(void);
|
|
|
|
void HandleTacticalReload(void);
|
|
void HandleTacticalTakeItem( void );
|
|
void HandleTacticalDropItem( UINT8 ubSlot );
|
|
void HandleTacticalTakeInvItem( INT32 iType );
|
|
void HandleTacticalStoreInvItem( void );
|
|
INT32 InvItemType( UINT16 usItem );
|
|
void HandleTacticalInventoryMenu( void );
|
|
void HandleTacticalMoveItems( void );
|
|
void TacticalInventoryMessageBoxCallBack( UINT8 ubExitValue );
|
|
void FortificationSettingCallBack( UINT8 ubExitValue );
|
|
void HandleTacticalCoverMenu( void );
|
|
void TacticalCoverMessageBoxCallBack( UINT8 ubExitValue );
|
|
void ActivateCheatsMessageBoxCallBack( UINT8 ubExitValue );
|
|
void HandleTacticalAmmoCrates( UINT8 magType );
|
|
void HandleTacticalTransformItem( void );
|
|
void HandleTacticalTransformFlashlight(void);
|
|
void HandleTacticalTransformLaser(void);
|
|
void HandleTacticalTransformStock(void);
|
|
void HandleTacticalTransformScope(void);
|
|
BOOLEAN FindTransformation(UINT16 usItem, TransformInfoStruct **pTransformation, BOOLEAN fTactical = FALSE);
|
|
BOOLEAN FindLaserTransformation(UINT16 usItem, TransformInfoStruct **pTransformation);
|
|
BOOLEAN FindStockTransformation(UINT16 usItem, TransformInfoStruct **pTransformation);
|
|
BOOLEAN FindFlashlightTransformation(UINT16 usItem, TransformInfoStruct **pTransformation);
|
|
BOOLEAN FindScopeTransformation(UINT16 usItem, TransformInfoStruct **pTransformation);
|
|
|
|
void GetTBMouseButtonInput( UINT32 *puiNewEvent )
|
|
{
|
|
QueryTBLeftButton( puiNewEvent );
|
|
QueryTBRightButton( puiNewEvent );
|
|
QueryTBWheel( puiNewEvent );
|
|
QueryTBMButton( puiNewEvent );
|
|
QueryTBX1Button( puiNewEvent );
|
|
QueryTBX2Button( puiNewEvent );
|
|
}
|
|
|
|
void QueryTBLeftButton( UINT32 *puiNewEvent )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos;
|
|
static BOOLEAN fClickHoldIntercepted = FALSE;
|
|
static BOOLEAN fCanCheckForSpeechAdvance = FALSE;
|
|
static INT32 sMoveClickGridNo = 0;
|
|
|
|
|
|
// LEFT MOUSE BUTTON
|
|
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
if (!GetMouseMapPos( &usMapPos ) && !gfUIShowExitSouth )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( gViewportRegion.ButtonState & MSYS_LEFT_BUTTON )
|
|
{
|
|
if ( !fLeftButtonDown )
|
|
{
|
|
fLeftButtonDown = TRUE;
|
|
RESETCOUNTER( LMOUSECLICK_DELAY_COUNTER );
|
|
|
|
{
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case CONFIRM_ACTION_MODE:
|
|
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
pSoldier->sStartGridNo = usMapPos;
|
|
}
|
|
break;
|
|
|
|
case MOVE_MODE:
|
|
|
|
if ( giUIMessageOverlay != -1 )
|
|
{
|
|
EndUIMessage( );
|
|
}
|
|
else
|
|
{
|
|
if ( !HandleCheckForExitArrowsInput( FALSE ) && gpItemPointer == NULL )
|
|
{
|
|
// First check if we clicked on a guy, if so, make selected if it's ours
|
|
if ( gfUIFullTargetFound && ( guiUIFullTargetFlags & OWNED_MERC ) )
|
|
{
|
|
if ( !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) )
|
|
{
|
|
fClickHoldIntercepted = TRUE;
|
|
|
|
// Select guy
|
|
if( GetSoldier( &pSoldier, gusUIFullTargetID ) && gpItemPointer == NULL )
|
|
{
|
|
if( pSoldier->bAssignment >= ON_DUTY )
|
|
{
|
|
// do nothing
|
|
fClickHoldIntercepted = FALSE;
|
|
}
|
|
else
|
|
{
|
|
*puiNewEvent = I_SELECT_MERC;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*puiNewEvent = I_SELECT_MERC;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( InUIPlanMode( ) )
|
|
{
|
|
AddUIPlan( usMapPos, UIPLAN_ACTION_MOVETO );
|
|
}
|
|
else
|
|
{
|
|
// We're on terrain in which we can walk, walk
|
|
// If we're on terrain,
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
|
|
INT8 bReturnVal = HandleMoveModeInteractiveClick( usMapPos, puiNewEvent );
|
|
|
|
// All's OK for interactive tile?
|
|
if ( bReturnVal == -2 )
|
|
{
|
|
// Confirm!
|
|
if ( SelectedMercCanAffordMove( ) )
|
|
{
|
|
*puiNewEvent = C_WAIT_FOR_CONFIRM;
|
|
}
|
|
}
|
|
else if ( bReturnVal == 0 )
|
|
{
|
|
if ( gfUIAllMoveOn )
|
|
{
|
|
*puiNewEvent = C_WAIT_FOR_CONFIRM;
|
|
}
|
|
else
|
|
{
|
|
if ( gsCurrentActionPoints == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
}
|
|
else if ( SelectedMercCanAffordMove( ) )
|
|
{
|
|
BOOLEAN fResult;
|
|
|
|
if ( ( fResult = UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) == 1 )
|
|
{
|
|
// ATE: CHECK IF WE CAN GET TO POSITION
|
|
// Check if we are not in combat
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
|
|
if ( gsCurrentActionPoints == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
}
|
|
else
|
|
{
|
|
*puiNewEvent = C_WAIT_FOR_CONFIRM;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( fResult == 2 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NOBODY_USING_REMOTE_STR ] );
|
|
}
|
|
else
|
|
{
|
|
//if ( sMapPos != sMoveClickGridNo || pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT )
|
|
//{
|
|
// sMoveClickGridNo = sMapPos;
|
|
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_MOVE_THERE_STR ] );
|
|
// Goto hand cursor mode....
|
|
// *puiNewEvent = M_CHANGE_TO_HANDMODE;
|
|
// gsOverItemsGridNo = sMapPos;
|
|
// gsOverItemsLevel = gsInterfaceLevel;
|
|
//}
|
|
//else
|
|
//{
|
|
// sMoveClickGridNo = 0;
|
|
// *puiNewEvent = M_CHANGE_TO_HANDMODE;
|
|
//}
|
|
|
|
}
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"Invalid move destination." );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// OK, our first right-click is an all-cycle
|
|
gfUICanBeginAllMoveCycle = FALSE;
|
|
}
|
|
fClickHoldIntercepted = TRUE;
|
|
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fClickHoldIntercepted = TRUE;
|
|
fIgnoreLeftUp = TRUE;
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if ( gfUIWaitingForUserSpeechAdvance )
|
|
{
|
|
fCanCheckForSpeechAdvance = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
// HERE FOR CLICK-DRAG CLICK
|
|
switch( gCurrentUIMode )
|
|
{
|
|
|
|
case MOVE_MODE:
|
|
|
|
// First check if we clicked on a guy, if so, make selected if it's ours
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
// Select guy
|
|
if ( ( guiUIFullTargetFlags & SELECTED_MERC) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) && !( MercPtrs[ gusUIFullTargetID ]->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
|
{
|
|
*puiNewEvent = M_CHANGE_TO_ADJPOS_MODE;
|
|
fIgnoreLeftUp = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// IF HERE, DO A CLICK-HOLD IF IN INTERVAL
|
|
if ( COUNTERDONE( LMOUSECLICK_DELAY_COUNTER ) && !fClickHoldIntercepted )
|
|
{
|
|
/* removed warning C4060 (jonathanl)
|
|
// Switch on UI mode
|
|
switch( gCurrentUIMode )
|
|
{
|
|
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( fLeftButtonDown )
|
|
{
|
|
if ( !fIgnoreLeftUp )
|
|
{
|
|
|
|
// FIRST CHECK FOR ANYTIME ( NON-INTERVAL ) CLICKS
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case ADJUST_STANCE_MODE:
|
|
|
|
// If button has come up, change to mocve mode
|
|
*puiNewEvent = PADJ_ADJUST_STANCE;
|
|
break;
|
|
}
|
|
|
|
// CHECK IF WE CLICKED-HELD
|
|
if ( COUNTERDONE( LMOUSECLICK_DELAY_COUNTER ) )
|
|
{
|
|
// LEFT CLICK-HOLD EVENT
|
|
// Switch on UI mode
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case CONFIRM_ACTION_MODE:
|
|
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( pSoldier->bDoBurst )
|
|
{
|
|
pSoldier->sEndGridNo = usMapPos;
|
|
|
|
gfBeginBurstSpreadTracking = FALSE;
|
|
|
|
if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo )
|
|
{
|
|
pSoldier->flags.fDoSpread = TRUE;
|
|
|
|
PickBurstLocations( pSoldier );
|
|
|
|
*puiNewEvent = CA_MERC_SHOOT;
|
|
}
|
|
else
|
|
{
|
|
pSoldier->flags.fDoSpread = FALSE;
|
|
}
|
|
|
|
fClickHoldIntercepted = TRUE;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
//LEFT CLICK NORMAL EVENT
|
|
// Switch on UI mode
|
|
if ( !fClickHoldIntercepted )
|
|
{
|
|
if ( giUIMessageOverlay != -1 )
|
|
{
|
|
EndUIMessage( );
|
|
}
|
|
else
|
|
{
|
|
if ( !HandleCheckForExitArrowsInput( TRUE ) )
|
|
{
|
|
if ( gpItemPointer != NULL )
|
|
{
|
|
if ( HandleItemPointerClick( usMapPos ) )
|
|
{
|
|
// getout of mode
|
|
EndItemPointer( );
|
|
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check for wiating for keyboard advance
|
|
if ( gfUIWaitingForUserSpeechAdvance && fCanCheckForSpeechAdvance)
|
|
{
|
|
// We have a key, advance!
|
|
DialogueAdvanceSpeech( );
|
|
}
|
|
else
|
|
{
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case MENU_MODE:
|
|
|
|
// If we get a hit here and we're in menu mode, quit the menu mode
|
|
EndMenuEvent( guiCurrentEvent );
|
|
break;
|
|
|
|
case IDLE_MODE:
|
|
|
|
// First check if we clicked on a guy, if so, make selected if it's ours
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
// Select guy
|
|
if ( guiUIFullTargetFlags & OWNED_MERC && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) )
|
|
{
|
|
*puiNewEvent = I_SELECT_MERC;
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case MOVE_MODE:
|
|
|
|
// Check if we should activate an interactive tile!
|
|
// Select guy
|
|
if ( ( guiUIFullTargetFlags & OWNED_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) )
|
|
{
|
|
// Select guy
|
|
if( GetSoldier( &pSoldier, gusUIFullTargetID ) && ( gpItemPointer == NULL ) && !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
|
{
|
|
if( pSoldier->bAssignment >= ON_DUTY )
|
|
{
|
|
PopupAssignmentMenuInTactical( pSoldier );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CONFIRM_MOVE_MODE:
|
|
|
|
*puiNewEvent = C_MOVE_MERC;
|
|
break;
|
|
|
|
case HANDCURSOR_MODE:
|
|
|
|
HandleHandCursorClick( usMapPos, puiNewEvent );
|
|
break;
|
|
|
|
case RADIOCURSOR_MODE:
|
|
|
|
HandleRadioCursorClick(usMapPos, puiNewEvent);
|
|
break;
|
|
|
|
case JUMPOVER_MODE:
|
|
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( EnoughPoints( pSoldier, gsCurrentActionPoints, 0, TRUE ) )
|
|
{
|
|
*puiNewEvent = JP_JUMP;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ACTION_MODE:
|
|
|
|
if ( InUIPlanMode( ) )
|
|
{
|
|
AddUIPlan( usMapPos, UIPLAN_ACTION_FIRE );
|
|
}
|
|
else
|
|
{
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( !HandleUIReloading( pSoldier ) )
|
|
{
|
|
// ATE: Reset refine aim..
|
|
pSoldier->aiData.bShownAimTime = 0;
|
|
|
|
if ( gsCurrentActionPoints == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
}
|
|
// Determine if we have enough action points!
|
|
else if ( UIMouseOnValidAttackLocation( pSoldier ) && SelectedMercCanAffordAttack( ) )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_CONFIM_ACTION;
|
|
pSoldier->sStartGridNo = usMapPos;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CONFIRM_ACTION_MODE:
|
|
if (GetSoldier(&pSoldier, gusSelectedSoldier))
|
|
{
|
|
//shadooow: this fixes merc randomly shooting in different direction than assigned
|
|
pSoldier->flags.fDoSpread = 0;
|
|
}
|
|
*puiNewEvent = CA_MERC_SHOOT;
|
|
break;
|
|
|
|
case LOOKCURSOR_MODE:
|
|
// If we cannot actually do anything, return to movement mode
|
|
*puiNewEvent = LC_LOOK;
|
|
break;
|
|
|
|
case TALKCURSOR_MODE:
|
|
|
|
if ( HandleTalkInit( ) )
|
|
{
|
|
*puiNewEvent = TA_TALKINGMENU;
|
|
}
|
|
break;
|
|
|
|
case GETTINGITEM_MODE:
|
|
|
|
// Remove menu!
|
|
// RemoveItemPickupMenu( );
|
|
break;
|
|
|
|
case TALKINGMENU_MODE:
|
|
|
|
//HandleTalkingMenuEscape( TRUE );
|
|
break;
|
|
|
|
case EXITSECTORMENU_MODE:
|
|
|
|
RemoveSectorExitMenu( FALSE );
|
|
break;
|
|
|
|
case OPENDOOR_MENU_MODE:
|
|
|
|
CancelOpenDoorMenu( );
|
|
HandleOpenDoorMenu( );
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Reset flag
|
|
fLeftButtonDown = FALSE;
|
|
fIgnoreLeftUp = FALSE;
|
|
fClickHoldIntercepted = FALSE;
|
|
fCanCheckForSpeechAdvance = FALSE;
|
|
gfFirstCycleMovementStarted = FALSE;
|
|
|
|
// Reset counter
|
|
RESETCOUNTER( LMOUSECLICK_DELAY_COUNTER );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// Set mouse down to false
|
|
//fLeftButtonDown = FALSE;
|
|
|
|
// OK, handle special cases like if we are dragging and holding for a burst spread and
|
|
// release mouse over another mouse region
|
|
if ( gfBeginBurstSpreadTracking )
|
|
{
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
pSoldier->flags.fDoSpread = FALSE;
|
|
}
|
|
gfBeginBurstSpreadTracking = FALSE;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void QueryTBRightButton( UINT32 *puiNewEvent )
|
|
{
|
|
static BOOLEAN fClickHoldIntercepted = FALSE;
|
|
static BOOLEAN fClickIntercepted = FALSE;
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos;
|
|
BOOLEAN fDone = FALSE;
|
|
if (!GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
|
|
// RIGHT MOUSE BUTTON
|
|
if ( gViewportRegion.ButtonState & MSYS_RIGHT_BUTTON )
|
|
{
|
|
if ( !fRightButtonDown )
|
|
{
|
|
fRightButtonDown = TRUE;
|
|
RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
|
|
}
|
|
|
|
// CHECK COMBINATIONS
|
|
if ( fLeftButtonDown )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
if ( gpItemPointer == NULL )
|
|
{
|
|
// IF HERE, DO A CLICK-HOLD IF IN INTERVAL
|
|
if ( COUNTERDONE( RMOUSECLICK_DELAY_COUNTER ) && !fClickHoldIntercepted )
|
|
{
|
|
// Switch on UI mode
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case IDLE_MODE:
|
|
case ACTION_MODE:
|
|
case HANDCURSOR_MODE:
|
|
case RADIOCURSOR_MODE:
|
|
case LOOKCURSOR_MODE:
|
|
case TALKCURSOR_MODE:
|
|
case MOVE_MODE:
|
|
|
|
// Check if we're on terrain
|
|
//if ( !gfUIFullTargetFound )
|
|
//{
|
|
// ATE:
|
|
fDone = FALSE;
|
|
|
|
if ( ( guiUIFullTargetFlags & OWNED_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) )
|
|
{
|
|
// Select guy
|
|
if( GetSoldier( &pSoldier, gusUIFullTargetID ) && ( gpItemPointer == NULL ) && !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
|
|
{
|
|
//if( pSoldier->bAssignment >= ON_DUTY )
|
|
{
|
|
PopupAssignmentMenuInTactical( pSoldier );
|
|
fClickHoldIntercepted = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( fDone == TRUE )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( gusSelectedSoldier != NOBODY && !fClickHoldIntercepted )
|
|
{
|
|
*puiNewEvent = U_MOVEMENT_MENU;
|
|
fClickHoldIntercepted = TRUE;
|
|
}
|
|
//}
|
|
//else
|
|
//{
|
|
// If we are on a selected guy
|
|
// if ( guiUIFullTargetFlags & SELECTED_MERC && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) )
|
|
// {
|
|
//*puiNewEvent = U_POSITION_MENU;
|
|
//fClickHoldIntercepted = TRUE;
|
|
// }
|
|
// else if ( guiUIFullTargetFlags & OWNED_MERC )
|
|
// {
|
|
// If we are on a non-selected guy selected guy
|
|
// }
|
|
|
|
//}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( fRightButtonDown )
|
|
{
|
|
|
|
if ( fLeftButtonDown )
|
|
{
|
|
fIgnoreLeftUp = TRUE;
|
|
|
|
if ( gpItemPointer == NULL )
|
|
{
|
|
// ATE:
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case CONFIRM_MOVE_MODE:
|
|
case MOVE_MODE:
|
|
|
|
if ( gfUICanBeginAllMoveCycle )
|
|
{
|
|
*puiNewEvent = M_CYCLE_MOVE_ALL;
|
|
}
|
|
else
|
|
{
|
|
if ( !gfFirstCycleMovementStarted )
|
|
{
|
|
gfFirstCycleMovementStarted = TRUE;
|
|
|
|
// OK, set this guy's movement mode to crawling fo rthat we will start cycling in run.....
|
|
if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING )
|
|
{
|
|
// ATE: UNLESS WE ARE IN RUNNING MODE ALREADY
|
|
MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = CRAWLING;
|
|
}
|
|
}
|
|
|
|
// Give event to cycle movement
|
|
*puiNewEvent = M_CYCLE_MOVEMENT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// ATE: Added cancel of burst mode....
|
|
if ( gfBeginBurstSpreadTracking )
|
|
{
|
|
gfBeginBurstSpreadTracking = FALSE;
|
|
gfRTClickLeftHoldIntercepted = TRUE;
|
|
MercPtrs[ gusSelectedSoldier ]->flags.fDoSpread = FALSE;
|
|
fClickHoldIntercepted = TRUE;
|
|
*puiNewEvent = A_END_ACTION;
|
|
gCurrentUIMode = MOVE_MODE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !fClickHoldIntercepted && !fClickIntercepted )
|
|
{
|
|
if ( gpItemPointer == NULL )
|
|
{
|
|
// ATE:
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
// sevenfm: ALT+RMB - TraitsMenu
|
|
if(_KeyDown(ALT))
|
|
{
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case MOVE_MODE:
|
|
case TALKCURSOR_MODE:
|
|
case ACTION_MODE:
|
|
case CONFIRM_ACTION_MODE:
|
|
case LOOKCURSOR_MODE:
|
|
TraitsMenu(usMapPos);
|
|
fClickIntercepted = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
// anv: CTRL+RMB - VehicleMenu
|
|
else if(_KeyDown(CTRL))
|
|
{
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case HANDCURSOR_MODE:
|
|
HandleHandCursorRightClick( usMapPos, puiNewEvent );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gfPlotNewMovement = TRUE;//shadooow: this fixes AP cost sometimes not recalculating when changing modes via right click
|
|
// Switch on UI mode
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case IDLE_MODE:
|
|
|
|
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;
|
|
break;
|
|
|
|
case ACTION_MODE:
|
|
|
|
// We have here a change to action mode
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
fClickIntercepted = TRUE;
|
|
break;
|
|
|
|
case CONFIRM_MOVE_MODE:
|
|
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
fClickIntercepted = TRUE;
|
|
break;
|
|
|
|
case HANDCURSOR_MODE:
|
|
// If we cannot actually do anything, return to movement mode
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
break;
|
|
|
|
case RADIOCURSOR_MODE:
|
|
// If we cannot actually do anything, return to movement mode
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
break;
|
|
|
|
case LOOKCURSOR_MODE:
|
|
case TALKCURSOR_MODE:
|
|
|
|
// If we cannot actually do anything, return to movement mode
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
break;
|
|
|
|
case CONFIRM_ACTION_MODE:
|
|
|
|
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
HandleRightClickAdjustCursor( pSoldier, usMapPos );
|
|
}
|
|
fClickIntercepted = TRUE;
|
|
break;
|
|
|
|
case MENU_MODE:
|
|
|
|
// If we get a hit here and we're in menu mode, quit the menu mode
|
|
EndMenuEvent( guiCurrentEvent );
|
|
fClickIntercepted = TRUE;
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
gfItemPointerDifferentThanDefault = !gfItemPointerDifferentThanDefault;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Reset flag
|
|
fRightButtonDown = FALSE;
|
|
fClickHoldIntercepted = FALSE;
|
|
fClickIntercepted = FALSE;
|
|
|
|
// Reset counter
|
|
RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
extern BOOLEAN gUIActionModeChangeDueToMouseOver;
|
|
|
|
void GetTBMousePositionInput( UINT32 *puiNewEvent )
|
|
{
|
|
INT32 usMapPos;
|
|
static INT32 usOldMapPos = 0;
|
|
SOLDIERTYPE *pSoldier;
|
|
BOOLEAN bHandleCode;
|
|
static BOOLEAN fOnValidGuy = FALSE;
|
|
static UINT32 uiMoveTargetSoldierId = NOBODY;
|
|
|
|
|
|
if (!GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
// Handle highlighting stuff
|
|
HandleObjectHighlighting( );
|
|
|
|
// Check if we have an item in our hands...
|
|
if ( gpItemPointer != NULL )
|
|
{
|
|
*puiNewEvent = A_ON_TERRAIN;
|
|
return;
|
|
}
|
|
|
|
// Switch on modes
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case LOCKUI_MODE:
|
|
*puiNewEvent = LU_ON_TERRAIN;
|
|
break;
|
|
|
|
case LOCKOURTURN_UI_MODE:
|
|
*puiNewEvent = LA_ON_TERRAIN;
|
|
break;
|
|
|
|
case IDLE_MODE:
|
|
*puiNewEvent = I_ON_TERRAIN;
|
|
break;
|
|
|
|
case ENEMYS_TURN_MODE:
|
|
*puiNewEvent = ET_ON_TERRAIN;
|
|
break;
|
|
|
|
case LOOKCURSOR_MODE:
|
|
*puiNewEvent = LC_ON_TERRAIN;
|
|
break;
|
|
|
|
case TALKCURSOR_MODE:
|
|
if ( uiMoveTargetSoldierId != NOBODY )
|
|
{
|
|
if( gfUIFullTargetFound )
|
|
{
|
|
if ( gusUIFullTargetID != uiMoveTargetSoldierId )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
return;
|
|
}
|
|
}
|
|
*puiNewEvent = T_ON_TERRAIN;
|
|
break;
|
|
|
|
case MOVE_MODE:
|
|
|
|
uiMoveTargetSoldierId = NOBODY;
|
|
|
|
// Check for being on terrain
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( IsValidJumpLocation( pSoldier, usMapPos, TRUE ) )
|
|
{
|
|
gsJumpOverGridNo = usMapPos;
|
|
*puiNewEvent = JP_ON_TERRAIN;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if( gfUIFullTargetFound )
|
|
{
|
|
// ATE: Don't do this automatically for enemies......
|
|
if ( MercPtrs[ gusUIFullTargetID ]->bTeam != ENEMY_TEAM )
|
|
{
|
|
uiMoveTargetSoldierId = gusUIFullTargetID;
|
|
if ( IsValidTalkableNPC( (UINT8)gusUIFullTargetID, FALSE, FALSE, FALSE ) && !_KeyDown( SHIFT ) && !AM_AN_EPC( pSoldier ) && !ValidQuickExchangePosition( ) )
|
|
{
|
|
*puiNewEvent = T_CHANGE_TO_TALKING;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*puiNewEvent = M_ON_TERRAIN;
|
|
break;
|
|
|
|
case ACTION_MODE:
|
|
|
|
// First check if we are on a guy, if so, make selected if it's ours
|
|
// Check if the guy is visible
|
|
guiUITargetSoldierId = NOBODY;
|
|
|
|
fOnValidGuy = FALSE;
|
|
|
|
if ( gfUIFullTargetFound )
|
|
//if ( gfUIFullTargetFound )
|
|
{
|
|
if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) )
|
|
{
|
|
guiUITargetSoldierId = gusUIFullTargetID;
|
|
|
|
if ( MercPtrs[ gusUIFullTargetID ]->bTeam != gbPlayerNum )
|
|
{
|
|
fOnValidGuy = TRUE;
|
|
//ddd turn off flag that indicates aim/autofire mode adjustment (aimed burst/auto)
|
|
brstmode = 0;
|
|
}
|
|
else
|
|
{
|
|
if ( gUIActionModeChangeDueToMouseOver )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( gUIActionModeChangeDueToMouseOver )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
return;
|
|
}
|
|
}
|
|
*puiNewEvent = A_ON_TERRAIN;
|
|
break;
|
|
|
|
case GETTINGITEM_MODE:
|
|
|
|
break;
|
|
|
|
case TALKINGMENU_MODE:
|
|
|
|
if ( HandleTalkingMenu( ) )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
break;
|
|
|
|
case EXITSECTORMENU_MODE:
|
|
|
|
if ( HandleSectorExitMenu( ) )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
break;
|
|
|
|
case OPENDOOR_MENU_MODE:
|
|
bHandleCode = HandleOpenDoorMenu( ); // I think its nicer to avoid assignments in conditionals (jonathanl)
|
|
if ( bHandleCode )
|
|
{
|
|
// OK, IF we are not canceling, set ui back!
|
|
if ( bHandleCode == 2 )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
break;
|
|
|
|
case JUMPOVER_MODE:
|
|
|
|
// ATE: Make sure!
|
|
if ( gsJumpOverGridNo != usMapPos )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
else
|
|
{
|
|
*puiNewEvent = JP_ON_TERRAIN;
|
|
}
|
|
break;
|
|
|
|
case CONFIRM_MOVE_MODE:
|
|
|
|
if ( usMapPos != usOldMapPos )
|
|
{
|
|
// Switch event out of confirm mode
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
|
|
// Set off ALL move....
|
|
gfUIAllMoveOn = FALSE;
|
|
|
|
// ERASE PATH
|
|
ErasePath( TRUE );
|
|
}
|
|
break;
|
|
|
|
case CONFIRM_ACTION_MODE:
|
|
|
|
// DONOT CANCEL IF BURST
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( pSoldier->bDoBurst )
|
|
{
|
|
pSoldier->sEndGridNo = usMapPos;
|
|
|
|
if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo && fLeftButtonDown )
|
|
{
|
|
pSoldier->flags.fDoSpread = TRUE;
|
|
gfBeginBurstSpreadTracking = TRUE;
|
|
}
|
|
|
|
if ( pSoldier->flags.fDoSpread )
|
|
{
|
|
// Accumulate gridno
|
|
AccumulateBurstLocation( usMapPos );
|
|
|
|
*puiNewEvent = CA_ON_TERRAIN;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// First check if we are on a guy, if so, make selected if it's ours
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
if ( guiUITargetSoldierId != gusUIFullTargetID )
|
|
{
|
|
// Switch event out of confirm mode
|
|
*puiNewEvent = CA_END_CONFIRM_ACTION;
|
|
}
|
|
else
|
|
{
|
|
*puiNewEvent = CA_ON_TERRAIN;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// OK, if we were on a guy, and now we are off, go back!
|
|
if ( fOnValidGuy )
|
|
{
|
|
// Switch event out of confirm mode
|
|
*puiNewEvent = CA_END_CONFIRM_ACTION;
|
|
}
|
|
else
|
|
{
|
|
if ( ConfirmActionCancel( usMapPos, usOldMapPos ) )
|
|
{
|
|
// Switch event out of confirm mode
|
|
*puiNewEvent = CA_END_CONFIRM_ACTION;
|
|
}
|
|
else
|
|
{
|
|
*puiNewEvent = CA_ON_TERRAIN;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HANDCURSOR_MODE:
|
|
|
|
*puiNewEvent = HC_ON_TERRAIN;
|
|
break;
|
|
|
|
case RADIOCURSOR_MODE:
|
|
break;
|
|
|
|
}
|
|
|
|
usOldMapPos = usMapPos;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void GetPolledKeyboardInput( UINT32 *puiNewEvent )
|
|
{
|
|
static BOOLEAN fShifted = FALSE;
|
|
static BOOLEAN fShifted2 = FALSE;
|
|
static BOOLEAN fCtrlDown = FALSE;
|
|
static BOOLEAN fAltDown = FALSE;
|
|
static BOOLEAN fDeleteDown=FALSE;
|
|
static BOOLEAN fEndDown=FALSE;
|
|
|
|
// CHECK FOR POLLED KEYS!!
|
|
// CHECK FOR CTRL
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case DONT_CHANGEMODE:
|
|
case CONFIRM_MOVE_MODE:
|
|
case CONFIRM_ACTION_MODE:
|
|
case LOOKCURSOR_MODE:
|
|
case TALKCURSOR_MODE:
|
|
case IDLE_MODE:
|
|
case MOVE_MODE:
|
|
case ACTION_MODE:
|
|
case HANDCURSOR_MODE:
|
|
case RADIOCURSOR_MODE:
|
|
|
|
if ( _KeyDown( CTRL ) )
|
|
{
|
|
if ( fCtrlDown == FALSE )
|
|
{
|
|
ErasePath( TRUE );
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
fCtrlDown = TRUE;
|
|
*puiNewEvent = HC_ON_TERRAIN;
|
|
|
|
}
|
|
if ( !(_KeyDown( CTRL ) ) && fCtrlDown )
|
|
{
|
|
fCtrlDown = FALSE;
|
|
*puiNewEvent = M_ON_TERRAIN;
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// CHECK FOR ALT
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case MOVE_MODE:
|
|
|
|
if ( _KeyDown( ALT ) )
|
|
{
|
|
if ( fAltDown == FALSE )
|
|
{
|
|
// Get currently selected guy and change reverse....
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
gUIUseReverse = TRUE;
|
|
ErasePath( TRUE );
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
}
|
|
fAltDown = TRUE;
|
|
|
|
}
|
|
if ( !(_KeyDown( ALT ) ) && fAltDown )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
gUIUseReverse = FALSE;
|
|
ErasePath( TRUE );
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
|
|
fAltDown = FALSE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Check realtime input!
|
|
if ( ( ( gTacticalStatus.uiFlags & REALTIME ) || !( gTacticalStatus.uiFlags & INCOMBAT ) ) )
|
|
{
|
|
//if ( _KeyDown( CAPS ) ) //&& !fShifted )
|
|
//{
|
|
// fShifted = TRUE;
|
|
// if ( gCurrentUIMode != ACTION_MODE && gCurrentUIMode != CONFIRM_ACTION_MODE )
|
|
// {
|
|
// *puiNewEvent = CA_ON_TERRAIN;
|
|
// }
|
|
//}
|
|
//if ( !(_KeyDown( CAPS ) ) && fShifted )
|
|
//{
|
|
// fShifted = FALSE;
|
|
// {
|
|
// *puiNewEvent = M_ON_TERRAIN;
|
|
// }
|
|
//}
|
|
|
|
|
|
if ( _KeyDown( SHIFT ) ) //&& !fShifted )
|
|
{
|
|
fShifted2 = TRUE;
|
|
if ( gCurrentUIMode != MOVE_MODE && gCurrentUIMode != CONFIRM_MOVE_MODE )
|
|
{
|
|
//puiNewEvent = M_ON_TERRAIN;
|
|
}
|
|
}
|
|
if ( !(_KeyDown( SHIFT ) ) && fShifted2 )
|
|
{
|
|
fShifted2 = FALSE;
|
|
if ( gCurrentUIMode != ACTION_MODE && gCurrentUIMode != CONFIRM_ACTION_MODE )
|
|
{
|
|
// *puiNewEvent = A_ON_TERRAIN;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if( _KeyDown( DEL ) && !fDeleteDown)
|
|
{
|
|
|
|
if ( _KeyDown( ALT ) )
|
|
SwitchToHostileTrapsView(); // added by Flugente
|
|
else
|
|
SwitchToEnemyView();
|
|
|
|
fDeleteDown = TRUE;
|
|
}
|
|
|
|
if( !_KeyDown( DEL ) && fDeleteDown )
|
|
{
|
|
|
|
if ( _KeyDown( ALT ) )
|
|
SwitchMineViewOff(); // added by Flugente
|
|
else
|
|
SwitchViewOff();
|
|
|
|
fDeleteDown = FALSE;
|
|
}
|
|
|
|
if( _KeyDown( END ) && !fEndDown)
|
|
{
|
|
|
|
if ( _KeyDown( ALT ) )
|
|
SwitchToTrapNetworkView(); // added by Flugente
|
|
else
|
|
SwitchToMercView();
|
|
|
|
fEndDown = TRUE;
|
|
}
|
|
|
|
if( !_KeyDown( END ) && fEndDown )
|
|
{
|
|
if ( _KeyDown( ALT ) )
|
|
SwitchMineViewOff(); // added by Flugente
|
|
else
|
|
SwitchViewOff();
|
|
|
|
|
|
fEndDown = FALSE;
|
|
}
|
|
}
|
|
|
|
UINT16 usitem = 1623;
|
|
|
|
void CheatCreateItem( )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
INT16 status = 100;
|
|
FLOAT temperature = 0.0;
|
|
|
|
if ( Item[usitem].foodtype )
|
|
temperature = OVERHEATING_MAX_TEMPERATURE;
|
|
|
|
// Flugente: spawn items while debugging
|
|
OBJECTTYPE newobj;
|
|
CreateItem( usitem, status, &newobj );
|
|
(newobj)[0]->data.bTemperature = temperature;
|
|
|
|
if ( !AutoPlaceObject( MercPtrs[ gusSelectedSoldier ], &newobj, FALSE ) )
|
|
AddItemToPool( MercPtrs[ gusSelectedSoldier ]->sGridNo, &newobj, 1, 0, 0, -1 );
|
|
}
|
|
}
|
|
|
|
INT32 mappos = 0;
|
|
|
|
void CheatNewMerc(int nProfileID)
|
|
{
|
|
if (nProfileID >= NUM_PROFILES || nProfileID < 0)
|
|
{
|
|
ScreenMsg(FONT_ORANGE, MSG_BETAVERSION, L"Invalid Profile ID.");
|
|
return;
|
|
}
|
|
|
|
MERC_HIRE_STRUCT HireMercStruct;
|
|
memset(&HireMercStruct, 0, sizeof(MERC_HIRE_STRUCT));
|
|
HireMercStruct.ubProfileID = nProfileID;
|
|
|
|
//DEF: temp
|
|
HireMercStruct.sSectorX = gWorldSectorX;
|
|
HireMercStruct.sSectorY = gWorldSectorY;
|
|
HireMercStruct.bSectorZ = gbWorldSectorZ;
|
|
HireMercStruct.ubInsertionCode = INSERTION_CODE_GRIDNO;
|
|
HireMercStruct.usInsertionData = mappos;
|
|
HireMercStruct.fCopyProfileItemsOver = TRUE;
|
|
HireMercStruct.iTotalContractLength = 7;
|
|
|
|
//specify when the merc should arrive
|
|
HireMercStruct.uiTimeTillMercArrives = 0;
|
|
|
|
//if we succesfully hired the merc
|
|
INT8 bReturnCode = HireMerc(&HireMercStruct);
|
|
|
|
if (bReturnCode == MERC_HIRE_FAILED)
|
|
{
|
|
ScreenMsg(FONT_ORANGE, MSG_BETAVERSION, L"Merc hire failed: Either already hired or dislikes you.");
|
|
}
|
|
// WDS - make number of mercenaries, etc. be configurable
|
|
else if (bReturnCode == MERC_HIRE_OVER_PLAYER_LIMIT)
|
|
{
|
|
ScreenMsg(FONT_ORANGE, MSG_BETAVERSION, L"Can't hire that many mercs.");
|
|
}
|
|
else
|
|
{
|
|
// Get soldier from profile
|
|
SOLDIERTYPE *pSoldier = FindSoldierByProfileID(nProfileID, FALSE);
|
|
|
|
MercArrivesCallback(pSoldier->ubID);
|
|
SelectSoldier(pSoldier->ubID, FALSE, TRUE);
|
|
}
|
|
}
|
|
|
|
void MercCreationCallBack(UINT8 ubResult)
|
|
{
|
|
if (ubResult == MSG_BOX_RETURN_OK && wcscmp(gszMsgBoxInputString, L"") > 0)
|
|
{
|
|
CheatNewMerc(_wtoi(gszMsgBoxInputString));
|
|
}
|
|
memset(gszMsgBoxInputString, 0, sizeof(gszMsgBoxInputString));
|
|
}
|
|
|
|
void ItemCreationCallBack( UINT8 ubResult )
|
|
{
|
|
if (ubResult == MSG_BOX_RETURN_OK && wcscmp(gszMsgBoxInputString,L"") > 0)
|
|
{
|
|
usitem = _wtoi( gszMsgBoxInputString );
|
|
CheatCreateItem( );
|
|
|
|
}
|
|
memset(gszMsgBoxInputString,0,sizeof(gszMsgBoxInputString));
|
|
}
|
|
|
|
extern BOOLEAN gfDisableRegionActive;
|
|
extern BOOLEAN gfUserTurnRegionActive;
|
|
|
|
void GetKeyboardInput( UINT32 *puiNewEvent )
|
|
{
|
|
InputAtom InputEvent;
|
|
BOOLEAN fKeyTaken = FALSE;
|
|
POINT MousePos;
|
|
//SOLDIERTYPE *pSoldier;
|
|
static BOOLEAN fShifted = FALSE;
|
|
static BOOLEAN fShifted2 = FALSE;
|
|
static BOOLEAN fAltDown = FALSE;
|
|
INT32 usMapPos;
|
|
|
|
CHAR16 zString[128];
|
|
|
|
GetCursorPos(&MousePos);
|
|
ScreenToClient(ghWindow, &MousePos); // In window coords!
|
|
|
|
GetMouseMapPos( &usMapPos );
|
|
|
|
while (DequeueEvent(&InputEvent) == TRUE)
|
|
{
|
|
// HOOK INTO MOUSE HOOKS
|
|
switch(InputEvent.usEvent)
|
|
{
|
|
case LEFT_BUTTON_DOWN:
|
|
MouseSystemHook(LEFT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown);
|
|
break;
|
|
case LEFT_BUTTON_UP:
|
|
MouseSystemHook(LEFT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y ,_LeftButtonDown, _RightButtonDown);
|
|
break;
|
|
case RIGHT_BUTTON_DOWN:
|
|
MouseSystemHook(RIGHT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown);
|
|
break;
|
|
case RIGHT_BUTTON_UP:
|
|
MouseSystemHook(RIGHT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown);
|
|
break;
|
|
|
|
}
|
|
|
|
// handle for fast help text for interface stuff
|
|
if( IsTheInterfaceFastHelpTextActive() )
|
|
{
|
|
if( InputEvent.usEvent == KEY_UP )
|
|
{
|
|
ShutDownUserDefineHelpTextRegions( );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
// Check for waiting for keyboard advance
|
|
if ( gfUIWaitingForUserSpeechAdvance && InputEvent.usEvent == KEY_UP )
|
|
{
|
|
// We have a key, advance!
|
|
DialogueAdvanceSpeech( );
|
|
|
|
// Ignore anything else
|
|
continue;
|
|
}
|
|
|
|
// ATE: if game paused because fo player, unpasue with any key
|
|
if ( gfPauseDueToPlayerGamePause && InputEvent.usEvent == KEY_UP )
|
|
{
|
|
HandlePlayerPauseUnPauseOfGame( );
|
|
|
|
continue;
|
|
}
|
|
|
|
if ( (InputEvent.usEvent == KEY_DOWN ) )
|
|
{
|
|
if ( giUIMessageOverlay != -1 )
|
|
{
|
|
EndUIMessage( );
|
|
continue;
|
|
}
|
|
|
|
// End auto bandage if we want....
|
|
if ( gTacticalStatus.fAutoBandageMode )
|
|
{
|
|
AutoBandage( FALSE );
|
|
*puiNewEvent = LU_ENDUILOCK;
|
|
}
|
|
}
|
|
|
|
if ( gUIKeyboardHook != NULL )
|
|
{
|
|
fKeyTaken = gUIKeyboardHook( &InputEvent );
|
|
}
|
|
if ( fKeyTaken )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
if( (InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ) )
|
|
{
|
|
HandlePlayerPauseUnPauseOfGame( );
|
|
}
|
|
*/
|
|
|
|
if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == PAUSE ) && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV) )
|
|
{
|
|
// Pause game!
|
|
HandlePlayerPauseUnPauseOfGame( );
|
|
}
|
|
|
|
// FIRST DO KEYS THAT ARE USED EVERYWHERE!
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'x') && ( InputEvent.usKeyState & ALT_DOWN ))
|
|
{
|
|
HandleShortCutExitState( );
|
|
//*puiNewEvent = I_EXIT;
|
|
}
|
|
#ifdef JA2UB
|
|
//Ja25 No meanwhiles
|
|
#else
|
|
if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == ESC) )
|
|
{
|
|
if ( AreInMeanwhile() && gCurrentMeanwhileDef.ubMeanwhileID != INTERROGATION )
|
|
{
|
|
DeleteTalkingMenu();
|
|
EndMeanwhile();
|
|
}
|
|
|
|
// Flugente: speed up dynamic dialogue boxes
|
|
// Note that this will behave oddly on the morning of January 1st 1970 :-)
|
|
DelayBoxDestructionBy( -gGameExternalOptions.sDynamicDialogueTimeOffset );
|
|
}
|
|
#endif
|
|
|
|
// BEGIN: by Lejardo for mouse-locking in game screen
|
|
// WANNE: If the game runs in windowed mode, the user can "lock" / "unlock" the mouse cursor
|
|
if ( iWindowedMode && !gfInKeyRingPopup && !gfInItemStackPopup)
|
|
{
|
|
if ((InputEvent.usEvent == KEY_DOWN ) && InputEvent.usParam == 'z' )
|
|
{
|
|
if( (InputEvent.usKeyState & CTRL_DOWN) && !(InputEvent.usKeyState & ALT_DOWN))
|
|
{
|
|
// Unlock the mouse cursor
|
|
if (gfMouseLockedOnBorder)
|
|
{
|
|
FreeMouseCursor( FALSE );
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_WINDOWED_MODE_RELEASE_MOUSE] );
|
|
}
|
|
// Lock the mouse cursor
|
|
else
|
|
{
|
|
SGPRect LJDRect;
|
|
|
|
LJDRect.iLeft = 0;
|
|
LJDRect.iTop = 0;
|
|
LJDRect.iRight = SCREEN_WIDTH;
|
|
LJDRect.iBottom = SCREEN_HEIGHT;
|
|
RestrictMouseCursor( &LJDRect );
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_WINDOWED_MODE_LOCK_MOUSE] );
|
|
}
|
|
|
|
gfMouseLockedOnBorder = !gfMouseLockedOnBorder;
|
|
}
|
|
}
|
|
}
|
|
// END: by Lejardo for mouse-locking in game screen
|
|
|
|
// WANNE: Just disabled for now, because we don't need it yet.
|
|
/*
|
|
// WANNE: If the game hangs on enemy turn, just press ALT + CTRL + E and the game will continue with enemy turn!!
|
|
if ( (InputEvent.usEvent == KEY_DOWN )&& (InputEvent.usKeyState & CTRL_DOWN) && ( InputEvent.usParam == 'e') )
|
|
{
|
|
if( InputEvent.usKeyState & ALT_DOWN )
|
|
{
|
|
if (gTacticalStatus.ubCurrentTeam != 0)
|
|
{
|
|
if( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
EndTurn( 1 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
if (!is_networked)
|
|
{
|
|
// Allow to load everywhere
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'l') )
|
|
{
|
|
if( InputEvent.usKeyState & ALT_DOWN )
|
|
{
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
gTacticalStatus.ubDisablePlayerInterrupts = FALSE;
|
|
|
|
gfSaveGame = FALSE;
|
|
gfCameDirectlyFromGame = TRUE;
|
|
|
|
SetOptionsPreviousScreen(GAME_SCREEN);
|
|
|
|
EscapeUILock();
|
|
// cancel, the player can move when it is not its turn!
|
|
//Heinz: 28.02.09 BUGFIX: player doesn't need to see save/load screen
|
|
//LeaveTacticalScreen( SAVE_LOAD_SCREEN );
|
|
DoQuickLoad();
|
|
}
|
|
}
|
|
else if( InputEvent.usKeyState & CTRL_DOWN )
|
|
{
|
|
// WANNE: Do not allow saving via the save screen when it is not our turn,
|
|
// because there is an exploit when you close the save window without saving, you can move your merc even it is not your turn
|
|
// IF UI HAS LOCKED, ONLY ALLOW EXIT!
|
|
if ( gfDisableRegionActive || gfUserTurnRegionActive )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
gfSaveGame = FALSE;
|
|
gfCameDirectlyFromGame = TRUE;
|
|
|
|
SetOptionsPreviousScreen(GAME_SCREEN);
|
|
LeaveTacticalScreen( SAVE_LOAD_SCREEN );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_networked)
|
|
{
|
|
// WANNE: Disabled the quick saving in a multiplayer game, because if you quit out of the save dialog,
|
|
// you can move your merc even if it is not your turn.
|
|
/*
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 's') )//allow saving 'always'//hayden
|
|
{
|
|
if( InputEvent.usKeyState & ALT_DOWN )
|
|
{
|
|
if( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
//if the game CAN be saved
|
|
if( CanGameBeSaved() )
|
|
{
|
|
guiPreviousOptionScreen = GAME_SCREEN;
|
|
//guiPreviousOptionScreen = guiCurrentScreen;
|
|
DoQuickSave();
|
|
}
|
|
else
|
|
{
|
|
//Display a message saying the player cant save now
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[ TCTL_MSG__IRON_MAN_CANT_SAVE_NOW ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL );
|
|
}
|
|
}
|
|
}
|
|
else if( InputEvent.usKeyState & CTRL_DOWN )
|
|
{
|
|
if( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
//if the game CAN be saved
|
|
if( CanGameBeSaved() )
|
|
{
|
|
gfSaveGame = TRUE;
|
|
gfCameDirectlyFromGame = TRUE;
|
|
|
|
guiPreviousOptionScreen = GAME_SCREEN;
|
|
LeaveTacticalScreen( SAVE_LOAD_SCREEN );
|
|
}
|
|
else
|
|
{
|
|
//Display a message saying the player cant save now
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[ TCTL_MSG__IRON_MAN_CANT_SAVE_NOW ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
//#ifdef DISABLE_MP_INTERRUPTS_IN_COOP
|
|
|
|
// WANNE: Not needed to show the override turn dialog
|
|
//#else
|
|
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'e') )
|
|
{
|
|
if( InputEvent.usKeyState & ALT_DOWN )
|
|
{
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
overide_turn();
|
|
}
|
|
}
|
|
}
|
|
|
|
//#endif
|
|
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'k') )
|
|
{
|
|
if( InputEvent.usKeyState & ALT_DOWN )
|
|
{
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
kick_player();
|
|
}
|
|
}
|
|
}
|
|
|
|
// OJW - 090209 - ingame chat
|
|
if (InputEvent.usEvent == KEY_UP && InputEvent.usParam == 'y')
|
|
{
|
|
if( !(InputEvent.usKeyState & ALT_DOWN) && !(InputEvent.usKeyState & CTRL_DOWN))
|
|
{
|
|
OpenChatMsgBox();
|
|
continue;
|
|
}
|
|
}
|
|
} // end is_networked
|
|
|
|
|
|
// Break of out IN CONV...
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ENTER ) && ( InputEvent.usKeyState & ALT_DOWN ) )
|
|
{
|
|
if ( gTacticalStatus.uiFlags & ENGAGED_IN_CONV )
|
|
{
|
|
gTacticalStatus.uiFlags &= (~ENGAGED_IN_CONV);
|
|
giNPCReferenceCount = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
{
|
|
if ( gTacticalStatus.ubCurrentTeam != gbPlayerNum )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ENTER ) && ( InputEvent.usKeyState & ALT_DOWN ) )
|
|
{
|
|
// ESCAPE ENEMY'S TURN
|
|
EndAIDeadlock();
|
|
|
|
// Decrease global busy counter...
|
|
gTacticalStatus.ubAttackBusyCount = 0;
|
|
#ifdef DEBUG_ATTACKBUSY
|
|
OutputDebugString( "Resetting attack busy due to keyboard interrupt.\n");
|
|
#endif
|
|
guiPendingOverrideEvent = LU_ENDUILOCK;
|
|
UIHandleLUIEndLock( NULL );
|
|
|
|
}
|
|
}
|
|
//Madd: removed from cheat mode
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ENTER ) && ( InputEvent.usKeyState & CTRL_DOWN ) )
|
|
{
|
|
EscapeUILock( );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) && (InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ENTER ) && ( InputEvent.usKeyState & CTRL_DOWN ) )
|
|
{
|
|
//UNLOCK UI
|
|
EscapeUILock( );
|
|
}
|
|
else if ( (InputEvent.usEvent == KEY_DOWN ) && InputEvent.usParam == ENTER )
|
|
{
|
|
// Cycle through enemys
|
|
CycleThroughKnownEnemies( );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( gfInTalkPanel )
|
|
{
|
|
HandleTalkingMenuKeys( &InputEvent, puiNewEvent );
|
|
}
|
|
|
|
// Do some checks based on what mode we are in
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case EXITSECTORMENU_MODE:
|
|
|
|
HandleSectorExitMenuKeys( &InputEvent, puiNewEvent );
|
|
continue;
|
|
|
|
case GETTINGITEM_MODE:
|
|
|
|
HandleItemMenuKeys( &InputEvent, puiNewEvent );
|
|
continue;
|
|
|
|
case MENU_MODE:
|
|
|
|
HandleMenuKeys( &InputEvent, puiNewEvent );
|
|
continue;
|
|
|
|
case OPENDOOR_MENU_MODE:
|
|
|
|
HandleOpenDoorMenuKeys( &InputEvent, puiNewEvent );
|
|
continue;
|
|
}
|
|
|
|
|
|
// CHECK ESC KEYS HERE....
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ESC ))
|
|
{
|
|
//EscapeUILock( );
|
|
#ifdef JA2TESTVERSION
|
|
if ( InAirRaid( ) )
|
|
{
|
|
EndAirRaid( );
|
|
}
|
|
#endif
|
|
|
|
// Cancel out of spread burst...
|
|
gfBeginBurstSpreadTracking = FALSE;
|
|
gfRTClickLeftHoldIntercepted = TRUE;
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
MercPtrs[ gusSelectedSoldier ]->flags.fDoSpread = FALSE;
|
|
}
|
|
|
|
// Before anything, delete popup box!
|
|
EndUIMessage( );
|
|
|
|
// CANCEL FROM PLANNING MODE!
|
|
if ( InUIPlanMode( ) )
|
|
{
|
|
EndUIPlan( );
|
|
continue;
|
|
}
|
|
|
|
if ( InItemDescriptionBox( ) )
|
|
{
|
|
DeleteItemDescriptionBox( );
|
|
continue;
|
|
}
|
|
else if( InKeyRingPopup( ) )
|
|
{
|
|
DeleteKeyRingPopup( );
|
|
continue;
|
|
}
|
|
|
|
if (gDragSelection.Active())
|
|
{
|
|
gDragSelection.Cancel();
|
|
continue;
|
|
}
|
|
else if (gReinforcementNumber.Active())
|
|
{
|
|
gReinforcementNumber.Cancel();
|
|
continue;
|
|
}
|
|
else if (gSoldierSelection.Active())
|
|
{
|
|
gSoldierSelection.Cancel();
|
|
continue;
|
|
}
|
|
else if (gArtilleryTeam.Active())
|
|
{
|
|
gArtilleryTeam.Cancel();
|
|
continue;
|
|
}
|
|
else if (gArtillerySector.Active())
|
|
{
|
|
gArtillerySector.Cancel();
|
|
continue;
|
|
}
|
|
else if (gReinforcementSector.Active())
|
|
{
|
|
gReinforcementSector.Cancel();
|
|
continue;
|
|
}
|
|
else if (gSkillSelection.Active())
|
|
{
|
|
gSkillSelection.Cancel();
|
|
continue;
|
|
}
|
|
else if (gTraitSelection.Active())
|
|
{
|
|
gTraitSelection.Cancel();
|
|
continue;
|
|
}
|
|
|
|
if ( gCurrentUIMode == MENU_MODE )
|
|
{
|
|
// If we get a hit here and we're in menu mode, quit the menu mode
|
|
EndMenuEvent( guiCurrentEvent );
|
|
continue;
|
|
}
|
|
|
|
if (gCurrentUIMode == HANDCURSOR_MODE || gCurrentUIMode == RADIOCURSOR_MODE)
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
continue;
|
|
}
|
|
|
|
if (!(gTacticalStatus.uiFlags & ENGAGED_IN_CONV))
|
|
{
|
|
if (gTacticalStatus.fAtLeastOneGuyOnMultiSelect)
|
|
{
|
|
// ATE: OK, stop any mercs who are moving by selection method....
|
|
StopRubberBandedMercFromMoving();
|
|
continue;
|
|
}
|
|
else if (gusSelectedSoldier != NOBODY &&
|
|
MercPtrs[gusSelectedSoldier] &&
|
|
!(gAnimControl[MercPtrs[gusSelectedSoldier]->usAnimState].uiFlags & ANIM_STATIONARY))
|
|
{
|
|
// If soldier is not stationary, stop
|
|
MercPtrs[gusSelectedSoldier]->StopSoldier();
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// sevenfm: also stop dragging
|
|
if (gusSelectedSoldier != NOBODY &&
|
|
MercPtrs[gusSelectedSoldier] &&
|
|
MercPtrs[gusSelectedSoldier]->IsDraggingSomeone(false))
|
|
{
|
|
MercPtrs[gusSelectedSoldier]->CancelDrag();
|
|
DirtyMercPanelInterface(MercPtrs[gusSelectedSoldier], DIRTYLEVEL2);
|
|
continue;
|
|
}
|
|
|
|
// sevenfm: unready weapon
|
|
if (gusSelectedSoldier != NOBODY &&
|
|
MercPtrs[gusSelectedSoldier] &&
|
|
WeaponReady(MercPtrs[gusSelectedSoldier]))
|
|
{
|
|
MercPtrs[gusSelectedSoldier]->InternalSoldierReadyWeapon(MercPtrs[gusSelectedSoldier]->ubDirection, TRUE, FALSE);
|
|
HandleSight(MercPtrs[gusSelectedSoldier], SIGHT_LOOK);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// CHECK ESC KEYS HERE....
|
|
if ((InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == BACKSPACE ) )
|
|
{
|
|
StopAnyCurrentlyTalkingSpeech( );
|
|
}
|
|
|
|
// IF UI HAS LOCKED, ONLY ALLOW EXIT!
|
|
if ( gfDisableRegionActive || gfUserTurnRegionActive )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Check all those we want if enemy's turn
|
|
if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == 'q') )
|
|
{
|
|
if ( InputEvent.usKeyState & ALT_DOWN )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
static BOOLEAN fShowRoofs = TRUE;
|
|
INT32 x;
|
|
UINT16 usType;
|
|
|
|
// Toggle removal of roofs...
|
|
fShowRoofs = !fShowRoofs;
|
|
|
|
for ( x = 0; x < WORLD_MAX; x++ )
|
|
{
|
|
for ( usType = FIRSTROOF; usType <= LASTSLANTROOF; usType++ )
|
|
{
|
|
HideStructOfGivenType( x, usType, (BOOLEAN)(!fShowRoofs) );
|
|
}
|
|
}
|
|
InvalidateWorldRedundency();
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
}
|
|
|
|
}
|
|
else if ( InputEvent.usKeyState & CTRL_DOWN )
|
|
{
|
|
#ifdef JA2BETAVERSION
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
LeaveTacticalScreen( ANIEDIT_SCREEN );
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_SOLDIERDEBUG;
|
|
}
|
|
else
|
|
{
|
|
//if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
// {
|
|
// if ( gusSelectedSoldier != NOBODY )
|
|
// {
|
|
// if ( gTacticalStatus.uiFlags & TURNBASED && !MercPtrs[ gusSelectedSoldier ]->fDontChargeReadyAPs )
|
|
// {
|
|
// INT16 apCost = GetAPsToReadyWeapon( MercPtrs[ gusSelectedSoldier ], 0 );
|
|
// if (MercPtrs[ gusSelectedSoldier ]->bActionPoints >= apCost )
|
|
// {
|
|
// DeductPoints( MercPtrs[ gusSelectedSoldier ],apCost , 0 );
|
|
// DirtyMercPanelInterface( MercPtrs[ gusSelectedSoldier ], DIRTYLEVEL2 );
|
|
// SoldierReadyWeapon( MercPtrs[ gusSelectedSoldier ] );
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// SoldierReadyWeapon( MercPtrs[ gusSelectedSoldier ] );
|
|
// }
|
|
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef JA2TESTVERSION
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '0') && ( InputEvent.usKeyState & ALT_DOWN ))
|
|
{
|
|
INT32 i = 0;
|
|
INT32 sGridNo;
|
|
INT32 iTime = GetJA2Clock( );
|
|
UINT8 ubLevel;
|
|
|
|
for ( i = 0; i < 1000; i++ )
|
|
{
|
|
CalculateLaunchItemChanceToGetThrough( MercPtrs[ gusSelectedSoldier ], &(MercPtrs[ gusSelectedSoldier ]->inv[ HANDPOS ] ), usMapPos, 0, 0, &sGridNo, TRUE, (INT8 *)&ubLevel, TRUE );
|
|
}
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Physics 100 times: %d", ( GetJA2Clock( ) - iTime ) );
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef NETWORKED
|
|
// DEF: Test Networking
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '0') && ( InputEvent.usKeyState & ALT_DOWN ))
|
|
{
|
|
DisplayMultiPlayerInfo();
|
|
}
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '9') && ( InputEvent.usKeyState & ALT_DOWN ))
|
|
{
|
|
DisplayDirectPlayInfo();
|
|
}
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '8') && ( InputEvent.usKeyState & ALT_DOWN ))
|
|
{
|
|
DisplayDirectPlayPlayerInfo();
|
|
}
|
|
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '7') && ( InputEvent.usKeyState & ALT_DOWN ))
|
|
{
|
|
SetDisplayFlag();
|
|
}
|
|
#endif
|
|
|
|
if( InputEvent.usEvent == KEY_DOWN )
|
|
{
|
|
BOOLEAN fAlt, fCtrl, fShift;
|
|
fAlt = InputEvent.usKeyState & ALT_DOWN ? TRUE : FALSE;
|
|
fCtrl = InputEvent.usKeyState & CTRL_DOWN ? TRUE : FALSE;
|
|
fShift = InputEvent.usKeyState & SHIFT_DOWN ? TRUE : FALSE;
|
|
switch( InputEvent.usParam )
|
|
{
|
|
case SPACE:
|
|
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ NEXTMERC_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
if ( !InKeyRingPopup( ) )
|
|
{
|
|
|
|
if (_KeyDown(CTRL))
|
|
{
|
|
checkLBEArrayIntegrity();
|
|
}
|
|
else if (_KeyDown(ALT))
|
|
{
|
|
checkLBEArrayIntegrity(true);
|
|
}
|
|
else if (_KeyDown(SHIFT))
|
|
{
|
|
SOLDIERTYPE *pNewSoldier;
|
|
INT32 iCurrentSquad;
|
|
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
// only allow if nothing in hand and if in SM panel, the Change Squad button must be enabled
|
|
if ( ( ( gsCurInterfacePanel != TEAM_PANEL ) || ( ButtonList[ iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
//Select next squad
|
|
iCurrentSquad = CurrentSquad( );
|
|
|
|
pNewSoldier = FindNextActiveSquad( MercPtrs[ gusSelectedSoldier ] );
|
|
|
|
if ( pNewSoldier->bAssignment != iCurrentSquad )
|
|
{
|
|
HandleLocateSelectMerc( pNewSoldier->ubID, LOCATEANDSELECT_MERC );
|
|
|
|
if ( gGameExternalOptions.fUseXMLSquadNames && pNewSoldier->bAssignment < min(ON_DUTY, gSquadNameVector.size() ) )
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE_STRING ], gSquadNameVector[pNewSoldier->bAssignment].c_str() );
|
|
else
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( CurrentSquad( ) + 1 ) );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( pNewSoldier->bAssignment + 1 ) );
|
|
|
|
// Center to guy....
|
|
//LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{ //Select next merc
|
|
UINT8 bID;
|
|
|
|
bID = FindNextMercInTeamPanel( MercPtrs[ gusSelectedSoldier ], FALSE, FALSE );
|
|
|
|
HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
|
|
|
|
ErasePath(TRUE);
|
|
gfPlotNewMovement = TRUE;
|
|
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
|
|
*puiNewEvent = M_ON_TERRAIN;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LEFTARROW:
|
|
// used for map scrolling
|
|
if ( fCtrl )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
SwapMercPortraits( MercPtrs[ gusSelectedSoldier ], -1 );
|
|
}
|
|
break;
|
|
|
|
case RIGHTARROW:
|
|
// used for map scrolling
|
|
if ( fCtrl )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
SwapMercPortraits( MercPtrs[ gusSelectedSoldier ], 1 );
|
|
}
|
|
break;
|
|
|
|
case INSERT:
|
|
GoIntoOverheadMap();
|
|
break;
|
|
|
|
case DEL:
|
|
// used for LOS display
|
|
break;
|
|
|
|
case HOME:
|
|
if ( gGameSettings.fOptions[ TOPTION_3D_CURSOR ] )
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_3D_CURSOR ] = FALSE;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_3DCURSOR_OFF ] );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_3D_CURSOR ] = TRUE;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_3DCURSOR_ON ] );
|
|
}
|
|
break;
|
|
|
|
case END:
|
|
// Lalien: commented out, to fix "end move & LOS bug" (same button has two different actions)
|
|
// if ( gusSelectedSoldier != NOBODY )
|
|
// {
|
|
// if ( CheckForMercContMove( MercPtrs[ gusSelectedSoldier ] ) )
|
|
// {
|
|
// // Continue
|
|
// ContinueMercMovement( MercPtrs[ gusSelectedSoldier ] );
|
|
// ErasePath( TRUE );
|
|
// }
|
|
// }
|
|
break;
|
|
|
|
case PGUP:
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
if( fCtrl )
|
|
AttemptToChangeFloorLevel( -1 ); //try to go up towards ground level
|
|
}
|
|
|
|
if ( guiCurrentScreen != DEBUG_SCREEN )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( ( gpItemPointer == NULL ) )
|
|
{
|
|
GotoHeigherStance( MercPtrs[ gusSelectedSoldier ] );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PGDN:
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
if( fCtrl )
|
|
AttemptToChangeFloorLevel( +1 ); //try to enter a lower underground level
|
|
}
|
|
|
|
if ( guiCurrentScreen != DEBUG_SCREEN )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( ( gpItemPointer == NULL ) )
|
|
{
|
|
GotoLowerStance( MercPtrs[ gusSelectedSoldier ] );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BACKSPACE:
|
|
// used for stopping speech
|
|
break;
|
|
|
|
case TAB:
|
|
// go to next tab in enhanced description box
|
|
if( ( fCtrl ) && InItemDescriptionBox( ) && gGameSettings.fOptions[ TOPTION_ENHANCED_DESC_BOX ] == TRUE )
|
|
{
|
|
if ( (Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON || Item[ gpItemDescObject->usItem ].usItemClass & IC_PUNCH)
|
|
&& gubDescGenPage == 0 && gubDescBoxPage == 1 )
|
|
{
|
|
gubDescGenPage = 1;
|
|
}
|
|
else if ( gubDescBoxPage < 2 )
|
|
{
|
|
gubDescGenPage = 0;
|
|
gubDescBoxPage++;
|
|
}
|
|
else
|
|
{
|
|
gubDescBoxPage = 0;
|
|
}
|
|
HandleItemDescTabButton( );
|
|
}
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
else if ( ( gpItemPointer == NULL ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ UPDOWN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
UIHandleChangeLevel( NULL );
|
|
|
|
if ( gsCurInterfacePanel == SM_PANEL )
|
|
{
|
|
// Remember soldier's new value
|
|
gpSMCurrentMerc->bUIInterfaceLevel = (INT8)gsInterfaceLevel;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case F1:
|
|
if( fShift )
|
|
{
|
|
HandleSelectMercSlot( 0, LOCATE_MERC_ONCE );
|
|
}
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 15 );
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
TestMeanWhile( 10 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 0, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F2:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 1, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 1 );
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
TestMeanWhile( 11 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 1, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F3:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 2, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 2 );
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
TestMeanWhile( 12 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 2, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F4:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 3, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 3 );
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
TestMeanWhile( 13 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 3, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F5:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 4, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 4 );
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
TestMeanWhile( 14 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 4, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F6:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 5, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 5 );
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
TestMeanWhile( 15 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 5, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F7:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 6, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 16 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 6, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F8:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 7, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 7 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 7, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F9:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 8, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fCtrl )
|
|
{
|
|
TestMeanWhile( 8 );
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
#ifdef JA2EDITOR
|
|
*puiNewEvent = I_ENTER_EDIT_MODE;
|
|
gfMercResetUponEditorEntry = !fAlt;
|
|
break;
|
|
#endif
|
|
HandleSelectMercSlot( 8, LOCATEANDSELECT_MERC );
|
|
}
|
|
break;
|
|
|
|
case F10:
|
|
if( fShift )
|
|
HandleSelectMercSlot( 9, LOCATE_MERC_ONCE );
|
|
#ifdef JA2TESTVERSION
|
|
else if( fAlt )
|
|
{
|
|
TestMeanWhile( 9 );
|
|
}
|
|
#endif
|
|
else
|
|
HandleSelectMercSlot( 9, LOCATEANDSELECT_MERC );
|
|
break;
|
|
|
|
case F11:
|
|
if( fAlt )
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
// Get selected soldier
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if( pSoldier->ubID == 46 )
|
|
{
|
|
// Change guy to drunk larry
|
|
ForceSoldierProfileID( pSoldier, 47 );
|
|
}
|
|
else
|
|
{
|
|
// Change guy to normal larry
|
|
ForceSoldierProfileID( pSoldier, 46 );
|
|
}
|
|
|
|
// Dirty interface
|
|
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
else
|
|
{
|
|
if( DEBUG_CHEAT_LEVEL( ) )
|
|
{
|
|
GetMouseMapPos( &gsQdsEnteringGridNo );
|
|
LeaveTacticalScreen( QUEST_DEBUG_SCREEN );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case F12:
|
|
#ifdef JA2TESTVERSION
|
|
if( fAlt )
|
|
{
|
|
UINT8 ubProfile = TONY;
|
|
|
|
GetMouseMapPos( &gsQdsEnteringGridNo );
|
|
AddShopkeeperToGridNo( ubProfile, gsQdsEnteringGridNo );
|
|
EnterShopKeeperInterfaceScreen( ubProfile );
|
|
}
|
|
#endif
|
|
//clear tactical of messages
|
|
if( fCtrl )
|
|
{
|
|
ClearTacticalMessageQueue( );
|
|
}
|
|
else if ( !fAlt )
|
|
{
|
|
ClearDisplayedListOfTacticalStrings( );
|
|
}
|
|
break;
|
|
|
|
case '-':
|
|
case '_':
|
|
//if the display cover or line of sight is being displayed
|
|
if( _KeyDown( END ) || _KeyDown( DEL ) )
|
|
{
|
|
//if( _KeyDown( DEL ) )
|
|
//ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover - 1 );
|
|
|
|
//if( _KeyDown( END ) )
|
|
//ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS - 1 );
|
|
}
|
|
else
|
|
{
|
|
if( fAlt )
|
|
{
|
|
if(MusicGetVolume() >= 20)
|
|
MusicSetVolume(MusicGetVolume()-20);
|
|
else
|
|
MusicSetVolume(0);
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
gTacticalStatus.bRealtimeSpeed = max( 1, gTacticalStatus.bRealtimeSpeed - 1 );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Decreasing Realtime speed to %d", gTacticalStatus.bRealtimeSpeed );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Using Normal Scroll Speed" );
|
|
gubCurScrollSpeedID = 1;
|
|
#endif
|
|
}
|
|
}
|
|
break;
|
|
|
|
case '+':
|
|
#ifdef JA2TESTVERSION
|
|
if( fAlt )
|
|
{
|
|
if(MusicGetVolume() <= 107)
|
|
MusicSetVolume(MusicGetVolume()+20);
|
|
else
|
|
MusicSetVolume(127);
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
gTacticalStatus.bRealtimeSpeed = min( MAX_REALTIME_SPEED_VAL, gTacticalStatus.bRealtimeSpeed+1 );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Increasing Realtime speed to %d", gTacticalStatus.bRealtimeSpeed );
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Using Higher Scroll Speed" );
|
|
gubCurScrollSpeedID = 2;
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case '=':
|
|
//if the display cover or line of sight is being displayed
|
|
if( _KeyDown( END ) || _KeyDown( DEL ) )
|
|
{
|
|
//f( _KeyDown( DEL ) )
|
|
//ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover + 1 );
|
|
|
|
//if( _KeyDown( END ) )
|
|
//ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS + 1 );
|
|
}
|
|
else
|
|
{
|
|
|
|
#ifdef JA2TESTVERSION
|
|
if( fAlt )
|
|
{
|
|
WarpGameTime( 60, TRUE );
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
// ATE: This key will select everybody in the sector
|
|
// Buggler: Disabled check for all merc display cover in turnbased mode
|
|
//if ( !(gTacticalStatus.uiFlags & INCOMBAT) )
|
|
//{
|
|
HandleTBSelectAllMercs();
|
|
//}
|
|
}
|
|
break;
|
|
|
|
case ',':
|
|
// Flugente: alternate for people without mousewheel to aim auto-only weapons
|
|
if ( gGameExternalOptions.bAimedBurstEnabled && gCurrentUIMode == CONFIRM_ACTION_MODE )
|
|
{
|
|
SOLDIERTYPE * pSoldier;
|
|
|
|
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
HandleRightClickAdjustCursor( pSoldier, usMapPos );
|
|
}
|
|
}
|
|
break;
|
|
|
|
// added by Flugente
|
|
case '.':
|
|
if ( fCtrl && fAlt ) //jikuja: Create item by reusing old entered number
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
CheatCreateItem( );
|
|
}
|
|
}
|
|
else if ( fCtrl )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
HandleTacticalFunctionSelection(MercPtrs[ gusSelectedSoldier ], usMapPos );
|
|
}
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, L"Enter ItemID", GAME_SCREEN, MSG_BOX_FLAG_INPUTBOX, ItemCreationCallBack, NULL );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetScopeMode( usMapPos );
|
|
}
|
|
|
|
break;
|
|
|
|
case '/':
|
|
// Center to guy....
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
LocateSoldier( gusSelectedSoldier, 10 );
|
|
}
|
|
break;
|
|
|
|
#if 0//dnl ch75 021113
|
|
case '\"':
|
|
Testing(1);
|
|
break;
|
|
case '\'':
|
|
Testing(2);
|
|
break;
|
|
#endif
|
|
|
|
case '`':
|
|
|
|
if( fAlt )
|
|
{
|
|
HandleTacticalStoreInvItem( );
|
|
}
|
|
else if(!AreInMeanwhile())
|
|
// Switch panels...
|
|
{
|
|
ToggleTacticalPanels();
|
|
}
|
|
break;
|
|
|
|
case '1':
|
|
if (fCtrl && fAlt)
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
//ChangeSoldiersBodyType( TANK_NW, TRUE );
|
|
// MercPtrs[ gusSelectedSoldier ]->flags.uiStatusFlags |= SOLDIER_CREATURE;
|
|
//EVENT_InitNewSoldierAnim( MercPtrs[ gusSelectedSoldier ], CRIPPLE_BEG, 0 , TRUE );
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem1 );
|
|
}
|
|
else
|
|
ChangeCurrentSquad( 0 );
|
|
break;
|
|
|
|
case '2':
|
|
if (fCtrl && fAlt)
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
ChangeSoldiersBodyType(INFANT_MONSTER, TRUE);
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem2 );
|
|
}
|
|
else if( fCtrl ) //toggle between the different npc debug modes
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ToggleQuestDebugModes( QD_NPC_MSG );
|
|
}
|
|
}
|
|
else
|
|
ChangeCurrentSquad( 1 );
|
|
break;
|
|
|
|
case '3':
|
|
if (fCtrl && fAlt)
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
MercPtrs[gusSelectedSoldier]->EVENT_InitNewSoldierAnim(KID_SKIPPING, 0, TRUE);
|
|
|
|
//ChangeSoldiersBodyType( LARVAE_MONSTER, TRUE );
|
|
//MercPtrs[ gusSelectedSoldier ]->usAttackingWeapon = TANK_CANNON;
|
|
//LocateSoldier( gusSelectedSoldier, FALSE );
|
|
//EVENT_FireSoldierWeapon( MercPtrs[ gusSelectedSoldier ], sMapPos );
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem3 );
|
|
}
|
|
else if( fCtrl ) //toggle between the different npc debug modes
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
CreateBloodCat();
|
|
}
|
|
}
|
|
else
|
|
ChangeCurrentSquad( 2 );
|
|
|
|
break;
|
|
|
|
case '4':
|
|
if (fCtrl && fAlt)
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
ChangeSoldiersBodyType(CRIPPLECIV, TRUE);
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem4 );
|
|
}
|
|
else
|
|
ChangeCurrentSquad( 3 );
|
|
|
|
//ChangeSoldiersBodyType( BLOODCAT, FALSE );
|
|
break;
|
|
|
|
case '5':
|
|
if (fCtrl && fAlt)
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
ChangeSoldiersBodyType(YAM_MONSTER, TRUE);
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem5 );
|
|
}
|
|
else
|
|
{
|
|
ChangeCurrentSquad( 4 );
|
|
|
|
if (is_networked)
|
|
grid_display();//hayden
|
|
}
|
|
break;
|
|
|
|
case '6':
|
|
if (fCtrl && fAlt)
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
ChangeSoldiersBodyType(BLOODCAT, TRUE);
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem(gGameExternalOptions.iQuickItem6);
|
|
}
|
|
else
|
|
{
|
|
ChangeCurrentSquad( 5 );
|
|
}
|
|
break;
|
|
|
|
case '7':
|
|
if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem7 );
|
|
}
|
|
else
|
|
{
|
|
ChangeCurrentSquad( 6 );
|
|
}
|
|
break;
|
|
|
|
case '8':
|
|
if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem8 );
|
|
}
|
|
else
|
|
{
|
|
ChangeCurrentSquad( 7 );
|
|
}
|
|
break;
|
|
|
|
case '9':
|
|
if( fAlt )
|
|
{
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem9 );
|
|
}
|
|
else
|
|
{
|
|
ChangeCurrentSquad( 8 );
|
|
}
|
|
break;
|
|
|
|
case '0':
|
|
if( fAlt )
|
|
{
|
|
// used for calculating item chance to get through in cheat mode
|
|
HandleTacticalTakeInvItem( gGameExternalOptions.iQuickItem0 );
|
|
}
|
|
else
|
|
{
|
|
ChangeCurrentSquad( 9 );
|
|
}
|
|
break;
|
|
|
|
case '!':
|
|
break;
|
|
|
|
case '@':
|
|
break;
|
|
|
|
case '#':
|
|
break;
|
|
|
|
case '$':
|
|
if(fCtrl && gGameExternalOptions.fEnableInventoryPoolQ)//dnl ch75 021113
|
|
DisplaySectorItemsInfo();
|
|
else
|
|
{
|
|
HandleTBSkillsMenu();
|
|
}
|
|
break;
|
|
|
|
case '%':
|
|
break;
|
|
|
|
case '^':
|
|
break;
|
|
|
|
case '&':
|
|
break;
|
|
|
|
case '*':
|
|
if ( fCtrl )
|
|
{
|
|
if ( gTacticalStatus.uiFlags & RED_ITEM_GLOW_ON )
|
|
{
|
|
gTacticalStatus.uiFlags &= (~RED_ITEM_GLOW_ON );
|
|
}
|
|
else
|
|
{
|
|
gTacticalStatus.uiFlags |= RED_ITEM_GLOW_ON;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case '(':
|
|
break;
|
|
|
|
case ')':
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
if ( fCtrl && fAlt )
|
|
{
|
|
// Flugente: fortification
|
|
// set details on how to place fortification nodes
|
|
// loop over all structure constructs, and select those entries that are possible in this map
|
|
std::vector<std::pair<INT16, STR16> > dropdownvector_1 = GetCurrentSectorAllowedFortificationTileSetVector( giCurrentTilesetID );
|
|
|
|
DropDownTemplate<DROPDOWNNR_MSGBOX_1>::getInstance( ).SetEntries( dropdownvector_1 );
|
|
|
|
if ( !dropdownvector_1.empty() )
|
|
{
|
|
BOOLEAN found = FALSE;
|
|
for ( std::vector<std::pair<INT16, STR16> >::iterator it = dropdownvector_1.begin( ); it != dropdownvector_1.end(); ++it )
|
|
{
|
|
if ( (*it).first == gCurrentFortificationStructure )
|
|
{
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !found )
|
|
gCurrentFortificationStructure = dropdownvector_1[0].first;
|
|
}
|
|
|
|
DropDownTemplate<DROPDOWNNR_MSGBOX_1>::getInstance( ).SetSelectedEntryKey( gCurrentFortificationStructure );
|
|
|
|
std::vector<std::pair<INT16, STR16> > dropdownvector_2 = GetTileSetIndexVector( gCurrentFortificationStructure );
|
|
|
|
DropDownTemplate<DROPDOWNNR_MSGBOX_2>::getInstance( ).SetEntries( dropdownvector_2 );
|
|
|
|
if ( !dropdownvector_2.empty( ) )
|
|
{
|
|
BOOLEAN found = FALSE;
|
|
for ( std::vector<std::pair<INT16, STR16> >::iterator it = dropdownvector_2.begin( ); it != dropdownvector_2.end( ); ++it )
|
|
{
|
|
if ( (*it).first == guiMessageBoxImageIndex )
|
|
{
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !found )
|
|
guiMessageBoxImageIndex = dropdownvector_2[0].first;
|
|
}
|
|
|
|
DropDownTemplate<DROPDOWNNR_MSGBOX_2>::getInstance( ).SetSelectedEntryKey( guiMessageBoxImageIndex );
|
|
|
|
if ( dropdownvector_1.empty( ) || dropdownvector_2.empty() )
|
|
{
|
|
CHAR16 text[100];
|
|
swprintf( text, szFortificationText[4], giCurrentTilesetID, gTilesets[giCurrentTilesetID].zName );
|
|
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, text, GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL );
|
|
}
|
|
else
|
|
{
|
|
CHAR16 text[100];
|
|
swprintf( text, szFortificationText[5], giCurrentTilesetID, gTilesets[giCurrentTilesetID].zName );
|
|
|
|
VOBJECT_DESC VObjectDesc;
|
|
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
|
|
|
|
sprintf( VObjectDesc.ImageFile, "TILESETS\\%d\\%s", giCurrentTilesetID, gStructureConstruct[gCurrentFortificationStructure].szTileSetName );
|
|
|
|
// even if AddVideoObject fails, we still set MSG_BOX_FLAG_IMAGE, as we might 'repair' it while the box is open
|
|
if ( !AddVideoObject( &VObjectDesc, &guiMessageBoxImage ) )
|
|
{
|
|
sprintf( VObjectDesc.ImageFile, "TILESETS\\0\\%s", gStructureConstruct[gCurrentFortificationStructure].szTileSetName );
|
|
|
|
AddVideoObject( &VObjectDesc, &guiMessageBoxImage );
|
|
}
|
|
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, text, GAME_SCREEN, (MSG_BOX_FLAG_OK | MSG_BOX_FLAG_DROPDOWN_1 | MSG_BOX_FLAG_DROPDOWN_2 | MSG_BOX_FLAG_IMAGE), FortificationSettingCallBack, NULL );
|
|
}
|
|
}
|
|
else if ( fCtrl )
|
|
{
|
|
// Flugente: fortification
|
|
INT32 sGridNo;
|
|
|
|
//Get the gridno the cursor is at
|
|
GetMouseMapPos( &sGridNo );
|
|
|
|
// a node to add a structure
|
|
AddFortificationPlanNode( sGridNo, (INT8)gsInterfaceLevel, gCurrentFortificationStructure, gCurrentFortificationTileLibraryIndex, TRUE );
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
// ToggleMercsNeverQuit();
|
|
static UINT8 ubAmbientSound = 0;
|
|
|
|
ubAmbientSound++;
|
|
|
|
if ( ubAmbientSound >= NUM_STEADY_STATE_AMBIENCES )
|
|
{
|
|
ubAmbientSound = 1;
|
|
}
|
|
|
|
SetSteadyStateAmbience( ubAmbientSound );
|
|
|
|
#else
|
|
//shadooow: trying to use autobandage during conversation will mess up game
|
|
// sevenfm: don't try to activate autobandage in hostile sector
|
|
if (CheckAutoBandage())
|
|
{
|
|
BeginAutoBandage();
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
HandleTBSkillsMenu();
|
|
}
|
|
break;
|
|
|
|
case 'A':
|
|
//CHRISL: Ammo Crate
|
|
//MM: Ammo Box
|
|
if (fCtrl)
|
|
HandleTacticalAmmoCrates( AMMO_CRATE );
|
|
else
|
|
HandleTacticalAmmoCrates( AMMO_BOX );
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_NEW_BADMERC;
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
// Flugente: fortification
|
|
INT32 sGridNo;
|
|
|
|
//Get the gridno the cursor is at
|
|
GetMouseMapPos( &sGridNo );
|
|
|
|
// a node to delete a structure
|
|
AddFortificationPlanNode( sGridNo, (INT8)gsInterfaceLevel, gCurrentFortificationStructure, gCurrentFortificationTileLibraryIndex, FALSE );
|
|
}
|
|
else
|
|
{
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( ( gpItemPointer == NULL ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ BURSTMODE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
SetBurstMode();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'B':
|
|
//Drop pack for all mercs on current map
|
|
HandleTBDropBackpacks();
|
|
break;
|
|
case 'c':
|
|
|
|
if ( fAlt && fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ToggleCliffDebug( );
|
|
}
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
CreateNextCivType();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
HandleTacticalCoverMenu();
|
|
}
|
|
else
|
|
{
|
|
HandleStanceChangeFromUIKeys( ANIM_CROUCH );
|
|
}
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
if ( fAlt )
|
|
ToggleHostileTrapsView(); // added by Flugente
|
|
else
|
|
ToggleEnemyView();
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
if( gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT )
|
|
{
|
|
if( gTacticalStatus.ubCurrentTeam == gbPlayerNum )
|
|
{
|
|
// nothing in hand and the Done button for whichever panel we're in must be enabled
|
|
if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons &&
|
|
( ( ( gsCurInterfacePanel == SM_PANEL ) && ( ButtonList[ iSMPanelButtons[ SM_DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ||
|
|
( ( gsCurInterfacePanel == TEAM_PANEL ) && ( ButtonList[ iTEAMPanelButtons[ TEAM_DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) )
|
|
{
|
|
if( fAlt )
|
|
{
|
|
INT32 cnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
for ( pSoldier = MercPtrs[ gbPlayerNum ], cnt = 0; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
|
|
{
|
|
if ( pSoldier->bActive && pSoldier->stats.bLife > 0 )
|
|
{
|
|
// Get APs back...
|
|
pSoldier->CalcNewActionPoints( );
|
|
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//End turn only if in combat and it is the player's turn
|
|
if ( fCtrl )
|
|
gTacticalStatus.ubDisablePlayerInterrupts = TRUE;
|
|
|
|
*puiNewEvent = I_ENDTURN;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef JA2TESTVERSION
|
|
else if( fCtrl )
|
|
{
|
|
AdvanceToNextDay();
|
|
}
|
|
#endif
|
|
// sevenfm: press 'd' in realtime to start turnbased
|
|
else
|
|
{
|
|
if ( (gTacticalStatus.uiFlags & INCOMBAT) || (NumEnemyInSector() != 0) )
|
|
{
|
|
EnterCombatMode( OUR_TEAM );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'D':
|
|
// SANDRO - changed from drop all to enable soldier tooltips
|
|
if ( gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] )
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] = FALSE;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SOLDIER_TOOLTIPS_OFF ] );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] = TRUE;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SOLDIER_TOOLTIPS_ON ] );
|
|
}
|
|
// if ( gGameSettings.fOptions[TOPTION_DROP_ALL] )
|
|
// {
|
|
// gGameSettings.fOptions[TOPTION_DROP_ALL] = FALSE;
|
|
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_OFF ] );
|
|
// }
|
|
// else
|
|
// {
|
|
// gGameSettings.fOptions[TOPTION_DROP_ALL] = TRUE;
|
|
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_ON ] );
|
|
// }
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
if( fAlt )
|
|
{
|
|
// used for override player's turn in network game
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ToggleViewAllMercs();
|
|
ToggleViewAllItems();
|
|
}
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
else if( fCtrl )
|
|
{
|
|
ToggleMapEdgepoints();
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
if ( pSoldier->aiData.bOppCnt > 0 )
|
|
{
|
|
// Cycle....
|
|
CycleVisibleEnemies( pSoldier );
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_ENEMIES_IN_SIGHT_STR ] );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'E':
|
|
//CHRISL: drop all items
|
|
if ( gusSelectedSoldier != NOBODY && !(gTacticalStatus.fEnemyInSector) )
|
|
{
|
|
SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
for(int i = BODYPOSFINAL; i<NUM_INV_SLOTS; i++)
|
|
{
|
|
if(pSoldier->inv[i].exists() == true)
|
|
{
|
|
AddItemToPool(pSoldier->sGridNo, &pSoldier->inv[i], 1, pSoldier->pathing.bLevel, 0, -1);
|
|
//pSoldier->inv[i].initialize();
|
|
DeleteObj(&pSoldier->inv[i]);
|
|
}
|
|
}
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
break;
|
|
|
|
case 'f':
|
|
if( fCtrl )
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
//Toggle Frame Rate Display
|
|
gbFPSDisplay = !gbFPSDisplay;
|
|
DisableFPSOverlay( (BOOLEAN)!gbFPSDisplay );
|
|
if( !gbFPSDisplay )
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
if ( gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] )
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] = FALSE;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_TRACKING_MODE_OFF ] );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] = TRUE;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_TRACKING_MODE_ON ] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
INT32 usGridNo;
|
|
|
|
//Get the gridno the cursor is at
|
|
GetMouseMapPos( &usGridNo );
|
|
|
|
// if the cursor location is valid
|
|
if ( !TileIsOutOfBounds(usGridNo) )
|
|
{
|
|
// sevenfm: code to check ubAdjacentSoldierCnt
|
|
/*MAP_ELEMENT *pMapElement;
|
|
pMapElement = &(gpWorldLevelData[usGridNo]);
|
|
ScreenMsg(FONT_ORANGE, MSG_INTERFACE, L"adjacent soldiers %d", pMapElement->ubAdjacentSoldierCnt);*/
|
|
|
|
// if there is a selected soldier
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
//if the cursor is over someone
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
//Display the range to the target
|
|
DisplayRangeToTarget( MercPtrs[gusSelectedSoldier], MercPtrs[gusUIFullTargetID]->sGridNo );
|
|
}
|
|
else
|
|
{
|
|
//Display the range to the target
|
|
DisplayRangeToTarget( MercPtrs[gusSelectedSoldier], usGridNo );
|
|
}
|
|
}
|
|
|
|
CHAR16 zOutputString[512];
|
|
swprintf( zOutputString, L"%s: %d", pUpdateMapInfoText[19], usGridNo);
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
|
|
|
|
// Flugente: print out structure tileset
|
|
if ( gGameExternalOptions.fPrintStructureTileset )
|
|
{
|
|
STRUCTURE * pStruct = FindStructure( usGridNo, ( STRUCTURE_TYPE_DEFINED ) );
|
|
if ( pStruct )
|
|
{
|
|
// if this is a multi-tile structure, be sure to use the base gridno
|
|
if ( !(pStruct->fFlags & STRUCTURE_BASE_TILE) )
|
|
{
|
|
pStruct = FindBaseStructure( pStruct );
|
|
}
|
|
|
|
if ( pStruct )
|
|
{
|
|
LEVELNODE* pNode = FindLevelNodeBasedOnStructure( pStruct->sGridNo, pStruct );
|
|
|
|
if ( pNode )
|
|
{
|
|
UINT32 uiTileType = 0;
|
|
if ( GetTileType( pNode->usIndex, &uiTileType ) )
|
|
{
|
|
std::string tilesestr = GetNameToTileSet( uiTileType );
|
|
|
|
CHAR16 whcarthing[100];
|
|
|
|
int nChars = MultiByteToWideChar( CP_ACP, 0, tilesestr.c_str(), -1, NULL, 0 );
|
|
MultiByteToWideChar( CP_UTF8, 0, tilesestr.c_str( ), -1, whcarthing, nChars );
|
|
|
|
swprintf( zOutputString, L"Tileset %d: Tilesetname: %s tileindex: %d", giCurrentTilesetID, whcarthing, pStruct->pDBStructureRef->pDBStructure->usStructureNumber );
|
|
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, zOutputString );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extern BOOLEAN InARoom( INT32 sGridNo, UINT16 *pusRoomNo );
|
|
|
|
UINT16 usRoom;
|
|
if ( InARoom( usGridNo, &usRoom ) )
|
|
{
|
|
swprintf( zOutputString, L"Room number: %d", usRoom );
|
|
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, zOutputString );
|
|
}
|
|
|
|
// display height
|
|
swprintf( zOutputString, L"Floor height: %d", gpWorldLevelData[usGridNo].sHeight );
|
|
ScreenMsg( FONT_MCOLOR_LTGREEN, MSG_INTERFACE, zOutputString );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'F':
|
|
if( fCtrl && UsingNewInventorySystem() == true )
|
|
{
|
|
HandleTBPickUpBackpacks();
|
|
}
|
|
SeperateItems();
|
|
if( fCtrl )
|
|
StackAndSort( TRUE );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] );
|
|
break;
|
|
|
|
case 'G':
|
|
if( fCtrl )
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
if (gTacticalStatus.uiFlags & GODMODE)
|
|
{
|
|
//ScreenMsg(FONT_MCOLOR_RED, MSG_INTERFACE, L"God mode deactivated.");
|
|
gTacticalStatus.uiFlags &= (~GODMODE);
|
|
}
|
|
else
|
|
{
|
|
//ScreenMsg(FONT_MCOLOR_RED, MSG_INTERFACE, L"God mode activated.");
|
|
gTacticalStatus.uiFlags |= GODMODE;
|
|
}
|
|
}
|
|
}
|
|
else if ( gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] )
|
|
{
|
|
gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] = FALSE;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_BURST_CURSOR_OFF ] );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] = TRUE;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_BURST_CURSOR_ON ] );
|
|
}
|
|
break;
|
|
case 'g':
|
|
if( fCtrl && fAlt )
|
|
{
|
|
HandleTBToggleFormation();
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
// Flugente: ask player whether he wants to activate cheats or not, but not in multiplayer
|
|
if ( !is_networked )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL() )
|
|
{
|
|
DoScreenIndependantMessageBox( pMessageStrings[MSG_PROMPT_CHEATS_DEACTIVATE], MSG_BOX_FLAG_YESNO, ActivateCheatsMessageBoxCallBack );
|
|
}
|
|
else
|
|
{
|
|
DoScreenIndependantMessageBox( pMessageStrings[MSG_PROMPT_CHEATS_ACTIVATE], MSG_BOX_FLAG_YESNO, ActivateCheatsMessageBoxCallBack );
|
|
}
|
|
}
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
//*puiNewEvent = I_NEW_MERC;
|
|
if (GetMouseMapPos(&mappos))
|
|
{
|
|
DoMessageBox(MSG_BOX_BASIC_SMALL_BUTTONS, L"Enter ProfileID", GAME_SCREEN, MSG_BOX_FLAG_INPUTBOX, MercCreationCallBack, NULL);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HandlePlayerTogglingLightEffects(TRUE);
|
|
}
|
|
break;
|
|
|
|
case 'H':
|
|
HandleTBSwapHands();
|
|
break;
|
|
|
|
case 'h':
|
|
if ( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
if ( gfReportHitChances )
|
|
{
|
|
gfReportHitChances = FALSE;
|
|
}
|
|
else
|
|
{
|
|
gfReportHitChances = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_TESTHIT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ShouldTheHelpScreenComeUp( HELP_SCREEN_TACTICAL, TRUE );
|
|
}
|
|
break;
|
|
case 'I':
|
|
//CHRISL: This will create a large number of objects for checking overloading //dnl ch75 251013
|
|
if(fAlt && fCtrl)
|
|
{
|
|
if(CHEATER_CHEAT_LEVEL())
|
|
{
|
|
for ( UINT16 i = FIRST_WEAPON; i<gMAXITEMS_READ; ++i )
|
|
{
|
|
if(i == 1580 || Item[i].ubWeight == 0 && !(i == 257 || i == 1006 || i == 1026 || i == 1183))//dnl!!! items 257, 1006, 1026, 1183 had weight 0 which need to be changed in xml
|
|
continue;
|
|
|
|
CreateItem(i, 100, &gTempObject);
|
|
AddItemToPool(usMapPos, &gTempObject, VISIBLE , 0, WORLD_ITEM_REACHABLE, 0);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'i':
|
|
if ( fCtrl && fAlt )
|
|
{
|
|
if ( gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] )
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = FALSE;
|
|
ToggleItemGlow( FALSE );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = TRUE;
|
|
ToggleItemGlow( TRUE );
|
|
}
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
CreateRandomItem();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
// free to use
|
|
}
|
|
else
|
|
{
|
|
// freed, use this only for a frequently-used new function
|
|
}
|
|
break;
|
|
|
|
case 'j':
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
gfNextFireJam = TRUE;
|
|
}
|
|
}
|
|
else if ( fCtrl )
|
|
{
|
|
#ifdef JA2BETAVERSION
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ToggleNPCRecordDisplay();
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
SOLDIERTYPE *pjSoldier;
|
|
if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) )
|
|
{
|
|
// Flugente: robots do not climb
|
|
if ( AM_A_ROBOT( pjSoldier ) )
|
|
break;
|
|
|
|
INT16 sAPCost;
|
|
INT16 sBPCost;
|
|
BOOLEAN fNearHeigherLevel;
|
|
BOOLEAN fNearLowerLevel;
|
|
INT8 bDirection;
|
|
|
|
// Make sure the merc is not collapsed!
|
|
if (!IsValidStance(pjSoldier, ANIM_CROUCH) )
|
|
{
|
|
if ( pjSoldier->bCollapsed && pjSoldier->bBreath < OKBREATH )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 4 ], pjSoldier->GetName() );
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
// Climb on roof
|
|
GetMercClimbDirection( pjSoldier->ubID, &fNearLowerLevel, &fNearHeigherLevel );
|
|
|
|
if ( fNearLowerLevel )
|
|
{
|
|
// No climbing when wearing a backpack!
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_NO_CLIMB] );
|
|
return;
|
|
}
|
|
|
|
if ( EnoughPoints( pjSoldier, GetAPsToClimbRoof( pjSoldier, TRUE ), GetBPsToClimbRoof( pjSoldier, TRUE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbDownRoof( );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( fNearHeigherLevel )
|
|
{
|
|
// No climbing when wearing a backpack!
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_NO_CLIMB] );
|
|
return;
|
|
}
|
|
|
|
if ( EnoughPoints( pjSoldier, GetAPsToClimbRoof( pjSoldier, FALSE ), GetBPsToClimbRoof( pjSoldier, FALSE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbUpRoof( );
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Jump over fence
|
|
if ( FindFenceJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
|
|
{
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
{
|
|
//Moa: no jumping whith backpack
|
|
//sAPCost = GetAPsToJumpFence( pjSoldier, TRUE );
|
|
//sBPCost = GetBPsToJumpFence( pjSoldier, TRUE );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_NO_CLIMB] );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
sAPCost = GetAPsToJumpFence( pjSoldier, FALSE );
|
|
sBPCost = GetBPsToJumpFence( pjSoldier, FALSE );
|
|
}
|
|
|
|
if ( EnoughPoints( pjSoldier, sAPCost, sBPCost, FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbFence( );
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Climb on walls
|
|
if (gGameExternalOptions.fCanClimbOnWalls == TRUE)
|
|
{
|
|
// No climbing when wearing a backpack!
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_NO_CLIMB] );
|
|
return;
|
|
}
|
|
|
|
if ( FindWallJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
|
|
{
|
|
if ( EnoughPoints( pjSoldier, GetAPsToJumpWall( pjSoldier, FALSE ), GetBPsToJumpWall( pjSoldier, FALSE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbWall( );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'J':
|
|
// WANNE: Jump through window?
|
|
if (gGameExternalOptions.fCanJumpThroughWindows == TRUE )
|
|
{
|
|
INT16 sAPCost;
|
|
INT16 sBPCost;
|
|
INT8 bDirection;
|
|
SOLDIERTYPE *lSoldier;
|
|
|
|
if ( GetSoldier( &lSoldier, gusSelectedSoldier ) )
|
|
{
|
|
// Flugente: robots do not climb
|
|
if ( AM_A_ROBOT( lSoldier ) )
|
|
break;
|
|
|
|
if ( FindWindowJumpDirection( lSoldier, lSoldier->sGridNo, lSoldier->ubDirection, &bDirection ) )
|
|
{
|
|
if ((UsingNewInventorySystem() == true) && lSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)lSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[lSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[lSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
{
|
|
//Moa: no jumping with backpack
|
|
//sAPCost = GetAPsToJumpThroughWindows( lSoldier, TRUE );
|
|
//sBPCost = GetBPsToJumpThroughWindows( lSoldier, TRUE );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_NO_CLIMB] );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
sAPCost = GetAPsToJumpFence( lSoldier, FALSE );
|
|
sBPCost = GetBPsToJumpFence( lSoldier, FALSE );
|
|
}
|
|
|
|
if (EnoughPoints(lSoldier, sAPCost, sBPCost, FALSE))
|
|
{
|
|
lSoldier->BeginSoldierClimbWindow( );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'k':
|
|
if( fAlt )
|
|
{
|
|
if ( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
// next shot by anybody is auto kill
|
|
if (gfNextShotKills)
|
|
{
|
|
gfNextShotKills = FALSE;
|
|
}
|
|
else
|
|
{
|
|
gfNextShotKills = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// used for kicking player out in networked game
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BeginKeyPanelFromKeyShortcut( );
|
|
}
|
|
break;
|
|
|
|
case 'K':
|
|
// Flugente: reworked this
|
|
//CHRISL: Swap gunsling
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
if ( fAlt )
|
|
// switch to knife, or from knife to gun
|
|
pSoldier->SwitchWeapons( TRUE );
|
|
else if ( fCtrl )
|
|
// switch to sidearm, or from sidearm to non-sidearm gun
|
|
pSoldier->SwitchWeapons( FALSE, TRUE );
|
|
else
|
|
// switch to and from gunsling
|
|
pSoldier->SwitchWeapons( );
|
|
}
|
|
break;
|
|
|
|
case 'l':
|
|
if(fCtrl && fAlt)
|
|
{
|
|
#ifdef JA2BETAVERSION
|
|
gfDisplayStrategicAILogs ^= TRUE;
|
|
if (gfDisplayStrategicAILogs)
|
|
{
|
|
ScreenMsg(FONT_LTKHAKI, MSG_INTERFACE, L"Strategic AI Log visually enabled.");
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg(FONT_LTKHAKI, MSG_INTERFACE, L"Strategic AI Log visually disabled.");
|
|
}
|
|
break;
|
|
#endif
|
|
}
|
|
else if (fAlt )
|
|
{
|
|
// used for quickloading
|
|
}
|
|
else if (fCtrl)
|
|
{
|
|
// used for loading game
|
|
}
|
|
else
|
|
{
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( ( gpItemPointer == NULL ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ LOOK_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
*puiNewEvent = LC_CHANGE_TO_LOOK;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'L':
|
|
HandleTacticalTransformFlashlight();
|
|
break;
|
|
|
|
case 'm':
|
|
if( fAlt )
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_LEVELNODEDEBUG;
|
|
CountLevelNodes();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Memory Used: %d + %d = %d vs: %d", guiMemTotal, giMemUsedInSurfaces, ( guiMemTotal + giMemUsedInSurfaces), ( giStartingMemValue - MemGetFree() ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// nothing in hand and the Map Screen button for whichever panel we're in must be enabled
|
|
if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons &&
|
|
( ( ( gsCurInterfacePanel == SM_PANEL ) && ( ButtonList[ iSMPanelButtons[ SM_MAP_SCREEN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ||
|
|
( ( gsCurInterfacePanel == TEAM_PANEL ) && ( ButtonList[ iTEAMPanelButtons[ TEAM_MAP_SCREEN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) )
|
|
{
|
|
// go to Map screen
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
GoToMapScreenFromTactical();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'M':
|
|
if( fAlt )
|
|
{
|
|
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
// Merge all items
|
|
StackAndSort( FALSE );
|
|
}
|
|
else
|
|
{
|
|
HandleTacticalMoveItems();
|
|
}
|
|
break;
|
|
|
|
// swap sungoggles and nightgoggles / put on gas masks
|
|
case 'N':
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 bLoop;
|
|
|
|
// emergency command: everybody in this sector puts on gasmasks
|
|
if ( fAlt )
|
|
{
|
|
for ( bLoop = gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier = MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++ )
|
|
{
|
|
if ( !AM_A_ROBOT( pTeamSoldier ) && pTeamSoldier->stats.bLife >= OKLIFE && (pTeamSoldier->sSectorX == gWorldSectorX) && (pTeamSoldier->sSectorY == gWorldSectorY) && (pTeamSoldier->bSectorZ == gbWorldSectorZ) )
|
|
{
|
|
WearGasMaskIfAvailable( pTeamSoldier );
|
|
}
|
|
}
|
|
|
|
// redraw panels
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fTeamPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
// HEADROCK HAM B2.8: Added call for CTRL-SHIFT-N to switch all soldiers to day/night.
|
|
else if ( fCtrl )
|
|
{
|
|
BOOLEAN fToNightVision;
|
|
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
if ( pTeamSoldier->inv[HEAD1POS].exists() || pTeamSoldier->inv[HEAD2POS].exists() )
|
|
{
|
|
fToNightVision = ( Item[pTeamSoldier->inv[HEAD1POS].usItem].brightlightvisionrangebonus > 0 || Item[pTeamSoldier->inv[HEAD2POS].usItem].brightlightvisionrangebonus > 0 );
|
|
break;
|
|
}
|
|
if ( bLoop == gTacticalStatus.Team[gbPlayerNum].bLastID )
|
|
{
|
|
// Default to night or day based on game hour
|
|
fToNightVision = NightTime();
|
|
}
|
|
}
|
|
}
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
// HEADROCK HAM 3.5: When this INI setting is enabled, ALL mercs in the current sector will do a goggle swap.
|
|
if (gGameExternalOptions.fGoggleSwapAffectsAllMercsInSector)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->sSectorX == gWorldSectorX && pTeamSoldier->sSectorY == gWorldSectorY && pTeamSoldier->bSectorZ == gbWorldSectorZ && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
SwapGogglesUniformly(pTeamSoldier, fToNightVision);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
SwapGogglesUniformly(pTeamSoldier, fToNightVision);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else // Shift-N
|
|
{
|
|
HandleTBSwapGoogles();
|
|
}
|
|
break;
|
|
|
|
case 'n':
|
|
if ( !AreInMeanwhile() )
|
|
{
|
|
if ( fAlt )
|
|
{
|
|
static UINT16 gQuoteNum = 0;
|
|
|
|
if ( INFORMATION_CHEAT_LEVEL() )
|
|
{
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
TacticalCharacterDialogue( MercPtrs[gusUIFullTargetID], gQuoteNum );
|
|
gQuoteNum++;
|
|
}
|
|
}
|
|
}
|
|
else if ( fCtrl )
|
|
{
|
|
#if 0
|
|
if ( INFORMATION_CHEAT_LEVEL() )
|
|
{
|
|
if ( gfUIShowCurIntTile ^= TRUE )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Turning Enhanced mouse detection ON." );
|
|
gubIntTileCheckFlags = INTILE_CHECK_FULL;
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Turning Enhanced mouse detection OFF." );
|
|
gubIntTileCheckFlags = INTILE_CHECK_SELECTIVE;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if ( !CycleSoldierFindStack( usMapPos ) )// Are we over a merc stack?
|
|
CycleIntTileFindStack( usMapPos ); // If not, now check if we are over a struct stack
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
if ( !AreInMeanwhile() )
|
|
{
|
|
if ( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL() )
|
|
{
|
|
gStrategicStatus.usPlayerKills += NumEnemiesInAnySector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
|
ObliterateSector();
|
|
}
|
|
}
|
|
else if ( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL() )
|
|
{
|
|
CreatePlayerControlledMonster();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// nothing in hand and the Options Screen button for whichever panel we're in must be enabled
|
|
if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[iSMPanelButtons[OPTIONS_BUTTON]]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
if ( !fDisableMapInterfaceDueToBattle )
|
|
{
|
|
// go to Options screen
|
|
SetOptionsPreviousScreen(GAME_SCREEN);
|
|
LeaveTacticalScreen( OPTIONS_SCREEN );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'O':
|
|
HandleTacticalTransformScope();
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
#ifdef JA2BETAVERSION
|
|
if( fAlt )
|
|
ToggleRealTimeConfirm();
|
|
else
|
|
#endif
|
|
|
|
#ifdef JA2TESTVERSION
|
|
if( fCtrl )
|
|
{
|
|
// CTRL-P: Display player's highest progress percentage
|
|
DumpSectorDifficultyInfo();
|
|
}
|
|
else
|
|
#endif
|
|
HandleStanceChangeFromUIKeys( ANIM_PRONE );
|
|
break;
|
|
|
|
case 'P':
|
|
|
|
HandleTacticalTransformStock();
|
|
|
|
break;
|
|
|
|
case 'q':
|
|
if( fCtrl )
|
|
{
|
|
if (gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE])
|
|
{
|
|
gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = FALSE;
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_GL_LOW_ANGLE]);
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = TRUE;
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_GL_HIGH_ANGLE]);
|
|
}
|
|
|
|
//HandleTBSwapHands( );
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
HandleTBSwapGunsling( );
|
|
}
|
|
else
|
|
{
|
|
SetScopeMode(usMapPos);
|
|
}
|
|
break;
|
|
|
|
case 'Q':
|
|
HandleTacticalDropItem( HANDPOS );
|
|
break;
|
|
|
|
// Make auto reload with magazines from sector inventory
|
|
case 'R':
|
|
HandleTBReloadAll();
|
|
|
|
break;
|
|
case 'r':
|
|
if( gusSelectedSoldier != NOBODY )
|
|
{
|
|
if( fAlt ) //reload selected merc's weapon
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ReloadWeapon( MercPtrs[ gusSelectedSoldier ], MercPtrs[ gusSelectedSoldier ]->ubAttackingHand );
|
|
}
|
|
else
|
|
HandleTBReload();
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HandleTBSoldierRun();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'S':
|
|
StackAndSort( TRUE );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] );
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if ( !AreInMeanwhile() )
|
|
{
|
|
if ( fCtrl )
|
|
{
|
|
if ( fAlt )
|
|
{
|
|
RemoveCharacterFromSquads( MercPtrs[gusSelectedSoldier] );
|
|
}
|
|
else if ( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) && !is_networked )
|
|
{
|
|
// WANNE: Do not allow saving via the save screen when it is not our turn,
|
|
// because there is an explit when you close the save window without saving, you can move your merc even it is not your turn
|
|
// IF UI HAS LOCKED, ONLY ALLOW EXIT!
|
|
if ( gfDisableRegionActive || gfUserTurnRegionActive )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//if the game CAN be saved
|
|
if ( CanGameBeSaved() )
|
|
{
|
|
gfSaveGame = TRUE;
|
|
gfCameDirectlyFromGame = TRUE;
|
|
|
|
SetOptionsPreviousScreen(GAME_SCREEN);
|
|
LeaveTacticalScreen( SAVE_LOAD_SCREEN );
|
|
}
|
|
else
|
|
{
|
|
//Display a message saying the player cant save now
|
|
switch ( gGameOptions.ubIronManMode )
|
|
{
|
|
case 2:
|
|
DoMapMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[TCTL_MSG__SOFT_IRON_MAN_CANT_SAVE_NOW], GAME_SCREEN, (UINT8)MSG_BOX_FLAG_OK, NULL );
|
|
break;
|
|
case 3:
|
|
CHAR16 zTemp[320];
|
|
swprintf( zTemp, zNewTacticalMessages[TCTL_MSG__EXTREME_IRON_MAN_CANT_SAVE_NOW], gGameExternalOptions.ubExtremeIronManSavingHour );
|
|
DoMapMessageBox( MSG_BOX_BASIC_STYLE, zTemp, GAME_SCREEN, (UINT8)MSG_BOX_FLAG_OK, NULL );
|
|
break;
|
|
default:
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[TCTL_MSG__IRON_MAN_CANT_SAVE_NOW], GAME_SCREEN, (UINT8)MSG_BOX_FLAG_OK, NULL, NULL );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( fAlt )
|
|
{
|
|
if ( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) && !is_networked )
|
|
{
|
|
//if the game CAN be saved
|
|
if ( CanGameBeSaved() )
|
|
{
|
|
SetOptionsPreviousScreen(GAME_SCREEN);
|
|
//guiPreviousOptionScreen = guiCurrentScreen;
|
|
DoQuickSave();
|
|
}
|
|
else
|
|
{
|
|
//Display a message saying the player cant save now
|
|
switch ( gGameOptions.ubIronManMode )
|
|
{
|
|
case 2:
|
|
DoMapMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[TCTL_MSG__SOFT_IRON_MAN_CANT_SAVE_NOW], GAME_SCREEN, MSG_BOX_FLAG_OK, NULL );
|
|
break;
|
|
case 3:
|
|
CHAR16 zTemp[320];
|
|
swprintf( zTemp, zNewTacticalMessages[TCTL_MSG__EXTREME_IRON_MAN_CANT_SAVE_NOW], gGameExternalOptions.ubExtremeIronManSavingHour );
|
|
DoMapMessageBox( MSG_BOX_BASIC_STYLE, zTemp, GAME_SCREEN, MSG_BOX_FLAG_OK, NULL );
|
|
break;
|
|
default:
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[TCTL_MSG__IRON_MAN_CANT_SAVE_NOW], GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
gfPlotNewMovement = TRUE;
|
|
HandleStanceChangeFromUIKeys( ANIM_STAND );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
TeleportSelectedSoldier();
|
|
}
|
|
}
|
|
else if( fCtrl && !is_networked)// ary-05/05/2009 : add forced turn mode
|
|
{
|
|
ToggleTurnMode();
|
|
}
|
|
else
|
|
ToggleTreeTops();
|
|
break;
|
|
|
|
case 'T':
|
|
if ( fCtrl && fShift && fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
TestCapture( );
|
|
|
|
//EnterCombatMode( gbPlayerNum );
|
|
}
|
|
}
|
|
else if ( fCtrl && fShift )
|
|
{
|
|
if (CHEATER_CHEAT_LEVEL())
|
|
{
|
|
swprintf(zString, L"%s cheat", pMessageStrings[MSG_SAVE_AUTOSAVE_TEXT]);
|
|
DoAutoSave(SAVE__TIMED_AUTOSAVE_SLOT1, zString);
|
|
}
|
|
}
|
|
else if ( fAlt && fShift )
|
|
{
|
|
//resort Team by ubID
|
|
SortSquadByID(MercPtrs[gusSelectedSoldier]->bTeam);
|
|
}
|
|
else
|
|
{
|
|
HandleTacticalTransformItem();
|
|
}
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
RefreshSoldier();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) && gusSelectedSoldier != NOBODY )
|
|
{
|
|
INT32 cnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
for ( pSoldier = MercPtrs[ gbPlayerNum ], cnt = 0; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
|
|
{
|
|
if ( pSoldier->bActive && pSoldier->stats.bLife > 0 )
|
|
{
|
|
if (pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE)
|
|
{
|
|
// Get breath back
|
|
pSoldier->bBreath = 100;
|
|
pSoldier->sBreathRed = 10000;
|
|
}
|
|
else
|
|
{
|
|
// Get breath back
|
|
pSoldier->bBreath = pSoldier->bBreathMax;
|
|
pSoldier->sBreathRed = 0;
|
|
}
|
|
// Get life back
|
|
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
|
|
pSoldier->bBleeding = 0;
|
|
|
|
// SANDRO - erase insta-healable injury
|
|
pSoldier->iHealableInjury = 0;
|
|
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
else if ( gusSelectedSoldier != NOBODY )
|
|
*puiNewEvent = M_CHANGE_TO_ACTION;
|
|
break;
|
|
|
|
case 'U':
|
|
break;
|
|
|
|
case 'v':
|
|
if( fAlt )
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
if( gfDoVideoScroll ^= TRUE )
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Video Scroll ON" );
|
|
else
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Video Scroll OFF" );
|
|
#endif
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
#ifdef SGP_VIDEO_DEBUGGING
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VObjects: %d", guiVObjectSize );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VSurfaces: %d", guiVSurfaceSize );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SGPVideoDump.txt updated..." );
|
|
PerformVideoInfoDumpIntoFile( "SGPVideoDump.txt", TRUE );
|
|
#else
|
|
HandleTacticalInventoryMenu();
|
|
#endif
|
|
}
|
|
else
|
|
DisplayGameSettings( );
|
|
|
|
break;
|
|
|
|
case 'V':
|
|
if( fAlt )
|
|
ToggleTrapNetworkView(); // added by Flugente
|
|
else
|
|
ToggleMercView();
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
if ( fCtrl && fAlt )
|
|
{
|
|
ToggleWireFrame();
|
|
}
|
|
else if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
// cycle item forward in primary hand
|
|
if ( InItemDescriptionBox( ) )
|
|
{
|
|
// Swap item in description panel...
|
|
CycleItemDescriptionItem( ITEMDESC_START_X, ITEMDESC_START_Y);
|
|
|
|
}
|
|
else
|
|
{
|
|
CycleSelectedMercsItem();
|
|
}
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
CreateItem( FLAMETHROWER, 100, &( MercPtrs[ gusSelectedSoldier ]->inv[ HANDPOS ]) );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( ( gpItemPointer == NULL ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ LOOK_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
*puiNewEvent = LC_CHANGE_TO_LOOK;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'W':
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
// cycle item backward in primary hand
|
|
if ( InItemDescriptionBox( ) )
|
|
{
|
|
// Swap item in description panel...
|
|
CycleItemDescriptionItem( ITEMDESC_START_X, ITEMDESC_START_Y);
|
|
|
|
}
|
|
else
|
|
{
|
|
CycleSelectedMercsItem();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
if ( !fCtrl && !fAlt )
|
|
{
|
|
// Exchange places...
|
|
SOLDIERTYPE *pSoldier1, *pSoldier2;
|
|
|
|
//Check if we have a good selected guy
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
pSoldier1 = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
BOOLEAN fFoundGoodTarget = FALSE;
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
// Get soldier...
|
|
pSoldier2 = MercPtrs[ gusUIFullTargetID ];
|
|
|
|
// Check if both OK....
|
|
if ( pSoldier1->stats.bLife >= OKLIFE && pSoldier2->ubID != gusSelectedSoldier )
|
|
{
|
|
if ( pSoldier2->stats.bLife >= OKLIFE )
|
|
{
|
|
if (CanSoldierReachGridNoInGivenTileLimit( pSoldier1, pSoldier2->sGridNo, 1, (INT8)gsInterfaceLevel ) )
|
|
{
|
|
// Exclude enemies....
|
|
if ( !pSoldier2->aiData.bNeutral && (pSoldier2->bSide != gbPlayerNum ) )
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( CanExchangePlaces( pSoldier1, pSoldier2, TRUE ) )
|
|
{
|
|
// All's good!
|
|
SwapMercPositions( pSoldier1, pSoldier2 );
|
|
|
|
DeductPoints( pSoldier1, APBPConstants[AP_EXCHANGE_PLACES], 0 );
|
|
DeductPoints( pSoldier2, APBPConstants[AP_EXCHANGE_PLACES], 0 );
|
|
}
|
|
}
|
|
fFoundGoodTarget = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( !fFoundGoodTarget )
|
|
{
|
|
HandleStanceChangeFromUIKeys( ANIM_PRONE );
|
|
}
|
|
}
|
|
}
|
|
else if ( fCtrl ) // The_Bob - real time sneaking, 01-06-09
|
|
{
|
|
HandleTBEnterTurnbased();
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
// used for exit game
|
|
}
|
|
break;
|
|
// The_Bob - real time sneaking, 01-06-09
|
|
case 'X': // shift-ctrl-x: toggle real time sneaking
|
|
if ( fCtrl )
|
|
{
|
|
HandleTBToggleSneak();
|
|
}
|
|
break;
|
|
|
|
case 'y':
|
|
if ( !AreInMeanwhile() )
|
|
{
|
|
if ( fAlt )
|
|
{
|
|
OBJECTTYPE Object;
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
if ( CHEATER_CHEAT_LEVEL() )
|
|
{
|
|
QuickCreateProfileMerc( CIV_TEAM, MARIA ); //Ira
|
|
|
|
// Recruit!
|
|
RecruitEPC( MARIA );
|
|
|
|
//Heinz: 28.02.09 BUGFIX: giving G41 to Maria only in cheat mode
|
|
// Create object and set
|
|
CreateItem( G41, 100, &Object );
|
|
|
|
pSoldier = FindSoldierByProfileID( MARIA, FALSE );
|
|
|
|
AutoPlaceObject( pSoldier, &Object, FALSE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// used for opening chatbox in networked game
|
|
if ( INFORMATION_CHEAT_LEVEL() )
|
|
{
|
|
*puiNewEvent = I_LOSDEBUG;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'Y':
|
|
HandleTacticalTransformLaser();
|
|
break;
|
|
|
|
case 'z':
|
|
if( fCtrl && fAlt )
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
ToggleZBuffer();
|
|
}
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
HandleTBToggleStealthAll();
|
|
}
|
|
else if ( fCtrl )
|
|
{
|
|
// used for "lock" / "unlock" the mouse cursor in windowed mode
|
|
}
|
|
else
|
|
{
|
|
HandleTBToggleStealth();
|
|
}
|
|
break;
|
|
|
|
case 'Z':
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void HandleTalkingMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent )
|
|
{
|
|
// CHECK ESC KEYS HERE....
|
|
if ( pInputEvent->usEvent == KEY_UP )
|
|
{
|
|
if ( pInputEvent->usParam == ESC )
|
|
{
|
|
//Handle esc in talking menu
|
|
if ( HandleTalkingMenuEscape( TRUE, TRUE ) )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
}
|
|
else if ( pInputEvent->usParam == BACKSPACE )
|
|
{
|
|
HandleTalkingMenuBackspace();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void HandleSectorExitMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent )
|
|
{
|
|
// CHECK ESC KEYS HERE....
|
|
if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC ))
|
|
{
|
|
//Handle esc in talking menu
|
|
RemoveSectorExitMenu( FALSE );
|
|
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
}
|
|
|
|
|
|
void HandleOpenDoorMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent )
|
|
{
|
|
// CHECK ESC KEYS HERE....
|
|
if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC ))
|
|
{
|
|
//Handle esc in talking menu
|
|
CancelOpenDoorMenu( );
|
|
HandleOpenDoorMenu( );
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
}
|
|
|
|
|
|
void HandleMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent )
|
|
{
|
|
// CHECK ESC KEYS HERE....
|
|
if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC ))
|
|
{
|
|
//Handle esc in talking menu
|
|
CancelMovementMenu( );
|
|
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
}
|
|
|
|
void HandleItemMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent )
|
|
{
|
|
// CHECK ESC KEYS HERE....
|
|
if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC ))
|
|
{
|
|
//Handle esc in talking menu
|
|
RemoveItemPickupMenu( );
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
}
|
|
|
|
BOOLEAN HandleCheckForExitArrowsInput( BOOLEAN fAdjustConfirm )
|
|
{
|
|
INT32 usMapPos;
|
|
|
|
// If not in move mode, return!
|
|
if ( gCurrentUIMode != MOVE_MODE )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if ( gusSelectedSoldier == NOBODY )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// ATE: Remove confirm for exit arrows...
|
|
fAdjustConfirm = TRUE;
|
|
gfUIConfirmExitArrows = TRUE;
|
|
|
|
|
|
//Return right away, saying that we are in this mode, don't do any normal stuff!
|
|
if ( guiCurrentUICursor == NOEXIT_EAST_UICURSOR || guiCurrentUICursor == NOEXIT_WEST_UICURSOR
|
|
|| guiCurrentUICursor == NOEXIT_NORTH_UICURSOR || guiCurrentUICursor == NOEXIT_SOUTH_UICURSOR ||
|
|
guiCurrentUICursor == NOEXIT_GRID_UICURSOR )
|
|
{
|
|
// Yeah, but add a message....
|
|
if( gfInvalidTraversal )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANNOT_LEAVE_SECTOR_FROM_SIDE_STR ] );
|
|
gfInvalidTraversal = FALSE;
|
|
}
|
|
else if( gfRobotWithoutControllerAttemptingTraversal )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 1 ] );
|
|
gfRobotWithoutControllerAttemptingTraversal = FALSE;
|
|
}
|
|
else if( gfLoneEPCAttemptingTraversal )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, pExitingSectorHelpText[ EXIT_GUI_ESCORTED_CHARACTERS_CANT_LEAVE_SECTOR_ALONE_STR ], MercPtrs[ gusSelectedSoldier ]->GetName() );
|
|
gfLoneEPCAttemptingTraversal = FALSE;
|
|
}
|
|
else if( gubLoneMercAttemptingToAbandonEPCs )
|
|
{
|
|
CHAR16 str[256];
|
|
if( gubLoneMercAttemptingToAbandonEPCs == 1 )
|
|
{ //Use the singular version of the string
|
|
if( gMercProfiles[ MercPtrs[ gusSelectedSoldier ]->ubProfile ].bSex == MALE )
|
|
{ //male singular
|
|
swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_MALE_SINGULAR ], MercPtrs[ gusSelectedSoldier ]->GetName(),
|
|
MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->GetName() );
|
|
}
|
|
else
|
|
{ //female singular
|
|
swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_FEMALE_SINGULAR ], MercPtrs[ gusSelectedSoldier ]->GetName(),
|
|
MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->GetName() );
|
|
}
|
|
}
|
|
else
|
|
{ //Use the plural version of the string
|
|
if( gMercProfiles[ MercPtrs[ gusSelectedSoldier ]->ubProfile ].bSex == MALE )
|
|
{ //male plural
|
|
swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_MALE_PLURAL ], MercPtrs[ gusSelectedSoldier ]->GetName() );
|
|
}
|
|
else
|
|
{ //female plural
|
|
swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_FEMALE_PLURAL ], MercPtrs[ gusSelectedSoldier ]->GetName() );
|
|
}
|
|
}
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, str );
|
|
gubLoneMercAttemptingToAbandonEPCs = FALSE;
|
|
}
|
|
else if( !gGameExternalOptions.fGridExitInTurnBased && ( gTacticalStatus.uiFlags & TURNBASED ) && ( gTacticalStatus.uiFlags & INCOMBAT ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANNOT_LEAVE_IN_TURN_MODE_STR ] );
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ MERC_IS_TOO_FAR_AWAY_STR ], MercPtrs[ gusSelectedSoldier ]->GetName() );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
// Check if we want to exit!
|
|
if ( guiCurrentUICursor == EXIT_GRID_UICURSOR || guiCurrentUICursor == CONFIRM_EXIT_GRID_UICURSOR )
|
|
{
|
|
if ( fAdjustConfirm )
|
|
{
|
|
if ( !gfUIConfirmExitArrows )
|
|
{
|
|
gfUIConfirmExitArrows = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if ( !GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Goto next sector
|
|
//SimulateMouseMovement( gusMouseXPos - 5, gusMouseYPos );
|
|
InitSectorExitMenu( DIRECTION_EXITGRID, usMapPos );
|
|
}
|
|
}
|
|
return( TRUE );
|
|
}
|
|
|
|
// Check if we want to exit!
|
|
if ( guiCurrentUICursor == EXIT_EAST_UICURSOR || guiCurrentUICursor == CONFIRM_EXIT_EAST_UICURSOR )
|
|
{
|
|
if ( fAdjustConfirm )
|
|
{
|
|
if ( !gfUIConfirmExitArrows )
|
|
{
|
|
gfUIConfirmExitArrows = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Goto next sector
|
|
//SimulateMouseMovement( gusMouseXPos - 5, gusMouseYPos );
|
|
InitSectorExitMenu( EAST, 0 );
|
|
}
|
|
}
|
|
return( TRUE );
|
|
}
|
|
if ( guiCurrentUICursor == EXIT_WEST_UICURSOR || guiCurrentUICursor == CONFIRM_EXIT_WEST_UICURSOR )
|
|
{
|
|
if ( fAdjustConfirm )
|
|
{
|
|
if ( !gfUIConfirmExitArrows )
|
|
{
|
|
gfUIConfirmExitArrows = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Goto next sector
|
|
//SimulateMouseMovement( gusMouseXPos + 5, gusMouseYPos );
|
|
InitSectorExitMenu( WEST, 0);
|
|
}
|
|
}
|
|
return( TRUE );
|
|
}
|
|
if ( guiCurrentUICursor == EXIT_NORTH_UICURSOR || guiCurrentUICursor == CONFIRM_EXIT_NORTH_UICURSOR )
|
|
{
|
|
if ( fAdjustConfirm )
|
|
{
|
|
if ( !gfUIConfirmExitArrows )
|
|
{
|
|
gfUIConfirmExitArrows = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Goto next sector
|
|
//SimulateMouseMovement( gusMouseXPos, gusMouseYPos + 5 );
|
|
InitSectorExitMenu( NORTH , 0);
|
|
}
|
|
}
|
|
return( TRUE );
|
|
}
|
|
if ( guiCurrentUICursor == EXIT_SOUTH_UICURSOR || guiCurrentUICursor == CONFIRM_EXIT_SOUTH_UICURSOR )
|
|
{
|
|
if ( fAdjustConfirm )
|
|
{
|
|
if ( !gfUIConfirmExitArrows )
|
|
{
|
|
gfUIConfirmExitArrows = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Goto next sector
|
|
//SimulateMouseMovement( gusMouseXPos, gusMouseYPos - 5);
|
|
InitSectorExitMenu( SOUTH, 0 );
|
|
}
|
|
}
|
|
return( TRUE );
|
|
}
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
//Simple function implementations called by keyboard input
|
|
|
|
void CreateRandomItem()
|
|
{
|
|
INT32 usMapPos;
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
CreateItem( (UINT16) (Random( 35 ) + 1), 100, &gTempObject );
|
|
AddItemToPool( usMapPos, &gTempObject, -1 , 0, 0, 0 );
|
|
}
|
|
}
|
|
|
|
void MakeSelectedSoldierTired()
|
|
{
|
|
// Key to make guy get tired!
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos;
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
CreateItem( TNT, 100, &gTempObject );
|
|
AddItemToPool( usMapPos, &gTempObject, -1, 0, 0, 0 );
|
|
}
|
|
|
|
// CHECK IF WE'RE ON A GUY ( EITHER SELECTED, OURS, OR THEIRS
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
// Get Soldier
|
|
GetSoldier( &pSoldier, gusUIFullTargetID );
|
|
|
|
//FatigueCharacter( pSoldier );
|
|
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
}
|
|
|
|
void ToggleRealTime( UINT32 *puiNewEvent )
|
|
{
|
|
if ( gTacticalStatus.uiFlags & TURNBASED )
|
|
{
|
|
// Change to real-time
|
|
gTacticalStatus.uiFlags &= (~TURNBASED);
|
|
gTacticalStatus.uiFlags |= REALTIME;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Switching to Realtime." );
|
|
}
|
|
else if ( gTacticalStatus.uiFlags & REALTIME )
|
|
{
|
|
// Change to turn-based
|
|
gTacticalStatus.uiFlags |= TURNBASED;
|
|
gTacticalStatus.uiFlags &=( ~REALTIME );
|
|
|
|
*puiNewEvent = M_ON_TERRAIN;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Switching to Turnbased." );
|
|
}
|
|
|
|
// Plot new path!
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
|
|
void ToggleViewAllMercs()
|
|
{
|
|
// Set option to show all mercs
|
|
if ( gTacticalStatus.uiFlags&SHOW_ALL_MERCS )
|
|
{
|
|
gTacticalStatus.uiFlags&= (~SHOW_ALL_MERCS );
|
|
}
|
|
else
|
|
{
|
|
gTacticalStatus.uiFlags|= SHOW_ALL_MERCS;
|
|
}
|
|
|
|
// RE-RENDER
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
}
|
|
|
|
void ToggleViewAllItems()
|
|
{
|
|
// Set option to show all mercs
|
|
if( gTacticalStatus.uiFlags & SHOW_ALL_ITEMS )
|
|
{
|
|
gTacticalStatus.uiFlags &= ~SHOW_ALL_ITEMS ;
|
|
}
|
|
else
|
|
{
|
|
gTacticalStatus.uiFlags |= SHOW_ALL_ITEMS;
|
|
}
|
|
|
|
if ( gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] )
|
|
{
|
|
ToggleItemGlow( TRUE );
|
|
}
|
|
else
|
|
{
|
|
ToggleItemGlow( FALSE );
|
|
}
|
|
|
|
// RE-RENDER
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
}
|
|
|
|
void TestExplosion()
|
|
{
|
|
INT32 usMapPos;
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
EXPLOSION_PARAMS ExpParams ;
|
|
ExpParams.uiFlags = 0;
|
|
ExpParams.ubOwner = NOBODY;
|
|
ExpParams.ubTypeID = STUN_BLAST;
|
|
ExpParams.sGridNo = usMapPos;
|
|
|
|
GenerateExplosion( &ExpParams );
|
|
|
|
PlayJA2Sample( EXPLOSION_1, RATE_11025, MIDVOLUME, 1, MIDDLEPAN );
|
|
}
|
|
}
|
|
|
|
void CycleSelectedMercsItem()
|
|
{
|
|
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CycleSelectedMercsItem"));
|
|
INT16 usOldItem;
|
|
SOLDIERTYPE *pSoldier;
|
|
// Cycle selected guy's item...
|
|
if( gusSelectedSoldier != NOBODY )
|
|
{
|
|
// Get soldier...
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
UINT16 usOldHandItem = pSoldier->inv[HANDPOS].usItem;
|
|
|
|
// Cycle item....
|
|
usOldItem = CycleItems(pSoldier->inv[ HANDPOS ].usItem);
|
|
|
|
CreateItem( (UINT16)usOldItem, 100, &( pSoldier->inv[ HANDPOS ]) );
|
|
|
|
pSoldier->ReLoadSoldierAnimationDueToHandItemChange( usOldHandItem, pSoldier->inv[HANDPOS].usItem );
|
|
|
|
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
|
|
}
|
|
}
|
|
|
|
void ToggleWireFrame()
|
|
{
|
|
if ( gGameSettings.fOptions[ TOPTION_TOGGLE_WIREFRAME ] )
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_TOGGLE_WIREFRAME ] = FALSE;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_WIREFRAMES_REMOVED ] );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_TOGGLE_WIREFRAME ] = TRUE;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_WIREFRAMES_ADDED ] );
|
|
}
|
|
|
|
SetRenderFlags(RENDER_FLAG_FULL );
|
|
}
|
|
|
|
void RefreshSoldier()
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos;
|
|
// CHECK IF WE'RE ON A GUY ( EITHER SELECTED, OURS, OR THEIRS
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
// Get Soldier
|
|
GetSoldier( &pSoldier, gusUIFullTargetID );
|
|
|
|
pSoldier->ReviveSoldier( );
|
|
|
|
}
|
|
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
sprintf( gDebugStr, "%d %d %d %d %d %d %d %d",
|
|
gubWorldMovementCosts[ usMapPos ][ 0 ][gsInterfaceLevel],
|
|
gubWorldMovementCosts[ usMapPos ][ 1 ][gsInterfaceLevel],
|
|
gubWorldMovementCosts[ usMapPos ][ 2 ][gsInterfaceLevel],
|
|
gubWorldMovementCosts[ usMapPos ][ 3 ][gsInterfaceLevel],
|
|
gubWorldMovementCosts[ usMapPos ][ 4 ][gsInterfaceLevel],
|
|
gubWorldMovementCosts[ usMapPos ][ 5 ][gsInterfaceLevel],
|
|
gubWorldMovementCosts[ usMapPos ][ 6 ][gsInterfaceLevel],
|
|
gubWorldMovementCosts[ usMapPos ][ 7 ][gsInterfaceLevel] );
|
|
}
|
|
|
|
void ChangeSoldiersBodyType( UINT8 ubBodyType, BOOLEAN fCreateNewPalette )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
if( gusSelectedSoldier != NOBODY )
|
|
{
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
pSoldier->ubBodyType = ubBodyType;
|
|
pSoldier->EVENT_InitNewSoldierAnim( STANDING, 0 , TRUE );
|
|
//SetSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
|
|
if( fCreateNewPalette )
|
|
{
|
|
pSoldier->CreateSoldierPalettes( );
|
|
|
|
switch( ubBodyType )
|
|
{
|
|
case ADULTFEMALEMONSTER:
|
|
case AM_MONSTER:
|
|
case YAF_MONSTER:
|
|
case YAM_MONSTER:
|
|
case LARVAE_MONSTER:
|
|
case INFANT_MONSTER:
|
|
case QUEENMONSTER:
|
|
|
|
pSoldier->flags.uiStatusFlags |= SOLDIER_MONSTER;
|
|
AssignCreatureInventory( pSoldier );
|
|
CreateItem( CREATURE_YOUNG_MALE_SPIT, 100, &(pSoldier->inv[HANDPOS]) );
|
|
|
|
break;
|
|
|
|
case TANK_NW:
|
|
case TANK_NE:
|
|
case COMBAT_JEEP:
|
|
|
|
pSoldier->flags.uiStatusFlags |= SOLDIER_VEHICLE;
|
|
//pSoldier->inv[ HANDPOS ].usItem = TANK_CANNON;
|
|
|
|
pSoldier->inv[ HANDPOS ].usItem = MINIMI;
|
|
pSoldier->bVehicleID = (INT8)AddVehicleToList( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, HUMMER );
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TeleportSelectedSoldier()
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos;
|
|
// CHECK IF WE'RE ON A GUY ( EITHER SELECTED, OURS, OR THEIRS
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
// Check level first....
|
|
if ( gsInterfaceLevel == 0 )
|
|
{
|
|
pSoldier->SetSoldierHeight( 0 );
|
|
TeleportSoldier( pSoldier, usMapPos, FALSE );
|
|
pSoldier->EVENT_StopMerc( pSoldier->sGridNo, pSoldier->ubDirection );
|
|
}
|
|
else
|
|
{
|
|
// Is there a roof?
|
|
if ( FindStructure( usMapPos, STRUCTURE_ROOF ) != NULL )
|
|
{
|
|
pSoldier->SetSoldierHeight( 50.0 );
|
|
|
|
TeleportSoldier( pSoldier, usMapPos, TRUE );
|
|
pSoldier->EVENT_StopMerc( pSoldier->sGridNo, pSoldier->ubDirection );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ToggleTurnMode()// ary-05/05/2009 : add forced turn mode
|
|
{
|
|
if ( !gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ] )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_FORCED_TURN_MODE ] );
|
|
gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ] = TRUE;
|
|
EnterCombatMode( OUR_TEAM ); // ary-05/05/2009 : randomize ? i'm leaving this for now due to "player makes the call, player gets dibs"
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_NORMAL_TURN_MODE ] );
|
|
gGameSettings.fOptions[ TOPTION_TOGGLE_TURN_MODE ] = FALSE;
|
|
}
|
|
}
|
|
|
|
void ToggleTreeTops()
|
|
{
|
|
if ( gGameSettings.fOptions[ TOPTION_TOGGLE_TREE_TOPS ] )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ REMOVING_TREETOPS_STR ] );
|
|
gGameSettings.fOptions[TOPTION_TOGGLE_TREE_TOPS] = FALSE;
|
|
WorldHideTrees( );
|
|
gTacticalStatus.uiFlags |= NOHIDE_REDUNDENCY;
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ SHOWING_TREETOPS_STR ]);
|
|
WorldShowTrees( );
|
|
gGameSettings.fOptions[TOPTION_TOGGLE_TREE_TOPS] = TRUE;
|
|
gTacticalStatus.uiFlags &= (~NOHIDE_REDUNDENCY);
|
|
}
|
|
|
|
// FOR THE NEXT RENDER LOOP, RE-EVALUATE REDUNDENT TILES
|
|
InvalidateWorldRedundency( );
|
|
}
|
|
|
|
void ToggleZBuffer()
|
|
{
|
|
// Set option to show all mercs
|
|
if ( gTacticalStatus.uiFlags&SHOW_Z_BUFFER )
|
|
{
|
|
gTacticalStatus.uiFlags&= (~SHOW_Z_BUFFER );
|
|
SetRenderFlags(SHOW_Z_BUFFER);
|
|
}
|
|
else
|
|
{
|
|
gTacticalStatus.uiFlags|= SHOW_Z_BUFFER;
|
|
}
|
|
}
|
|
|
|
void TogglePlanningMode()
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos;
|
|
// DO ONLY IN TURNED BASED!
|
|
if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
// CANCEL FROM PLANNING MODE!
|
|
if ( InUIPlanMode( ) )
|
|
{
|
|
EndUIPlan( );
|
|
}
|
|
else if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case MOVE_MODE:
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
BeginUIPlan( pSoldier );
|
|
AddUIPlan( usMapPos, UIPLAN_ACTION_MOVETO );
|
|
}
|
|
break;
|
|
case ACTION_MODE:
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
BeginUIPlan( pSoldier );
|
|
AddUIPlan( usMapPos, UIPLAN_ACTION_FIRE );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SetBurstMode()
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
ChangeWeaponMode( MercPtrs[ gusSelectedSoldier ] );
|
|
}
|
|
}
|
|
|
|
void SetScopeMode( INT32 usMapPos )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
if ( GetMouseMapPos( &usMapPos ))
|
|
ChangeScopeMode( MercPtrs[ gusSelectedSoldier ], usMapPos );
|
|
else
|
|
ChangeScopeMode( MercPtrs[ gusSelectedSoldier ], NOWHERE );
|
|
|
|
// reevaluate sight
|
|
ManLooksForOtherTeams( MercPtrs[ gusSelectedSoldier ] );
|
|
}
|
|
}
|
|
|
|
void ObliterateSector()
|
|
{
|
|
INT32 cnt;
|
|
SOLDIERTYPE *pTSoldier;
|
|
|
|
// Kill everybody!
|
|
cnt = gTacticalStatus.Team[ gbPlayerNum ].bLastID + 1;
|
|
|
|
#ifdef JA2BETAVERSION
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Obliterating Sector!" );
|
|
#endif
|
|
|
|
for ( pTSoldier = MercPtrs[ cnt ]; cnt < MAX_NUM_SOLDIERS; pTSoldier++, cnt++ )
|
|
{
|
|
if ( pTSoldier->bActive && !pTSoldier->aiData.bNeutral && (pTSoldier->bSide != gbPlayerNum ) )
|
|
{
|
|
// ANITILE_PARAMS AniParams;
|
|
// memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) );
|
|
// AniParams.sGridNo = pTSoldier->sGridNo;
|
|
// AniParams.ubLevelID = ANI_STRUCT_LEVEL;
|
|
// AniParams.usTileType = FIRSTEXPLOSION;
|
|
// AniParams.usTileIndex = FIRSTEXPLOSION1;
|
|
// AniParams.sDelay = 80;
|
|
// AniParams.sStartFrame = 0;
|
|
// AniParams.uiFlags = ANITILE_FORWARD;
|
|
|
|
// CreateAnimationTile( &AniParams );
|
|
//PlayJA2Sample( EXPLOSION_1, RATE_11025, MIDVOLUME, 1, MIDDLEPAN );
|
|
|
|
pTSoldier->EVENT_SoldierGotHit( 1, 400, 0, pTSoldier->ubDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pTSoldier->bAimShotLocation, 0, NOWHERE );
|
|
}
|
|
}
|
|
}
|
|
|
|
void RandomizeMercProfile()
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
// Get selected soldier
|
|
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
// Change guy!
|
|
ForceSoldierProfileID( pSoldier, (UINT8)Random( 30 ) );
|
|
|
|
// Dirty interface
|
|
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
|
|
}
|
|
}
|
|
|
|
void CreateNextCivType()
|
|
{
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
static INT8 ubBodyType = FATCIV;
|
|
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = NO_PROFILE;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.ubBodyType = ubBodyType;
|
|
MercCreateStruct.ubDirection = SOUTH;
|
|
|
|
++ubBodyType;
|
|
|
|
if ( ubBodyType > KIDCIV )
|
|
{
|
|
ubBodyType = FATCIV;
|
|
}
|
|
|
|
MercCreateStruct.bTeam = CIV_TEAM;
|
|
MercCreateStruct.sInsertionGridNo = usMapPos;
|
|
RandomizeNewSoldierStats( &MercCreateStruct );
|
|
|
|
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
|
{
|
|
AddSoldierToSector( iNewIndex );
|
|
|
|
// So we can see them!
|
|
AllTeamsLookForAll(NO_INTERRUPTS);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ToggleCliffDebug()
|
|
{
|
|
// Set option to show all mercs
|
|
if ( gTacticalStatus.uiFlags&DEBUGCLIFFS )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Cliff debug OFF." );
|
|
|
|
gTacticalStatus.uiFlags&= (~DEBUGCLIFFS );
|
|
SetRenderFlags(RENDER_FLAG_FULL);
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Cliff debug ON." );
|
|
|
|
gTacticalStatus.uiFlags|= DEBUGCLIFFS;
|
|
}
|
|
}
|
|
|
|
void CreateCow()
|
|
{
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = NO_PROFILE;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.ubBodyType = COW;
|
|
//MercCreateStruct.bTeam = SOLDIER_CREATE_AUTO_TEAM;
|
|
MercCreateStruct.bTeam = CIV_TEAM;
|
|
MercCreateStruct.sInsertionGridNo = usMapPos;
|
|
RandomizeNewSoldierStats( &MercCreateStruct );
|
|
|
|
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
|
{
|
|
AddSoldierToSector( iNewIndex );
|
|
|
|
// So we can see them!
|
|
AllTeamsLookForAll(NO_INTERRUPTS);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreateBloodCat()
|
|
{
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = NO_PROFILE;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.ubBodyType = BLOODCAT;
|
|
//MercCreateStruct.bTeam = SOLDIER_CREATE_AUTO_TEAM;
|
|
MercCreateStruct.bTeam = CREATURE_TEAM;
|
|
MercCreateStruct.sInsertionGridNo = usMapPos;
|
|
RandomizeNewSoldierStats( &MercCreateStruct );
|
|
|
|
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
|
{
|
|
AddSoldierToSector( iNewIndex );
|
|
|
|
// So we can see them!
|
|
AllTeamsLookForAll(NO_INTERRUPTS);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreatePlayerControlledCow()
|
|
{
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = 12;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.ubBodyType = COW;
|
|
MercCreateStruct.sInsertionGridNo = usMapPos;
|
|
MercCreateStruct.bTeam = SOLDIER_CREATE_AUTO_TEAM;
|
|
MercCreateStruct.fPlayerMerc = TRUE;
|
|
|
|
RandomizeNewSoldierStats( &MercCreateStruct );
|
|
|
|
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
|
{
|
|
AddSoldierToSector( iNewIndex );
|
|
|
|
// So we can see them!
|
|
AllTeamsLookForAll(NO_INTERRUPTS);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ToggleRealTimeConfirm()
|
|
{
|
|
|
|
}
|
|
|
|
/*
|
|
void GrenadeTest1()
|
|
{
|
|
// Get mousexy
|
|
INT16 sX, sY;
|
|
if ( GetMouseXY( &sX, &sY ) )
|
|
{
|
|
OBJECTTYPE Object;
|
|
Object.usItem = MUSTARD_GRENADE;
|
|
Object[0]->data.objectStatus = 100;
|
|
Object.ubNumberOfObjects = 1;
|
|
CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, -20, 20, 158, NOBODY, THROW_ARM_ITEM, 0, FALSE );
|
|
}
|
|
}
|
|
|
|
void GrenadeTest2()
|
|
{
|
|
// Get mousexy
|
|
INT16 sX, sY;
|
|
if ( GetMouseXY( &sX, &sY ) )
|
|
{
|
|
OBJECTTYPE Object;
|
|
Object.usItem = HAND_GRENADE;
|
|
Object[0]->data.objectStatus = 100;
|
|
Object.ubNumberOfObjects = 1;
|
|
CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, 0, -30, 158, NOBODY, THROW_ARM_ITEM, 0, FALSE );
|
|
}
|
|
}
|
|
|
|
void GrenadeTest3()
|
|
{
|
|
// Get mousexy
|
|
INT16 sX, sY;
|
|
if ( GetMouseXY( &sX, &sY ) )
|
|
{
|
|
OBJECTTYPE Object;
|
|
Object.usItem = HAND_GRENADE;
|
|
Object[0]->data.objectStatus = 100;
|
|
Object.ubNumberOfObjects = 1;
|
|
CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, -10, 10, 158, NOBODY, THROW_ARM_ITEM, 0, FALSE );
|
|
}
|
|
}
|
|
*/
|
|
void CreatePlayerControlledMonster()
|
|
{
|
|
INT32 usMapPos;
|
|
if ( GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = NO_PROFILE;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
|
|
//Note: only gets called if Alt and/or Ctrl isn't pressed!
|
|
if ( _KeyDown( INSERT ) )
|
|
MercCreateStruct.ubBodyType = QUEENMONSTER;
|
|
//MercCreateStruct.ubBodyType = LARVAE_MONSTER;
|
|
else
|
|
MercCreateStruct.ubBodyType = ADULTFEMALEMONSTER;
|
|
MercCreateStruct.bTeam = SOLDIER_CREATE_AUTO_TEAM;
|
|
MercCreateStruct.sInsertionGridNo = usMapPos;
|
|
RandomizeNewSoldierStats( &MercCreateStruct );
|
|
|
|
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
|
{
|
|
AddSoldierToSector( iNewIndex );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT16 usMapPos, BOOLEAN fMovementMode, UINT8 ubSeatIndex )
|
|
{
|
|
// Look for an item pool
|
|
INT32 sActionGridNo;
|
|
UINT8 ubDirection;
|
|
SOLDIERTYPE *pTSoldier;
|
|
INT16 sAPCost = 0;
|
|
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
|
|
|
// 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 )
|
|
{
|
|
// Find a gridno closest to sweetspot...
|
|
sActionGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, pTSoldier, TRUE );
|
|
|
|
if (!TileIsOutOfBounds(sActionGridNo))
|
|
{
|
|
// Calculate AP costs...
|
|
//sAPCost = GetAPsToBeginFirstAid( pSoldier );
|
|
sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
|
|
|
|
if ( EnoughPoints( pSoldier, sAPCost, 0, TRUE ) )
|
|
{
|
|
pSoldier->DoMercBattleSound( BATTLE_SOUND_OK1 );
|
|
|
|
// CHECK IF WE ARE AT THIS GRIDNO NOW
|
|
if ( pSoldier->sGridNo != sActionGridNo )
|
|
{
|
|
// SEND PENDING ACTION
|
|
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
|
|
pSoldier->EVENT_InternalGetNewSoldierPath( sActionGridNo, pSoldier->usUIMovementMode, 3 , pSoldier->flags.fNoAPToFinishMove );
|
|
}
|
|
else
|
|
{
|
|
pSoldier->EVENT_SoldierEnterVehicle( pTSoldier->sGridNo, ubDirection, ubSeatIndex );
|
|
}
|
|
|
|
// OK, set UI
|
|
SetUIBusy( pSoldier->ubID );
|
|
//guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
|
|
|
|
return( -1 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
void HandleRadioCursorClick(INT32 usMapPos, UINT32 *puiNewEvent)
|
|
{
|
|
SOLDIERTYPE * pSoldier = NULL;
|
|
GetSoldier(&pSoldier, gusSelectedSoldier);
|
|
|
|
if (pSoldier &&
|
|
pTMilitiaSoldier &&
|
|
pTMilitiaSoldier->bActive &&
|
|
pTMilitiaSoldier->bInSector &&
|
|
pTMilitiaSoldier->stats.bLife >= OKLIFE)
|
|
{
|
|
INT32 sMoveSpot = usMapPos;
|
|
BOOLEAN fClimbingNecessary;
|
|
INT32 sClimbSpot;
|
|
INT32 iPathCost = EstimatePathCostToLocation(pTMilitiaSoldier, sMoveSpot, (INT8)gsInterfaceLevel, FALSE, &fClimbingNecessary, &sClimbSpot);
|
|
|
|
// See if we can get there
|
|
if (iPathCost > 0)
|
|
{
|
|
// sevenfm: change from stationary/patrol etc
|
|
pTMilitiaSoldier->aiData.bOrders = STATIONARY;
|
|
pTMilitiaSoldier->aiData.bAttitude = DEFENSIVE;
|
|
|
|
// sevenfm: set this spot as original point
|
|
pTMilitiaSoldier->aiData.sPatrolGrid[0] = sMoveSpot;
|
|
|
|
CancelAIAction(pTMilitiaSoldier, TRUE);
|
|
if (fClimbingNecessary)
|
|
{
|
|
pTMilitiaSoldier->aiData.bNextAction = AI_ACTION_MOVE_TO_CLIMB;
|
|
pTMilitiaSoldier->aiData.usNextActionData = sClimbSpot;
|
|
pTMilitiaSoldier->sAbsoluteFinalDestination = sMoveSpot;
|
|
|
|
BeginMultiPurposeLocator(sClimbSpot, pTMilitiaSoldier->pathing.bLevel, FALSE);
|
|
}
|
|
else
|
|
{
|
|
pTMilitiaSoldier->aiData.bNextAction = AI_ACTION_SEEK_OPPONENT;
|
|
pTMilitiaSoldier->aiData.usNextActionData = sMoveSpot;
|
|
|
|
BeginMultiPurposeLocator(sMoveSpot, pTMilitiaSoldier->pathing.bLevel, FALSE);
|
|
}
|
|
RESETTIMECOUNTER(pTMilitiaSoldier->timeCounters.AICounter, 100);
|
|
|
|
//pTMilitiaSoldier->usSoldierFlagMask |= SOLDIER_MILITIA_ORDER;
|
|
}
|
|
else
|
|
{
|
|
pTMilitiaSoldier->DoMercBattleSound(BATTLE_SOUND_CURSE1);
|
|
}
|
|
}
|
|
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
|
|
return;
|
|
}
|
|
|
|
void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
LEVELNODE *pIntTile;
|
|
INT32 sIntTileGridNo;
|
|
INT32 sActionGridNo;
|
|
UINT8 ubDirection;
|
|
INT16 sAPCost;
|
|
INT32 sAdjustedGridNo;
|
|
STRUCTURE *pStructure = NULL;
|
|
ITEM_POOL *pItemPool;
|
|
BOOLEAN fIgnoreItems = FALSE;
|
|
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
// If we are out of breath, no cursor...
|
|
if ( pSoldier->bBreath < OKBREATH && pSoldier->bCollapsed )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, FALSE, 0 ) == -1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Check if we are on a merc... if so.. steal!
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
// Flugente: allow stealing if the other guy is an enemy, OR if we are on the same team
|
|
if ( (( guiUIFullTargetFlags & ENEMY_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC )) || (AllowedToStealFromTeamMate(pSoldier->ubID, (UINT8)gusUIFullTargetID) && guiUIFullTargetFlags & OWNED_MERC) )
|
|
{
|
|
sActionGridNo = FindAdjacentGridEx( pSoldier, MercPtrs[ gusUIFullTargetID ]->sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
|
|
if ( sActionGridNo == -1 )
|
|
{
|
|
sActionGridNo = sAdjustedGridNo;
|
|
}
|
|
|
|
// Steal!
|
|
sAPCost = GetAPsToStealItem( pSoldier, MercPtrs[ gusUIFullTargetID ], sActionGridNo ); // SANDRO - added target variable
|
|
|
|
if ( EnoughPoints( pSoldier, sAPCost, 0, TRUE ) )
|
|
{
|
|
MercStealFromMerc( pSoldier, MercPtrs[ gusUIFullTargetID ] );
|
|
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Default action gridno to mouse....
|
|
sActionGridNo = usMapPos;
|
|
|
|
// If we are over an interactive struct, adjust gridno to this....
|
|
pIntTile = ConditionalGetCurInteractiveTileGridNoAndStructure( &sIntTileGridNo , &pStructure, FALSE );
|
|
if ( pIntTile != NULL )
|
|
{
|
|
sActionGridNo = sIntTileGridNo;
|
|
|
|
//if ( pStructure->fFlags & ( STRUCTURE_SWITCH | STRUCTURE_ANYDOOR ) )
|
|
if ( pStructure->fFlags & ( STRUCTURE_SWITCH ) )
|
|
{
|
|
fIgnoreItems = TRUE;
|
|
}
|
|
|
|
if ( pStructure->fFlags & ( STRUCTURE_ANYDOOR ) && sActionGridNo != usMapPos )
|
|
{
|
|
fIgnoreItems = TRUE;
|
|
}
|
|
}
|
|
|
|
// Check if we are over an item pool
|
|
// ATE: Ignore items will be set if over a switch interactive tile...
|
|
if ( GetItemPool( sActionGridNo, &pItemPool, pSoldier->pathing.bLevel ) && ITEMPOOL_VISIBLE( pItemPool ) && !fIgnoreItems )
|
|
{
|
|
if ( AM_AN_EPC( pSoldier ) )
|
|
{
|
|
// Display message
|
|
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ EPC_CANNOT_DO_THAT ] );
|
|
}
|
|
else if ( UIOkForItemPickup( pSoldier, sActionGridNo ) )
|
|
{
|
|
INT8 bZLevel = GetLargestZLevelOfItemPool( pItemPool );
|
|
|
|
SoldierPickupItem( pSoldier, pItemPool->iItemIndex, sActionGridNo, bZLevel );
|
|
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( pIntTile != NULL && !( pStructure->fFlags & STRUCTURE_HASITEMONTOP ) )
|
|
{
|
|
sActionGridNo = FindAdjacentGridEx( pSoldier, sIntTileGridNo, &ubDirection, NULL, FALSE, TRUE );
|
|
if ( sActionGridNo == -1 )
|
|
{
|
|
sActionGridNo = sIntTileGridNo;
|
|
}
|
|
|
|
// If this is not the same tile as ours, check if we can get to dest!
|
|
if ( sActionGridNo != pSoldier->sGridNo && gsCurrentActionPoints == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
}
|
|
else
|
|
{
|
|
if ( SelectedMercCanAffordMove( ) )
|
|
{
|
|
*puiNewEvent = C_MOVE_MERC;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// ATE: Here, the poor player wants to search something that does not exist...
|
|
// Why should we not let them make fools of themselves....?
|
|
if ( AM_AN_EPC( pSoldier ) )
|
|
{
|
|
// Display message
|
|
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ EPC_CANNOT_DO_THAT ] );
|
|
}
|
|
else
|
|
{
|
|
// Check morale, if < threashold, refuse...
|
|
if ( pSoldier->aiData.bMorale < 30 )
|
|
{
|
|
TacticalCharacterDialogue( pSoldier, QUOTE_REFUSING_ORDER );
|
|
}
|
|
else
|
|
{
|
|
if ( gsCurrentActionPoints == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
}
|
|
else
|
|
{
|
|
SoldierPickupItem( pSoldier, NOTHING, sActionGridNo, 0 );
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 );
|
|
|
|
|
|
void ExchangeMessageBoxCallBack( UINT8 bExitValue )
|
|
{
|
|
if ( bExitValue == MSG_BOX_RETURN_YES )
|
|
{
|
|
SwapMercPositions( gpExchangeSoldier1, gpExchangeSoldier2 );
|
|
}
|
|
}
|
|
|
|
|
|
INT8 HandleMoveModeInteractiveClick( INT32 usMapPos, UINT32 *puiNewEvent )
|
|
{
|
|
// Look for an item pool
|
|
ITEM_POOL *pItemPool;
|
|
BOOLEAN fContinue = TRUE;
|
|
SOLDIERTYPE *pSoldier;
|
|
LEVELNODE *pIntTile;
|
|
INT32 sIntTileGridNo;
|
|
INT32 sActionGridNo;
|
|
UINT8 ubDirection;
|
|
INT8 bReturnCode = 0;
|
|
INT8 bZLevel;
|
|
STRUCTURE *pStructure = NULL;
|
|
|
|
if( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
// If we are out of breath, no cursor...
|
|
// if ( pSoldier->bBreath < OKBREATH )
|
|
//{
|
|
// return( -1 );
|
|
//}
|
|
|
|
// ATE: If we are a vehicle, no moving!
|
|
if ( !gGameExternalOptions.fAllowDrivingVehiclesInTactical && pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ VEHICLE_CANT_MOVE_IN_TACTICAL ] );
|
|
return( -3 );
|
|
}
|
|
|
|
//if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) )
|
|
if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_PASSENGER ) )
|
|
{
|
|
// anv: there's some weird bug with moving invisible passengers after loading game, that should solve it
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ VEHICLE_CANT_MOVE_IN_TACTICAL ] );
|
|
// actually, you know what, let's switch to vehicle using the occasion
|
|
HandleLocateSelectMerc( GetDriver(MercPtrs[ pSoldier->ubID ]->iVehicleId)->ubID, 0 );
|
|
return( -3 );
|
|
}
|
|
|
|
if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER ) )
|
|
{
|
|
pSoldier = GetSoldierStructureForVehicle( MercPtrs[ pSoldier->ubID ]->iVehicleId );
|
|
}
|
|
|
|
// OK, check for height differences.....
|
|
if ( gpWorldLevelData[ usMapPos ].sHeight != gpWorldLevelData[ pSoldier->sGridNo ].sHeight )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_GET_THERE ] );
|
|
return( -1 );
|
|
}
|
|
|
|
// See if we are over a vehicle, and walk up to it and enter....
|
|
if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, TRUE, 0 ) == -1 )
|
|
{
|
|
return( -1 );
|
|
}
|
|
|
|
// Check if we are over a civillian....
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
if ( ValidQuickExchangePosition( ) )
|
|
{
|
|
// Check if we can...
|
|
if ( CanExchangePlaces( pSoldier, MercPtrs[ gusUIFullTargetID ], TRUE ) )
|
|
{
|
|
gpExchangeSoldier1 = pSoldier;
|
|
gpExchangeSoldier2 = MercPtrs[ gusUIFullTargetID ];
|
|
|
|
// Do message box...
|
|
//DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ EXCHANGE_PLACES_REQUESTER ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, ExchangeMessageBoxCallBack, NULL );
|
|
SwapMercPositions( gpExchangeSoldier1, gpExchangeSoldier2 );
|
|
}
|
|
}
|
|
return( -3 );
|
|
}
|
|
|
|
pIntTile = GetCurInteractiveTileGridNoAndStructure( &sIntTileGridNo, &pStructure );
|
|
|
|
if ( pIntTile != NULL )
|
|
{
|
|
bReturnCode = -3;
|
|
|
|
// Check if we are over an item pool, take precedence over that.....
|
|
// EXCEPT FOR SWITCHES!
|
|
if ((pStructure->fFlags & STRUCTURE_OPEN || !(pStructure->fFlags & STRUCTURE_OPENABLE)) && !(pStructure->fFlags & (STRUCTURE_SWITCH|STRUCTURE_ANYDOOR)) && GetItemPool(sIntTileGridNo, &pItemPool, pSoldier->pathing.bLevel))
|
|
{
|
|
if ( AM_AN_EPC( pSoldier ) )
|
|
{
|
|
// Display message
|
|
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ EPC_CANNOT_DO_THAT ] );
|
|
bReturnCode = -1;
|
|
}
|
|
else if ( UIOkForItemPickup( pSoldier, sIntTileGridNo ) )
|
|
{
|
|
bZLevel = GetLargestZLevelOfItemPool( pItemPool );
|
|
|
|
if ( AnyItemsVisibleOnLevel( pItemPool, bZLevel ) )
|
|
{
|
|
fContinue = FALSE;
|
|
|
|
SetUIBusy( pSoldier->ubID );
|
|
|
|
if ( ( gTacticalStatus.uiFlags & INCOMBAT ) && ( gTacticalStatus.uiFlags & TURNBASED ) )
|
|
{
|
|
//puiNewEvent = C_WAIT_FOR_CONFIRM;
|
|
SoldierPickupItem( pSoldier, pItemPool->iItemIndex, sIntTileGridNo, bZLevel );
|
|
}
|
|
else
|
|
{
|
|
BeginDisplayTimedCursor( OKHANDCURSOR_UICURSOR, 300 );
|
|
|
|
SoldierPickupItem( pSoldier, pItemPool->iItemIndex, sIntTileGridNo, bZLevel );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( fContinue )
|
|
{
|
|
sActionGridNo = FindAdjacentGridEx( MercPtrs[ gusSelectedSoldier ], sIntTileGridNo, &ubDirection, NULL, FALSE, TRUE );
|
|
if ( sActionGridNo == -1 )
|
|
{
|
|
sActionGridNo = sIntTileGridNo;
|
|
}
|
|
|
|
// If this is not the same tile as ours, check if we can get to dest!
|
|
if ( sActionGridNo != MercPtrs[ gusSelectedSoldier ]->sGridNo && gsCurrentActionPoints == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
|
|
bReturnCode = -1;
|
|
}
|
|
else
|
|
{
|
|
bReturnCode = -2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return( bReturnCode );
|
|
}
|
|
|
|
|
|
BOOLEAN HandleUIReloading( SOLDIERTYPE *pSoldier )
|
|
{
|
|
INT16 bAPs = 0;
|
|
|
|
// CHECK OUR CURRENT CURSOR...
|
|
|
|
// Do we have the ammo to reload?
|
|
if ( guiCurrentUICursor == GOOD_RELOAD_UICURSOR )
|
|
{
|
|
// Check APs to reload...
|
|
bAPs = GetAPsToAutoReload( pSoldier, false );
|
|
|
|
if ( EnoughPoints( pSoldier, bAPs, 0,TRUE ) )
|
|
{
|
|
// OK, we have some ammo we can reload.... reload now!
|
|
if ( !AutoReload( pSoldier, false ) )
|
|
{
|
|
// Do we say we could not reload gun...?
|
|
}
|
|
|
|
// ATE: Re-examine cursor info!
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
}
|
|
return( TRUE );
|
|
}
|
|
|
|
if ( guiCurrentUICursor == BAD_RELOAD_UICURSOR )
|
|
{
|
|
// OK, we have been told to reload but have no ammo...
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"No ammo to reload." );
|
|
if ( Random( 3 ) == 0 )
|
|
{
|
|
TacticalCharacterDialogue( pSoldier, QUOTE_OUT_OF_AMMO );
|
|
}
|
|
return( TRUE );
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
BOOLEAN ConfirmActionCancel( INT32 usMapPos, INT32 usOldMapPos )
|
|
{
|
|
// OK, most times we want to leave confirm mode if our
|
|
// gridno is different... but if we are in the grenade throw
|
|
// confirm UI, we want a bigger radius...
|
|
//if ( InAimCubeUI( ) )
|
|
//{
|
|
// Calculate distence between both gridnos.....
|
|
// if ( GetRangeFromGridNoDiff( GetInAimCubeUIGridNo( ), usOldMapPos ) > 1 )
|
|
//if ( sMapPos != usOldMapPos )
|
|
// {
|
|
// return( TRUE );
|
|
// }
|
|
//
|
|
//else
|
|
{
|
|
if ( usMapPos != usOldMapPos )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
void ChangeCurrentSquad( INT32 iSquad )
|
|
{
|
|
// only allow if nothing in hand and the Change Squad button for whichever panel we're in must be enabled
|
|
if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons &&
|
|
( ( gsCurInterfacePanel != TEAM_PANEL ) || ( ButtonList[ iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
INT32 cnt, cnt2, iCurrentSquad;
|
|
INT32 cnt3 = -1;
|
|
|
|
// Buggler: dynamic tactical squad hotkey assignments only take into account squads present in sector
|
|
//find the actual squad ID present in tactical map
|
|
for( cnt = 0 ; cnt < NUMBER_OF_SQUADS; cnt++ )
|
|
{
|
|
for( cnt2 = 0; cnt2 < NUMBER_OF_SOLDIERS_PER_SQUAD; cnt2++ )
|
|
{
|
|
if ( Squad[ cnt ][ cnt2 ] != NULL && Squad[ cnt ][ cnt2 ]->bInSector && OK_INTERRUPT_MERC( Squad[ cnt ][ cnt2 ] ) && OK_CONTROLLABLE_MERC( Squad[ cnt ][ cnt2 ] ) )
|
|
{
|
|
cnt3++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( iSquad == cnt3 )
|
|
break;
|
|
}
|
|
|
|
if ( IsSquadOnCurrentTacticalMap( cnt ) )
|
|
{
|
|
//resort the squad in case the order has, for any reason, changed
|
|
SortSquadByID( (INT8)cnt );
|
|
|
|
iCurrentSquad = CurrentSquad( );
|
|
|
|
if ( cnt != iCurrentSquad )
|
|
{
|
|
//set active squad
|
|
SetCurrentSquad( cnt, FALSE );
|
|
|
|
if ( gGameExternalOptions.fUseXMLSquadNames && cnt < min(ON_DUTY, gSquadNameVector.size()) )
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE_STRING ], gSquadNameVector[cnt].c_str() );
|
|
else
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ACTIVE ], ( cnt + 1 ) );
|
|
|
|
ErasePath( TRUE );
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleSelectMercSlot( UINT8 ubPanelSlot, INT8 bCode )
|
|
{
|
|
UINT8 ubID;
|
|
|
|
if ( GetPlayerIDFromInterfaceTeamSlot( ubPanelSlot, &ubID ) )
|
|
{
|
|
HandleLocateSelectMerc( ubID, bCode );
|
|
|
|
ErasePath( TRUE );
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
}
|
|
|
|
void TestMeanWhile( INT32 iID )
|
|
{
|
|
MEANWHILE_DEFINITION MeanwhileDef;
|
|
INT32 cnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
MeanwhileDef.sSectorX = gModSettings.ubMeanwhilePalaceSectorX; //3
|
|
MeanwhileDef.sSectorY = gModSettings.ubMeanwhilePalaceSectorY; //16
|
|
MeanwhileDef.ubNPCNumber = QUEEN;
|
|
MeanwhileDef.usTriggerEvent = 0;
|
|
MeanwhileDef.ubMeanwhileID = (UINT8)iID;
|
|
|
|
if ( iID == INTERROGATION )
|
|
{
|
|
UINT8 numPrisoners = 0;
|
|
MeanwhileDef.sSectorX = gModSettings.ubMeanwhileInterrogatePOWSectorX; //7
|
|
MeanwhileDef.sSectorY = gModSettings.ubMeanwhileInterrogatePOWSectorY; //14
|
|
|
|
// Loop through our mercs and set gridnos once some found.....
|
|
// look for all mercs on the same team,
|
|
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
|
|
|
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
|
|
{
|
|
// Are we a POW in this sector?
|
|
if ( pSoldier->bActive && pSoldier->bInSector )
|
|
{
|
|
|
|
ChangeSoldiersAssignment( pSoldier, ASSIGNMENT_POW );
|
|
|
|
pSoldier->sSectorX = gModSettings.ubMeanwhileInterrogatePOWSectorX; //7
|
|
pSoldier->sSectorY = gModSettings.ubMeanwhileInterrogatePOWSectorY; //14
|
|
if (++numPrisoners > 2) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ScheduleMeanwhileEvent( &MeanwhileDef, 10 );
|
|
}
|
|
|
|
void EscapeUILock( )
|
|
{
|
|
//UNLOCK UI
|
|
UnSetUIBusy( (UINT8)gusSelectedSoldier );
|
|
|
|
// Decrease global busy counter...
|
|
gTacticalStatus.ubAttackBusyCount = 0;
|
|
#ifdef DEBUG_ATTACKBUSY
|
|
OutputDebugString( "Resetting attack busy due to escape of UI lock.\n");
|
|
#endif
|
|
guiPendingOverrideEvent = LU_ENDUILOCK;
|
|
UIHandleLUIEndLock( NULL );
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
#include "Map Edgepoints.h"
|
|
void ToggleMapEdgepoints()
|
|
{
|
|
#ifdef JA2EDITOR
|
|
static BOOLEAN fToggleEdgepointDisplay = FALSE;
|
|
if( fToggleEdgepointDisplay ^= TRUE )
|
|
{ //Show edgepoints
|
|
ShowMapEdgepoints();
|
|
}
|
|
else
|
|
{ //Hide edgepoints
|
|
HideMapEdgepoints();
|
|
}
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef JA2BETAVERSION
|
|
BOOLEAN gfMercsNeverQuit = FALSE;
|
|
void ToggleMercsNeverQuit()
|
|
{
|
|
if( gfMercsNeverQuit )
|
|
{
|
|
gfMercsNeverQuit = FALSE;
|
|
ScreenMsg( FONT_RED, MSG_BETAVERSION, L"Merc contract expiring enabled." );
|
|
}
|
|
else
|
|
{
|
|
gfMercsNeverQuit ^= TRUE;
|
|
ScreenMsg( FONT_RED, MSG_BETAVERSION, L"Merc contract expiring disabled." );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// silversurfer: This function handles switching between prone, crouching and standing stance. Running is handled in function HandleTBSoldierRun().
|
|
void HandleStanceChangeFromUIKeys( UINT8 ubAnimHeight )
|
|
{
|
|
// If we have multiple guys selected, make all change stance!
|
|
SOLDIERTYPE * pSoldier;
|
|
INT32 cnt;
|
|
|
|
if ( gTacticalStatus.fAtLeastOneGuyOnMultiSelect && !( gTacticalStatus.uiFlags & INCOMBAT ) )
|
|
{
|
|
// OK, loop through all guys who are 'multi-selected' and
|
|
// check if our currently selected guy is amoung the
|
|
// lucky few.. if not, change to a guy who is...
|
|
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
|
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++ )
|
|
{
|
|
if ( pSoldier->bActive && pSoldier->bInSector )
|
|
{
|
|
if ( pSoldier->flags.uiStatusFlags & SOLDIER_MULTI_SELECTED )
|
|
{
|
|
// silversurfer: If we decide to stand up or press "s" again while we are standing we should reset movement to walk mode.
|
|
// If we want to run we have to press "r" which is handled elsewhere.
|
|
if ( ubAnimHeight == ANIM_STAND )
|
|
{
|
|
if ( pSoldier->usUIMovementMode != WALKING && pSoldier->usUIMovementMode != RUNNING && pSoldier->usUIMovementMode != WALKING_WEAPON_RDY && pSoldier->usUIMovementMode != WALKING_DUAL_RDY && pSoldier->usUIMovementMode != WALKING_ALTERNATIVE_RDY )
|
|
{
|
|
UIHandleSoldierStanceChange( pSoldier->ubID, ANIM_STAND );
|
|
pSoldier->flags.fUIMovementFast = 0;
|
|
}
|
|
else
|
|
{
|
|
pSoldier->flags.fUIMovementFast = 0;
|
|
pSoldier->usUIMovementMode = WALKING;
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
}
|
|
else
|
|
UIHandleSoldierStanceChange( pSoldier->ubID, ubAnimHeight );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( gusSelectedSoldier != NOBODY )
|
|
{
|
|
pSoldier = MercPtrs[ (UINT8)gusSelectedSoldier ];
|
|
// silversurfer: If we decide to stand up or press "s" again while we are standing we should reset movement to walk mode.
|
|
// If we want to run we have to press "r" which is handled elsewhere.
|
|
if ( ubAnimHeight == ANIM_STAND )
|
|
{
|
|
if ( pSoldier->usUIMovementMode != WALKING && pSoldier->usUIMovementMode != RUNNING && pSoldier->usUIMovementMode != WALKING_WEAPON_RDY && pSoldier->usUIMovementMode != WALKING_DUAL_RDY && pSoldier->usUIMovementMode != WALKING_ALTERNATIVE_RDY )
|
|
{
|
|
UIHandleSoldierStanceChange( pSoldier->ubID, ANIM_STAND );
|
|
pSoldier->flags.fUIMovementFast = 0;
|
|
}
|
|
else
|
|
{
|
|
if (pSoldier->IsCowering())
|
|
{
|
|
pSoldier->StopCoweringAnimation();
|
|
UINT16 usNewState = pSoldier->GetNewSoldierStateFromNewStance(ubAnimHeight);
|
|
pSoldier->usPendingAnimation = usNewState;
|
|
}
|
|
|
|
pSoldier->flags.fUIMovementFast = 0;
|
|
pSoldier->usUIMovementMode = WALKING;
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pSoldier->IsCowering())
|
|
{
|
|
pSoldier->StopCoweringAnimation();
|
|
UINT16 usNewState = pSoldier->GetNewSoldierStateFromNewStance(ubAnimHeight);
|
|
if (gAnimControl[pSoldier->usAnimState].ubEndHeight != ubAnimHeight)
|
|
pSoldier->usPendingAnimation = usNewState;
|
|
}
|
|
else if (pSoldier->bCollapsed && pSoldier->bBreath >= OKBREATH)
|
|
{
|
|
pSoldier->BeginSoldierGetup();
|
|
}
|
|
else
|
|
{
|
|
UIHandleSoldierStanceChange(pSoldier->ubID, ubAnimHeight);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ToggleStealthMode( SOLDIERTYPE *pSoldier )
|
|
{
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ giSMStealthButton ]->uiFlags & BUTTON_ENABLED ) )
|
|
{
|
|
if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// ATE: Toggle stealth
|
|
if ( gpSMCurrentMerc != NULL && pSoldier->ubID == gpSMCurrentMerc->ubID )
|
|
{
|
|
gfUIStanceDifferent = TRUE;
|
|
}
|
|
|
|
pSoldier->bStealthMode = ! pSoldier->bStealthMode;
|
|
gfPlotNewMovement = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
|
|
if ( pSoldier->bStealthMode )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_ON_STEALTHMODE ], pSoldier->GetName() );
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_OFF_STEALTHMODE ], pSoldier->GetName() );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void HandleStealthChangeFromUIKeys( )
|
|
{
|
|
// If we have multiple guys selected, make all change stance!
|
|
SOLDIERTYPE * pSoldier;
|
|
INT32 cnt;
|
|
|
|
if ( gTacticalStatus.fAtLeastOneGuyOnMultiSelect && !( gTacticalStatus.uiFlags & INCOMBAT ) )
|
|
{
|
|
// OK, loop through all guys who are 'multi-selected' and
|
|
// check if our currently selected guy is amoung the
|
|
// lucky few.. if not, change to a guy who is...
|
|
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
|
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++ )
|
|
{
|
|
if ( pSoldier->bActive && !AM_A_ROBOT( pSoldier ) && pSoldier->bInSector )
|
|
{
|
|
if ( pSoldier->flags.uiStatusFlags & SOLDIER_MULTI_SELECTED )
|
|
{
|
|
ToggleStealthMode( pSoldier );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( gusSelectedSoldier != NOBODY )
|
|
{
|
|
if ( !AM_A_ROBOT( MercPtrs[ gusSelectedSoldier ] ) )
|
|
{
|
|
ToggleStealthMode( MercPtrs[ gusSelectedSoldier ] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void TestCapture( )
|
|
{
|
|
INT32 cnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
UINT32 uiNumChosen = 0;
|
|
|
|
//StartQuest( QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY );
|
|
//EndQuest( QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY );
|
|
|
|
BeginCaptureSquence( );
|
|
|
|
gStrategicStatus.uiFlags &= (~STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE );
|
|
|
|
// loop through soldiers and pick 3 lucky ones....
|
|
for ( cnt = gTacticalStatus.Team[gbPlayerNum].bFirstID, pSoldier=MercPtrs[cnt]; cnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; cnt++, pSoldier++ )
|
|
{
|
|
if ( pSoldier->stats.bLife >= OKLIFE && pSoldier->bActive && pSoldier->bInSector )
|
|
{
|
|
if ( uiNumChosen < 3 )
|
|
{
|
|
EnemyCapturesPlayerSoldier( pSoldier );
|
|
|
|
// Remove them from tectical....
|
|
pSoldier->RemoveSoldierFromGridNo( );
|
|
|
|
uiNumChosen++;
|
|
}
|
|
}
|
|
}
|
|
|
|
EndCaptureSequence( );
|
|
}
|
|
|
|
|
|
void PopupAssignmentMenuInTactical( SOLDIERTYPE *pSoldier )
|
|
{
|
|
// do something
|
|
fShowAssignmentMenu = TRUE;
|
|
CreateDestroyAssignmentPopUpBoxes( );
|
|
SetTacticalPopUpAssignmentBoxXY( );
|
|
DetermineBoxPositions( );
|
|
DetermineWhichAssignmentMenusCanBeShown( );
|
|
fFirstClickInAssignmentScreenMask = TRUE;
|
|
gfIgnoreScrolling = TRUE;
|
|
}
|
|
|
|
//lal
|
|
void PopupMilitiaControlMenu( SOLDIERTYPE *pSoldier )
|
|
{
|
|
// do something
|
|
fShowMilitiaControlMenu = TRUE;
|
|
CreateDestroyMilitiaControlPopUpBoxes( );
|
|
SetTacticalPopUpMilitiaControlBoxXY( pSoldier );
|
|
DetermineMilitiaControlBoxPositions();
|
|
DetermineWhichMilitiaControlMenusCanBeShown( );
|
|
fFirstClickInMilitiaControlScreenMask = TRUE;
|
|
gfIgnoreScrolling = TRUE;
|
|
}
|
|
|
|
INT32 PickPocket(MERCPROFILESTRUCT *pProfile, UINT8 ppStart, UINT8 ppStop, UINT16 usItem, UINT8 iNumber, UINT8 * cap);
|
|
|
|
bool BadGoggles(SOLDIERTYPE *pTeamSoldier)
|
|
{
|
|
// WDS - Smart goggle switching
|
|
// NOTE: Investigate using GetItemVisionRangeBonus from Items.cpp???
|
|
if (!gGameExternalOptions.smartGoggleSwitch)
|
|
return false;
|
|
else
|
|
{
|
|
// Look through the head slots and find any sort of goggle. Check if it is bad for this time of day.
|
|
// silversurfer: also check if we are underground, sun goggles and night vision bonus are useless underground
|
|
for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot)
|
|
{
|
|
// check if we are below ground
|
|
if ( pTeamSoldier->bSectorZ > 0 )
|
|
{
|
|
// we don't want a cave vision penalty
|
|
if ( Item[pTeamSoldier->inv[headSlot].usItem].cavevisionrangebonus < 0 )
|
|
return true;
|
|
}
|
|
|
|
// if we are above ground
|
|
else
|
|
{
|
|
// at night we don't want a night vision penalty
|
|
if ( NightTime() )
|
|
{
|
|
if ( Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus < 0 )
|
|
return true;
|
|
}
|
|
// at daytime we don't want a day vision penalty
|
|
// also if we have a bright light penalty make sure that is doesn't exceed the day vision bonus
|
|
else if ( Item[pTeamSoldier->inv[headSlot].usItem].dayvisionrangebonus < 0 ||
|
|
( Item[pTeamSoldier->inv[headSlot].usItem].dayvisionrangebonus + Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus ) < 0 )
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
|
|
{
|
|
// WDS - Smart goggle switching
|
|
// NOTE: Investigate using GetItemVisionRangeBonus from Items.cpp???
|
|
// Look through the head slots and find any sort of goggle or an empty spot
|
|
OBJECTTYPE * pGoggles = 0;
|
|
int slotToUse = -1;
|
|
INT8 swapSlot = -1;
|
|
BOOLEAN isAttach = FALSE;
|
|
|
|
for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot)
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus != 0) )
|
|
{
|
|
slotToUse = headSlot;
|
|
break;
|
|
}
|
|
if ( (Item[pTeamSoldier->inv[headSlot].usItem].dayvisionrangebonus != 0) )
|
|
{
|
|
slotToUse = headSlot;
|
|
break;
|
|
}
|
|
else if ( (Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus != 0) )
|
|
{
|
|
slotToUse = headSlot;
|
|
break;
|
|
}
|
|
else if ( (Item[pTeamSoldier->inv[headSlot].usItem].cavevisionrangebonus != 0) )
|
|
{
|
|
slotToUse = headSlot;
|
|
break;
|
|
}
|
|
else if (pTeamSoldier->inv[headSlot].exists() == false)
|
|
{
|
|
slotToUse = headSlot;
|
|
}
|
|
}
|
|
|
|
if (slotToUse == -1)
|
|
{
|
|
// No place to swap in a new goggle, give up
|
|
return;
|
|
}
|
|
|
|
// Find the best goggles for the current time of day anywhere in inventory
|
|
// silversurfer: also check if underground
|
|
if (DayTime() && pTeamSoldier->bSectorZ == 0)
|
|
{
|
|
pGoggles = FindSunGogglesInInv( pTeamSoldier, &swapSlot, &isAttach, TRUE );
|
|
}
|
|
else
|
|
{
|
|
pGoggles = FindNightGogglesInInv( pTeamSoldier, &swapSlot, &isAttach, TRUE );
|
|
}
|
|
|
|
if (pGoggles)
|
|
{
|
|
// We need to check that pGoggles is compatible with whatever is in the other face slot
|
|
int otherFaceSlot = (slotToUse == HEAD1POS?HEAD2POS:HEAD1POS);
|
|
if(pTeamSoldier->inv[otherFaceSlot].exists() == true && !CompatibleFaceItem(pGoggles->usItem, pTeamSoldier->inv[otherFaceSlot].usItem))
|
|
pGoggles = NULL;
|
|
}
|
|
|
|
if (pGoggles)
|
|
{
|
|
// Now either swap or equip the best one that was found
|
|
if (pTeamSoldier->inv[slotToUse].exists())
|
|
{
|
|
if(CanItemFitInPosition(pTeamSoldier, &pTeamSoldier->inv[slotToUse], swapSlot, TRUE))
|
|
SwapObjs( pTeamSoldier, slotToUse, pGoggles, TRUE );
|
|
else if (swapSlot == HELMETPOS)
|
|
SwapObjs(pTeamSoldier, slotToUse, pGoggles, TRUE);
|
|
else if((pTeamSoldier->inv[HELMETPOS].exists()== true && pTeamSoldier->inv[HELMETPOS].AttachObject(pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE)) ||
|
|
AutoPlaceObject(pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE))
|
|
pGoggles->MoveThisObjectTo(pTeamSoldier->inv[slotToUse], 1, pTeamSoldier, slotToUse);
|
|
else
|
|
{
|
|
CHAR16 zTemp[ 100 ];
|
|
swprintf( zTemp, Message[ STR_CANNOT_ATTACH_ANY_SLOT ], ItemNames[ pTeamSoldier->inv[slotToUse].usItem ] );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, zTemp );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pGoggles->MoveThisObjectTo(pTeamSoldier->inv[slotToUse], 1, pTeamSoldier, slotToUse);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No goggles to equip, should the current ones be unequiped?
|
|
if (pTeamSoldier->inv[slotToUse].exists())
|
|
{
|
|
if ((DayTime() && Item[pTeamSoldier->inv[slotToUse].usItem].nightvisionrangebonus > 0 && pTeamSoldier->bSectorZ == 0) ||
|
|
((!DayTime() || pTeamSoldier->bSectorZ > 0) && (Item[pTeamSoldier->inv[slotToUse].usItem].brightlightvisionrangebonus > 0)))
|
|
{
|
|
// It's day and we're wearing night goggles (or vice-versa), find a place to stash them
|
|
if (pTeamSoldier->inv[ HELMETPOS ].exists())
|
|
{
|
|
if (pTeamSoldier->inv[ HELMETPOS ].AttachObject( NULL, &pTeamSoldier->inv[slotToUse] ))
|
|
{
|
|
// It worked!
|
|
}
|
|
else
|
|
{
|
|
/* //If we're here we already know we can't attach, don't we?
|
|
// Try dumping it anywhere in inventory because it doesn't attach to the helmet
|
|
if (NASValidAttachment( pTeamSoldier->inv[slotToUse].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
|
|
pTeamSoldier->inv[slotToUse][0]->attachments.size() < MAX_ATTACHMENTS)
|
|
{
|
|
pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE, 0 );
|
|
}
|
|
else
|
|
*/
|
|
//{
|
|
// Remove sungoggles.
|
|
PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE);
|
|
//}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* //again useless?
|
|
// Try dumping it anywhere in inventory given there's no helemt
|
|
if (NASValidAttachment( pTeamSoldier->inv[slotToUse].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
|
|
pTeamSoldier->inv[slotToUse][0]->attachments.size() < MAX_ATTACHMENTS)
|
|
{
|
|
pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE, 0 );
|
|
}
|
|
else
|
|
*/
|
|
//{
|
|
// Remove sungoggles.
|
|
PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE);
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fTeamPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
pTeamSoldier->DeleteSoldierLight( );
|
|
pTeamSoldier->PositionSoldierLight( );
|
|
}
|
|
|
|
// HEADROCK HAM B2.8: This function does the same as SwapGoggles, with a twist. It changes all worn goggles in the
|
|
// team uniformly, so that everyone is wearing either nightvision or dayvision, regardless of what they were wearing
|
|
// before. The check is based on the headgear of the first character in the group (he'll switch, and everyone else
|
|
// will switch to match him.
|
|
|
|
void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
|
|
{
|
|
/* CHRISL - Adjusted this option to allow the game to search through Helmet attachments
|
|
as well as inventory positions.
|
|
*/
|
|
OBJECTTYPE * pObj;
|
|
OBJECTTYPE * pGoggles = NULL;
|
|
INT8 bSlot1;
|
|
int bestBonus;
|
|
bool itemFound = false;
|
|
INT8 swapSlot = -1;
|
|
BOOLEAN isAttach = FALSE;
|
|
|
|
//CHRISL: Before doing anything, we should look at both head slots to see if either slot has some sort of goggles
|
|
for(bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++)
|
|
{
|
|
if(Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0)
|
|
itemFound = true;
|
|
if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0)
|
|
itemFound = true;
|
|
}
|
|
//2 head slots
|
|
for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++)
|
|
{
|
|
// if wearing sungoggles
|
|
if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 )
|
|
{
|
|
if (fToNightVision == TRUE) // Only if we want to switch to nightvision!
|
|
{
|
|
itemFound = true;
|
|
bestBonus = 0;
|
|
pGoggles = FindNightGogglesInInv( pTeamSoldier, &swapSlot, &isAttach );
|
|
//search for better goggles on the helmet
|
|
if (pGoggles)
|
|
{
|
|
bestBonus = Item[pGoggles->usItem].nightvisionrangebonus;
|
|
}
|
|
//search helmet and vest
|
|
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
|
|
{
|
|
pObj = &(pTeamSoldier->inv[gear]);
|
|
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
|
{
|
|
if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists())
|
|
{
|
|
pGoggles = &(*iter);
|
|
bestBonus = Item[ iter->usItem ].nightvisionrangebonus;
|
|
}
|
|
}
|
|
}
|
|
if ( pGoggles )
|
|
{
|
|
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
|
|
break;
|
|
}
|
|
else if (Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus <= 0)
|
|
{ //WarmSteel - just try and see if it works
|
|
//if (NASValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
|
|
// pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
|
|
if ( pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 ) )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Remove nightgoggles.
|
|
PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// else if wearing NVGs
|
|
else if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0)
|
|
{
|
|
if (fToNightVision == FALSE) // Only if we want to switch to dayvision!
|
|
{
|
|
itemFound = true;
|
|
bestBonus = 0;
|
|
pGoggles = FindSunGogglesInInv( pTeamSoldier, &swapSlot, &isAttach );
|
|
//search for better goggles on the helmet
|
|
if (pGoggles)
|
|
{
|
|
bestBonus = Item[pGoggles->usItem].brightlightvisionrangebonus;
|
|
}
|
|
//search helmet and vest
|
|
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
|
|
{
|
|
pObj = &(pTeamSoldier->inv[gear]);
|
|
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
|
{
|
|
if ( Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists())
|
|
{
|
|
pGoggles = &(*iter);
|
|
bestBonus = Item[ iter->usItem ].brightlightvisionrangebonus;
|
|
}
|
|
}
|
|
}
|
|
if ( pGoggles )
|
|
{
|
|
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
|
|
break;
|
|
}
|
|
else if (Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus <= 0)
|
|
{ //WarmSteel - try
|
|
//if (NASValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
|
|
// pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
|
|
if ( pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 ) )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Remove nightgoggles.
|
|
PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// else if not wearing anything and no goggles found
|
|
else if(itemFound == false && pTeamSoldier->inv[bSlot1].exists() == false)
|
|
{
|
|
bestBonus = 0;
|
|
// search helmet and vest for goggles of some kind
|
|
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
|
|
{
|
|
pObj = &(pTeamSoldier->inv[gear]);
|
|
for(attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
|
{
|
|
if(iter->exists()){
|
|
if(fToNightVision == FALSE && Item[iter->usItem].brightlightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
|
|
{
|
|
pGoggles = &(*iter);
|
|
bestBonus = Item[iter->usItem].brightlightvisionrangebonus;
|
|
}
|
|
else if(fToNightVision == TRUE && Item[iter->usItem].nightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
|
|
{
|
|
pGoggles = &(*iter);
|
|
bestBonus = Item[iter->usItem].nightvisionrangebonus;
|
|
}
|
|
}
|
|
}
|
|
if(pGoggles)
|
|
{
|
|
pGoggles->MoveThisObjectTo(pTeamSoldier->inv[bSlot1], 1, pTeamSoldier, bSlot1);
|
|
pObj->RemoveAttachment(pGoggles);
|
|
break;
|
|
}
|
|
}
|
|
if(pTeamSoldier->inv[bSlot1].exists() == false)
|
|
{
|
|
if(fToNightVision == FALSE)
|
|
pGoggles = FindSunGogglesInInv( pTeamSoldier, &swapSlot, &isAttach );
|
|
else
|
|
pGoggles = FindNightGogglesInInv( pTeamSoldier, &swapSlot, &isAttach );
|
|
if(pGoggles)
|
|
{
|
|
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fTeamPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
pTeamSoldier->DeleteSoldierLight( );
|
|
pTeamSoldier->PositionSoldierLight( );
|
|
}
|
|
|
|
void SeperateItems()
|
|
{
|
|
if ( !(gTacticalStatus.fEnemyInSector) )
|
|
{
|
|
HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
|
for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) //for all items in sector
|
|
{
|
|
if ( (gWorldItems[ uiLoop ].bVisible == TRUE) && (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_ARMED_BOMB) )//item exists, is reachable, is visible and is not trapped
|
|
{
|
|
for (int x = 0; x < gWorldItems[ uiLoop ].object.ubNumberOfObjects; ++x) {
|
|
if (( Item[ gWorldItems[ uiLoop ].object.usItem ].usItemClass == IC_GUN ) && (gGameExternalOptions.gfShiftFUnloadWeapons == TRUE) )//item is a gun and unloading is allowed
|
|
{
|
|
//Remove magazine
|
|
if ( (gWorldItems[ uiLoop ].object[x]->data.gun.usGunAmmoItem != NONE) && (gWorldItems[ uiLoop ].object[x]->data.gun.ubGunShotsLeft > 0) )
|
|
{
|
|
CreateAmmo(gWorldItems[ uiLoop ].object[x]->data.gun.usGunAmmoItem, &gTempObject, gWorldItems[ uiLoop ].object[x]->data.gun.ubGunShotsLeft);
|
|
gWorldItems[ uiLoop ].object[x]->data.gun.ubGunShotsLeft = 0;
|
|
gWorldItems[ uiLoop ].object[x]->data.gun.usGunAmmoItem = NONE;
|
|
// HEADROCK HAM 3.5: Clear ammo type
|
|
gWorldItems[ uiLoop ].object[x]->data.gun.ubGunAmmoType = NONE;
|
|
|
|
// put it on the ground
|
|
AddItemToPool( gWorldItems[ uiLoop ].sGridNo, &gTempObject, 1, gWorldItems[ uiLoop ].ubLevel, WORLD_ITEM_REACHABLE , -1 );
|
|
}
|
|
}
|
|
|
|
//remove attachments
|
|
//WarmSteel - This causes a crash when unloading attachments, then sorting, then selling all items in the sector in the map screen.
|
|
//It is likely to be caused here because when i accidentally broke this part the bug didn't occur.
|
|
//TODO : fix this.
|
|
if ( gGameExternalOptions.gfShiftFRemoveAttachments == TRUE )
|
|
{
|
|
//CHRISL: We run into a problem here because GetFreeWorldItemIndex, which gets called
|
|
// from AddItemToPool, resets gWorldItems when it increases it's size. This means
|
|
// iter loses it's relationship which causes a CTD if we use this hotkey and there
|
|
// aren't enough open WorldItems to accomodate all the attachments we're seperating.
|
|
UINT8 size = 0, cnt = 0, uiLoopCnt = 0;
|
|
// uiLoopCnt is an extra failsafe. I think I've already managed to eliminate the
|
|
// infinite loop, but just in case, we'll use uiLoopCnt to force a break after a
|
|
// certain point.
|
|
|
|
// Iterate backwards through attachments in order to detach grenades from underbarrel
|
|
// launchers before detaching the launchers (and their grenade slots) themselves.
|
|
// Since the size of the attachmentList remains constant under NAS but decrements by one
|
|
// under OAS, recheck the list size every iteration in order to calculate an rindex.
|
|
while((size = gWorldItems[uiLoop].object[x]->attachments.size()) != cnt)
|
|
{
|
|
gTempObject = *gWorldItems[uiLoop].object[x]->GetAttachmentAtIndex(size - 1 - cnt);
|
|
|
|
//WarmSteel - This actually still works with NAS, be it by accident
|
|
if (gWorldItems[ uiLoop ].object.RemoveAttachment(&gTempObject,0,x))
|
|
{
|
|
AddItemToPool( gWorldItems[ uiLoop ].sGridNo, &gTempObject, 1, gWorldItems[ uiLoop ].ubLevel, WORLD_ITEM_REACHABLE , -1 );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ ATTACHMENT_REMOVED ] );
|
|
}
|
|
else
|
|
{
|
|
cnt++;
|
|
}
|
|
|
|
uiLoopCnt ++;
|
|
if(uiLoopCnt > 100)
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Bob: also empty out LBE items in sector inventory
|
|
if (gWorldItems[uiLoop].object.IsActiveLBE(x)) {
|
|
LBENODE * lbePtr = gWorldItems[uiLoop].object.GetLBEPointer(x);
|
|
|
|
for (auto lbeInvIter = lbePtr->inv.begin(); lbeInvIter != lbePtr->inv.end(); lbeInvIter++) {
|
|
OBJECTTYPE * LBEStack = lbeInvIter._Ptr;
|
|
|
|
if (LBEStack->usItem != 0 && LBEStack->exists()) {
|
|
AddItemToPool(gWorldItems[uiLoop].sGridNo, LBEStack, 1, gWorldItems[uiLoop].ubLevel, WORLD_ITEM_REACHABLE, -1);
|
|
}
|
|
}
|
|
DestroyLBE(&(gWorldItems[uiLoop].object), x);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] );
|
|
}
|
|
}
|
|
|
|
void StackAndSort( BOOLEAN fRestrictToAmmo )
|
|
{
|
|
if (! ( gTacticalStatus.fEnemyInSector ) )
|
|
{
|
|
HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
|
|
|
for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ )
|
|
{
|
|
if ( (gWorldItems[ uiLoop ].bVisible == TRUE) && (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_ARMED_BOMB) )//item exists, is reachable, is visible and is not trapped
|
|
{
|
|
//start by putting all identical items into one large pile regardless of stacking limits so we can merge them
|
|
WORLDITEM dummyItem = gWorldItems[uiLoop];
|
|
RemoveItemFromPool(gWorldItems[uiLoop].sGridNo,(uiLoop),gWorldItems[uiLoop].ubLevel);
|
|
RemoveItemFromWorld(uiLoop);
|
|
for(UINT32 i = uiLoop+1; i < guiNumWorldItems; i++)
|
|
{
|
|
if(dummyItem.object.usItem == gWorldItems[i].object.usItem && gWorldItems[i].bVisible == TRUE && gWorldItems[i].fExists && (gWorldItems[i].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[i].usFlags & WORLD_ITEM_ARMED_BOMB))
|
|
{
|
|
dummyItem.object.AddObjectsToStack(gWorldItems[i].object,-1,NULL,NUM_INV_SLOTS,MAX_OBJECTS_PER_SLOT,false);
|
|
if(gWorldItems[i].object.exists() == false && gWorldItems[i].fExists)
|
|
{
|
|
RemoveItemFromPool(gWorldItems[i].sGridNo,i,gWorldItems[i].ubLevel);
|
|
RemoveItemFromWorld(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
//merge items in stack
|
|
if(fRestrictToAmmo == FALSE || Item[dummyItem.object.usItem].usItemClass == IC_AMMO)
|
|
CleanUpStack(&dummyItem.object, NULL);
|
|
|
|
//return item to world
|
|
AddItemToPool(dummyItem.sGridNo, &dummyItem.object, dummyItem.bVisible, dummyItem.ubLevel, dummyItem.usFlags, dummyItem.bRenderZHeightAboveLevel, dummyItem.soldierID);
|
|
|
|
//find out how many items can be put in a big slot
|
|
UINT8 ubSlotLimit = ItemSlotLimit( &gWorldItems[ uiLoop ].object, STACK_SIZE_LIMIT );
|
|
|
|
/* //if we still have some space
|
|
INT32 i = 0;
|
|
while ( gWorldItems[ uiLoop ].object.ubNumberOfObjects < ubSlotLimit )
|
|
{
|
|
i++;
|
|
//if the next item is the same
|
|
if ( gWorldItems[ uiLoop ].object.usItem == gWorldItems[ uiLoop + i ].object.usItem )
|
|
{
|
|
// Clean up ammo stacks prior to trying to merge them
|
|
if(fRestrictToAmmo == FALSE || Item[gWorldItems[uiLoop].object.usItem].usItemClass == IC_AMMO)
|
|
{
|
|
CleanUpStack(&gWorldItems[uiLoop].object, NULL);
|
|
CleanUpStack(&gWorldItems[uiLoop+i].object, NULL);
|
|
}
|
|
INT8 ubObjCount = ubSlotLimit - gWorldItems[ uiLoop ].object.ubNumberOfObjects;
|
|
INT8 bPointsToMove = __min( ubObjCount, gWorldItems[ uiLoop + i ].object.ubNumberOfObjects );
|
|
|
|
gWorldItems[ uiLoop ].object.AddObjectsToStack( (gWorldItems[ uiLoop + i ].object), bPointsToMove);
|
|
if(fRestrictToAmmo == FALSE || Item[gWorldItems[uiLoop].object.usItem].usItemClass == IC_AMMO)
|
|
CleanUpStack(&gWorldItems[uiLoop].object, NULL);
|
|
//CHRISL: After adding the object to the stack, we need to delete the old object from
|
|
// both gWorldItems and the ItemPool otherwise we cause a CTD.
|
|
if(gWorldItems[uiLoop+i].object.exists() == false && gWorldItems[ uiLoop ].fExists)
|
|
{
|
|
RemoveItemFromPool(gWorldItems[uiLoop+i].sGridNo,(uiLoop+i),gWorldItems[uiLoop+i].ubLevel);
|
|
RemoveItemFromWorld(uiLoop+i);
|
|
}
|
|
}
|
|
//CHRISL: by changing this to a condition, we can use this hotkey immediately after the
|
|
// SHITFT+F hotkey. Otherwise, if a stackable item ends up at the end of the inventory
|
|
// list, we won't be able to add it to the initial stack.
|
|
else if(uiLoop+i == guiNumWorldItems)
|
|
{
|
|
break;
|
|
}
|
|
}*/
|
|
}
|
|
}
|
|
NotifySoldiersToLookforItems( );
|
|
//HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void QueryTBMButton( UINT32 *puiNewEvent )
|
|
{
|
|
INT32 sMapPos;
|
|
|
|
if (!GetMouseMapPos( &sMapPos ) )
|
|
return;
|
|
|
|
if (gViewportRegion.ButtonState & MSYS_MIDDLE_BUTTON) // MID MOUSE BUTTON
|
|
{
|
|
if ( !fMiddleButtonDown )
|
|
{
|
|
fMiddleButtonDown = TRUE;
|
|
//RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
|
|
}
|
|
}
|
|
else if ( fMiddleButtonDown )
|
|
{
|
|
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
if(gGameExternalOptions.bAlternateMouseCommands)
|
|
HandleAltMouseTBMButton( puiNewEvent );
|
|
else
|
|
HandleMouseTBMButton( puiNewEvent );
|
|
}
|
|
fMiddleButtonDown = FALSE;
|
|
// Reset counter
|
|
//RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
|
|
}
|
|
}//void QueryTBMButton( UINT32 *puiNewEvent )
|
|
|
|
void QueryTBWheel( UINT32 *puiNewEvent )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos=0;
|
|
|
|
gViewportRegion.WheelState = gViewportRegion.WheelState * ( gGameSettings.fOptions[TOPTION_INVERT_WHEEL] ? -1 : 1 );
|
|
// stub
|
|
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
if ( gViewportRegion.WheelState != 0 )
|
|
{
|
|
//printf("wheel %d\n", gViewportRegion.WheelState);
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"wheel %d", gViewportRegion.WheelState);
|
|
if ( gpItemPointer == NULL )
|
|
{
|
|
// ATE:
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
// Switch on UI mode
|
|
switch( gCurrentUIMode )
|
|
{
|
|
|
|
case MOVE_MODE:
|
|
case CONFIRM_MOVE_MODE:
|
|
case HANDCURSOR_MODE:
|
|
case RADIOCURSOR_MODE:
|
|
if(gGameExternalOptions.bAlternateMouseCommands)
|
|
HandleAltMouseTBWheel();
|
|
else
|
|
HandleMouseTBWheel();
|
|
case IDLE_MODE:
|
|
case ACTION_MODE:
|
|
case LOCKOURTURN_UI_MODE:
|
|
case LOOKCURSOR_MODE:
|
|
case LOCKUI_MODE:
|
|
case TALKCURSOR_MODE:
|
|
case MENU_MODE:
|
|
break;
|
|
case CONFIRM_ACTION_MODE:
|
|
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if( gGameExternalOptions.bAimedBurstEnabled )
|
|
HandleWheelAdjustCursor( pSoldier, usMapPos, -gViewportRegion.WheelState, brstmode );
|
|
else
|
|
HandleWheelAdjustCursorWOAB( pSoldier, usMapPos, -gViewportRegion.WheelState);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
ResetWheelState( &gViewportRegion );
|
|
}
|
|
}
|
|
}
|
|
|
|
void QueryTBX1Button( UINT32 *puiNewEvent )
|
|
{
|
|
INT32 sMapPos;
|
|
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
if (!GetMouseMapPos( &sMapPos ) )
|
|
return;
|
|
|
|
if (gViewportRegion.ButtonState & MSYS_X1_BUTTON) // MID MOUSE BUTTON
|
|
{
|
|
if ( !fX1ButtonDown )
|
|
{
|
|
fX1ButtonDown = TRUE;
|
|
//RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( fX1ButtonDown )
|
|
{
|
|
//*puiNewEvent = LC_LOOK;
|
|
fX1ButtonDown = FALSE;
|
|
|
|
if(gGameExternalOptions.bAlternateMouseCommands)
|
|
HandleAltMouseTBX1Button( puiNewEvent );
|
|
else
|
|
HandleMouseTBX1Button( puiNewEvent );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void QueryTBX2Button( UINT32 *puiNewEvent )
|
|
{
|
|
INT32 sMapPos;
|
|
if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
if (!GetMouseMapPos( &sMapPos ) )
|
|
return;
|
|
|
|
if (gViewportRegion.ButtonState & MSYS_X2_BUTTON) // MID MOUSE BUTTON
|
|
{
|
|
if ( !fX2ButtonDown )
|
|
{
|
|
fX2ButtonDown = TRUE;
|
|
//RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
|
|
}
|
|
}
|
|
else if ( fX2ButtonDown )
|
|
{
|
|
fX2ButtonDown = FALSE;
|
|
if(gGameExternalOptions.bAlternateMouseCommands)
|
|
HandleAltMouseTBX2Button( puiNewEvent );
|
|
else
|
|
HandleMouseTBX2Button( puiNewEvent );
|
|
}
|
|
}
|
|
}
|
|
|
|
//silversurfer: this allows swapping of merc portraits in tactical screen using CTRL+LEFTARROW / CTRL+RIGHTARROW
|
|
void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection )
|
|
{
|
|
// only swap mercs when the Team Panel is active
|
|
if ( gsCurInterfacePanel != TEAM_PANEL )
|
|
return;
|
|
|
|
// if someone is talking don't swap!
|
|
if ( gpCurrentTalkingFace != NULL )
|
|
return;
|
|
|
|
UINT8 ubSourceMerc = (UINT8)gusSelectedSoldier;
|
|
UINT8 ubTargetMerc;
|
|
INT32 iSourceFace;
|
|
INT32 iTargetFace;
|
|
UINT8 ubGroupID = pSoldier->ubGroupID;
|
|
INT8 bOldPosition = GetTeamSlotFromPlayerID ( MercPtrs[ ubSourceMerc ]->ubID );
|
|
INT8 bNewPosition = bOldPosition + bDirection;
|
|
SOLDIERTYPE TempMenptr = Menptr[ 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[ pVehicleList[ pVehicle->bVehicleID ].ubVehicleType ].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 )
|
|
{
|
|
ubTargetMerc = gTeamPanel[ bNewPosition ].ubID;
|
|
|
|
// Hey, you're dead. I don't want to swap with you.
|
|
if ( MercPtrs[ubTargetMerc]->stats.bLife <= 0 )
|
|
{
|
|
RebuildCurrentSquad( );
|
|
return;
|
|
}
|
|
|
|
// store face indexes
|
|
iSourceFace = MercPtrs[ ubSourceMerc ]->iFaceIndex;
|
|
iTargetFace = MercPtrs[ ubTargetMerc ]->iFaceIndex;
|
|
FACETYPE TempFace = gFacesData[ iSourceFace ];
|
|
|
|
// swap the data
|
|
Menptr[ ubSourceMerc ] = Menptr[ ubTargetMerc ];
|
|
Menptr[ ubTargetMerc ] = TempMenptr;
|
|
// also swap face data, otherwise face gear, opp count etc won't update
|
|
gFacesData[ iSourceFace ] = gFacesData[ iTargetFace ];
|
|
gFacesData[ iTargetFace ] = TempFace;
|
|
|
|
// update IDs in the data so they match array index again
|
|
Menptr[ ubSourceMerc ].ubID = ubSourceMerc;
|
|
Menptr[ ubTargetMerc ].ubID = ubTargetMerc;
|
|
gFacesData[ iSourceFace ].iID = iSourceFace;
|
|
gFacesData[ iTargetFace ].iID = iTargetFace;
|
|
|
|
// update soldier ID so they match merc index again
|
|
gFacesData[ iSourceFace ].ubSoldierID = ubSourceMerc;
|
|
gFacesData[ iTargetFace ].ubSoldierID = ubTargetMerc;
|
|
|
|
// update face index in merc data
|
|
Menptr[ ubSourceMerc ].iFaceIndex = iSourceFace;
|
|
Menptr[ ubTargetMerc ].iFaceIndex = iTargetFace;
|
|
|
|
// update group info
|
|
RemovePlayerFromGroup( ubGroupID, MercPtrs[ ubSourceMerc ] );
|
|
RemovePlayerFromGroup( ubGroupID, MercPtrs[ ubTargetMerc ] );
|
|
AddPlayerToGroup( ubGroupID, MercPtrs[ ubSourceMerc ] );
|
|
AddPlayerToGroup( ubGroupID, MercPtrs[ ubTargetMerc ] );
|
|
SortSquadByID( MercPtrs[ ubSourceMerc ]->bAssignment );
|
|
RebuildCurrentSquad( );
|
|
|
|
// don't forget to renew selection of merc
|
|
gusSelectedSoldier = ubTargetMerc;
|
|
|
|
// refresh interface
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fTeamPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
}
|
|
|
|
|
|
// sevenfm: new mouse commands
|
|
void HandleAltMouseTBWheel( void )
|
|
{
|
|
if (!(gTacticalStatus.uiFlags & ENGAGED_IN_CONV) &&
|
|
((gsCurInterfacePanel != SM_PANEL) || (ButtonList[iSMPanelButtons[NEXTMERC_BUTTON]]->uiFlags & BUTTON_ENABLED)))
|
|
{
|
|
if (gViewportRegion.WheelState > 0) // wheel up
|
|
{
|
|
if (_KeyDown(ALT))
|
|
if (_KeyDown(SHIFT))
|
|
{
|
|
if (_KeyDown(CTRL)) // SHIFT+CTRL+ALT
|
|
;
|
|
else // SHIFT+ALT
|
|
;
|
|
}
|
|
else if (_KeyDown(CTRL)) // CTRL+ALT
|
|
HandleTBPickUpBackpacks();
|
|
else // ALT
|
|
HandleTBGotoHigherStance();
|
|
else if (_KeyDown(CTRL))
|
|
{
|
|
if (_KeyDown(SHIFT)) // SHIFT+CTRL
|
|
;
|
|
else // CTRL
|
|
HandleTBLocatePrevMerc();
|
|
}
|
|
else if (_KeyDown(SHIFT)) // SHIFT
|
|
HandleTBCycleThroughVisibleEnemiesBackward();
|
|
else
|
|
HandleTBLevelUp();
|
|
}
|
|
else // wheel down
|
|
{
|
|
if (_KeyDown(ALT))
|
|
if (_KeyDown(SHIFT))
|
|
{
|
|
if (_KeyDown(CTRL)) // SHIFT+CTRL+ALT
|
|
;
|
|
else // SHIFT+ALT
|
|
;
|
|
}
|
|
else if (_KeyDown(CTRL)) // CTRL+ALT
|
|
HandleTBDropBackpacks();
|
|
else // ALT
|
|
HandleTBGotoLowerStance();
|
|
else if (_KeyDown(CTRL))
|
|
{
|
|
if (_KeyDown(SHIFT)) // SHIFT+CTRL
|
|
;
|
|
else // CTRL
|
|
HandleTBLocateNextMerc();
|
|
}
|
|
else if (_KeyDown(SHIFT)) // SHIFT
|
|
HandleTBCycleThroughVisibleEnemies();
|
|
else
|
|
HandleTBLevelDown();
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleAltMouseTBMButton(UINT32 *puiNewEvent)
|
|
{
|
|
INT32 usMapPos;
|
|
GetMouseMapPos(&usMapPos);
|
|
|
|
if (_KeyDown(ALT))
|
|
if (_KeyDown(SHIFT))
|
|
{
|
|
if (_KeyDown(CTRL)) // SHIFT+CTRL+ALT
|
|
;
|
|
else // SHIFT+ALT
|
|
;// reserved
|
|
}
|
|
else if (_KeyDown(CTRL)) // CTRL+ALT
|
|
HandleTacticalReload();
|
|
else // ALT
|
|
HandleTBToggleFireMode();
|
|
else if (_KeyDown(CTRL))
|
|
{
|
|
if (_KeyDown(SHIFT)) // SHIFT+CTRL
|
|
;
|
|
else // CTRL
|
|
SetScopeMode(usMapPos);
|
|
}
|
|
else if (_KeyDown(SHIFT)) // SHIFT
|
|
HandleTacticalTransformItem();
|
|
else // Button
|
|
HandleTBLook(puiNewEvent);
|
|
}
|
|
|
|
void HandleAltMouseTBX1Button(UINT32 *puiNewEvent)
|
|
{
|
|
if (_KeyDown(ALT))
|
|
if (_KeyDown(SHIFT))
|
|
{
|
|
if (_KeyDown(CTRL)) // SHIFT+CTRL+ALT
|
|
;
|
|
else // SHIFT+ALT
|
|
;
|
|
}
|
|
else if (_KeyDown(CTRL)) // CTRL+ALT
|
|
ToggleTrapNetworkView();
|
|
else // ALT
|
|
HandleTBSwapGunsling();
|
|
else if (_KeyDown(CTRL))
|
|
{
|
|
if (_KeyDown(SHIFT)) // SHIFT+CTRL
|
|
;
|
|
else // CTRL
|
|
HandleTBSwapHands();
|
|
}
|
|
else if (_KeyDown(SHIFT)) // SHIFT
|
|
;
|
|
else // Button
|
|
HandleTBShowLOS();
|
|
}
|
|
|
|
void HandleAltMouseTBX2Button(UINT32 *puiNewEvent)
|
|
{
|
|
if (_KeyDown(ALT))
|
|
if (_KeyDown(SHIFT))
|
|
{
|
|
if (_KeyDown(CTRL)) // SHIFT+CTRL+ALT
|
|
;
|
|
else // SHIFT+ALT
|
|
;
|
|
}
|
|
else if (_KeyDown(CTRL)) // CTRL+ALT
|
|
ToggleHostileTrapsView();
|
|
else // ALT
|
|
HandleTBToggleFormation();
|
|
else if (_KeyDown(CTRL))
|
|
{
|
|
if (_KeyDown(SHIFT)) // SHIFT+CTRL
|
|
;
|
|
else // CTRL
|
|
HandleTBJump();
|
|
}
|
|
else if (_KeyDown(SHIFT)) // SHIFT
|
|
HandleTBJumpThroughWindow();
|
|
else // Button
|
|
HandleTBShowCover();
|
|
}
|
|
|
|
// sevenfm: these functions keep original mouse code functionality
|
|
void HandleMouseTBWheel( void )
|
|
{
|
|
UINT8 bID;
|
|
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ NEXTMERC_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
{
|
|
if ( gViewportRegion.WheelState > 0 )
|
|
{
|
|
//change stance ->DOWN
|
|
if ( _KeyDown( ALT ) )
|
|
{ if ( (gusSelectedSoldier != NOBODY) && ( gpItemPointer == NULL ) )
|
|
GotoLowerStance(MercPtrs[ gusSelectedSoldier ]);
|
|
return;
|
|
}
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
bID = FindPrevActiveAndAliveMerc( MercPtrs[ gusSelectedSoldier ], TRUE, TRUE );
|
|
HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
|
|
ErasePath(TRUE);
|
|
gfPlotNewMovement = TRUE;
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
//change stance ->UP
|
|
if ( _KeyDown( ALT ) )
|
|
{ if ( (gusSelectedSoldier != NOBODY) && ( gpItemPointer == NULL ) )
|
|
GotoHeigherStance( MercPtrs[ gusSelectedSoldier ] );
|
|
return;
|
|
}
|
|
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"wheel %d", gViewportRegion.WheelState);
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{ //Select next merc
|
|
bID = FindNextMercInTeamPanel( MercPtrs[ gusSelectedSoldier ], FALSE, FALSE );
|
|
HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
|
|
ErasePath(TRUE);
|
|
gfPlotNewMovement = TRUE;
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
//*puiNewEvent = M_ON_TERRAIN; ????????????????
|
|
}
|
|
}
|
|
|
|
void HandleMouseTBMButton( UINT32 *puiNewEvent )
|
|
{
|
|
if ( _KeyDown( ALT ) )
|
|
{
|
|
// toggle fire mode
|
|
if ( ( gpItemPointer == NULL ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ BURSTMODE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
SetBurstMode();
|
|
}
|
|
else
|
|
{
|
|
HandleTBLook( puiNewEvent );
|
|
}
|
|
}
|
|
|
|
void HandleMouseTBX1Button( UINT32 *puiNewEvent )
|
|
{
|
|
if ( !_KeyDown( ALT ) && !_KeyDown( SHIFT ))
|
|
{
|
|
UIHandleChangeLevel( NULL );
|
|
}
|
|
else if( _KeyDown( SHIFT ) )
|
|
{
|
|
HandleTBJumpThroughWindow();
|
|
}
|
|
else if (_KeyDown( ALT ) )
|
|
{
|
|
HandleTBJump();
|
|
}
|
|
}
|
|
void HandleMouseTBX2Button( UINT32 *puiNewEvent )
|
|
{
|
|
if ( _KeyDown( ALT ) )
|
|
AutoReload( MercPtrs[ gusSelectedSoldier ] );
|
|
else
|
|
HandleTBToggleStealthAll();
|
|
}
|
|
|
|
// sevenfm: common TurnBased functionality
|
|
void HandleTBLook( UINT32 *puiNewEvent )
|
|
{
|
|
//*puiNewEvent = LC_LOOK;
|
|
if(gCurrentUIMode == CONFIRM_ACTION_MODE)
|
|
brstmode=(brstmode==1)?0:1;
|
|
else
|
|
{
|
|
ErasePath( TRUE );
|
|
*puiNewEvent = LC_ON_TERRAIN;
|
|
}
|
|
}
|
|
void HandleTBJump( void )
|
|
{
|
|
SOLDIERTYPE *pjSoldier;
|
|
if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) )
|
|
{
|
|
INT16 sAPCost;
|
|
INT16 sBPCost;
|
|
BOOLEAN fNearHeigherLevel;
|
|
BOOLEAN fNearLowerLevel;
|
|
INT8 bDirection;
|
|
|
|
// Make sure the merc is not collapsed!
|
|
if (!IsValidStance(pjSoldier, ANIM_CROUCH) )
|
|
{
|
|
if ( pjSoldier->bCollapsed && pjSoldier->bBreath < OKBREATH )
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 4 ], pjSoldier->GetName() );
|
|
return;
|
|
}
|
|
|
|
// Climb on roofs
|
|
GetMercClimbDirection( pjSoldier->ubID, &fNearLowerLevel, &fNearHeigherLevel );
|
|
|
|
if ( fNearLowerLevel )
|
|
{
|
|
// CHRISL: Turn off manual jumping while wearing a backpack
|
|
if (UsingNewInventorySystem() == true && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
|
|
return;
|
|
|
|
if ( EnoughPoints( pjSoldier, GetAPsToClimbRoof( pjSoldier, TRUE ), GetBPsToClimbRoof( pjSoldier, TRUE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbDownRoof( );
|
|
}
|
|
}
|
|
|
|
if ( fNearHeigherLevel )
|
|
{
|
|
// No climbing when wearing a backpack!
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
|
|
return;
|
|
|
|
if ( EnoughPoints( pjSoldier, GetAPsToClimbRoof( pjSoldier, FALSE ), GetBPsToClimbRoof( pjSoldier, FALSE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbUpRoof( );
|
|
}
|
|
}
|
|
|
|
// Jump over fence
|
|
if ( FindFenceJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
|
|
{
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
|
|
{
|
|
sAPCost = GetAPsToJumpFence( pjSoldier, TRUE );
|
|
sBPCost = GetBPsToJumpFence( pjSoldier, TRUE );
|
|
}
|
|
else
|
|
{
|
|
sAPCost = GetAPsToJumpFence( pjSoldier, FALSE );
|
|
sBPCost = GetBPsToJumpFence( pjSoldier, FALSE );
|
|
}
|
|
|
|
if ( EnoughPoints( pjSoldier, sAPCost, sBPCost, FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbFence( );
|
|
}
|
|
}
|
|
|
|
// Climb on walls
|
|
if (gGameExternalOptions.fCanClimbOnWalls == TRUE)
|
|
{
|
|
if ( FindWallJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
|
|
{
|
|
// No climbing when wearing a backpack!
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
|
|
return;
|
|
|
|
if ( EnoughPoints( pjSoldier, GetAPsToJumpWall( pjSoldier, FALSE ), GetBPsToJumpWall( pjSoldier, FALSE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbWall( );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void HandleTBJumpThroughWindow( void ){
|
|
// WANNE: Jump through window?
|
|
if (gGameExternalOptions.fCanJumpThroughWindows == TRUE )
|
|
{
|
|
INT16 sAPCost;
|
|
INT16 sBPCost;
|
|
SOLDIERTYPE *pjSoldier;
|
|
INT8 bDirection;
|
|
|
|
if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( FindWindowJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
|
|
{
|
|
if ((UsingNewInventorySystem() == true) && pjSoldier->inv[BPACKPOCKPOS].exists() == true
|
|
//JMich.BackpackClimb
|
|
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pjSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pjSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
|
|
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pjSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
|
|
|
|
{
|
|
sAPCost = GetAPsToJumpThroughWindows( pjSoldier, TRUE );
|
|
sBPCost = GetBPsToJumpThroughWindows( pjSoldier, TRUE );
|
|
}
|
|
else
|
|
{
|
|
sAPCost = GetAPsToJumpFence( pjSoldier, FALSE );
|
|
sBPCost = GetBPsToJumpFence( pjSoldier, FALSE );
|
|
}
|
|
if (EnoughPoints(pjSoldier, sAPCost, sBPCost, FALSE))
|
|
{
|
|
pjSoldier->BeginSoldierClimbWindow();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void HandleTBToggleStealthAll( void )
|
|
{
|
|
// Toggle squad's stealth mode.....
|
|
// For each guy on squad...
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 bLoop;
|
|
BOOLEAN fStealthOn = FALSE;
|
|
|
|
// Check if at least one guy is on stealth....
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) )
|
|
{
|
|
if ( pTeamSoldier->bStealthMode )
|
|
fStealthOn = TRUE;
|
|
}
|
|
}
|
|
|
|
fStealthOn = !fStealthOn;
|
|
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
if ( gpSMCurrentMerc != NULL && bLoop == gpSMCurrentMerc->ubID )
|
|
gfUIStanceDifferent = TRUE;
|
|
pTeamSoldier->bStealthMode = fStealthOn;
|
|
}
|
|
}
|
|
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
|
|
// OK, display message
|
|
if ( fStealthOn )
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ON_STEALTHMODE ] );
|
|
else
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_OFF_STEALTHMODE ] );
|
|
}
|
|
void HandleTBToggleFireMode( void )
|
|
{
|
|
// toggle fire mode
|
|
if ( ( gpItemPointer == NULL ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ BURSTMODE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
SetBurstMode();
|
|
}
|
|
void HandleTBSelectAllMercs( void )
|
|
{
|
|
SOLDIERTYPE * pSoldier;
|
|
INT32 cnt;
|
|
|
|
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
|
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++ )
|
|
{
|
|
|
|
// Check if this guy is OK to control....
|
|
if ( OK_CONTROLLABLE_MERC( pSoldier ) && !( pSoldier->flags.uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_PASSENGER | SOLDIER_DRIVER ) ) )
|
|
{
|
|
pSoldier->flags.uiStatusFlags |= SOLDIER_MULTI_SELECTED;
|
|
}
|
|
}
|
|
EndMultiSoldierSelection( TRUE );
|
|
}
|
|
void HandleTBCycleThroughKnownEnemies( void )
|
|
{
|
|
if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
// if ( (InputEvent.usEvent == KEY_DOWN ) && InputEvent.usParam == ENTER )
|
|
CycleThroughKnownEnemies( );
|
|
}
|
|
}
|
|
void HandleTBCycleThroughKnownEnemiesBackward( void )
|
|
{
|
|
if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
// if ( (InputEvent.usEvent == KEY_DOWN ) && InputEvent.usParam == ENTER )
|
|
CycleThroughKnownEnemies( TRUE );
|
|
}
|
|
}
|
|
void HandleTBCycleThroughVisibleEnemies( void )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
if ( pSoldier->aiData.bOppCnt > 0 )
|
|
{
|
|
// Cycle....
|
|
CycleVisibleEnemies( pSoldier );
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_ENEMIES_IN_SIGHT_STR ] );
|
|
}
|
|
}
|
|
}
|
|
void HandleTBCycleThroughVisibleEnemiesBackward( void )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
if ( pSoldier->aiData.bOppCnt > 0 )
|
|
{
|
|
// Cycle....
|
|
CycleVisibleEnemiesBackward( pSoldier );
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_ENEMIES_IN_SIGHT_STR ] );
|
|
}
|
|
}
|
|
}
|
|
void HandleTBLocateSoldier( void )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
LocateSoldier( gusSelectedSoldier, 10 );
|
|
}
|
|
}
|
|
void HandleTBChangeLevel( void )
|
|
{
|
|
if ( gpItemPointer == NULL )
|
|
UIHandleChangeLevel( NULL );
|
|
}
|
|
void HandleTBSwapHands( void )
|
|
{
|
|
// swap primary & secondary hand
|
|
if ( gusSelectedSoldier != NOBODY && !AM_A_ROBOT( MercPtrs[ gusSelectedSoldier ] ))
|
|
{
|
|
SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
UINT16 usOldHandItem = pSoldier->inv[HANDPOS].usItem;
|
|
SwapHandItems( pSoldier );
|
|
pSoldier->ReLoadSoldierAnimationDueToHandItemChange( usOldHandItem, pSoldier->inv[HANDPOS].usItem );
|
|
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
}
|
|
void HandleTBSwapGunsling( void )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
if ( gusSelectedSoldier != NOBODY && UsingNewInventorySystem() == true)
|
|
{
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
pSoldier->SwitchWeapons( );
|
|
}
|
|
}
|
|
void HandleTBSwapKnife( void )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY && UsingNewInventorySystem() == true)
|
|
{
|
|
SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
pSoldier->SwitchWeapons( TRUE );
|
|
}
|
|
}
|
|
void HandleTBSwapSidearm( void )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY && UsingNewInventorySystem() == true)
|
|
{
|
|
SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
pSoldier->SwitchWeapons( FALSE, TRUE );
|
|
}
|
|
}
|
|
void HandleTBSwapGoogles( void )
|
|
{
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 bLoop;
|
|
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
// HEADROCK HAM 3.5: When this INI setting is enabled, ALL mercs in the current sector will do a goggle swap.
|
|
if (gGameExternalOptions.fGoggleSwapAffectsAllMercsInSector)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->sSectorX == gWorldSectorX && pTeamSoldier->sSectorY == gWorldSectorY && pTeamSoldier->bSectorZ == gbWorldSectorZ && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
SwapGoggles(pTeamSoldier);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
SwapGoggles(pTeamSoldier);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void HandleTBToggleFormation( void )
|
|
{
|
|
// Flugente: toggle formation
|
|
if ( gGameSettings.fOptions[TOPTION_MERCENARY_FORMATIONS] )
|
|
{
|
|
gGameSettings.fOptions[TOPTION_MERCENARY_FORMATIONS] = FALSE;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_FORMATIONS_OFF ] );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[TOPTION_MERCENARY_FORMATIONS] = TRUE;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_FORMATIONS_ON ] );
|
|
}
|
|
}
|
|
void HandleTBEnterTurnbased( void )
|
|
{
|
|
if (!is_networked)
|
|
{
|
|
// ctrl-x: enter turn based while sneaking - check if RT sneak is on, iw we're not already in combat and if we actually see any enemies
|
|
if (gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK]) // changed by SANDRO
|
|
{
|
|
BOOLEAN fSneakingInRealTime = true;
|
|
|
|
if( gTacticalStatus.uiFlags & INCOMBAT )
|
|
{ // Don't allow this in combat
|
|
if (!gGameExternalOptions.fQuietRealTimeSneak)
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_IN_COMBAT_ALREADY]);
|
|
fSneakingInRealTime = false;
|
|
}
|
|
|
|
if( WeSeeNoOne() )
|
|
{ // Don't allow this if no enemies are seen - we have the forced turn mode for that
|
|
if (!gGameExternalOptions.fQuietRealTimeSneak)
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_NO_ENEMIES]);
|
|
fSneakingInRealTime = false;
|
|
}
|
|
|
|
if (fSneakingInRealTime)
|
|
EnterCombatMode(OUR_TEAM);
|
|
}
|
|
}
|
|
}
|
|
void HandleTBToggleSneak( void )
|
|
{
|
|
if (!is_networked)
|
|
{
|
|
// SANDRO - changed the real time sneak switch to be in the preferences
|
|
if (gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK])
|
|
{
|
|
gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] = false;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_SNEAKING_OFF]);
|
|
|
|
if( !WeSeeNoOne() ) // if we're sneaking up on someone, enter turn-based
|
|
EnterCombatMode(OUR_TEAM);
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] = true;
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_SNEAKING_ON]);
|
|
}
|
|
}
|
|
}
|
|
void HandleTBToggleStealth( void )
|
|
{
|
|
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
|
|
if ( ( gpItemPointer == NULL ) )
|
|
{
|
|
HandleStealthChangeFromUIKeys( );
|
|
}
|
|
}
|
|
void HandleTBReload( void )
|
|
{
|
|
AutoReload( MercPtrs[ gusSelectedSoldier ] );
|
|
}
|
|
void HandleTBReloadAll( void )
|
|
{
|
|
if (! ( gTacticalStatus.fEnemyInSector ) )
|
|
{
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
UINT8 bLoop;
|
|
UINT16 bullets;
|
|
OBJECTTYPE *pGun, *pAmmo, *pAmmoMags;
|
|
|
|
// Search for soldier
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
// Search for gun in soldier inventory
|
|
UINT32 invsize = pTeamSoldier->inv.size();
|
|
for (UINT32 bLoop2 = 0; bLoop2 < invsize; ++bLoop2)
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & (IC_GUN | IC_LAUNCHER)) )
|
|
{
|
|
pGun = &(pTeamSoldier->inv[bLoop2]);
|
|
|
|
UINT16 gunmagsize = GetMagSize( pGun );
|
|
|
|
//if magazine is not full
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < gunmagsize )
|
|
{
|
|
// Search for ammo in sector
|
|
for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; ++uiLoop )
|
|
{
|
|
if ( (gWorldItems[ uiLoop ].bVisible == TRUE) && (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_ARMED_BOMB) )//item exists, is reachable, is visible and is not trapped
|
|
{
|
|
if ( ( Item[ gWorldItems[ uiLoop ].object.usItem ].usItemClass & IC_AMMO ) ) // the item is ammo
|
|
{
|
|
pAmmo = &( gWorldItems[ uiLoop ].object );
|
|
|
|
if ( CompatibleAmmoForGun( pAmmo, pGun ) ) // can use the ammo with this gun
|
|
{
|
|
// same ammo type in gun and magazine
|
|
if ( Magazine[Item[(*pGun)[0]->data.gun.usGunAmmoItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType )
|
|
{
|
|
ReloadGun( pTeamSoldier, pGun, pAmmo );
|
|
}
|
|
|
|
if ((*pAmmo)[0]->data.ubShotsLeft == 0)
|
|
{
|
|
RemoveItemFromPool( gWorldItems[ uiLoop ].sGridNo, uiLoop, gWorldItems[ uiLoop ].ubLevel );
|
|
}
|
|
|
|
// if gun is full, we can stop this
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft >= gunmagsize )
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//CHRISL: if not enough ammo in sector, reload using ammo carried in inventory
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < gunmagsize )
|
|
{
|
|
AutoReload( pTeamSoldier );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//MM: loop thru the soldiers again (lazy copy/paste :p). could do it all at once, but then there may not be enough ammo from the world items to fill everyone's guns first
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
// Search for ammo in soldier inventory
|
|
UINT32 invsize = pTeamSoldier->inv.size();
|
|
for (UINT32 bLoop2 = 0; bLoop2 < invsize; ++bLoop2)
|
|
{
|
|
if ( Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_AMMO )
|
|
{
|
|
pAmmoMags = &(pTeamSoldier->inv[bLoop2]);
|
|
|
|
for ( UINT16 stackMag = 0; stackMag < (*pAmmoMags).ubNumberOfObjects; stackMag++ )
|
|
{
|
|
if ( (*pAmmoMags)[stackMag]->data.ubShotsLeft < Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubMagSize )
|
|
{
|
|
// Search for ammo in sector
|
|
for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; ++uiLoop )
|
|
{
|
|
if ( (gWorldItems[ uiLoop ].bVisible == TRUE) && (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_ARMED_BOMB) )//item exists, is reachable, is visible and is not trapped
|
|
{
|
|
if ( ( Item[ gWorldItems[ uiLoop ].object.usItem ].usItemClass & IC_AMMO ) ) // the item is ammo
|
|
{
|
|
pAmmo = &( gWorldItems[ uiLoop ].object );
|
|
|
|
if ( Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubCalibre == Magazine[Item[pAmmo->usItem].ubClassIndex].ubCalibre ) // same calibre
|
|
{
|
|
// same ammo type
|
|
if ( Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType )
|
|
{
|
|
bullets = Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubMagSize - (*pAmmoMags)[stackMag]->data.ubShotsLeft;
|
|
|
|
if ((*pAmmo)[0]->data.ubShotsLeft < bullets)
|
|
bullets = (*pAmmo)[0]->data.ubShotsLeft;
|
|
|
|
(*pAmmoMags)[stackMag]->data.ubShotsLeft += bullets;
|
|
(*pAmmo)[0]->data.ubShotsLeft -= bullets;
|
|
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
|
|
if ((*pAmmo)[0]->data.ubShotsLeft == 0)
|
|
{
|
|
RemoveItemFromPool( gWorldItems[ uiLoop ].sGridNo, uiLoop, gWorldItems[ uiLoop ].ubLevel );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//MM: if magazines still are partly empty, look through inventory for boxes and crates
|
|
if ( (*pAmmoMags)[stackMag]->data.ubShotsLeft < Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubMagSize )
|
|
{
|
|
UINT32 invsize = pTeamSoldier->inv.size();
|
|
for (UINT32 uiLoop = 0; uiLoop < invsize; ++uiLoop)
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[uiLoop].usItem].usItemClass & IC_AMMO) && Magazine[Item[pTeamSoldier->inv[uiLoop].usItem].ubClassIndex].ubMagType >= AMMO_BOX )
|
|
{
|
|
pAmmo = &(pTeamSoldier->inv[uiLoop]);
|
|
|
|
if ( Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubCalibre == Magazine[Item[pAmmo->usItem].ubClassIndex].ubCalibre ) // same calibre
|
|
{
|
|
// same ammo type
|
|
if ( Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType )
|
|
{
|
|
bullets = Magazine[Item[pAmmoMags->usItem].ubClassIndex].ubMagSize - (*pAmmoMags)[stackMag]->data.ubShotsLeft;
|
|
|
|
if ((*pAmmo)[0]->data.ubShotsLeft < bullets)
|
|
bullets = (*pAmmo)[0]->data.ubShotsLeft;
|
|
|
|
(*pAmmoMags)[stackMag]->data.ubShotsLeft += bullets;
|
|
(*pAmmo)[0]->data.ubShotsLeft -= bullets;
|
|
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
|
|
if ((*pAmmo)[0]->data.ubShotsLeft == 0)
|
|
DeleteObj(pAmmo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsWeaponAttached(pGun, IC_GUN))
|
|
{
|
|
OBJECTTYPE *pGun2 = FindAttachedWeapon(pGun, IC_GUN);
|
|
|
|
UINT16 gunmagsize2 = GetMagSize( pGun2 );
|
|
|
|
if ( (*pGun2)[0]->data.gun.ubGunShotsLeft < gunmagsize2 )
|
|
{
|
|
// Search for ammo in sector
|
|
for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; ++uiLoop )
|
|
{
|
|
if ( (gWorldItems[ uiLoop ].bVisible == TRUE) && (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_ARMED_BOMB) )//item exists, is reachable, is visible and is not trapped
|
|
{
|
|
if ( ( Item[ gWorldItems[ uiLoop ].object.usItem ].usItemClass & IC_AMMO ) ) // the item is ammo
|
|
{
|
|
pAmmo = &( gWorldItems[ uiLoop ].object );
|
|
|
|
if ( CompatibleAmmoForGun( pAmmo, pGun2 ) ) // can use the ammo with this gun
|
|
{
|
|
// same ammo type in gun and magazine
|
|
if ( Magazine[Item[(*pGun2)[0]->data.gun.usGunAmmoItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType )
|
|
{
|
|
ReloadGun( pTeamSoldier, pGun2, pAmmo );
|
|
}
|
|
|
|
if ((*pAmmo)[0]->data.ubShotsLeft == 0)
|
|
{
|
|
RemoveItemFromPool( gWorldItems[ uiLoop ].sGridNo, uiLoop, gWorldItems[ uiLoop ].ubLevel );
|
|
}
|
|
|
|
// if gun is full, we can stop this
|
|
if ( (*pGun2)[0]->data.gun.ubGunShotsLeft >= gunmagsize2 )
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//CHRISL: if not enough ammo in sector, reload using ammo carried in inventory
|
|
if ( (*pGun2)[0]->data.gun.ubGunShotsLeft < gunmagsize2 )
|
|
{
|
|
AutoReload( pTeamSoldier );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
UINT8 bLoop;
|
|
OBJECTTYPE *pGun, *pAmmo;
|
|
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++bLoop, pTeamSoldier++)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[HANDPOS].usItem].usItemClass & (IC_GUN | IC_LAUNCHER) ) )
|
|
{
|
|
if ( ( gTacticalStatus.uiFlags & INCOMBAT ) )
|
|
{
|
|
// Flugente: check for underbarrel weapons and use that object if necessary
|
|
pGun = pTeamSoldier->GetUsedWeapon( &(pTeamSoldier->inv[HANDPOS]) );
|
|
|
|
//magazine is not full
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
|
|
{
|
|
AutoReload( pTeamSoldier );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Search for gun in soldier inventory
|
|
UINT32 invsize = pTeamSoldier->inv.size();
|
|
for (UINT32 bLoop2 = 0; bLoop2 < invsize; ++bLoop2)
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & (IC_GUN | IC_LAUNCHER)) )
|
|
{
|
|
pGun = &(pTeamSoldier->inv[bLoop2]);
|
|
|
|
UINT16 gunmagsize = GetMagSize( pGun );
|
|
|
|
//if magazine is not full
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < gunmagsize )
|
|
{
|
|
// Search for ammo in soldier inventory
|
|
for ( UINT32 uiLoop = 0; uiLoop < invsize; ++uiLoop )
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[uiLoop].usItem].usItemClass & IC_AMMO ) ) // the item is ammo
|
|
{
|
|
pAmmo = &(pTeamSoldier->inv[uiLoop]);
|
|
|
|
if ( CompatibleAmmoForGun( pAmmo, pGun ) ) // can use the ammo with this gun
|
|
{
|
|
// same ammo type in gun and magazine
|
|
if ( Magazine[Item[(*pGun)[0]->data.gun.usGunAmmoItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType )
|
|
{
|
|
ReloadGun( pTeamSoldier, pGun, pAmmo );
|
|
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
|
|
// if gun is full, we can stop this
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft >= gunmagsize )
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTBShowCover( void )
|
|
{
|
|
ToggleEnemyView();
|
|
}
|
|
void HandleTBShowMines( void )
|
|
{
|
|
ToggleHostileTrapsView();
|
|
}
|
|
void HandleTBShowLOS( void )
|
|
{
|
|
ToggleMercView();
|
|
}
|
|
|
|
void HandleTBToggleTrapNetworkView( void )
|
|
{
|
|
ToggleTrapNetworkView();
|
|
}
|
|
|
|
|
|
void HandleTBGotoHigherStance( void )
|
|
{
|
|
if ( (gusSelectedSoldier != NOBODY) && ( gpItemPointer == NULL ) )
|
|
GotoHeigherStance(MercPtrs[ gusSelectedSoldier ]);
|
|
}
|
|
void HandleTBGotoLowerStance( void )
|
|
{
|
|
if ( (gusSelectedSoldier != NOBODY) && ( gpItemPointer == NULL ) )
|
|
GotoLowerStance( MercPtrs[ gusSelectedSoldier ] );
|
|
}
|
|
void HandleTBLocateNextMerc( void )
|
|
{
|
|
UINT8 bID;
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{ //Select next merc
|
|
bID = FindNextMercInTeamPanel( MercPtrs[ gusSelectedSoldier ], FALSE, FALSE );
|
|
HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
void HandleTBLocatePrevMerc( void )
|
|
{
|
|
UINT8 bID;
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
bID = FindPrevActiveAndAliveMerc( MercPtrs[ gusSelectedSoldier ], TRUE, TRUE );
|
|
HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
|
|
void HandleTBLevelDown(void)
|
|
{
|
|
if (gsInterfaceLevel > 0 &&
|
|
gpItemPointer == NULL &&
|
|
(gsCurInterfacePanel != SM_PANEL || ButtonList[iSMPanelButtons[UPDOWN_BUTTON]]->uiFlags & BUTTON_ENABLED))
|
|
{
|
|
UIHandleChangeLevel(NULL);
|
|
|
|
if (gsCurInterfacePanel == SM_PANEL)
|
|
{
|
|
// Remember soldier's new value
|
|
gpSMCurrentMerc->bUIInterfaceLevel = (INT8)gsInterfaceLevel;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTBLevelUp(void)
|
|
{
|
|
if (gsInterfaceLevel == 0 &&
|
|
gpItemPointer == NULL &&
|
|
(gsCurInterfacePanel != SM_PANEL || ButtonList[iSMPanelButtons[UPDOWN_BUTTON]]->uiFlags & BUTTON_ENABLED))
|
|
{
|
|
UIHandleChangeLevel(NULL);
|
|
|
|
if (gsCurInterfacePanel == SM_PANEL)
|
|
{
|
|
// Remember soldier's new value
|
|
gpSMCurrentMerc->bUIInterfaceLevel = (INT8)gsInterfaceLevel;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTBDropBackpacks( void )
|
|
{
|
|
//if( UsingNewInventorySystem() && gusSelectedSoldier != NOBODY )
|
|
if( UsingNewInventorySystem() )
|
|
{
|
|
//SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
UINT8 ubLoop;
|
|
|
|
INT16 sAPCost = APBPConstants[AP_BACK_PACK];
|
|
INT32 iBPCost = APBPConstants[BP_BACK_PACK];
|
|
|
|
for( ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubLoop++ )
|
|
{
|
|
pTeamSoldier=MercPtrs[ ubLoop ];
|
|
|
|
if( OK_CONTROLLABLE_MERC( pTeamSoldier ) &&
|
|
OK_INTERRUPT_MERC( pTeamSoldier ) &&
|
|
!AM_A_ROBOT( pTeamSoldier ) &&
|
|
EnoughPoints(pTeamSoldier, sAPCost, iBPCost, FALSE) &&
|
|
//pTeamSoldier->bAssignment == pSoldier->bAssignment &&
|
|
pTeamSoldier->bAssignment < ON_DUTY &&
|
|
pTeamSoldier->inv[BPACKPOCKPOS].exists() &&
|
|
!pTeamSoldier->flags.DropPackFlag )
|
|
{
|
|
if( ChangeDropPackStatus(pTeamSoldier, TRUE) )
|
|
{
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_SOLDIER_DROP], pTeamSoldier->GetName());
|
|
}
|
|
}
|
|
}
|
|
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_ALL_DROP] );
|
|
}
|
|
}
|
|
|
|
void HandleTBPickUpBackpacks( void )
|
|
{
|
|
//if( UsingNewInventorySystem() && gusSelectedSoldier != NOBODY )
|
|
if( UsingNewInventorySystem() )
|
|
{
|
|
//SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
UINT8 ubLoop;
|
|
|
|
INT16 sAPCost = APBPConstants[AP_BACK_PACK];
|
|
INT32 iBPCost = APBPConstants[BP_BACK_PACK];
|
|
|
|
for( ubLoop = gTacticalStatus.Team[gbPlayerNum].bFirstID; ubLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; ubLoop++ )
|
|
{
|
|
pTeamSoldier=MercPtrs[ubLoop];
|
|
|
|
if( OK_CONTROLLABLE_MERC( pTeamSoldier ) &&
|
|
OK_INTERRUPT_MERC( pTeamSoldier ) &&
|
|
!AM_A_ROBOT( pTeamSoldier ) &&
|
|
EnoughPoints(pTeamSoldier, sAPCost, iBPCost, FALSE) &&
|
|
//pTeamSoldier->bAssignment == pSoldier->bAssignment &&
|
|
pTeamSoldier->bAssignment < ON_DUTY &&
|
|
!pTeamSoldier->inv[BPACKPOCKPOS].exists() &&
|
|
pTeamSoldier->flags.DropPackFlag )
|
|
{
|
|
if( ChangeDropPackStatus(pTeamSoldier, FALSE) )
|
|
{
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_SOLDIER_PICKUP], pTeamSoldier->GetName());
|
|
}
|
|
}
|
|
}
|
|
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, NewInvMessage[NIV_ALL_PICKUP] );
|
|
}
|
|
}
|
|
|
|
void HandleTBSoldierRun( void )
|
|
{
|
|
SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER ) )
|
|
{
|
|
pSoldier = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
|
|
}
|
|
if ( !pSoldier->MercInWater() && !(pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT ) )
|
|
{
|
|
//change selected merc to run
|
|
if ( pSoldier->usUIMovementMode != WALKING
|
|
&& pSoldier->usUIMovementMode != RUNNING
|
|
&& pSoldier->usUIMovementMode != WALKING_WEAPON_RDY
|
|
&& pSoldier->usUIMovementMode != WALKING_DUAL_RDY
|
|
&& pSoldier->usUIMovementMode != WALKING_ALTERNATIVE_RDY )
|
|
{
|
|
UIHandleSoldierStanceChange( (UINT8)pSoldier->ubID, ANIM_STAND );
|
|
pSoldier->flags.fUIMovementFast = 1;
|
|
}
|
|
else
|
|
{
|
|
if (pSoldier->IsCowering())
|
|
{
|
|
pSoldier->StopCoweringAnimation();
|
|
UINT16 usNewState = pSoldier->GetNewSoldierStateFromNewStance(ANIM_STAND);
|
|
pSoldier->usPendingAnimation = usNewState;
|
|
}
|
|
|
|
pSoldier->flags.fUIMovementFast = 1;
|
|
pSoldier->usUIMovementMode = RUNNING;
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTacticalAmmoCrates( UINT8 magType )
|
|
{
|
|
if(gTacticalStatus.fEnemyInSector)
|
|
return;
|
|
|
|
INT32 crateItem;
|
|
INT32 worldItem;
|
|
//UINT8 magType;
|
|
bool mergeSuccessful, ammoPresent;
|
|
int loopCount = 0;
|
|
OBJECTTYPE newCrate;
|
|
ammoPresent = true;
|
|
|
|
while (ammoPresent && loopCount <= 10)
|
|
{
|
|
//look through all sector items for ammo.
|
|
for(unsigned int wItem = 0; wItem < guiNumWorldItems; wItem++)
|
|
{
|
|
crateItem = 0;
|
|
mergeSuccessful = false;
|
|
if(Item[gWorldItems[wItem].object.usItem].usItemClass == IC_AMMO && gWorldItems[wItem].bVisible == TRUE && gWorldItems[wItem].fExists && (gWorldItems[wItem].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[wItem].usFlags & WORLD_ITEM_ARMED_BOMB))
|
|
{
|
|
worldItem = gWorldItems[wItem].object.usItem;
|
|
//we don't want to do anything if the world item is already an ammo crate/box
|
|
if(Magazine[Item[worldItem].ubClassIndex].ubMagType == magType)
|
|
continue;
|
|
|
|
//we have a valid, ammo item. Look through Items.xml and see if we have an ammo crate for
|
|
// this ammo type
|
|
for (UINT32 iLoop = 0; iLoop < gMAXITEMS_READ; ++iLoop)
|
|
{
|
|
//if ammo crate && calibers match && Ammo Types match
|
|
if(Item[iLoop].usItemClass == IC_AMMO && Magazine[Item[iLoop].ubClassIndex].ubMagType == magType && Magazine[Item[iLoop].ubClassIndex].ubCalibre == Magazine[Item[worldItem].ubClassIndex].ubCalibre && Magazine[Item[iLoop].ubClassIndex].ubAmmoType == Magazine[Item[worldItem].ubClassIndex].ubAmmoType)
|
|
{
|
|
crateItem = iLoop;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//if we found a crateItem in the list, we first want to see if we already have an item created
|
|
if(crateItem != 0)
|
|
{
|
|
//look through world items first
|
|
for(unsigned int loop=0; loop < guiNumWorldItems; ++loop)
|
|
{
|
|
if(gWorldItems[loop].object.usItem == crateItem)
|
|
{
|
|
DistributeStatus(&gWorldItems[wItem].object, &gWorldItems[loop].object, Magazine[Item[crateItem].ubClassIndex].ubMagSize);
|
|
if(gWorldItems[wItem].object.ubNumberOfObjects < 1)
|
|
{
|
|
mergeSuccessful = true;
|
|
RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel);
|
|
RemoveItemFromWorld(wItem);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
//no crates in sector inventory. search merc inventories
|
|
if(!mergeSuccessful)
|
|
{
|
|
for(int loop=0; loop<(int)OUR_TEAM_SIZE_NO_VEHICLE; ++loop)
|
|
{
|
|
if(MercPtrs[loop]->bActive && MercPtrs[loop]->bInSector)
|
|
{
|
|
UINT32 invsize = MercPtrs[loop]->inv.size();
|
|
for(UINT32 pocket=0; pocket < invsize; ++pocket)
|
|
{
|
|
if(MercPtrs[loop]->inv[pocket].usItem == crateItem)
|
|
{
|
|
DistributeStatus(&gWorldItems[wItem].object, &MercPtrs[loop]->inv[pocket], Magazine[Item[crateItem].ubClassIndex].ubMagSize);
|
|
if(gWorldItems[wItem].object.ubNumberOfObjects < 1)
|
|
{
|
|
mergeSuccessful = true;
|
|
RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel);
|
|
RemoveItemFromWorld(wItem);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(mergeSuccessful == true)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//no crates in merc inventory. create a new sector item
|
|
if(!mergeSuccessful)
|
|
{
|
|
CreateAmmo(crateItem, &newCrate, 0);
|
|
DistributeStatus(&gWorldItems[wItem].object, &newCrate, Magazine[Item[crateItem].ubClassIndex].ubMagSize);
|
|
AddItemToPool(gWorldItems[wItem].sGridNo, &newCrate, 1, gWorldItems[wItem].ubLevel, gWorldItems[wItem].usFlags, gWorldItems[wItem].bRenderZHeightAboveLevel);
|
|
if(gWorldItems[wItem].object.ubNumberOfObjects < 1)
|
|
{
|
|
mergeSuccessful = true;
|
|
RemoveItemFromPool(gWorldItems[wItem].sGridNo,(wItem),gWorldItems[wItem].ubLevel);
|
|
RemoveItemFromWorld(wItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we added to / created a box/crate, then we're fine to reset this
|
|
if ( mergeSuccessful )
|
|
loopCount = 0;
|
|
|
|
//MM: loop through ammo multiple times, as boxes and crates may take a few passes to fill
|
|
ammoPresent = false;
|
|
for(unsigned int wItem = 0; wItem < guiNumWorldItems; ++wItem)
|
|
{
|
|
if(Item[gWorldItems[wItem].object.usItem].usItemClass == IC_AMMO && gWorldItems[wItem].bVisible == TRUE && gWorldItems[wItem].fExists && (gWorldItems[wItem].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[wItem].usFlags & WORLD_ITEM_ARMED_BOMB))
|
|
{
|
|
worldItem = gWorldItems[wItem].object.usItem;
|
|
if(Magazine[Item[worldItem].ubClassIndex].ubMagType == magType)
|
|
continue;
|
|
|
|
loopCount++;
|
|
ammoPresent = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
StackAndSort(TRUE);
|
|
}
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] );
|
|
}
|
|
|
|
void HandleTacticalInventoryMenu( void )
|
|
{
|
|
for( INT32 cnt = 0; cnt < TACTICAL_INVENTORY_DIALOG_NUM; ++cnt)
|
|
{
|
|
wcscpy( gzUserDefinedButton[cnt], szTacticalInventoryDialogString[cnt+1] );
|
|
gzUserDefinedButtonColor[cnt] = 0;
|
|
}
|
|
|
|
gzUserDefinedButtonColor[0] = FONT_MCOLOR_LTGRAY;
|
|
gzUserDefinedButtonColor[1] = FONT_MCOLOR_LTGRAY;
|
|
gzUserDefinedButtonColor[2] = FONT_MCOLOR_LTGRAY;
|
|
gzUserDefinedButtonColor[3] = FONT_MCOLOR_LTGRAY;
|
|
gzUserDefinedButtonColor[4] = FONT_ORANGE;
|
|
gzUserDefinedButtonColor[5] = FONT_ORANGE;
|
|
gzUserDefinedButtonColor[6] = FONT_ORANGE;
|
|
gzUserDefinedButtonColor[7] = FONT_ORANGE;
|
|
|
|
gzUserDefinedButtonColor[8] = FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[9] = FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[10] = FONT_MCOLOR_LTYELLOW;
|
|
gzUserDefinedButtonColor[11] = FONT_MCOLOR_LTYELLOW;
|
|
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, szTacticalInventoryDialogString[0], GAME_SCREEN, MSG_BOX_FLAG_GENERIC_SIXTEEN_BUTTONS, TacticalInventoryMessageBoxCallBack, NULL );
|
|
}
|
|
|
|
void TacticalInventoryMessageBoxCallBack( UINT8 ubExitValue )
|
|
{
|
|
switch( ubExitValue )
|
|
{
|
|
case 1: // switch NVG
|
|
HandleTBSwapGoogles();
|
|
break;
|
|
case 2: // reload ALL
|
|
HandleTBReloadAll();
|
|
break;
|
|
case 3: // move items (Shift+m)
|
|
HandleTacticalMoveItems();
|
|
break;
|
|
case 4:
|
|
break;
|
|
case 5: // sort items
|
|
StackAndSort( TRUE );
|
|
break;
|
|
case 6: // merge items
|
|
StackAndSort( FALSE );
|
|
break;
|
|
case 7: // remove att
|
|
SeperateItems();
|
|
break;
|
|
case 8: // organize items
|
|
SeperateItems();
|
|
StackAndSort( FALSE );
|
|
break;
|
|
case 9: // ammo crates
|
|
HandleTacticalAmmoCrates( AMMO_CRATE );
|
|
break;
|
|
case 10: // ammo boxes
|
|
HandleTacticalAmmoCrates( AMMO_BOX );
|
|
break;
|
|
case 11: // drop backpacks
|
|
HandleTBDropBackpacks();
|
|
break;
|
|
case 12: // pickup backpacks
|
|
HandleTBPickUpBackpacks();
|
|
break;
|
|
case 13:
|
|
break;
|
|
case 14:
|
|
break;
|
|
case 15:
|
|
break;
|
|
case 16:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void FortificationSettingCallBack( UINT8 ubExitValue )
|
|
{
|
|
gCurrentFortificationStructure = (UINT8)(DropDownTemplate<DROPDOWNNR_MSGBOX_1>::getInstance( ).GetSelectedEntryKey( ));
|
|
gCurrentFortificationTileLibraryIndex = (UINT8)(DropDownTemplate<DROPDOWNNR_MSGBOX_2>::getInstance( ).GetSelectedEntryKey( ));
|
|
}
|
|
|
|
void HandleTacticalCoverMenu( void )
|
|
{
|
|
for( INT32 cnt = 0; cnt < TACTICAL_COVER_DIALOG_NUM; ++cnt)
|
|
{
|
|
wcscpy( gzUserDefinedButton[cnt], szTacticalCoverDialogString[cnt+1] );
|
|
gzUserDefinedButtonColor[cnt] = 0;
|
|
}
|
|
gzUserDefinedButtonColor[0] = 0;
|
|
gzUserDefinedButtonColor[1] = (gubDrawMode != COVER_DRAW_ENEMY_VIEW) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[2] = (gubDrawMode != COVER_DRAW_MERC_VIEW) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[3] = 0;
|
|
gzUserDefinedButtonColor[4] = gDisplayEnemyRoles ? FONT_MCOLOR_LTGREEN : FONT_LTRED;
|
|
gzUserDefinedButtonColor[5] = (gubDrawMode != DRAW_MODE_FORTIFY) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[6] = (gubDrawMode != DRAW_MODE_TRACKER_SMELL) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[7] = (gubDrawMode != DRAW_MODE_WEAPONDATA) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[8] = (gubDrawMode != MINES_DRAW_PLAYERTEAM_NETWORKS) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[9] = (gubDrawMode != MINES_DRAW_NETWORKCOLOURING) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[10] = (gubDrawMode != MINES_DRAW_DETECT_ENEMY) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[11] = 0;
|
|
gzUserDefinedButtonColor[12] = (gubDrawMode != MINES_DRAW_NET_A) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[13] = (gubDrawMode != MINES_DRAW_NET_B) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[14] = (gubDrawMode != MINES_DRAW_NET_C) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
gzUserDefinedButtonColor[15] = (gubDrawMode != MINES_DRAW_NET_D) ? FONT_LTRED : FONT_MCOLOR_LTGREEN;
|
|
|
|
DoMessageBox( MSG_BOX_BASIC_STYLE, szTacticalCoverDialogString[0], GAME_SCREEN, MSG_BOX_FLAG_GENERIC_SIXTEEN_BUTTONS, TacticalCoverMessageBoxCallBack, NULL );
|
|
}
|
|
|
|
void TacticalCoverMessageBoxCallBack( UINT8 ubExitValue )
|
|
{
|
|
switch( ubExitValue )
|
|
{
|
|
case 1:
|
|
gubDrawMode = DRAW_MODE_OFF;
|
|
break;
|
|
case 2:
|
|
gubDrawMode = COVER_DRAW_ENEMY_VIEW;
|
|
break;
|
|
case 3:
|
|
gubDrawMode = COVER_DRAW_MERC_VIEW;
|
|
break;
|
|
case 4:
|
|
break;
|
|
case 5:
|
|
gDisplayEnemyRoles = !gDisplayEnemyRoles;
|
|
break;
|
|
case 6:
|
|
if ( gubDrawMode == DRAW_MODE_FORTIFY )
|
|
gubDrawMode = DRAW_MODE_OFF;
|
|
else
|
|
gubDrawMode = DRAW_MODE_FORTIFY;
|
|
break;
|
|
case 7:
|
|
if ( gubDrawMode == DRAW_MODE_TRACKER_SMELL )
|
|
gubDrawMode = DRAW_MODE_OFF;
|
|
else
|
|
gubDrawMode = DRAW_MODE_TRACKER_SMELL;
|
|
break;
|
|
case 8:
|
|
if ( gubDrawMode == DRAW_MODE_WEAPONDATA )
|
|
gubDrawMode = DRAW_MODE_OFF;
|
|
else
|
|
gubDrawMode = DRAW_MODE_WEAPONDATA;
|
|
break;
|
|
case 9:
|
|
gubDrawMode = MINES_DRAW_PLAYERTEAM_NETWORKS;
|
|
break;
|
|
case 10:
|
|
gubDrawMode = MINES_DRAW_NETWORKCOLOURING;
|
|
break;
|
|
case 11:
|
|
gubDrawMode = MINES_DRAW_DETECT_ENEMY;
|
|
break;
|
|
case 12:
|
|
break;
|
|
case 13:
|
|
gubDrawMode = MINES_DRAW_NET_A;
|
|
break;
|
|
case 14:
|
|
gubDrawMode = MINES_DRAW_NET_B;
|
|
break;
|
|
case 15:
|
|
gubDrawMode = MINES_DRAW_NET_C;
|
|
break;
|
|
case 16:
|
|
gubDrawMode = MINES_DRAW_NET_D;
|
|
break;
|
|
}
|
|
|
|
DisplayCover( TRUE );
|
|
|
|
if( ubExitValue <= TACTICAL_COVER_DIALOG_NUM )
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szTacticalCoverDialogPrintString[ubExitValue-1]);
|
|
}
|
|
|
|
void ActivateCheatsMessageBoxCallBack( UINT8 ubExitValue )
|
|
{
|
|
if ( ubExitValue == MSG_BOX_RETURN_YES )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
RESET_CHEAT_LEVEL( );
|
|
}
|
|
else
|
|
{
|
|
ACTIVATE_CHEAT_LEVEL( );
|
|
|
|
// ATE; We're done.... start cheat mode....
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_CHEAT_LEVEL_TWO] );
|
|
SetHistoryFact( HISTORY_CHEAT_ENABLED, 0, GetWorldTotalMin( ), -1, -1 );
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTacticalTransformItem(void)
|
|
{
|
|
UINT16 usItem;
|
|
TransformInfoStruct *pTransformation;
|
|
|
|
SOLDIERTYPE* pSoldier;
|
|
if (!GetSoldier(&pSoldier, gusSelectedSoldier))
|
|
return;
|
|
|
|
if (!pSoldier->inv[HANDPOS].exists())
|
|
return;
|
|
|
|
// ATE: Don't do this if in a fire animation.....
|
|
if (gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_FIRE)
|
|
return;
|
|
|
|
// don't do this when EDB is active
|
|
if (gpItemDescObject)
|
|
return;
|
|
|
|
usItem = pSoldier->inv[HANDPOS].usItem;
|
|
|
|
if (FindTransformation(usItem, &pTransformation, TRUE))
|
|
{
|
|
if (pTransformation->usAPCost > 0 && gTacticalStatus.uiFlags & INCOMBAT && gTacticalStatus.uiFlags & TURNBASED)
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s (%d AP)", pTransformation->szMenuRowText, pTransformation->usAPCost);
|
|
else
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pTransformation->szMenuRowText);
|
|
|
|
// let's pretend we are calling this from EDB
|
|
gpItemDescObject = &pSoldier->inv[HANDPOS];
|
|
|
|
gpItemDescObject->TransformObject(pSoldier, 0, pTransformation, NULL);
|
|
|
|
// cleanup
|
|
gpItemDescObject = NULL;
|
|
|
|
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
}
|
|
}
|
|
|
|
BOOLEAN FindTransformation(UINT16 usItem, TransformInfoStruct **pTransformation, BOOLEAN fTactical)
|
|
{
|
|
// find transformation
|
|
for ( UINT32 x = 0; x < MAXITEMS + 1; ++x )
|
|
{
|
|
if ( Transform[x].usItem == (UINT16)-1 )
|
|
{
|
|
break;
|
|
}
|
|
if (Transform[x].usItem == usItem &&
|
|
(!fTactical ||
|
|
HasItemFlag(usItem, CORPSE) ||
|
|
Transform[x].usResult[0] != usItem && Item[Transform[x].usResult[0]].usItemClass == Item[usItem].usItemClass ||
|
|
Transform[x].usResult[0] != usItem && Item[Transform[x].usResult[0]].ItemSize == Item[usItem].ItemSize))
|
|
{
|
|
*pTransformation = &Transform[x];
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void HandleTacticalMoveItems( void )
|
|
{
|
|
// Move all sector items to current mercs feet
|
|
if ( !(gTacticalStatus.fEnemyInSector) )
|
|
{
|
|
HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
|
|
|
SOLDIERTYPE *pSoldier;
|
|
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
|
{
|
|
|
|
for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; ++uiLoop ) //for all items in sector
|
|
{
|
|
if ( (gWorldItems[ uiLoop ].bVisible == TRUE) && (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) && !(gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_ARMED_BOMB) && (gWorldItems[ uiLoop ].sGridNo != pSoldier->sGridNo) )//item exists and is reachable and is not already on soldiers tile
|
|
{
|
|
MoveItemPools(gWorldItems[ uiLoop ].sGridNo, pSoldier->sGridNo, gWorldItems[ uiLoop ].ubLevel, pSoldier->pathing.bLevel);
|
|
}
|
|
}
|
|
|
|
NotifySoldiersToLookforItems( );
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTacticalStoreInvItem( void )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
UINT8 ubStoreSlot = 0;
|
|
UINT16 APTotalCost = 0;
|
|
|
|
if( gusSelectedSoldier != NOBODY )
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
else
|
|
return;
|
|
|
|
if ( !UsingNewInventorySystem() )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEMS_ONLY_NIV ] );
|
|
return;
|
|
}
|
|
|
|
if( !pSoldier->inv[HANDPOS].exists() )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEMS_NO_ITEM_IN_HAND ] );
|
|
return;
|
|
}
|
|
|
|
if( pSoldier->usQuickItemId == pSoldier->inv[HANDPOS].usItem &&
|
|
( CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], pSoldier->ubQuickItemSlot, FALSE) && !pSoldier->inv[pSoldier->ubQuickItemSlot].exists() ) )
|
|
ubStoreSlot = pSoldier->ubQuickItemSlot;
|
|
|
|
// find slot to store HANDPOS in
|
|
for(UINT8 i = GUNSLINGPOCKPOS; i < NUM_INV_SLOTS && ubStoreSlot == 0; ++i)
|
|
{
|
|
// take first slot that hand item would fit
|
|
if ( ( CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], i, FALSE) && !pSoldier->inv[i].exists() ) )
|
|
{
|
|
ubStoreSlot = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ubStoreSlot == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEMS_NOWHERE_TO_PLACE ] );
|
|
return;
|
|
}
|
|
|
|
// calculate needed APs
|
|
if ( UsingInventoryCostsAPSystem() )
|
|
{
|
|
APTotalCost += GetInvMovementCost(&pSoldier->inv[HANDPOS], HANDPOS, ubStoreSlot );
|
|
if( !EnoughPoints( pSoldier, APTotalCost, 0, TRUE ) )
|
|
return;
|
|
|
|
// move item from HANDPOS to found ubStoreSlot
|
|
DeductPoints( pSoldier, APTotalCost, 0 );
|
|
}
|
|
|
|
pSoldier->inv[HANDPOS].MoveThisObjectTo(pSoldier->inv[ubStoreSlot], 1, pSoldier);
|
|
|
|
// swap hands
|
|
if( pSoldier->inv[SECONDHANDPOS].exists() )
|
|
SwapHandItems( pSoldier );
|
|
|
|
// update interface
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
pSoldier->HandleFlashLights();
|
|
}
|
|
|
|
void HandleTacticalTakeInvItem( INT32 iType )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
UINT8 ubItemSlot = HANDPOS;
|
|
UINT16 APTotalCost = 0;
|
|
|
|
if( iType == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEM_NO_DEFINED_ITEM ] );
|
|
return;
|
|
}
|
|
|
|
if( gusSelectedSoldier != NOBODY )
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
else
|
|
return;
|
|
|
|
if ( !UsingNewInventorySystem() )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEMS_ONLY_NIV ] );
|
|
return;
|
|
}
|
|
|
|
// check if item is already in main hand
|
|
if ( pSoldier->inv[HANDPOS].exists() &&
|
|
( iType > 0 ? ( pSoldier->inv[HANDPOS].usItem == iType ) : ( InvItemType( pSoldier->inv[HANDPOS].usItem ) == iType ) ) )
|
|
return;
|
|
|
|
if( pSoldier->inv[HANDPOS].exists() && pSoldier->inv[SECONDHANDPOS].exists() )
|
|
{
|
|
// try to free HANDPOS for new item
|
|
HandleTacticalStoreInvItem();
|
|
}
|
|
|
|
// both hands are full
|
|
if( pSoldier->inv[HANDPOS].exists() && pSoldier->inv[SECONDHANDPOS].exists() )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEM_NO_FREE_HAND ] );
|
|
return;
|
|
}
|
|
|
|
// search for type of item
|
|
for(UINT8 i = GUNSLINGPOCKPOS; i < NUM_INV_SLOTS; ++i)
|
|
{
|
|
if ( pSoldier->inv[i].exists() &&
|
|
!Item[ pSoldier->inv[i].usItem ].twohanded &&
|
|
( iType > 0 ? ( pSoldier->inv[i].usItem == iType ) : ( InvItemType( pSoldier->inv[i].usItem ) == iType ) ) )
|
|
{
|
|
ubItemSlot = i;
|
|
break;
|
|
}
|
|
}
|
|
// if not found item
|
|
if( ubItemSlot == HANDPOS )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEM_NOT_FOUND ]);
|
|
return;
|
|
}
|
|
|
|
// remember item slot and id
|
|
pSoldier->usQuickItemId = pSoldier->inv[ubItemSlot].usItem;
|
|
pSoldier->ubQuickItemSlot = ubItemSlot;
|
|
|
|
if ( UsingInventoryCostsAPSystem() )
|
|
{
|
|
APTotalCost += GetInvMovementCost(&pSoldier->inv[ubItemSlot], ubItemSlot, HANDPOS);
|
|
if( !EnoughPoints( pSoldier, APTotalCost, 0, TRUE ) )
|
|
return;
|
|
}
|
|
|
|
if( !CanItemFitInPosition( pSoldier, &pSoldier->inv[ubItemSlot], HANDPOS, FALSE ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ QUICK_ITEM_CANNOT_TAKE ] );
|
|
return;
|
|
}
|
|
|
|
// if item in main hand exists -> move it to second hand
|
|
if( pSoldier->inv[HANDPOS].exists() )
|
|
HandleTBSwapHands();
|
|
|
|
// move item to handpos
|
|
if ( UsingInventoryCostsAPSystem() )
|
|
DeductPoints( pSoldier, APTotalCost, 0 );
|
|
pSoldier->inv[ubItemSlot].MoveThisObjectTo(pSoldier->inv[HANDPOS], 1, pSoldier);
|
|
|
|
// update interface
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
pSoldier->HandleFlashLights();
|
|
}
|
|
|
|
INT32 InvItemType( UINT16 usItem )
|
|
{
|
|
if( usItem == XRAY_DEVICE )
|
|
return INV_ITEM_TYPE_XRAY;
|
|
if( Item[ usItem ].firstaidkit )
|
|
return INV_ITEM_TYPE_FIRSTAID;
|
|
if( Item[ usItem ].usItemClass == IC_BLADE )
|
|
return INV_ITEM_TYPE_MELEE;
|
|
if( Item[ usItem ].usItemClass == IC_PUNCH && !HasItemFlag( usItem, TASER ) )
|
|
return INV_ITEM_TYPE_HTH;
|
|
if( HasItemFlag( usItem, HANDCUFFS ) )
|
|
//if( Item[ usItem ].usItemClass == IC_MISC && Item[ usItem ].usItemFlag & HANDCUFFS )
|
|
return INV_ITEM_TYPE_HANDCUFFS;
|
|
//Item[ uiItem ].usSpotting
|
|
if( Item[ usItem ].usItemClass == IC_MISC && Item[ usItem ].dayvisionrangebonus )
|
|
return INV_ITEM_TYPE_BINOCULARS;
|
|
if( HasItemFlag( usItem, TASER ) )
|
|
return INV_ITEM_TYPE_TASER;
|
|
if( Item[ usItem ].usItemClass == IC_GUN && !Item[ usItem ].twohanded && Weapon[Item[ usItem ].ubClassIndex].ubWeaponType <= GUN_SMG )
|
|
return INV_ITEM_TYPE_SIDEARM;
|
|
if( Item[ usItem ].usItemClass == IC_MISC && Item[ usItem ].metaldetector )
|
|
return INV_ITEM_TYPE_METALDETECTOR;
|
|
|
|
return INV_ITEM_TYPE_UNKNOWN;
|
|
}
|
|
|
|
void HandleTacticalDropItem( UINT8 ubSlot )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
UINT16 APTotalCost = 0;
|
|
|
|
if( gusSelectedSoldier != NOBODY )
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
else
|
|
return;
|
|
|
|
if( pSoldier->inv[ ubSlot ].exists() )
|
|
{
|
|
if ( UsingInventoryCostsAPSystem() )
|
|
{
|
|
APTotalCost += GetInvMovementCost(&pSoldier->inv[ubSlot], ubSlot, HANDPOS);
|
|
APTotalCost += GetBasicAPsToPickupItem( pSoldier );
|
|
if( !EnoughPoints( pSoldier, APTotalCost, 0, TRUE ) )
|
|
return;
|
|
DeductPoints( pSoldier, APTotalCost, 0 );
|
|
}
|
|
|
|
SoldierDropItem( pSoldier, &pSoldier->inv[ ubSlot ] );
|
|
DeleteObj( &(pSoldier->inv[ ubSlot ]) );
|
|
}
|
|
}
|
|
|
|
void HandleTacticalTakeItem( void )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
if( gusSelectedSoldier != NOBODY )
|
|
pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
else
|
|
return;
|
|
|
|
if( gpItemPointer == NULL )
|
|
{
|
|
//not holding anything
|
|
if( pSoldier->inv[HANDPOS].exists() )
|
|
{
|
|
pSoldier->inv[HANDPOS].MoveThisObjectTo(gItemPointer);
|
|
gpItemPointer = &gItemPointer;
|
|
}
|
|
}
|
|
|
|
// update interface
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
pSoldier->HandleFlashLights();
|
|
|
|
// Set mouse
|
|
if( gpItemPointer->exists() )
|
|
{
|
|
guiExternVo = GetInterfaceGraphicForItem( &(Item[ gpItemPointer->usItem ]) );
|
|
gusExternVoSubIndex = g_bUsePngItemImages ? 0 : Item[ gpItemPointer->usItem ].ubGraphicNum;
|
|
|
|
MSYS_ChangeRegionCursor( &gMPanelRegion , EXTERN_CURSOR );
|
|
MSYS_SetCurrentCursor( EXTERN_CURSOR );
|
|
|
|
fMapInventoryItem=TRUE;
|
|
fTeamPanelDirty=TRUE;
|
|
}
|
|
}
|
|
|
|
void HandleTacticalReload()
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT16 bAPs = 0;
|
|
|
|
if (gusSelectedSoldier != NOBODY)
|
|
pSoldier = MercPtrs[gusSelectedSoldier];
|
|
else
|
|
return;
|
|
|
|
// Do we have the ammo to reload?
|
|
// Check APs to reload...
|
|
bAPs = GetAPsToAutoReload(pSoldier, false);
|
|
|
|
if (EnoughPoints(pSoldier, bAPs, 0, TRUE))
|
|
{
|
|
// OK, we have some ammo we can reload.... reload now!
|
|
if ( !AutoReload(pSoldier, false) )
|
|
{
|
|
// Do we say we could not reload gun...?
|
|
pSoldier->DoMercBattleSound(BATTLE_SOUND_CURSE1);
|
|
//TacticalCharacterDialogue( pSoldier, QUOTE_OUT_OF_AMMO );
|
|
}
|
|
|
|
// ATE: Re-examine cursor info!
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
}
|
|
}
|
|
|
|
extern OBJECTTYPE *gpItemDescOrigAttachmentObject;
|
|
|
|
void HandleTacticalTransformScope(void)
|
|
{
|
|
UINT16 usItem;
|
|
TransformInfoStruct *pTransformation;
|
|
OBJECTTYPE* pObj;
|
|
|
|
SOLDIERTYPE* pSoldier;
|
|
if (!GetSoldier(&pSoldier, gusSelectedSoldier))
|
|
return;
|
|
|
|
if (!pSoldier->inv[HANDPOS].exists())
|
|
return;
|
|
|
|
// ATE: Don't do this if in a fire animation.....
|
|
if (gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_FIRE)
|
|
return;
|
|
|
|
// don't do this when EDB is active
|
|
if (gpItemDescObject)
|
|
return;
|
|
|
|
usItem = pSoldier->inv[HANDPOS].usItem;
|
|
//GetMouseMapPos(&usGridNo);
|
|
|
|
// check attachments
|
|
attachmentList::iterator iter;
|
|
pObj = &(pSoldier->inv[HANDPOS]);
|
|
|
|
// check all attachments, search for available transformations
|
|
for (iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
|
{
|
|
if (iter->exists() && Item[iter->usItem].usItemClass == IC_MISC && Item[iter->usItem].attachmentclass & AC_SCOPE)
|
|
{
|
|
usItem = Item[iter->usItem].uiIndex;
|
|
|
|
// check flashlight transformation
|
|
if (FindScopeTransformation(usItem, &pTransformation) &&
|
|
pTransformation->usResult[0] != 0 &&
|
|
Item[usItem].scopemagfactor != Item[pTransformation->usResult[0]].scopemagfactor)
|
|
{
|
|
if (pTransformation->usAPCost > 0 && gTacticalStatus.uiFlags & INCOMBAT && gTacticalStatus.uiFlags & TURNBASED)
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s (%d AP)", pTransformation->szMenuRowText, pTransformation->usAPCost);
|
|
else
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pTransformation->szMenuRowText);
|
|
|
|
// let's pretend we are calling this from EDB
|
|
gpItemDescObject = pObj;
|
|
gpItemDescOrigAttachmentObject = &(*iter);
|
|
|
|
gpItemDescOrigAttachmentObject->TransformObject(pSoldier, 0, pTransformation, gpItemDescObject);
|
|
|
|
// cleanup
|
|
gpItemDescObject = NULL;
|
|
gpItemDescOrigAttachmentObject = NULL;
|
|
|
|
pSoldier->aiData.bShownAimTime = 0;
|
|
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTacticalTransformLaser(void)
|
|
{
|
|
UINT16 usItem;
|
|
TransformInfoStruct *pTransformation;
|
|
OBJECTTYPE* pObj;
|
|
|
|
SOLDIERTYPE* pSoldier;
|
|
if (!GetSoldier(&pSoldier, gusSelectedSoldier))
|
|
return;
|
|
|
|
if (!pSoldier->inv[HANDPOS].exists())
|
|
return;
|
|
|
|
// ATE: Don't do this if in a fire animation.....
|
|
if (gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_FIRE)
|
|
return;
|
|
|
|
// don't do this when EDB is active
|
|
if (gpItemDescObject)
|
|
return;
|
|
|
|
usItem = pSoldier->inv[HANDPOS].usItem;
|
|
|
|
// check attachments
|
|
attachmentList::iterator iter;
|
|
pObj = &(pSoldier->inv[HANDPOS]);
|
|
|
|
// check all attachments, search for available transformations
|
|
for (iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
|
{
|
|
if (iter->exists() && Item[iter->usItem].usItemClass == IC_MISC && Item[iter->usItem].attachmentclass & AC_LASER)
|
|
{
|
|
usItem = Item[iter->usItem].uiIndex;
|
|
|
|
// check flashlight transformation
|
|
if (FindLaserTransformation(usItem, &pTransformation) &&
|
|
pTransformation->usResult[0] != 0 &&
|
|
Item[usItem].bestlaserrange != Item[pTransformation->usResult[0]].bestlaserrange)
|
|
{
|
|
if (pTransformation->usAPCost > 0 && gTacticalStatus.uiFlags & INCOMBAT && gTacticalStatus.uiFlags & TURNBASED)
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s (%d AP)", pTransformation->szMenuRowText, pTransformation->usAPCost);
|
|
else
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pTransformation->szMenuRowText);
|
|
|
|
// let's pretend we are calling this from EDB
|
|
gpItemDescObject = pObj;
|
|
gpItemDescOrigAttachmentObject = &(*iter);
|
|
|
|
gpItemDescOrigAttachmentObject->TransformObject(pSoldier, 0, pTransformation, gpItemDescObject);
|
|
|
|
// cleanup
|
|
gpItemDescObject = NULL;
|
|
gpItemDescOrigAttachmentObject = NULL;
|
|
|
|
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTacticalTransformStock(void)
|
|
{
|
|
UINT16 usItem;
|
|
TransformInfoStruct *pTransformation;
|
|
OBJECTTYPE* pObj;
|
|
|
|
SOLDIERTYPE* pSoldier;
|
|
if (!GetSoldier(&pSoldier, gusSelectedSoldier))
|
|
return;
|
|
|
|
if (!pSoldier->inv[HANDPOS].exists())
|
|
return;
|
|
|
|
// ATE: Don't do this if in a fire animation.....
|
|
if (gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_FIRE)
|
|
return;
|
|
|
|
// don't do this when EDB is active
|
|
if (gpItemDescObject)
|
|
return;
|
|
|
|
usItem = pSoldier->inv[HANDPOS].usItem;
|
|
|
|
// check if can transform item
|
|
if (FindStockTransformation(usItem, &pTransformation))
|
|
{
|
|
if (pTransformation->usAPCost > 0 && (gTacticalStatus.uiFlags & INCOMBAT && gTacticalStatus.uiFlags & TURNBASED))
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s (%d AP)", pTransformation->szMenuRowText, pTransformation->usAPCost);
|
|
else
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pTransformation->szMenuRowText);
|
|
|
|
// let's pretend we are calling this from EDB
|
|
gpItemDescObject = &pSoldier->inv[HANDPOS];
|
|
gpItemDescObject->TransformObject(pSoldier, 0, pTransformation, NULL);
|
|
|
|
// cleanup
|
|
gpItemDescObject = NULL;
|
|
|
|
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
// check attachments
|
|
attachmentList::iterator iter;
|
|
pObj = &(pSoldier->inv[HANDPOS]);
|
|
|
|
// check all attachments, search for available transformations
|
|
for (iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
|
{
|
|
if (iter->exists() && Item[iter->usItem].usItemClass == IC_MISC && Item[iter->usItem].attachmentclass & AC_STOCK)
|
|
{
|
|
usItem = Item[iter->usItem].uiIndex;
|
|
|
|
// check flashlight transformation
|
|
if (FindStockTransformation(usItem, &pTransformation) &&
|
|
pTransformation->usResult[0] != 0)
|
|
{
|
|
if (pTransformation->usAPCost > 0 && gTacticalStatus.uiFlags & INCOMBAT && gTacticalStatus.uiFlags & TURNBASED)
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s (%d AP)", pTransformation->szMenuRowText, pTransformation->usAPCost);
|
|
else
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pTransformation->szMenuRowText);
|
|
|
|
// let's pretend we are calling this from EDB
|
|
gpItemDescObject = pObj;
|
|
gpItemDescOrigAttachmentObject = &(*iter);
|
|
|
|
gpItemDescOrigAttachmentObject->TransformObject(pSoldier, 0, pTransformation, gpItemDescObject);
|
|
|
|
// cleanup
|
|
gpItemDescObject = NULL;
|
|
gpItemDescOrigAttachmentObject = NULL;
|
|
|
|
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleTacticalTransformFlashlight(void)
|
|
{
|
|
UINT16 usItem;
|
|
TransformInfoStruct *pTransformation;
|
|
OBJECTTYPE* pObj;
|
|
|
|
SOLDIERTYPE* pSoldier;
|
|
if (!GetSoldier(&pSoldier, gusSelectedSoldier))
|
|
return;
|
|
|
|
if (!pSoldier->inv[HANDPOS].exists())
|
|
return;
|
|
|
|
// ATE: Don't do this if in a fire animation.....
|
|
if (gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_FIRE)
|
|
return;
|
|
|
|
// don't do this when EDB is active
|
|
if (gpItemDescObject)
|
|
return;
|
|
|
|
usItem = pSoldier->inv[HANDPOS].usItem;
|
|
|
|
// first try a transformation of item
|
|
if (FindFlashlightTransformation(usItem, &pTransformation))
|
|
{
|
|
if (pTransformation->usAPCost > 0 && gTacticalStatus.uiFlags & INCOMBAT && gTacticalStatus.uiFlags & TURNBASED)
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s (%d AP)", pTransformation->szMenuRowText, pTransformation->usAPCost);
|
|
else
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pTransformation->szMenuRowText);
|
|
|
|
// let's pretend we are calling this from EDB
|
|
gpItemDescObject = &pSoldier->inv[HANDPOS];
|
|
|
|
gpItemDescObject->TransformObject(pSoldier, 0, pTransformation, NULL);
|
|
|
|
// cleanup
|
|
gpItemDescObject = NULL;
|
|
|
|
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
// check attachments
|
|
attachmentList::iterator iter;
|
|
pObj = &(pSoldier->inv[HANDPOS]);
|
|
|
|
// check all attachments, search for available transformations
|
|
for (iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
|
|
{
|
|
if (iter->exists() && Item[iter->usItem].usItemClass == IC_MISC)
|
|
{
|
|
usItem = Item[iter->usItem].uiIndex;
|
|
|
|
// check flashlight transformation
|
|
if (FindFlashlightTransformation(usItem, &pTransformation))
|
|
{
|
|
if (pTransformation->usAPCost > 0 && gTacticalStatus.uiFlags & INCOMBAT && gTacticalStatus.uiFlags & TURNBASED)
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s (%d AP)", pTransformation->szMenuRowText, pTransformation->usAPCost);
|
|
else
|
|
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pTransformation->szMenuRowText);
|
|
|
|
// let's pretend we are calling this from EDB
|
|
gpItemDescObject = pObj;
|
|
gpItemDescOrigAttachmentObject = &(*iter);
|
|
|
|
gpItemDescOrigAttachmentObject->TransformObject(pSoldier, 0, pTransformation, gpItemDescObject);
|
|
|
|
// cleanup
|
|
gpItemDescObject = NULL;
|
|
gpItemDescOrigAttachmentObject = NULL;
|
|
|
|
DirtyMercPanelInterface(pSoldier, DIRTYLEVEL2);
|
|
gfUIForceReExamineCursorData = TRUE;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOLEAN FindLaserTransformation(UINT16 usItem, TransformInfoStruct **pTransformation)
|
|
{
|
|
// find transformation
|
|
for (INT32 x = 0; x < MAXITEMS + 1; x++)
|
|
{
|
|
if (Transform[x].usItem == (UINT16)-1)
|
|
{
|
|
break;
|
|
}
|
|
if (Transform[x].usItem == usItem &&
|
|
Transform[x].usResult[0] != 0 &&
|
|
Transform[x].usResult[0] != usItem &&
|
|
Item[Transform[x].usResult[0]].usItemClass & IC_MISC &&
|
|
Item[Transform[x].usResult[0]].attachmentclass & AC_LASER)
|
|
{
|
|
*pTransformation = &Transform[x];
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN FindStockTransformation(UINT16 usItem, TransformInfoStruct **pTransformation)
|
|
{
|
|
// find transformation
|
|
for (INT32 x = 0; x < MAXITEMS + 1; x++)
|
|
{
|
|
if (Transform[x].usItem == (UINT16)-1)
|
|
{
|
|
break;
|
|
}
|
|
if (Transform[x].usItem == usItem &&
|
|
Transform[x].usResult[0] != 0 &&
|
|
Transform[x].usResult[0] != usItem &&
|
|
(Item[Transform[x].usResult[0]].usItemClass == Item[usItem].usItemClass && Transform[x].usResult[0] != usItem && Item[Transform[x].usResult[0]].ItemSize != Item[usItem].ItemSize ||
|
|
Item[Transform[x].usResult[0]].usItemClass & IC_MISC && Item[Transform[x].usResult[0]].attachmentclass & AC_STOCK))
|
|
{
|
|
*pTransformation = &Transform[x];
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN FindFlashlightTransformation(UINT16 usItem, TransformInfoStruct **pTransformation)
|
|
{
|
|
// find transformation
|
|
for (INT32 x = 0; x < MAXITEMS + 1; x++)
|
|
{
|
|
if (Transform[x].usItem == (UINT16)-1)
|
|
{
|
|
break;
|
|
}
|
|
if (Transform[x].usItem == usItem &&
|
|
Transform[x].usResult[0] != 0 &&
|
|
Transform[x].usResult[0] != usItem &&
|
|
Item[Transform[x].usResult[0]].usFlashLightRange != Item[usItem].usFlashLightRange)
|
|
{
|
|
*pTransformation = &Transform[x];
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN FindScopeTransformation(UINT16 usItem, TransformInfoStruct **pTransformation)
|
|
{
|
|
INT32 iFoundIndex;
|
|
FLOAT scope;
|
|
|
|
// search for higher magnification first
|
|
iFoundIndex = MAXITEMS;
|
|
scope = Item[usItem].scopemagfactor;
|
|
for (INT32 x = 0; x < MAXITEMS + 1; x++)
|
|
{
|
|
if (Transform[x].usItem == (UINT16)-1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (Transform[x].usItem == usItem &&
|
|
Transform[x].usResult[0] != 0 &&
|
|
Item[Transform[x].usResult[0]].usItemClass & IC_MISC &&
|
|
Item[Transform[x].usResult[0]].attachmentclass & AC_SCOPE &&
|
|
Item[Transform[x].usResult[0]].scopemagfactor > Item[usItem].scopemagfactor &&
|
|
(iFoundIndex == MAXITEMS || Item[Transform[x].usResult[0]].scopemagfactor < scope))
|
|
{
|
|
scope = Item[Transform[x].usResult[0]].scopemagfactor;
|
|
iFoundIndex = x;
|
|
}
|
|
}
|
|
if (iFoundIndex != MAXITEMS)
|
|
{
|
|
*pTransformation = &Transform[iFoundIndex];
|
|
return TRUE;
|
|
}
|
|
|
|
// search for lowest magnification
|
|
iFoundIndex = MAXITEMS;
|
|
scope = Item[usItem].scopemagfactor;
|
|
for (INT32 x = 0; x < MAXITEMS + 1; x++)
|
|
{
|
|
if (Transform[x].usItem == (UINT16)-1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (Transform[x].usItem == usItem &&
|
|
Transform[x].usResult[0] != 0 &&
|
|
Item[Transform[x].usResult[0]].usItemClass & IC_MISC &&
|
|
Item[Transform[x].usResult[0]].attachmentclass & AC_SCOPE &&
|
|
Item[Transform[x].usResult[0]].scopemagfactor < scope)
|
|
{
|
|
scope = Item[Transform[x].usResult[0]].scopemagfactor;
|
|
iFoundIndex = x;
|
|
}
|
|
}
|
|
if (iFoundIndex != MAXITEMS)
|
|
{
|
|
*pTransformation = &Transform[iFoundIndex];
|
|
return TRUE;
|
|
}
|
|
|
|
// search for any transformation
|
|
for (INT32 x = 0; x < MAXITEMS + 1; x++)
|
|
{
|
|
if (Transform[x].usItem == (UINT16)-1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (Transform[x].usItem == usItem &&
|
|
Transform[x].usResult[0] != 0 &&
|
|
Item[Transform[x].usResult[0]].usItemClass & IC_MISC &&
|
|
Item[Transform[x].usResult[0]].attachmentclass & AC_SCOPE)
|
|
{
|
|
*pTransformation = &Transform[x];
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void HandleTBSkillsMenu(void)
|
|
{
|
|
// Flugente: trait skill selection menu.
|
|
INT32 usMapPos;
|
|
if (GetMouseMapPos(&usMapPos))
|
|
{
|
|
TraitsMenu(usMapPos);
|
|
}
|
|
else if (gusSelectedSoldier != NOBODY && MercPtrs[gusSelectedSoldier] && !TileIsOutOfBounds(MercPtrs[gusSelectedSoldier]->sGridNo))
|
|
{
|
|
LocateGridNo(MercPtrs[gusSelectedSoldier]->sGridNo);
|
|
TraitsMenu(MercPtrs[gusSelectedSoldier]->sGridNo);
|
|
}
|
|
}
|
|
|
|
BOOLEAN CheckAutoBandage(void)
|
|
{
|
|
if (!(gTacticalStatus.uiFlags & INCOMBAT) && NumEnemyInSector() == 0 && DialogueQueueIsEmpty())
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|