#include "builddefines.h" #include #include "Button System.h" #include "mousesystem.h" #include "jascreens.h" #include "gamescreen.h" #include "strategicmap.h" #include "Game Clock.h" #include "sysutil.h" #include "Font Control.h" #include "Text.h" #include "Render Dirty.h" #include "Cursors.h" #include "Strategic Exit GUI.h" #include "MercTextBox.h" #include "renderworld.h" #include "Overhead.h" #include "Cursor Control.h" #include "input.h" #include "english.h" #include "Strategic Movement.h" #include "Squads.h" #include "Assignments.h" #include "Soldier macros.h" #include "PreBattle Interface.h" #include "strategic.h" #include "MessageBoxScreen.h" #include "Quests.h" #include "Creature Spreading.h" #include "Queen Command.h" // added by Flugente #ifdef JA2UB #include "Ja25_Tactical.h" #endif BOOLEAN gfInSectorExitMenu = FALSE; void CheckLoadMapCallback( GUI_BUTTON *btn, INT32 reason ); void SingleMoveCallback(GUI_BUTTON *btn, INT32 reason ); void AllMoveCallback(GUI_BUTTON *btn, INT32 reason ); void OKCallback(GUI_BUTTON *btn, INT32 reason ); void CancelCallback(GUI_BUTTON *btn, INT32 reason ); void SectorExitBackgroundCallback( MOUSE_REGION * pRegion, INT32 iReason ); void SingleRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ); void AllRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ); void LoadRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ); void SingleRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason ); void AllRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason ); void LoadRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason ); typedef struct { MOUSE_REGION BackRegion; MOUSE_REGION SingleRegion; MOUSE_REGION LoadRegion; MOUSE_REGION AllRegion; UINT32 uiLoadCheckButton; UINT32 uiSingleMoveButton; UINT32 uiAllMoveButton; UINT32 uiOKButton; UINT32 uiCancelButton; INT32 iBoxId; INT32 iButtonImages; UINT16 usWidth; UINT16 usHeight; INT16 sX; INT16 sY; INT32 sAdditionalData;//dnl ch56 151009 UINT8 ubFlags; UINT8 ubLeaveSectorType; UINT8 ubLeaveSectorCode; UINT8 ubDirection; UINT8 ubNumPeopleOnSquad; INT16 bSingleMoveWillIsolateEPC; //if not -1, then that means the slot number is an EPC INT8 bHandled; BOOLEAN fRender; BOOLEAN fGotoSector; BOOLEAN fGotoSectorText; BOOLEAN fSingleMove; BOOLEAN fAllMove; BOOLEAN fSingleMoveDisabled; BOOLEAN fGotoSectorDisabled; BOOLEAN fAllMoveDisabled; BOOLEAN fGotoSectorHilighted; BOOLEAN fSingleMoveHilighted; BOOLEAN fAllMoveHilighted; BOOLEAN fMultipleSquadsInSector; BOOLEAN fSingleMoveOn; BOOLEAN fAllMoveOn; BOOLEAN fSelectedMercIsEPC; BOOLEAN fSquadHasMultipleEPCs; BOOLEAN fUncontrolledRobotInSquad; } EXIT_DIALOG_STRUCT; EXIT_DIALOG_STRUCT gExitDialog; UINT8 gubExitGUIDirection; INT32 gsExitGUIAdditionalData;//dnl ch56 151009 INT16 gsWarpWorldX; INT16 gsWarpWorldY; INT8 gbWarpWorldZ; INT32 gsWarpGridNo; //KM: New method is coded for more sophistocated rules. All the information is stored within the gExitDialog struct // and calculated upon entry to this function instead of passing in multiple arguments and calculating it prior. BOOLEAN InternalInitSectorExitMenu( UINT8 ubDirection, INT32 sAdditionalData )//dnl ch56 151009 { UINT32 uiTraverseTimeInMinutes; SOLDIERTYPE *pSoldier; SGPRect aRect; UINT16 usTextBoxWidth, usTextBoxHeight; INT32 usMapPos = 0; INT8 bExitCode = -1; BOOLEAN OkExitCode; //STEP 1: Calculate the information for the exit gui memset( &gExitDialog, 0, sizeof( EXIT_DIALOG_STRUCT ) ); gExitDialog.bSingleMoveWillIsolateEPC = -1; // OK, bring up dialogue... first determine some logic here... switch( ubDirection ) { case EAST: bExitCode = EAST_STRATEGIC_MOVE; break; case WEST: bExitCode = WEST_STRATEGIC_MOVE; break; case NORTH: bExitCode = NORTH_STRATEGIC_MOVE; break; case SOUTH: bExitCode = SOUTH_STRATEGIC_MOVE; break; case DIRECTION_EXITGRID: bExitCode = -1; usMapPos = sAdditionalData; break; } OkExitCode = OKForSectorExit( bExitCode, usMapPos, &uiTraverseTimeInMinutes ); if( uiTraverseTimeInMinutes <= 5 ) { //if the traverse time is short, then traversal is percieved to be instantaneous. gExitDialog.fGotoSectorText = TRUE; } if( OkExitCode == 1 ) { gExitDialog.fAllMoveDisabled = TRUE; gExitDialog.fSingleMoveOn = TRUE; gExitDialog.fSingleMove = TRUE; if( gfRobotWithoutControllerAttemptingTraversal ) { gfRobotWithoutControllerAttemptingTraversal = FALSE; gExitDialog.fUncontrolledRobotInSquad = TRUE; } } else if( OkExitCode == 2 ) { gExitDialog.fAllMoveOn = TRUE; gExitDialog.fAllMove = TRUE; } // anv: vehicle always move with all passengers inside if( gusSelectedSoldier->bAssignment == VEHICLE ) { gExitDialog.fSingleMoveDisabled = TRUE; gExitDialog.fSingleMoveOn = FALSE; gExitDialog.fSingleMove = FALSE; gExitDialog.fAllMoveDisabled = FALSE; gExitDialog.fAllMoveOn = TRUE; gExitDialog.fAllMove = TRUE; } if ( gTacticalStatus.uiFlags & INCOMBAT ) { INT32 cnt = 0; for( SoldierID id = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; id <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++id ) { if( OK_INSECTOR_MERC( id ) ) cnt++; } if( cnt != 1 ) { gExitDialog.fGotoSectorDisabled = TRUE; } } //STEP 2: Setup the exit gui EnterModalTactical( TACTICAL_MODAL_WITHMOUSE ); gfIgnoreScrolling = TRUE; aRect.iTop = 0; aRect.iLeft = 0; aRect.iBottom = INV_INTERFACE_START_Y; aRect.iRight = SCREEN_WIDTH; if( gExitDialog.fAllMoveOn ) { //either an all-move in non-combat, or the last concious guy in combat. gExitDialog.fGotoSector = TRUE; } gExitDialog.ubNumPeopleOnSquad = NumberOfPlayerControllableMercsInSquad( gusSelectedSoldier->bAssignment ); //Determine for( SoldierID id = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; id <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++id ) { if( id == gusSelectedSoldier ) { continue; } pSoldier = id; if( !pSoldier->flags.fBetweenSectors && pSoldier->sSectorX == gWorldSectorX && pSoldier->sSectorY == gWorldSectorY && pSoldier->bSectorZ == gbWorldSectorZ && pSoldier->stats.bLife >= OKLIFE && ( pSoldier->bAssignment != gusSelectedSoldier->bAssignment || ( pSoldier->bAssignment == VEHICLE && pSoldier->iVehicleId != gusSelectedSoldier->iVehicleId ) ) && pSoldier->bAssignment != ASSIGNMENT_POW && pSoldier->bAssignment != IN_TRANSIT && pSoldier->bAssignment != ASSIGNMENT_DEAD && pSoldier->bAssignment != ASSIGNMENT_MINIEVENT && pSoldier->bAssignment != ASSIGNMENT_REBELCOMMAND && !(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) ) { //KM: We need to determine if there are more than one squad (meaning other concious mercs in a different squad or assignment) // These conditions were done to the best of my knowledge, so if there are other situations that require modification, // then feel free to do so. // anv: added skipping vehicles and checking if soldiers on the same assignment aren't just in two different vehicles gExitDialog.fMultipleSquadsInSector = TRUE; break; } } // Double check that ... // if we are a EPC and are the selected guy, make single move off and disable it.... if ( AM_AN_EPC( gusSelectedSoldier ) ) { // Check if there are more than one in this squad if ( gExitDialog.ubNumPeopleOnSquad > 1 ) { gExitDialog.fSingleMoveOn = FALSE; gExitDialog.fAllMoveOn = TRUE; gExitDialog.fSelectedMercIsEPC = TRUE; } gExitDialog.fSingleMoveDisabled = TRUE; } else { //check to see if we have one selected merc and one or more EPCs. //If so, don't allow the selected merc to leave by himself. //Assuming that the matching squad assignment is in the same sector. UINT16 ubNumMercs = 1; //selected soldier is a merc UINT16 ubNumEPCs = 0; for( SoldierID id = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; id <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++id ) { if( id == gusSelectedSoldier ) { continue; } if( id->bAssignment == gusSelectedSoldier->bAssignment ) { if( AM_AN_EPC( id ) ) { ubNumEPCs++; //record the slot of the epc. If there are more than one EPCs, then //it doesn't matter. This is used in building the text message explaining //why the selected merc can't leave. This is how we extract the EPC's name. gExitDialog.bSingleMoveWillIsolateEPC = id; } else { //We have more than one merc, so we will allow the selected merc to leave alone if //the user so desired. ubNumMercs++; break; } } } if( ubNumMercs == 1 ) { gExitDialog.fSingleMoveOn = FALSE; gExitDialog.fAllMoveOn = TRUE; gExitDialog.fSingleMoveDisabled = TRUE; if( ubNumEPCs > 1 ) { gExitDialog.fSquadHasMultipleEPCs = TRUE;; } } } if( gTacticalStatus.fEnemyInSector ) { if( gExitDialog.fMultipleSquadsInSector ) { //We have multiple squads in a hostile sector. That means that we can't load the adjacent sector. gExitDialog.fGotoSectorDisabled = TRUE; gExitDialog.fGotoSector = FALSE; } else if ( gbWorldSectorZ <= 0 && NumNonPlayerTeamMembersInSector( gWorldSectorX, gWorldSectorY, MILITIA_TEAM ) ) { //Leaving this sector will result in militia being forced to fight the battle, can't load adjacent sector. gExitDialog.fGotoSectorDisabled = TRUE; gExitDialog.fGotoSector = FALSE; } if( !gExitDialog.fMultipleSquadsInSector && !gExitDialog.fAllMoveOn ) { gExitDialog.fGotoSectorDisabled = TRUE; gExitDialog.fGotoSector = FALSE; } } if( !gExitDialog.fMultipleSquadsInSector && gExitDialog.fAllMoveOn ) { gExitDialog.fGotoSectorDisabled = TRUE; } gExitDialog.ubDirection = ubDirection; gExitDialog.sAdditionalData = sAdditionalData; gExitDialog.iBoxId = PrepareMercPopupBox( -1, DIALOG_MERC_POPUP_BACKGROUND, DIALOG_MERC_POPUP_BORDER, TacticalStr[ EXIT_GUI_TITLE_STR ], 100, 85, 2, 75, &usTextBoxWidth, &usTextBoxHeight ); gExitDialog.sX = (INT16)( ( ( ( aRect.iRight - aRect.iLeft ) - usTextBoxWidth ) / 2 ) + aRect.iLeft ); gExitDialog.sY = (INT16)( ( ( ( aRect.iBottom - aRect.iTop ) - usTextBoxHeight ) / 2 ) + aRect.iTop ); gExitDialog.usWidth = usTextBoxWidth; gExitDialog.usHeight = usTextBoxHeight; guiPendingOverrideEvent = EX_EXITSECTORMENU; HandleTacticalUI( ); gfInSectorExitMenu = TRUE; MSYS_DefineRegion( &(gExitDialog.BackRegion), 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_HIGHEST-1, CURSOR_NORMAL, MSYS_NO_CALLBACK, SectorExitBackgroundCallback ); gExitDialog.iButtonImages = LoadButtonImage( "INTERFACE\\popupbuttons.sti", -1,0,-1,1,-1 ); MSYS_DefineRegion( &gExitDialog.SingleRegion, (INT16)(gExitDialog.sX + 20), (INT16)(gExitDialog.sY + 37), (INT16)(gExitDialog.sX + 45 + 120), (INT16)(gExitDialog.sY + 37 + 12), MSYS_PRIORITY_HIGHEST, CURSOR_NORMAL, SingleRegionMoveCallback, SingleRegionCallback ); MSYS_AllowDisabledRegionFastHelp( &gExitDialog.SingleRegion, TRUE ); MSYS_DefineRegion( &(gExitDialog.AllRegion), (INT16)(gExitDialog.sX + 20), (INT16)(gExitDialog.sY + 57), (INT16)(gExitDialog.sX + 45 + 120), (INT16)(gExitDialog.sY + 57 + 12), MSYS_PRIORITY_HIGHEST, CURSOR_NORMAL, AllRegionMoveCallback, AllRegionCallback ); MSYS_AllowDisabledRegionFastHelp( &gExitDialog.AllRegion, TRUE ); MSYS_DefineRegion( &(gExitDialog.LoadRegion), (INT16)(gExitDialog.sX + 155), (INT16)(gExitDialog.sY + 45), (INT16)(gExitDialog.sX + 180 + 85), (INT16)(gExitDialog.sY + 45 + 15), MSYS_PRIORITY_HIGHEST, CURSOR_NORMAL, LoadRegionMoveCallback, LoadRegionCallback ); MSYS_AllowDisabledRegionFastHelp( &gExitDialog.LoadRegion, TRUE ); gExitDialog.uiLoadCheckButton = CreateCheckBoxButton( (INT16)(gExitDialog.sX + 155 ), (INT16)(gExitDialog.sY + 43 ), "INTERFACE\\popupcheck.sti", MSYS_PRIORITY_HIGHEST, CheckLoadMapCallback ); gExitDialog.uiSingleMoveButton = CreateCheckBoxButton( (INT16)(gExitDialog.sX + 20 ), (INT16)(gExitDialog.sY + 35 ), "INTERFACE\\popupradiobuttons.sti", MSYS_PRIORITY_HIGHEST, SingleMoveCallback ); gExitDialog.uiAllMoveButton = CreateCheckBoxButton( (INT16)(gExitDialog.sX + 20 ), (INT16)(gExitDialog.sY + 55 ), "INTERFACE\\popupradiobuttons.sti", MSYS_PRIORITY_HIGHEST, AllMoveCallback ); gExitDialog.uiOKButton = CreateIconAndTextButton( gExitDialog.iButtonImages, TacticalStr[ OK_BUTTON_TEXT_STR ], FONT12ARIAL, FONT_MCOLOR_WHITE, DEFAULT_SHADOW, FONT_MCOLOR_WHITE, DEFAULT_SHADOW, TEXT_CJUSTIFIED, (INT16)(gExitDialog.sX + 65 ), (INT16)(gExitDialog.sY + 78 ), BUTTON_TOGGLE ,MSYS_PRIORITY_HIGHEST, DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)OKCallback ); gExitDialog.uiCancelButton = CreateIconAndTextButton( gExitDialog.iButtonImages, TacticalStr[ CANCEL_BUTTON_TEXT_STR ], FONT12ARIAL, FONT_MCOLOR_WHITE, DEFAULT_SHADOW, FONT_MCOLOR_WHITE, DEFAULT_SHADOW, TEXT_CJUSTIFIED, (INT16)(gExitDialog.sX + 135 ), (INT16)(gExitDialog.sY + 78 ), BUTTON_TOGGLE ,MSYS_PRIORITY_HIGHEST, DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)CancelCallback ); gfIgnoreScrolling = TRUE; InterruptTime(); PauseGame(); LockPauseState( 21 ); return( TRUE ); } void DoneFadeInWarp( void ) { } void DoneFadeOutWarpCallback( void ) { SOLDIERTYPE *pSoldier; // Warp! // Set insertion data... SoldierID cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; // look for all mercs on the same team, for ( ; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++cnt ) { pSoldier = cnt; // Are we in this sector, On the current squad? if ( pSoldier->bActive && pSoldier->stats.bLife >= OKLIFE && pSoldier->bInSector ) { gfTacticalTraversal = TRUE; SetGroupSectorValue( gsWarpWorldX, gsWarpWorldY, gbWarpWorldZ, pSoldier->ubGroupID ); // Set next sectore pSoldier->sSectorX = gsWarpWorldX; pSoldier->sSectorY = gsWarpWorldY; pSoldier->bSectorZ = gbWarpWorldZ; // Set gridno pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO; pSoldier->usStrategicInsertionData = gsWarpGridNo; // Set direction to face.... pSoldier->ubInsertionDirection = 100 + NORTHWEST; } } // OK, insertion data found, enter sector! SetCurrentWorldSector( gsWarpWorldX, gsWarpWorldY, gbWarpWorldZ ); // OK, once down here, adjust the above map with crate info.... gfTacticalTraversal = FALSE; gpTacticalTraversalGroup = NULL; gpTacticalTraversalChosenSoldier = NULL; gFadeInDoneCallback = DoneFadeInWarp; FadeInGameScreen( ); } void WarpToSurfaceCallback( UINT8 bExitValue ) { if( bExitValue == MSG_BOX_RETURN_YES ) { gFadeOutDoneCallback = DoneFadeOutWarpCallback; FadeOutGameScreen( ); } else { InternalInitSectorExitMenu( gubExitGUIDirection, gsExitGUIAdditionalData ); } } BOOLEAN InitSectorExitMenu( UINT8 ubDirection, INT32 sAdditionalData )//dnl ch56 151009 { gubExitGUIDirection = ubDirection; gsExitGUIAdditionalData = sAdditionalData; if ( gbWorldSectorZ >= 2 && gubQuest[ QUEST_CREATURES ] == QUESTDONE ) { if ( GetWarpOutOfMineCodes( &gsWarpWorldX, &gsWarpWorldY, &gbWarpWorldZ, &gsWarpGridNo ) ) { // ATE: Check if we are in a creature lair and bring up box if so.... DoMessageBox( MSG_BOX_BASIC_STYLE, gzLateLocalizedString[ 33 ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, WarpToSurfaceCallback, NULL ); return( TRUE ); } } return( InternalInitSectorExitMenu( ubDirection, sAdditionalData ) ); } void UpdateSectorExitMenu( ) { if ( gExitDialog.fGotoSector ) { ButtonList[ gExitDialog.uiLoadCheckButton ]->uiFlags |= BUTTON_CLICKED_ON; } else { ButtonList[ gExitDialog.uiLoadCheckButton ]->uiFlags &= (~BUTTON_CLICKED_ON ); } if ( gExitDialog.fSingleMove ) { ButtonList[ gExitDialog.uiSingleMoveButton ]->uiFlags |= BUTTON_CLICKED_ON; } else { ButtonList[ gExitDialog.uiSingleMoveButton ]->uiFlags &=(~BUTTON_CLICKED_ON ); } if ( gExitDialog.fAllMove ) { ButtonList[ gExitDialog.uiAllMoveButton ]->uiFlags |= BUTTON_CLICKED_ON; } else { ButtonList[ gExitDialog.uiAllMoveButton ]->uiFlags &=(~BUTTON_CLICKED_ON ); } if ( gExitDialog.fGotoSectorDisabled ) { DisableButton( gExitDialog.uiLoadCheckButton ); MSYS_DisableRegion(&(gExitDialog.LoadRegion ) ); if( gExitDialog.fMultipleSquadsInSector && gExitDialog.fGotoSectorText && gTacticalStatus.fEnemyInSector ) { //We have multiple squads in a hostile sector. That means that we can't load the adjacent sector. SetButtonFastHelpText( gExitDialog.uiLoadCheckButton, pExitingSectorHelpText[ EXIT_GUI_CANT_LEAVE_HOSTILE_SECTOR_HELPTEXT ] ); SetRegionFastHelpText( &gExitDialog.LoadRegion, pExitingSectorHelpText[ EXIT_GUI_CANT_LEAVE_HOSTILE_SECTOR_HELPTEXT ] ); } else if( gExitDialog.fGotoSectorText ) { //travesal is quick enough to allow the player to "warp" to the next sector and we MUST load it. SetButtonFastHelpText( gExitDialog.uiLoadCheckButton, pExitingSectorHelpText[ EXIT_GUI_MUST_LOAD_ADJACENT_SECTOR_HELPTEXT ] ); SetRegionFastHelpText( &gExitDialog.LoadRegion, pExitingSectorHelpText[ EXIT_GUI_MUST_LOAD_ADJACENT_SECTOR_HELPTEXT ] ); } else { //traversal takes too long to warrant instant travel (we MUST go to mapscreen) SetButtonFastHelpText( gExitDialog.uiLoadCheckButton, pExitingSectorHelpText[ EXIT_GUI_MUST_GOTO_MAPSCREEN_HELPTEXT ] ); SetRegionFastHelpText( &gExitDialog.LoadRegion, pExitingSectorHelpText[ EXIT_GUI_MUST_GOTO_MAPSCREEN_HELPTEXT ] ); } } else { EnableButton( gExitDialog.uiLoadCheckButton ); MSYS_EnableRegion(&(gExitDialog.LoadRegion ) ); if( gExitDialog.fGotoSectorText ) { //travesal is quick enough to allow the player to "warp" to the next sector and we load it. SetButtonFastHelpText( gExitDialog.uiLoadCheckButton, pExitingSectorHelpText[ EXIT_GUI_LOAD_ADJACENT_SECTOR_HELPTEXT ] ); SetRegionFastHelpText( &gExitDialog.LoadRegion, pExitingSectorHelpText[ EXIT_GUI_LOAD_ADJACENT_SECTOR_HELPTEXT ] ); } else { //traversal takes too long to warrant instant travel (we go to mapscreen) SetButtonFastHelpText( gExitDialog.uiLoadCheckButton, pExitingSectorHelpText[ EXIT_GUI_GOTO_MAPSCREEN_HELPTEXT ] ); SetRegionFastHelpText( &gExitDialog.LoadRegion, pExitingSectorHelpText[ EXIT_GUI_GOTO_MAPSCREEN_HELPTEXT ] ); } } if ( gExitDialog.fSingleMoveDisabled ) { DisableButton( gExitDialog.uiSingleMoveButton ); MSYS_DisableRegion(&(gExitDialog.SingleRegion) ); if( gExitDialog.fSelectedMercIsEPC ) { //EPCs cannot leave the sector alone and must be escorted CHAR16 str[ 256 ]; swprintf( str, pExitingSectorHelpText[ EXIT_GUI_ESCORTED_CHARACTERS_MUST_BE_ESCORTED_HELPTEXT ], gusSelectedSoldier->name ); SetButtonFastHelpText( gExitDialog.uiSingleMoveButton, str ); SetRegionFastHelpText( &gExitDialog.SingleRegion, str ); } else if( gExitDialog.bSingleMoveWillIsolateEPC != -1 ) { //It has been previously determined that there are only two mercs in the squad, the selected merc //isn't an EPC, but the other merc is. That means that this merc cannot leave the sector alone //as he would isolate the EPC. CHAR16 str[ 256 ]; if( !gExitDialog.fSquadHasMultipleEPCs ) { if( gMercProfiles[ gusSelectedSoldier->ubProfile ].bSex == MALE ) { //male singular swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_MALE_SINGULAR ], gusSelectedSoldier->name, MercPtrs[ gExitDialog.bSingleMoveWillIsolateEPC ]->name ); } else { //female singular swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_FEMALE_SINGULAR ], gusSelectedSoldier->name, MercPtrs[ gExitDialog.bSingleMoveWillIsolateEPC ]->name ); } } else { if( gMercProfiles[ gusSelectedSoldier->ubProfile ].bSex == MALE ) { //male plural swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_MALE_PLURAL ], gusSelectedSoldier->name ); } else { //female plural swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_FEMALE_PLURAL ], gusSelectedSoldier->name ); } } SetButtonFastHelpText( gExitDialog.uiSingleMoveButton, str ); SetRegionFastHelpText( &gExitDialog.SingleRegion, str ); } } else { CHAR16 str[ 256 ]; EnableButton( gExitDialog.uiSingleMoveButton ); MSYS_EnableRegion(&(gExitDialog.SingleRegion) ); swprintf( str, pExitingSectorHelpText[ EXIT_GUI_SINGLE_TRAVERSAL_WILL_SEPARATE_SQUADS_HELPTEXT ], gusSelectedSoldier->name ); SetButtonFastHelpText( gExitDialog.uiSingleMoveButton, str ); SetRegionFastHelpText( &gExitDialog.SingleRegion, str ); } if ( gExitDialog.fAllMoveDisabled ) { DisableButton( gExitDialog.uiAllMoveButton ); MSYS_DisableRegion(&(gExitDialog.AllRegion) ); if( gExitDialog.fUncontrolledRobotInSquad ) { SetButtonFastHelpText( gExitDialog.uiAllMoveButton, gzLateLocalizedString[ 1 ] ); SetRegionFastHelpText( &gExitDialog.AllRegion, gzLateLocalizedString[ 1 ] ); } else { SetButtonFastHelpText( gExitDialog.uiAllMoveButton, pExitingSectorHelpText[ EXIT_GUI_ALL_MERCS_MUST_BE_TOGETHER_TO_ALLOW_HELPTEXT ] ); SetRegionFastHelpText( &gExitDialog.AllRegion, pExitingSectorHelpText[ EXIT_GUI_ALL_MERCS_MUST_BE_TOGETHER_TO_ALLOW_HELPTEXT ] ); } } else { EnableButton( gExitDialog.uiAllMoveButton ); MSYS_EnableRegion(&(gExitDialog.AllRegion) ); SetButtonFastHelpText( gExitDialog.uiAllMoveButton, pExitingSectorHelpText[ EXIT_GUI_ALL_TRAVERSAL_WILL_MOVE_CURRENT_SQUAD_HELPTEXT ] ); SetRegionFastHelpText( &gExitDialog.AllRegion, pExitingSectorHelpText[ EXIT_GUI_ALL_TRAVERSAL_WILL_MOVE_CURRENT_SQUAD_HELPTEXT ] ); } } void RenderSectorExitMenu( ) { InputAtom Event; RestoreBackgroundRects(); // ATE: Reset mouse Y gsGlobalCursorYOffset = 0; SetCurrentCursorFromDatabase( CURSOR_NORMAL ); while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) { if( Event.usEvent == KEY_DOWN ) { switch( Event.usParam ) { case ESC: RemoveSectorExitMenu( FALSE ); return; case ENTER: RemoveSectorExitMenu( TRUE ); return; } } } UpdateSectorExitMenu( ); RenderMercPopUpBoxFromIndex( gExitDialog.iBoxId, gExitDialog.sX, gExitDialog.sY, FRAME_BUFFER ); InvalidateRegion( gExitDialog.sX, gExitDialog.sY, gExitDialog.usWidth, gExitDialog.usHeight ); SetFont( FONT12ARIAL ); SetFontBackground( FONT_MCOLOR_BLACK ); if ( gExitDialog.fSingleMoveDisabled ) { SetFontForeground( FONT_MCOLOR_DKGRAY ); } else if ( gExitDialog.fSingleMoveHilighted ) { SetFontForeground( FONT_MCOLOR_LTYELLOW ); } else { SetFontForeground( FONT_MCOLOR_WHITE ); } mprintf( gExitDialog.sX + 45, gExitDialog.sY + 37, TacticalStr[ EXIT_GUI_SELECTED_MERC_STR ] ); if ( gExitDialog.fAllMoveDisabled ) { SetFontForeground( FONT_MCOLOR_DKGRAY ); } else if ( gExitDialog.fAllMoveHilighted ) { SetFontForeground( FONT_MCOLOR_LTYELLOW ); } else { SetFontForeground( FONT_MCOLOR_WHITE ); } mprintf( gExitDialog.sX + 45, gExitDialog.sY + 57, TacticalStr[ EXIT_GUI_ALL_MERCS_IN_SQUAD_STR ] ); if ( gExitDialog.fGotoSectorDisabled ) { SetFontForeground( FONT_MCOLOR_DKGRAY ); } else if ( gExitDialog.fGotoSectorHilighted ) { SetFontForeground( FONT_MCOLOR_LTYELLOW ); } else { SetFontForeground( FONT_MCOLOR_WHITE ); } if( gExitDialog.fGotoSectorText ) { //only if tactical traversal is from one town sector to another town sector (5 minute convenience warp) mprintf( gExitDialog.sX + 180, gExitDialog.sY + 45, TacticalStr[ EXIT_GUI_GOTO_SECTOR_STR ] ); } else { //most sectors don't allow tactical traversal. Exiting results in entering the mapscreen. mprintf( gExitDialog.sX + 180, gExitDialog.sY + 45, TacticalStr[ EXIT_GUI_GOTO_MAP_STR ] ); } SaveBackgroundRects(); RenderFastHelp(); MarkAButtonDirty( gExitDialog.uiLoadCheckButton ); MarkAButtonDirty( gExitDialog.uiSingleMoveButton ); MarkAButtonDirty( gExitDialog.uiAllMoveButton ); MarkAButtonDirty( gExitDialog.uiOKButton ); MarkAButtonDirty( gExitDialog.uiCancelButton ); } BOOLEAN HandleSectorExitMenu( ) { return( FALSE ); //Why??? } void RemoveSectorExitMenu( BOOLEAN fOk ) { CHAR16 Str[ 50 ]; if ( gfInSectorExitMenu ) { guiPendingOverrideEvent = A_CHANGE_TO_MOVE; RemoveButton( gExitDialog.uiLoadCheckButton ); RemoveButton( gExitDialog.uiSingleMoveButton ); RemoveButton( gExitDialog.uiAllMoveButton ); RemoveButton( gExitDialog.uiOKButton ); RemoveButton( gExitDialog.uiCancelButton ); UnloadButtonImage( gExitDialog.iButtonImages ); MSYS_RemoveRegion(&(gExitDialog.BackRegion) ); MSYS_RemoveRegion(&(gExitDialog.SingleRegion) ); MSYS_RemoveRegion(&(gExitDialog.AllRegion) ); MSYS_RemoveRegion(&(gExitDialog.LoadRegion) ); //Remove the popup box RemoveMercPopupBoxFromIndex( gExitDialog.iBoxId ); gExitDialog.iBoxId = -1; gfIgnoreScrolling = FALSE; SetRenderFlags( RENDER_FLAG_FULL ); gfInSectorExitMenu = FALSE; UnLockPauseState(); UnPauseGame(); EndModalTactical(); gfIgnoreScrolling = FALSE; // if we are an EPC, don't allow this if nobody else on squad if ( fOk && AM_AN_EPC( gusSelectedSoldier ) ) { // Check if there are more than one in this squad if ( gExitDialog.ubNumPeopleOnSquad == 0 ) { swprintf( Str, pMessageStrings[ MSG_EPC_CANT_TRAVERSE ], gusSelectedSoldier->name ); DoMessageBox( MSG_BOX_BASIC_STYLE, Str, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL ); return; } } if ( fOk ) { #ifdef JA2UB //ja25 ub //If this is the sector with the power fan if( gWorldSectorX == 13 && gWorldSectorY == 10 && gbWorldSectorZ == 0 ) { //Remeber how the player got through HandleHowPlayerGotThroughFan(); } #endif // Handle the effects here! if ( gExitDialog.fAllMove && gExitDialog.fGotoSector && gExitDialog.fGotoSectorText ) { JumpIntoAdjacentSector( gExitDialog.ubDirection, JUMP_ALL_LOAD_NEW, gExitDialog.sAdditionalData ); return; } //KM : August 6, 1999 Patch fix // Added the !gExitDialog.fGotoSectorText to the conditions to prevent the player from LOADING an // adjacent sector (this only happens when instant traversal is overriden because of a battle in progress // in the previous sector if ( gExitDialog.fAllMove && ( !gExitDialog.fGotoSector || !gExitDialog.fGotoSectorText ) ) { // Here, move all men out of sector but don't load new one... JumpIntoAdjacentSector( gExitDialog.ubDirection, JUMP_ALL_NO_LOAD, gExitDialog.sAdditionalData ); } if ( gExitDialog.fSingleMove && gExitDialog.fGotoSector && gExitDialog.fGotoSectorText ) { JumpIntoAdjacentSector( gExitDialog.ubDirection, JUMP_SINGLE_LOAD_NEW, gExitDialog.sAdditionalData ); return; } //KM : August 6, 1999 Patch fix // Added the !gExitDialog.fGotoSectorText to the conditions to prevent the player from LOADING an // adjacent sector (this only happens when instant traversal is overriden because of a battle in progress // in the previous sector if ( gExitDialog.fSingleMove && ( !gExitDialog.fGotoSector || !gExitDialog.fGotoSectorText ) ) { // Here, move all men out of sector but don't load new one... JumpIntoAdjacentSector( gExitDialog.ubDirection, JUMP_SINGLE_NO_LOAD, gExitDialog.sAdditionalData ); } } } } void CheckLoadMapCallback( GUI_BUTTON *btn, INT32 reason ) { if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { gExitDialog.fGotoSector =!gExitDialog.fGotoSector; } } void SingleMoveAction() { //KM: New logic Mar2 '99 if( !gExitDialog.fMultipleSquadsInSector ) { if( gTacticalStatus.fEnemyInSector ) { //if enemy in sector, and mercs will be left behind, prevent user from selecting load gExitDialog.fGotoSectorDisabled = TRUE; gExitDialog.fGotoSector = FALSE; } else { //freedom to load or not load gExitDialog.fGotoSectorDisabled = FALSE; } } else { gExitDialog.fGotoSector = FALSE; } gExitDialog.fSingleMove = TRUE; gExitDialog.fAllMove = FALSE; //end //previous logic /* gExitDialog.fGotoSector = FALSE; gExitDialog.fSingleMove = TRUE; gExitDialog.fAllMove = FALSE; */ } void AllMoveAction() { //KM: New logic Mar2 '99 if( !gExitDialog.fMultipleSquadsInSector ) { gExitDialog.fGotoSectorDisabled = TRUE; gExitDialog.fGotoSector = TRUE; } gExitDialog.fSingleMove = FALSE; gExitDialog.fAllMove = TRUE; //end //previous logic /* gExitDialog.fSingleMove = FALSE; gExitDialog.fAllMove = TRUE; */ } void SingleMoveCallback(GUI_BUTTON *btn, INT32 reason ) { if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { SingleMoveAction(); } } void AllMoveCallback(GUI_BUTTON *btn, INT32 reason ) { if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { AllMoveAction(); } } void OKCallback(GUI_BUTTON *btn, INT32 reason ) { if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { btn->uiFlags |= BUTTON_CLICKED_ON; } else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { btn->uiFlags &= (~BUTTON_CLICKED_ON ); // OK, exit RemoveSectorExitMenu( TRUE ); } } void CancelCallback(GUI_BUTTON *btn, INT32 reason ) { if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { btn->uiFlags |= BUTTON_CLICKED_ON; } else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { btn->uiFlags &= (~BUTTON_CLICKED_ON ); // OK, exit RemoveSectorExitMenu( FALSE ); } } void SectorExitBackgroundCallback( MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { //gMsgBox.bHandled = MSG_BOX_RETURN_NO; } } void SingleRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { SingleMoveAction(); } } void AllRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { AllMoveAction(); } } void LoadRegionCallback( MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { gExitDialog.fGotoSector =!gExitDialog.fGotoSector; } } void SingleRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_MOVE ) { gExitDialog.fSingleMoveHilighted = TRUE; } else if ( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { gExitDialog.fSingleMoveHilighted = FALSE; } } void AllRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_MOVE ) { gExitDialog.fAllMoveHilighted = TRUE; } else if ( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { gExitDialog.fAllMoveHilighted = FALSE; } } void LoadRegionMoveCallback( MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_MOVE ) { gExitDialog.fGotoSectorHilighted = TRUE; } else if ( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { gExitDialog.fGotoSectorHilighted = FALSE; } }