mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- 'Ctrl+Tab' for next tab in Enhanced Description Box at Strategic & Tactical Screen ('Tab' also possible in Strategic Screen as previously not in used)
- 'M' for Multiplayer in Main Menu Screen
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5668 3b4a5df2-a311-0410-b5c6-a8a6f20db521
7131 lines
197 KiB
C++
7131 lines
197 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 "wcheck.h"
|
|
#include "stdlib.h"
|
|
#include "debug.h"
|
|
#include "math.h"
|
|
#include "jascreens.h"
|
|
#include "pathai.h"
|
|
//#include "Soldier Control.h"
|
|
#include "Animation Control.h"
|
|
#include "Animation Data.h"
|
|
#include "Event Pump.h"
|
|
#include "Timer Control.h"
|
|
#include "cursors.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 "gamescreen.h"
|
|
#include "spread burst.h"
|
|
#include "tile animation.h"
|
|
#include "merc entering.h"
|
|
#include "explosion control.h"
|
|
#include "QuestDebug.h"
|
|
#include "assignments.h"
|
|
#include "EditScreen.h"
|
|
#include "SaveLoadGame.h"
|
|
#include "Structure Wrap.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 "GameVersion.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"
|
|
#endif
|
|
|
|
#include "Quest Debug System.h"
|
|
#include "connect.h"
|
|
#include "fresh_header.h"
|
|
|
|
|
|
#include "IMP Skill Trait.h" // added by Flugente
|
|
|
|
//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;
|
|
|
|
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;
|
|
|
|
|
|
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;
|
|
|
|
|
|
//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( );
|
|
|
|
|
|
|
|
UINT8 gubCheatLevel = STARTING_CHEAT_LEVEL;
|
|
|
|
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 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 )
|
|
{
|
|
INT8 bReturnVal = FALSE;
|
|
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
|
|
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 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:
|
|
|
|
*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 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 )
|
|
{
|
|
// Switch on UI mode
|
|
switch( gCurrentUIMode )
|
|
{
|
|
case IDLE_MODE:
|
|
|
|
break;
|
|
|
|
case MOVE_MODE:
|
|
|
|
// 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 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 ����� ������, ����������� �� ����� ������������\����������� ������� (���������� �������)
|
|
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;
|
|
|
|
}
|
|
|
|
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:
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
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;
|
|
BOOLEAN fGoodCheatLevelKey = FALSE;
|
|
|
|
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;
|
|
}
|
|
#if (defined JA2UB)
|
|
//Ja25 No meanwhiles
|
|
#else
|
|
if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == ESC) )
|
|
{
|
|
if ( AreInMeanwhile() && gCurrentMeanwhileDef.ubMeanwhileID != INTERROGATION )
|
|
{
|
|
DeleteTalkingMenu();
|
|
EndMeanwhile();
|
|
}
|
|
}
|
|
#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)
|
|
{
|
|
SGPRect LJDRect;
|
|
if ((InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == 'z' || InputEvent.usParam == 'y'))
|
|
{
|
|
if( (InputEvent.usKeyState & CTRL_DOWN) && !(InputEvent.usKeyState & ALT_DOWN))
|
|
{
|
|
// Unlock the mouse cursor
|
|
if (gfMouseLockedOnBorder)
|
|
{
|
|
FreeMouseCursor();
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_WINDOWED_MODE_RELEASE_MOUSE] );
|
|
}
|
|
// Lock the mouse cursor
|
|
else
|
|
{
|
|
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 ) )
|
|
{
|
|
gfSaveGame = FALSE;
|
|
gfCameDirectlyFromGame = TRUE;
|
|
|
|
guiPreviousOptionScreen = GAME_SCREEN;
|
|
|
|
// 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;
|
|
|
|
guiPreviousOptionScreen = 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'e') )
|
|
{
|
|
if( InputEvent.usKeyState & ALT_DOWN )
|
|
{
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
overide_turn();
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
// Befone anything, delete popup box!
|
|
EndUIMessage( );
|
|
|
|
// CANCEL FROM PLANNING MODE!
|
|
if ( InUIPlanMode( ) )
|
|
{
|
|
EndUIPlan( );
|
|
}
|
|
|
|
if ( InItemDescriptionBox( ) )
|
|
{
|
|
DeleteItemDescriptionBox( );
|
|
}
|
|
else if( InKeyRingPopup( ) )
|
|
{
|
|
DeleteKeyRingPopup( );
|
|
}
|
|
|
|
if ( gCurrentUIMode == MENU_MODE )
|
|
{
|
|
// If we get a hit here and we're in menu mode, quit the menu mode
|
|
EndMenuEvent( guiCurrentEvent );
|
|
}
|
|
|
|
if ( gCurrentUIMode == HANDCURSOR_MODE )
|
|
{
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
// If soldier is not stationary, stop
|
|
MercPtrs[ gusSelectedSoldier ]->StopSoldier( );
|
|
*puiNewEvent = A_CHANGE_TO_MOVE;
|
|
}
|
|
// ATE: OK, stop any mercs who are moving by selection method....
|
|
StopRubberBandedMercFromMoving( );
|
|
}
|
|
|
|
}
|
|
|
|
// 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( 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 );
|
|
|
|
//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 );
|
|
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
|
|
*puiNewEvent = M_ON_TERRAIN;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TAB:
|
|
// go to next tab in enhanced description box
|
|
if( ( fCtrl ) && InItemDescriptionBox( ) && gGameSettings.fOptions[ TOPTION_ENHANCED_DESC_BOX ] == TRUE )
|
|
{
|
|
if ( gubDescBoxPage < 2 )
|
|
{
|
|
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 '1':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
//ChangeSoldiersBodyType( TANK_NW, TRUE );
|
|
// MercPtrs[ gusSelectedSoldier ]->flags.uiStatusFlags |= SOLDIER_CREATURE;
|
|
//EVENT_InitNewSoldierAnim( MercPtrs[ gusSelectedSoldier ], CRIPPLE_BEG, 0 , TRUE );
|
|
}
|
|
}
|
|
else
|
|
ChangeCurrentSquad( 0 );
|
|
break;
|
|
|
|
case '2':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ChangeSoldiersBodyType( INFANT_MONSTER, TRUE );
|
|
}
|
|
}
|
|
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( 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( fCtrl ) //toggle between the different npc debug modes
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
CreateBloodCat();
|
|
}
|
|
}
|
|
else
|
|
ChangeCurrentSquad( 2 );
|
|
|
|
break;
|
|
|
|
case '4':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ChangeSoldiersBodyType( CRIPPLECIV, TRUE );
|
|
}
|
|
}
|
|
else
|
|
ChangeCurrentSquad( 3 );
|
|
|
|
//ChangeSoldiersBodyType( BLOODCAT, FALSE );
|
|
break;
|
|
|
|
case '5':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ChangeSoldiersBodyType( YAM_MONSTER, TRUE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ChangeCurrentSquad( 4 );
|
|
|
|
if (is_networked)
|
|
grid_display();//hayden
|
|
}
|
|
break;
|
|
|
|
case '6':
|
|
ChangeCurrentSquad( 5 );
|
|
break;
|
|
|
|
case '7':
|
|
ChangeCurrentSquad( 6 );
|
|
break;
|
|
|
|
case '8':
|
|
ChangeCurrentSquad( 7 );
|
|
break;
|
|
|
|
case '9':
|
|
ChangeCurrentSquad( 8 );
|
|
|
|
case '0':
|
|
ChangeCurrentSquad( 9 );
|
|
|
|
case 'x':
|
|
|
|
if ( !fCtrl && !fAlt )
|
|
{
|
|
// Exchange places...
|
|
SOLDIERTYPE *pSoldier1, *pSoldier2;
|
|
|
|
//Check if we have a good selected guy
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
pSoldier1 = MercPtrs[ gusSelectedSoldier ];
|
|
|
|
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 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
else if ( fCtrl ) // The_Bob - real time sneaking, 01-06-09
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
// The_Bob - real time sneaking, 01-06-09
|
|
case 'X': // shift-ctrl-x: toggle real time sneaking
|
|
if ( fCtrl )
|
|
{
|
|
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]);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case '/':
|
|
|
|
// Center to guy....
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
LocateSoldier( gusSelectedSoldier, 10 );
|
|
}
|
|
break;
|
|
|
|
|
|
case 'a':
|
|
|
|
if ( fCtrl )
|
|
{
|
|
#ifdef GERMAN
|
|
if ( gubCheatLevel == 3 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else if ( gubCheatLevel == 5 )
|
|
{
|
|
gubCheatLevel++;
|
|
// 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 );
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL();
|
|
}
|
|
#else
|
|
if ( gubCheatLevel == 1 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL();
|
|
}
|
|
#endif
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
// ToggleMercsNeverQuit();
|
|
static UINT8 ubAmbientSound = 0;
|
|
|
|
ubAmbientSound++;
|
|
|
|
if ( ubAmbientSound >= NUM_STEADY_STATE_AMBIENCES )
|
|
{
|
|
ubAmbientSound = 1;
|
|
}
|
|
|
|
SetSteadyStateAmbience( ubAmbientSound );
|
|
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
BeginAutoBandage( );
|
|
}
|
|
break;
|
|
|
|
case 'A':
|
|
//CHRISL: Ammo Crate
|
|
//MM: Ammo Box
|
|
if(!(gTacticalStatus.fEnemyInSector))
|
|
{
|
|
INT32 crateItem;
|
|
INT32 worldItem;
|
|
UINT8 magType;
|
|
bool mergeSuccessful, ammoPresent;
|
|
int loopCount = 0;
|
|
OBJECTTYPE newCrate;
|
|
ammoPresent = true;
|
|
|
|
if (fCtrl)
|
|
magType = AMMO_CRATE;
|
|
else
|
|
magType = AMMO_BOX;
|
|
|
|
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(int iLoop = 0; iLoop < MAXITEMS; iLoop++)
|
|
{
|
|
if (Item[iLoop].usItemClass == 0)
|
|
break; //no more valid items after this point
|
|
|
|
//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)gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs; loop++)
|
|
{
|
|
if(MercPtrs[loop]->bActive && MercPtrs[loop]->bInSector)
|
|
{
|
|
for(unsigned int pocket=0; pocket < MercPtrs[loop]->inv.size(); 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] );
|
|
}
|
|
break;
|
|
case 'J':
|
|
case 'j':
|
|
if ( fShift )
|
|
{
|
|
// WANNE: Jump through window?
|
|
if (gGameExternalOptions.fCanJumpThroughWindows == TRUE )
|
|
{
|
|
INT16 sAPCost;
|
|
INT16 sBPCost;
|
|
INT8 bDirection;
|
|
SOLDIERTYPE *lSoldier;
|
|
|
|
if ( GetSoldier( &lSoldier, gusSelectedSoldier ) )
|
|
{
|
|
if ( FindWindowJumpDirection( lSoldier, lSoldier->sGridNo, lSoldier->ubDirection, &bDirection ) )
|
|
{
|
|
if((UsingNewInventorySystem() == true) && lSoldier->inv[BPACKPOCKPOS].exists() == true)
|
|
{
|
|
sAPCost = GetAPsToJumpThroughWindows( lSoldier, TRUE );
|
|
sBPCost = GetBPsToJumpThroughWindows( lSoldier, TRUE );
|
|
}
|
|
else
|
|
{
|
|
sAPCost = GetAPsToJumpFence( lSoldier, FALSE );
|
|
sBPCost = GetBPsToJumpFence( lSoldier, FALSE );
|
|
}
|
|
|
|
if (EnoughPoints(lSoldier, sAPCost, sBPCost, FALSE))
|
|
{
|
|
lSoldier->BeginSoldierClimbWindow( );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else 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 ) )
|
|
{
|
|
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->name );
|
|
}
|
|
|
|
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)
|
|
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)
|
|
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)
|
|
{
|
|
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)
|
|
return;
|
|
|
|
if ( EnoughPoints( pjSoldier, GetAPsToJumpWall( pjSoldier, FALSE ), GetBPsToJumpWall( pjSoldier, FALSE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbWall( );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_NEW_BADMERC;
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
#ifndef GERMAN
|
|
if ( gubCheatLevel == 2 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else if ( gubCheatLevel == 3 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else if ( gubCheatLevel == 5 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL( );
|
|
}
|
|
#else
|
|
if ( gubCheatLevel == 6 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL( );
|
|
}
|
|
#endif
|
|
//gGameSettings.fOptions[ TOPTION_HIDE_BULLETS ] ^= TRUE;
|
|
}
|
|
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
|
|
if(UsingNewInventorySystem() == true)
|
|
{
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 bLoop;
|
|
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 ) && pTeamSoldier->inv[BPACKPOCKPOS].exists() == true )
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && !AM_A_ROBOT( pTeamSoldier ) && pTeamSoldier->inv[BPACKPOCKPOS].exists() == true )
|
|
{
|
|
ChangeDropPackStatus(pTeamSoldier, TRUE);
|
|
}
|
|
}
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
break;
|
|
case 'c':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
CreateNextCivType();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ToggleCliffDebug();
|
|
}
|
|
}
|
|
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
|
|
*puiNewEvent = I_ENDTURN;
|
|
}
|
|
}
|
|
}
|
|
#ifdef JA2TESTVERSION
|
|
else if( fCtrl )
|
|
AdvanceToNextDay();
|
|
#endif
|
|
break;
|
|
|
|
|
|
|
|
case 'e':
|
|
|
|
if( fAlt )
|
|
{
|
|
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_TACKING_MODE_OFF ] );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] = TRUE;
|
|
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_TACKING_MODE_ON ] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
INT32 usGridNo;
|
|
|
|
//Get the gridno the cursor is at
|
|
GetMouseMapPos( &usGridNo );
|
|
|
|
//if there is a selected soldier, and the cursor location is valid
|
|
if( gusSelectedSoldier != NOBODY && !TileIsOutOfBounds(usGridNo))
|
|
{
|
|
//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 );
|
|
}
|
|
|
|
#ifdef JA2TESTVERSION
|
|
CHAR16 zOutputString[512];
|
|
swprintf( zOutputString, L"gridno: %d", usGridNo);
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
|
|
#endif
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'F':
|
|
if( fCtrl && UsingNewInventorySystem() == true )
|
|
{
|
|
// pick up back packs
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 bLoop;
|
|
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
|
|
{
|
|
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && !AM_A_ROBOT( pTeamSoldier ) && pTeamSoldier->inv[BPACKPOCKPOS].exists() == false )
|
|
{
|
|
ChangeDropPackStatus(pTeamSoldier, FALSE);
|
|
}
|
|
}
|
|
}
|
|
SeperateItems();
|
|
if( fCtrl )
|
|
StackAndSort( TRUE );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] );
|
|
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 'q':
|
|
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 ] );
|
|
}
|
|
break;
|
|
|
|
|
|
case 'G':
|
|
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 )
|
|
{
|
|
#ifdef GERMAN
|
|
if ( gubCheatLevel == 1 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL();
|
|
}
|
|
#else
|
|
if ( gubCheatLevel == 0 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL();
|
|
}
|
|
#endif
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_NEW_MERC;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HandlePlayerTogglingLightEffects( TRUE );
|
|
}
|
|
break;
|
|
case 'H':
|
|
// 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;
|
|
}
|
|
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
|
|
if( fAlt && fCtrl )
|
|
{
|
|
INT32 tempMapPos = usMapPos;
|
|
if( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
for(UINT16 i = 1; i < 1300; i++)
|
|
{
|
|
if(i == OWNERSHIP || i == CHALICE)
|
|
continue;
|
|
//tempMapPos = sMapPos + (i / 200);
|
|
CreateItem(i, 100, &gTempObject);
|
|
AddItemToPool( tempMapPos, &gTempObject, VISIBLE , 0, WORLD_ITEM_REACHABLE, 0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
case 'i':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
CreateRandomItem();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
#ifdef GERMAN
|
|
if ( gubCheatLevel == 0 )
|
|
{
|
|
fGoodCheatLevelKey = TRUE;
|
|
gubCheatLevel++;
|
|
}
|
|
#else
|
|
if ( gubCheatLevel == 4 )
|
|
{
|
|
gubCheatLevel++;
|
|
fGoodCheatLevelKey = TRUE;
|
|
// 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 );
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL();
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if ( gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] )
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = FALSE;
|
|
ToggleItemGlow( FALSE );
|
|
}
|
|
else
|
|
{
|
|
gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = TRUE;
|
|
ToggleItemGlow( TRUE );
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case '$':
|
|
|
|
|
|
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
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
}
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BeginKeyPanelFromKeyShortcut( );
|
|
}
|
|
break;
|
|
|
|
case 'K':
|
|
//CHRISL: Swap gunsling
|
|
if ( gusSelectedSoldier != NOBODY && UsingNewInventorySystem() == true)
|
|
{
|
|
SOLDIERTYPE *pSoldier = MercPtrs[ gusSelectedSoldier ];
|
|
BOOLEAN handFit = (CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], GUNSLINGPOCKPOS, FALSE) || (pSoldier->inv[HANDPOS].exists() == false && pSoldier->inv[SECONDHANDPOS].exists() == false));
|
|
BOOLEAN slingFit = (CanItemFitInPosition(pSoldier, &pSoldier->inv[GUNSLINGPOCKPOS], HANDPOS, FALSE) || pSoldier->inv[GUNSLINGPOCKPOS].exists() == false);
|
|
|
|
if(Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].twohanded && pSoldier->inv[SECONDHANDPOS].exists() == true)
|
|
handFit = FALSE;
|
|
|
|
if( handFit == TRUE && slingFit == TRUE)
|
|
{
|
|
if (gGameOptions.fInventoryCostsAP)
|
|
{
|
|
UINT8 APCost = 0;
|
|
if (pSoldier->inv[GUNSLINGPOCKPOS].exists())
|
|
{
|
|
APCost += ( APBPConstants [ AP_INV_FROM_SLING ] + APBPConstants [ AP_INV_TO_HANDS ] );
|
|
if (gGameExternalOptions.uWeightDivisor != 0)
|
|
APCost += DynamicAdjustAPConstants((int)((Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].ubWeight) / gGameExternalOptions.uWeightDivisor),(int)((Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].ubWeight) / gGameExternalOptions.uWeightDivisor));
|
|
}
|
|
if (pSoldier->inv[HANDPOS].exists())
|
|
{
|
|
APCost += ( APBPConstants [ AP_INV_TO_SLING ] + APBPConstants [ AP_INV_FROM_HANDS ] );
|
|
if (gGameExternalOptions.uWeightDivisor != 0)
|
|
APCost += DynamicAdjustAPConstants((int)((Item[pSoldier->inv[HANDPOS].usItem].ubWeight) / gGameExternalOptions.uWeightDivisor),(int)((Item[pSoldier->inv[HANDPOS].usItem].ubWeight) / gGameExternalOptions.uWeightDivisor));
|
|
}
|
|
APCost = __min(APCost, APBPConstants[AP_INV_MAX_COST]);
|
|
if (pSoldier->bActionPoints >= APCost)
|
|
{
|
|
// SANDRO - I dared to change this to use the apropriate function, as that function is actually important for IIS
|
|
//pSoldier->bActionPoints -= APCost;
|
|
DeductPoints( pSoldier, APCost, 0 );
|
|
|
|
SwapObjs(&pSoldier->inv[HANDPOS], &pSoldier->inv[GUNSLINGPOCKPOS]);
|
|
HandleTacticalEffectsOfEquipmentChange(pSoldier, HANDPOS, pSoldier->inv[GUNSLINGPOCKPOS].usItem, pSoldier->inv[HANDPOS].usItem);
|
|
}
|
|
else
|
|
{
|
|
CHAR16 zOutputString[512];
|
|
swprintf( zOutputString, New113Message[MSG113_INVENTORY_APS_INSUFFICIENT], APCost, pSoldier->bActionPoints);
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SwapObjs(&pSoldier->inv[HANDPOS], &pSoldier->inv[GUNSLINGPOCKPOS]);
|
|
HandleTacticalEffectsOfEquipmentChange(pSoldier, HANDPOS, pSoldier->inv[GUNSLINGPOCKPOS].usItem, pSoldier->inv[HANDPOS].usItem);
|
|
}
|
|
}
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
break;
|
|
|
|
case INSERT:
|
|
GoIntoOverheadMap();
|
|
break;
|
|
|
|
// Lalien: commented out, to fix "end move & LOS bug" (same button has two different actions)
|
|
//case END:
|
|
|
|
// if ( gusSelectedSoldier != NOBODY )
|
|
// {
|
|
// if ( CheckForMercContMove( MercPtrs[ gusSelectedSoldier ] ) )
|
|
// {
|
|
// // Continue
|
|
// ContinueMercMovement( MercPtrs[ gusSelectedSoldier ] );
|
|
// ErasePath( TRUE );
|
|
// }
|
|
// }
|
|
// 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;
|
|
|
|
#ifdef JA2BETAVERSION
|
|
case 'L':
|
|
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
|
|
|
|
case 'l':
|
|
if (fAlt )
|
|
{
|
|
|
|
}
|
|
else if (fCtrl)
|
|
{
|
|
}
|
|
else
|
|
/*
|
|
if( fAlt )
|
|
{
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
LeaveTacticalScreen( GAME_SCREEN );
|
|
|
|
DoQuickLoad();
|
|
}
|
|
}
|
|
|
|
else if( fCtrl )
|
|
{
|
|
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
|
|
{
|
|
|
|
gfSaveGame = FALSE;
|
|
gfCameDirectlyFromGame = TRUE;
|
|
|
|
guiPreviousOptionScreen = GAME_SCREEN;
|
|
LeaveTacticalScreen( SAVE_LOAD_SCREEN );
|
|
}
|
|
*//*
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_LEVELNODEDEBUG;
|
|
CountLevelNodes();
|
|
}
|
|
*//*
|
|
}
|
|
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 '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
|
|
{
|
|
// 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( );
|
|
}
|
|
}
|
|
}
|
|
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 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 '*':
|
|
|
|
if ( gTacticalStatus.uiFlags & RED_ITEM_GLOW_ON )
|
|
{
|
|
gTacticalStatus.uiFlags &= (~RED_ITEM_GLOW_ON );
|
|
}
|
|
else
|
|
{
|
|
gTacticalStatus.uiFlags |= RED_ITEM_GLOW_ON;
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
// swap sungoggles and nightgoggles
|
|
case 'N':
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 bLoop;
|
|
BOOLEAN fToNightVision;
|
|
|
|
// HEADROCK HAM B2.8: Added call for CTRL-SHIFT-N to switch all soldiers to day/night.
|
|
if ( fCtrl )
|
|
{
|
|
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
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'n':
|
|
|
|
if( fAlt )
|
|
{
|
|
static UINT16 gQuoteNum = 0;
|
|
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
if( gfUIFullTargetFound )
|
|
{
|
|
TacticalCharacterDialogue( MercPtrs[ gusUIFullTargetID ], gQuoteNum );
|
|
gQuoteNum++;
|
|
}
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
#ifdef GERMAN
|
|
if ( gubCheatLevel == 4 )
|
|
{
|
|
fGoodCheatLevelKey = TRUE;
|
|
gubCheatLevel++;
|
|
#if 0
|
|
// ATE: Level one reached.....
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CHEAT_LEVEL_ONE ] );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL();
|
|
}
|
|
#endif
|
|
|
|
#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( 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
|
|
guiPreviousOptionScreen = GAME_SCREEN;
|
|
LeaveTacticalScreen( OPTIONS_SCREEN );
|
|
}
|
|
}
|
|
}
|
|
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;
|
|
|
|
|
|
|
|
// Make auto reload with magazines from sector inventory
|
|
case 'R':
|
|
if (! ( gTacticalStatus.fEnemyInSector ) )
|
|
{
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 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
|
|
for (UINT32 bLoop2 = 0; bLoop2 < pTeamSoldier->inv.size(); bLoop2++)
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass == IC_LAUNCHER) )
|
|
{
|
|
pGun = &(pTeamSoldier->inv[bLoop2]);
|
|
//if magazine is not full
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
|
|
{
|
|
|
|
// 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 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//CHRISL: if not enough ammo in sector, reload using ammo carried in inventory
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
|
|
{
|
|
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
|
|
for (UINT32 bLoop2 = 0; bLoop2 < pTeamSoldier->inv.size(); 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 )
|
|
{
|
|
for (UINT32 uiLoop = 0; uiLoop < pTeamSoldier->inv.size(); 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 (IsUnderBarrelAttached(pGun))
|
|
{
|
|
OBJECTTYPE *pGun2 = FindAttachment_UnderBarrel(pGun);
|
|
if ( (*pGun2)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun2 ) )
|
|
{
|
|
|
|
// 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 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//CHRISL: if not enough ammo in sector, reload using ammo carried in inventory
|
|
if ( (*pGun2)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun2 ) )
|
|
{
|
|
AutoReload( pTeamSoldier );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SOLDIERTYPE *pTeamSoldier;
|
|
INT8 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) || (Item[pTeamSoldier->inv[HANDPOS].usItem].usItemClass == 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
|
|
for (UINT32 bLoop2 = 0; bLoop2 < pTeamSoldier->inv.size(); bLoop2++)
|
|
{
|
|
if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass == IC_LAUNCHER) )
|
|
{
|
|
pGun = &(pTeamSoldier->inv[bLoop2]);
|
|
//if magazine is not full
|
|
if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
|
|
{
|
|
|
|
// Search for ammo in soldier inventory
|
|
for ( UINT32 uiLoop = 0; uiLoop < pTeamSoldier->inv.size(); 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case 'r':
|
|
if( gusSelectedSoldier != NOBODY )
|
|
{
|
|
if( fAlt ) //reload selected merc's weapon
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
ReloadWeapon( MercPtrs[ gusSelectedSoldier ], MercPtrs[ gusSelectedSoldier ]->ubAttackingHand );
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !MercPtrs[ gusSelectedSoldier ]->MercInWater( ) && !(MercPtrs[ gusSelectedSoldier ]->flags.uiStatusFlags & SOLDIER_ROBOT ) )
|
|
{
|
|
//change selected merc to run
|
|
if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING
|
|
&& MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING
|
|
&& MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING_WEAPON_RDY
|
|
&& MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING_DUAL_RDY
|
|
&& MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING_ALTERNATIVE_RDY )
|
|
{
|
|
UIHandleSoldierStanceChange( (UINT8)gusSelectedSoldier, ANIM_STAND );
|
|
MercPtrs[ gusSelectedSoldier ]->flags.fUIMovementFast = 1;
|
|
}
|
|
else
|
|
{
|
|
MercPtrs[ gusSelectedSoldier ]->flags.fUIMovementFast = 1;
|
|
MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = RUNNING;
|
|
gfPlotNewMovement = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'S':
|
|
StackAndSort( TRUE );
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] );
|
|
break;
|
|
|
|
case 's':
|
|
|
|
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;
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if( fAlt )
|
|
{
|
|
if( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV )&& !is_networked )
|
|
{
|
|
//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( gusSelectedSoldier != NOBODY )
|
|
{
|
|
gfPlotNewMovement = TRUE;
|
|
HandleStanceChangeFromUIKeys( ANIM_STAND );
|
|
}
|
|
break;
|
|
|
|
case 't':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
TeleportSelectedSoldier();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
TestCapture( );
|
|
|
|
//EnterCombatMode( gbPlayerNum );
|
|
}
|
|
}
|
|
else
|
|
ToggleTreeTops();
|
|
break;
|
|
|
|
case 'T':
|
|
if ( fCtrl && fShift && fAlt && !is_networked)// ary-05/05/2009 : add forced turn mode
|
|
{
|
|
ToggleTurnMode();
|
|
}
|
|
else if ( fCtrl && fShift )
|
|
{
|
|
//SaveGame( SAVE__TIMED_AUTOSAVE_SLOT1, L"Auto Save 1" );
|
|
swprintf( zString, L"%s %d",pMessageStrings[ 90 ],SAVE__TIMED_AUTOSAVE_SLOT1);
|
|
DoAutoSave(SAVE__TIMED_AUTOSAVE_SLOT1,zString);
|
|
}
|
|
else
|
|
{
|
|
//resort Team by ubID
|
|
SortSquadByID(MercPtrs[gusSelectedSoldier]->bTeam);
|
|
}
|
|
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
|
|
if (! (gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
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 );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
RefreshSoldier();
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
INT32 cnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
#ifdef GERMAN
|
|
if ( gubCheatLevel == 2 )
|
|
{
|
|
fGoodCheatLevelKey = TRUE;
|
|
gubCheatLevel++;
|
|
}
|
|
else
|
|
{
|
|
RESET_CHEAT_LEVEL();
|
|
}
|
|
#endif
|
|
|
|
if ( CHEATER_CHEAT_LEVEL( ) && gusSelectedSoldier != NOBODY )
|
|
{
|
|
for ( pSoldier = MercPtrs[ gbPlayerNum ], cnt = 0; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
|
|
{
|
|
if ( pSoldier->bActive && pSoldier->stats.bLife > 0 )
|
|
{
|
|
// Get breath back
|
|
pSoldier->bBreath = pSoldier->bBreathMax;
|
|
|
|
// Get life back
|
|
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
|
|
pSoldier->bBleeding = 0;
|
|
pSoldier->bPoisonBleeding = 0;
|
|
// SANDRO - erase insta-healable injury
|
|
pSoldier->iHealableInjury = 0;
|
|
|
|
fInterfacePanelDirty = DIRTYLEVEL2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
else if ( gusSelectedSoldier != NOBODY )
|
|
*puiNewEvent = M_CHANGE_TO_ACTION;
|
|
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 );
|
|
#endif
|
|
}
|
|
else
|
|
DisplayGameSettings( );
|
|
|
|
break;
|
|
|
|
case 'V':
|
|
if( fAlt )
|
|
ToggleTrapNetworkView(); // added by Flugente
|
|
else
|
|
ToggleMercView();
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
case 'W':
|
|
if( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
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
|
|
ToggleWireFrame();
|
|
break;
|
|
|
|
case 'y':
|
|
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( (UINT16) G41, 100, &Object );
|
|
|
|
pSoldier = FindSoldierByProfileID( MARIA, FALSE );
|
|
|
|
AutoPlaceObject( pSoldier, &Object, FALSE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
*puiNewEvent = I_LOSDEBUG;
|
|
}
|
|
}
|
|
//else if( gusSelectedSoldier != NOBODY )
|
|
break;
|
|
|
|
// added by Flugente
|
|
case '.':
|
|
if ( fCtrl )
|
|
{
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
HandleTacticalFunctionSelection(MercPtrs[ gusSelectedSoldier ], usMapPos );
|
|
}
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
// Flugente: spawn items while debugging
|
|
/*if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
static UINT16 usitem = 1623;
|
|
static INT16 status = 100;
|
|
static FLOAT temperature = 0.0;
|
|
|
|
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 );
|
|
|
|
CreateItem( usitem, status, &newobj );
|
|
(newobj)[0]->data.bTemperature = temperature;
|
|
|
|
if ( !AutoPlaceObject( MercPtrs[ gusSelectedSoldier ], &newobj, FALSE ) )
|
|
AddItemToPool( MercPtrs[ gusSelectedSoldier ]->sGridNo, &newobj, 1, 0, 0, -1 );
|
|
}*/
|
|
}
|
|
else
|
|
{
|
|
SetScopeMode( usMapPos );
|
|
}
|
|
|
|
break;
|
|
|
|
case 'z':
|
|
if( fCtrl && fAlt )
|
|
{
|
|
if ( INFORMATION_CHEAT_LEVEL( ) )
|
|
{
|
|
ToggleZBuffer();
|
|
}
|
|
}
|
|
else if ( fAlt )
|
|
{
|
|
// 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 ] );
|
|
}
|
|
}
|
|
}
|
|
else if ( fCtrl )
|
|
{
|
|
// used for "lock" / "unlock" the mouse cursor in windowed mode
|
|
}
|
|
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 ) )
|
|
{
|
|
HandleStealthChangeFromUIKeys( );
|
|
}
|
|
}
|
|
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( fAlt )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
EnvBeginRainStorm( 1 );
|
|
}
|
|
}
|
|
else if( fCtrl )
|
|
{
|
|
if ( CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
EnvEndRainStorm( );
|
|
}
|
|
}
|
|
else
|
|
// Switch panels...
|
|
{
|
|
ToggleTacticalPanels();
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
#ifdef GERMAN
|
|
if ( !fGoodCheatLevelKey && gubCheatLevel < 5 )
|
|
{
|
|
RESET_CHEAT_LEVEL( );
|
|
}
|
|
#else
|
|
if ( !fGoodCheatLevelKey && gubCheatLevel < 4 )
|
|
{
|
|
RESET_CHEAT_LEVEL( );
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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 ]->name );
|
|
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 ]->name,
|
|
MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->name );
|
|
}
|
|
else
|
|
{ //female singular
|
|
swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_FEMALE_SINGULAR ], MercPtrs[ gusSelectedSoldier ]->name,
|
|
MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->name );
|
|
}
|
|
}
|
|
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 ]->name );
|
|
}
|
|
else
|
|
{ //female plural
|
|
swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_FEMALE_PLURAL ], MercPtrs[ gusSelectedSoldier ]->name );
|
|
}
|
|
}
|
|
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 ]->name );
|
|
}
|
|
|
|
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( (UINT16)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:
|
|
|
|
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 ] );
|
|
WorldHideTrees( );
|
|
gTacticalStatus.uiFlags |= NOHIDE_REDUNDENCY;
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ SHOWING_TREETOPS_STR ]);
|
|
WorldShowTrees( );
|
|
gTacticalStatus.uiFlags &= (~NOHIDE_REDUNDENCY);
|
|
}
|
|
gGameSettings.fOptions[ TOPTION_TOGGLE_TREE_TOPS ] = !gGameSettings.fOptions[ TOPTION_TOGGLE_TREE_TOPS ];
|
|
|
|
// 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 ], 0 );
|
|
|
|
// 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( 0, 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()
|
|
{
|
|
INT16 sWorldX, sWorldY;
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
static INT8 bBodyType = FATCIV;
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = NO_PROFILE;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.bBodyType = bBodyType;
|
|
MercCreateStruct.ubDirection = SOUTH;
|
|
|
|
bBodyType++;
|
|
|
|
if ( bBodyType > KIDCIV )
|
|
{
|
|
bBodyType = 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()
|
|
{
|
|
INT16 sWorldX, sWorldY;
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = NO_PROFILE;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.bBodyType = 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()
|
|
{
|
|
INT16 sWorldX, sWorldY;
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = NO_PROFILE;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.bBodyType = 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()
|
|
{
|
|
INT16 sWorldX, sWorldY;
|
|
SOLDIERCREATE_STRUCT MercCreateStruct;
|
|
INT32 usMapPos;
|
|
// Get Grid Corrdinates of mouse
|
|
if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) )
|
|
{
|
|
INT8 iNewIndex;
|
|
|
|
MercCreateStruct.ubProfile = 12;
|
|
MercCreateStruct.sSectorX = gWorldSectorX;
|
|
MercCreateStruct.sSectorY = gWorldSectorY;
|
|
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
|
MercCreateStruct.bBodyType = 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()
|
|
{
|
|
INT16 sWorldX, sWorldY;
|
|
INT32 usMapPos;
|
|
if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && 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.bBodyType = QUEENMONSTER;
|
|
//MercCreateStruct.bBodyType = LARVAE_MONSTER;
|
|
else
|
|
MercCreateStruct.bBodyType = 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 )
|
|
{
|
|
// Look for an item pool
|
|
INT32 sActionGridNo;
|
|
UINT8 ubDirection;
|
|
SOLDIERTYPE *pTSoldier;
|
|
INT16 sAPCost = 0;
|
|
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
pTSoldier = MercPtrs[ gusUIFullTargetID ];
|
|
|
|
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 );
|
|
|
|
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.ubPendingActionAnimCount = 0;
|
|
|
|
// WALK UP TO DEST FIRST
|
|
pSoldier->EVENT_InternalGetNewSoldierPath( sActionGridNo, pSoldier->usUIMovementMode, 3 , pSoldier->flags.fNoAPToFinishMove );
|
|
}
|
|
else
|
|
{
|
|
pSoldier->EVENT_SoldierEnterVehicle( pTSoldier->sGridNo, ubDirection );
|
|
}
|
|
|
|
// OK, set UI
|
|
SetUIBusy( pSoldier->ubID );
|
|
//guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
|
|
|
|
return( -1 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
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 ) == -1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
// Check if we are on a merc... if so.. steal!
|
|
if ( gfUIFullTargetFound )
|
|
{
|
|
if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_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;
|
|
|
|
bZLevel = GetZLevelOfItemPoolGivenStructure( sActionGridNo, pSoldier->pathing.bLevel, pStructure );
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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 ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ VEHICLE_CANT_MOVE_IN_TACTICAL ] );
|
|
return( -3 );
|
|
}
|
|
|
|
// 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 ) == -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 ( GetItemPool( sIntTileGridNo, &pItemPool, pSoldier->pathing.bLevel ) && !( pStructure->fFlags & ( STRUCTURE_SWITCH | STRUCTURE_ANYDOOR ) ) )
|
|
{
|
|
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 );
|
|
|
|
if ( EnoughPoints( pSoldier, bAPs, 0,TRUE ) )
|
|
{
|
|
// OK, we have some ammo we can reload.... reload now!
|
|
if ( !AutoReload( pSoldier ) )
|
|
{
|
|
// 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 ) ) )
|
|
{
|
|
if ( IsSquadOnCurrentTacticalMap( iSquad ) )
|
|
{
|
|
//resort the squad in case the order has, for any reason, changed
|
|
SortSquadByID((INT8)iSquad);
|
|
SetCurrentSquad( iSquad, FALSE );
|
|
}
|
|
}
|
|
}
|
|
|
|
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 = 3;
|
|
MeanwhileDef.sSectorY = 16;
|
|
MeanwhileDef.ubNPCNumber = QUEEN;
|
|
MeanwhileDef.usTriggerEvent = 0;
|
|
MeanwhileDef.ubMeanwhileID = (UINT8)iID;
|
|
|
|
if ( iID == INTERROGATION )
|
|
{
|
|
MeanwhileDef.sSectorX = 7;
|
|
MeanwhileDef.sSectorY = 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 = 7;
|
|
pSoldier->sSectorY = 14;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
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
|
|
|
|
|
|
void HandleStanceChangeFromUIKeys( UINT8 ubAnimHeight )
|
|
{
|
|
// If we have multiple guys selected, make all change stance!
|
|
SOLDIERTYPE * pSoldier;
|
|
INT32 cnt;
|
|
|
|
if ( gTacticalStatus.fAtLeastOneGuyOnMultiSelect )
|
|
{
|
|
// 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 )
|
|
{
|
|
UIHandleSoldierStanceChange( pSoldier->ubID, ubAnimHeight );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( gusSelectedSoldier != NOBODY )
|
|
UIHandleSoldierStanceChange( (UINT8)gusSelectedSoldier, 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 ) )
|
|
{
|
|
// 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->name );
|
|
}
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_OFF_STEALTHMODE ], pSoldier->name );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void HandleStealthChangeFromUIKeys( )
|
|
{
|
|
// If we have multiple guys selected, make all change stance!
|
|
SOLDIERTYPE * pSoldier;
|
|
INT32 cnt;
|
|
|
|
if ( gTacticalStatus.fAtLeastOneGuyOnMultiSelect )
|
|
{
|
|
// 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 sodliers 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((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 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.
|
|
while(gWorldItems[uiLoop].object[x]->attachments.size() != cnt)
|
|
{
|
|
gTempObject = *gWorldItems[uiLoop].object[x]->GetAttachmentAtIndex(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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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 ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
|
|
{
|
|
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 ( _KeyDown( ALT ) )
|
|
{
|
|
//������������ ������ ����
|
|
if ( ( gpItemPointer == NULL ) &&
|
|
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ BURSTMODE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
|
|
SetBurstMode();
|
|
}
|
|
else
|
|
{//*puiNewEvent = LC_LOOK;
|
|
if(gCurrentUIMode == CONFIRM_ACTION_MODE)
|
|
brstmode=(brstmode==1)?0:1;
|
|
else{
|
|
ErasePath( TRUE );
|
|
*puiNewEvent = LC_ON_TERRAIN;
|
|
}
|
|
}
|
|
|
|
fMiddleButtonDown = FALSE;
|
|
// Reset counter
|
|
//RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
|
|
}
|
|
}
|
|
}//void QueryTBMButton( UINT32 *puiNewEvent )
|
|
|
|
void QueryTBWheel( UINT32 *puiNewEvent )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
INT32 usMapPos=0;
|
|
UINT8 bID;
|
|
|
|
// 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:
|
|
|
|
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 ]);
|
|
break;
|
|
}
|
|
if ( gusSelectedSoldier != NOBODY )
|
|
{
|
|
bID = FindPrevActiveAndAliveMerc( MercPtrs[ gusSelectedSoldier ], TRUE, TRUE );
|
|
HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
//change stance ->UP
|
|
if ( _KeyDown( ALT ) )
|
|
{ if ( (gusSelectedSoldier != NOBODY) && ( gpItemPointer == NULL ) )
|
|
GotoHeigherStance( MercPtrs[ gusSelectedSoldier ] );
|
|
break;
|
|
}
|
|
|
|
//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 );
|
|
// Center to guy....
|
|
LocateSoldier( gusSelectedSoldier, SETLOCATOR );
|
|
}
|
|
}
|
|
//*puiNewEvent = M_ON_TERRAIN; ????????????????
|
|
}
|
|
|
|
case IDLE_MODE:
|
|
case ACTION_MODE:
|
|
case LOCKOURTURN_UI_MODE:
|
|
case LOOKCURSOR_MODE:
|
|
case LOCKUI_MODE:
|
|
case TALKCURSOR_MODE:
|
|
case MENU_MODE:
|
|
case HANDCURSOR_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 ( !_KeyDown( ALT ) && !_KeyDown( SHIFT ))
|
|
{
|
|
UIHandleChangeLevel( NULL );
|
|
}
|
|
else if( _KeyDown( SHIFT ) )
|
|
{
|
|
// 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)
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (_KeyDown( ALT ) )
|
|
{
|
|
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->name );
|
|
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)
|
|
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)
|
|
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)
|
|
{
|
|
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)
|
|
return;
|
|
|
|
if ( EnoughPoints( pjSoldier, GetAPsToJumpWall( pjSoldier, FALSE ), GetBPsToJumpWall( pjSoldier, FALSE ), FALSE ) )
|
|
{
|
|
pjSoldier->BeginSoldierClimbWall( );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 ( _KeyDown( ALT ) )
|
|
AutoReload( MercPtrs[ gusSelectedSoldier ] );
|
|
else
|
|
// 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 ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|