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