// WANNE: SCROLL BUTTONS CODE IS OUTCOMMENTED (search for // WANNE: ) #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #include "HelpScreen.h" #else #include "mapscreen.h" #include #include #include #include "gameloop.h" #include "sgp.h" #include "vobject.h" #include "wcheck.h" #include "worlddef.h" #include "input.h" #include "font.h" #include "screenids.h" #include "screens.h" #include "gameloop.h" #include "overhead.h" #include "sysutil.h" #include "input.h" #include "Event Pump.h" #include "Font Control.h" #include "Timer Control.h" #include "Interface.h" #include "Handle UI.h" #include "Interface Items.h" #include "interface utils.h" #include "lighting.h" #include #include #include "cursors.h" #include "Soldier Profile.h" #include "Interface Cursors.h" #include "Interface Panels.h" #include "Interface Control.h" #include "sys globals.h" #include "environment.h" #include "Radar Screen.h" #include "Render Dirty.h" #include "utilities.h" #include "Game Init.h" #include "renderworld.h" #include "finances.h" #include "message.h" #include "math.h" #include "vsurface.h" #include "vobject_blitters.h" #include "faces.h" #include "PopUpBox.h" #include "Game Clock.h" #include "items.h" #include "vobject.h" #include "Cursor Control.h" #include "text.h" #include "strategic.h" #include "strategicmap.h" #include "interface.h" #include "strategic pathing.h" #include "Map Screen Interface Bottom.h" #include "Map Screen Interface Border.h" #include "Map Screen Interface Map.h" #include "Map Screen Interface.h" #include "Strategic Pathing.h" #include "Assignments.h" #include "Squads.h" #include "Merc Contract.h" #include "Sound Control.h" #include "strategic turns.h" #include "Dialogue Control.h" #include "Map Screen Interface TownMine Info.h" #include "PreBattle Interface.h" #include "Personnel.h" #include "Animated ProgressBar.h" #include "Queen Command.h" #include "LaptopSave.h" #include "Map Screen Interface Map Inventory.h" #include "Vehicles.h" #include "Map Screen Helicopter.h" #include "gamescreen.h" #include "line.h" #include "english.h" #include "Fade Screen.h" #include "Strategic Mines.h" #include "GameVersion.h" #include "SaveLoadScreen.h" #include "Options Screen.h" #include "Auto Resolve.h" #include "meanwhile.h" #include "Campaign.h" #include "Random.h" #include "Air Raid.h" #include "quests.h" #include "Town Militia.h" #include "weapons.h" #include "Player Command.h" #include "Multi Language Graphic Utils.h" #include "HelpScreen.h" #include "Soldier macros.h" #include "Map Information.h" #include "cheats.h" #include "Strategic Town Loyalty.h" #include "GameSettings.h" #include "_Ja25EnglishText.h" #include "Militia Control.h" #include "Tactical Save.h" #include "Explosion Control.h" #include "Creature Spreading.h" #include "email.h" #include "Strategic Status.h" #include "Soldier Create.h" #endif // DEFINES #define MAX_SORT_METHODS 6 // Cursors #define SCREEN_CURSOR CURSOR_NORMAL // Fonts #define CHAR_FONT BLOCKFONT2 // COMPFONT #define ETA_FONT BLOCKFONT2 // Colors #define CHAR_INFO_PANEL_BLOCK_COLOR 60 #define FONT_MAP_DKYELLOW 170 #define CHAR_TITLE_FONT_COLOR 6 #define CHAR_TEXT_FONT_COLOR 5 #define STARTING_COLOR_NUM 5 #define MAP_TIME_UNDER_THIS_DISPLAY_AS_HOURS ( 3 * 24 * 60 ) #define MIN_KB_TO_DO_PRE_LOAD ( 32 * 1024 ) #define DELAY_PER_FLASH_FOR_DEPARTING_PERSONNEL 500 #define GLOW_DELAY 70 #define ASSIGNMENT_DONE_FLASH_TIME 500 #define MINS_TO_FLASH_CONTRACT_TIME (4 * 60) // Coordinate defines #define TOWN_INFO_X 0 #define TOWN_INFO_Y 1 #define PLAYER_INFO_X 0 #define PLAYER_INFO_Y 107 // item description #define MAP_ITEMDESC_START_X 0 #define MAP_ITEMDESC_START_Y PLAYER_INFO_Y #define INV_REGION_X PLAYER_INFO_X #define INV_REGION_Y PLAYER_INFO_Y #define INV_REGION_WIDTH 261 #define INV_REGION_HEIGHT 359-94 #define INV_BTN_X PLAYER_INFO_X + 217 #define INV_BTN_Y PLAYER_INFO_Y + 210 #define MAP_ARMOR_LABEL_X 208 #define MAP_ARMOR_LABEL_Y 180 #define MAP_ARMOR_X 209 #define MAP_ARMOR_Y 189 #define MAP_ARMOR_PERCENT_X 229 #define MAP_ARMOR_PERCENT_Y 190 #define MAP_WEIGHT_LABEL_X 173 #define MAP_WEIGHT_LABEL_Y 256 #define MAP_WEIGHT_X 176 #define MAP_WEIGHT_Y 266 #define MAP_WEIGHT_PERCENT_X 196 #define MAP_WEIGHT_PERCENT_Y 266 #define MAP_CAMMO_LABEL_X 178 #define MAP_CAMMO_LABEL_Y 283 #define MAP_CAMMO_X 176 #define MAP_CAMMO_Y 292 #define MAP_CAMMO_PERCENT_X 196 #define MAP_CAMMO_PERCENT_Y 293 #define MAP_PERCENT_WIDTH 20 #define MAP_PERCENT_HEIGHT 10 #define MAP_INV_STATS_TITLE_FONT_COLOR 6 #define MAP_INV_STATS_TEXT_FONT_COLOR 5 #define PLAYER_INFO_FACE_START_X 9 #define PLAYER_INFO_FACE_START_Y 17 #define PLAYER_INFO_FACE_END_X 60 #define PLAYER_INFO_FACE_END_Y 76 #define INV_BODY_X 71 #define INV_BODY_Y 116 #define NAME_X 4 #define NAME_WIDTH 55 - NAME_X #define ASSIGN_X 60 #define ASSIGN_WIDTH 111 - ASSIGN_X #define SLEEP_X 116 #define SLEEP_WIDTH 135 - SLEEP_X #define LOC_X 140 #define LOC_WIDTH 172 - LOC_X #define DEST_ETA_X 177 #define DEST_ETA_WIDTH 210 - DEST_ETA_X #define TIME_REMAINING_X 215 #define TIME_REMAINING_WIDTH 243 - TIME_REMAINING_X #define CLOCK_Y_START (MAP_BORDER_Y_OFFSET + 298) // 298 #define DEST_PLOT_X (MAP_BORDER_X_OFFSET + 463) //463 #define DEST_PLOT_Y (MAP_BORDER_Y_OFFSET + 345) //345 #define CLOCK_ETA_X (MAP_BORDER_X_OFFSET + 484) //463 - 15 + 6 + 30 #define CLOCK_HOUR_X_START (MAP_BORDER_X_OFFSET + 518) //463 + 25 + 30 #define CLOCK_MIN_X_START (MAP_BORDER_X_OFFSET + 538) //463 + 45 + 30 // contract #define CONTRACT_X 185 #define CONTRACT_Y 50 // trash can #define TRASH_CAN_X 176 #define TRASH_CAN_Y 211 + PLAYER_INFO_Y #define TRASH_CAN_WIDTH 193 - 165 #define TRASH_CAN_HEIGHT 239 - 217 //Text offsets #define Y_OFFSET 2 // The boxes defines #define TRAIN_Y_OFFSET 53 #define TRAIN_X_OFF 65 #define TRAIN_WID 80 #define TRAIN_HEIG 47 #define STRING_X_OFFSET 10 #define STRING_Y_OFFSET 5 #define POP_UP_BOX_X 120 #define POP_UP_BOX_Y 0 #define POP_UP_BOX_WIDTH 60 #define POP_UP_BOX_HEIGHT 100 #define MOUSE_PTR_Y_OFFSET 3 #define POP_UP_Y_OFFSET 3 #define TRAIN_TEXT_Y_OFFSET 4 // char stat positions #define STR_X ( 112 ) #define STR_Y 42 #define DEX_X STR_X #define DEX_Y 32 #define AGL_X STR_X #define AGL_Y 22 #define LDR_X STR_X #define LDR_Y 52 #define WIS_X STR_X #define WIS_Y 62 #define LVL_X ( 159 ) #define LVL_Y AGL_Y #define MRK_X LVL_X #define MRK_Y DEX_Y #define EXP_X LVL_X #define EXP_Y STR_Y #define MEC_X LVL_X #define MEC_Y LDR_Y #define MED_X LVL_X #define MED_Y WIS_Y #define STAT_WID 15 #define STAT_HEI GetFontHeight(CHAR_FONT) #define PIC_NAME_X 8 #define PIC_NAME_Y (66 + 3) #define PIC_NAME_WID 60 - PIC_NAME_X #define PIC_NAME_HEI 75 - PIC_NAME_Y #define CHAR_NAME_X 14 #define CHAR_NAME_Y (2 + 3) #define CHAR_NAME_WID 164 - CHAR_NAME_X #define CHAR_NAME_HEI 11 - CHAR_NAME_Y #define CHAR_LOC_X 76 #define CHAR_LOC_Y 84 #define CHAR_LOC_WID 16 #define CHAR_LOC_HEI 9 #define CHAR_TIME_REMAINING_X 207 #define CHAR_TIME_REMAINING_Y 65 #define CHAR_TIME_REMAINING_WID 258 - CHAR_TIME_REMAINING_X #define CHAR_TIME_REMAINING_HEI GetFontHeight(CHAR_FONT) #define CHAR_SALARY_X CHAR_TIME_REMAINING_X #define CHAR_SALARY_Y 79 #define CHAR_SALARY_WID CHAR_TIME_REMAINING_WID - 8 // for right justify #define CHAR_SALARY_HEI CHAR_TIME_REMAINING_HEI #define CHAR_MEDICAL_X CHAR_TIME_REMAINING_X #define CHAR_MEDICAL_Y 93 #define CHAR_MEDICAL_WID CHAR_TIME_REMAINING_WID - 8 // for right justify #define CHAR_MEDICAL_HEI CHAR_TIME_REMAINING_HEI #define CHAR_ASSIGN_X 182 #define CHAR_ASSIGN1_Y 18 #define CHAR_ASSIGN2_Y 31 #define CHAR_ASSIGN_WID 257 - 178 #define CHAR_ASSIGN_HEI 39 - 29 #define CHAR_HP_X 133 #define CHAR_HP_Y 77 + 3 #define CHAR_HP_WID 175 - CHAR_HP_X #define CHAR_HP_HEI 90 - CHAR_HP_Y #define CHAR_MORALE_X 133 #define CHAR_MORALE_Y 91 + 3 #define CHAR_MORALE_WID 175 - CHAR_MORALE_X #define CHAR_MORALE_HEI 101 - CHAR_MORALE_Y #define CROSS_X 195 #define CROSS_Y 83 #define CROSS_HEIGHT 20 #define CROSS_WIDTH 20 #define CHAR_PAY_X 150 #define CHAR_PAY_Y 80+4 #define CHAR_PAY_HEI GetFontHeight(CHAR_FONT) #define CHAR_PAY_WID CROSS_X-CHAR_PAY_X #define SOLDIER_PIC_X 9 #define SOLDIER_PIC_Y 20 #define SOLDIER_HAND_X 6 #define SOLDIER_HAND_Y 81 //#define TM_INV_WIDTH 58 //#define TM_INV_HEIGHT 23 // WANNE: The position of the clock in the strategy screen //#define CLOCK_X (SCREEN_WIDTH - 86) //554 //#define CLOCK_Y (SCREEN_HEIGHT - 21) //459 #define RGB_WHITE ( FROMRGB( 255, 255, 255 ) ) #define RGB_YELLOW ( FROMRGB( 255, 255, 0 ) ) #define RGB_NEAR_BLACK ( FROMRGB( 0, 0, 1 ) ) // ENUMS // ARM: NOTE that these map "events" are never actually saved in a player's game in any way enum { MAP_EVENT_NONE, MAP_EVENT_CLICK_SECTOR, MAP_EVENT_PLOT_PATH, MAP_EVENT_CANCEL_PATH, #ifdef JA2BETAVERSION MAP_EVENT_VIEWAI #endif }; // STRUCTURES / TYPEDEFS struct rgbcolor { UINT8 ubRed; UINT8 ubGreen; UINT8 ubBlue; }; typedef struct rgbcolor RGBCOLOR; struct lineoftext { STR16 pLineText; UINT32 uiFont; struct lineoftext *pNext; }; typedef struct lineoftext LineText; typedef LineText *LineTextPtr; struct popbox { UINT16 usTopX; UINT16 usTopY; UINT16 usWidth; UINT16 usHeight; LineTextPtr pBoxText; struct popbox *pNext; }; typedef struct popbox PopUpBox; typedef PopUpBox *PopUpBoxPtr; // TABLES RGBCOLOR GlowColorsA[]={ {0,0,0}, {25,0,0}, {50,0,0}, {75,0,0}, {100,0,0}, {125,0,0}, {150,0,0}, {175,0,0}, {200,0,0}, {225,0,0}, {250,0,0}, }; /* unused RGBCOLOR GlowColorsB[]={ {0,0,0}, {25,25,0}, {50,50,0}, {75,75,0}, {100,100,0}, {125,125,0}, {150,150,0}, {175,175,0}, {200,200,0}, {225,225,0}, {255,255,0}, }; RGBCOLOR GlowColorsC[]={ {0,0,0}, {25,0,25}, {50,0,50}, {75,0,75}, {100,0,100}, {125,0,125}, {150,0,150}, {175,0,175}, {200,0,200}, {225,0,225}, {255,0,255}, }; */ //SGPPoint gMapSortButtons[ MAX_SORT_METHODS ]={ // {12,125}, // {68,125}, // {124,125}, // {148,125}, // {185,125}, // {223,125}, //}; SGPPoint gMapSortButtons[ MAX_SORT_METHODS ]={ {5,113}, {61,113}, {117,113}, {141,113}, {178,113}, {216,113}, }; // map screen's inventory panel pockets - top right corner coordinates INV_REGION_DESC gMapScreenInvPocketXY[] = { 204,116, // HELMETPOS 204,145, // VESTPOS 204,205, // LEGPOS, 21, 116, // HEAD1POS 21, 140, // HEAD2POS 21, 194, // HANDPOS, 21, 218, // SECONDHANDPOS 98, 251, // BIGPOCK1 98, 275, // BIGPOCK2 98, 299, // BIGPOCK3 98, 323, // BIGPOCK4 22, 251, // SMALLPOCK1 22, 275, // SMALLPOCK2 22, 299, // SMALLPOCK3 22, 323, // SMALLPOCK4 60, 251, // SMALLPOCK5 60, 275, // SMALLPOCK6 60, 299, // SMALLPOCK7 60, 323 // SMALLPOCK8 }; INV_REGION_DESC gSCamoXY = { INV_BODY_X, INV_BODY_Y // X, Y Location of Map screen's Camouflage region }; // WANNE: // buttons images //UINT32 guiMapMercsScrollButtonsImage[ 2 ]; //UINT32 guiMapMercsScrollButtons[ 2 ]; // //UINT32 guiMapVehicleScrollButtonsImage[ 2 ]; //UINT32 guiMapVehicleScrollButtons [ 2 ]; extern UINT16 usVehicleY; // WANNE: // button enums //enum{ // MAP_SCROLL_MERCS_UP =0, // MAP_SCROLL_MERCS_DOWN, //}; // //enum{ // MAP_SCROLL_VEHICLE_UP =0, // MAP_SCROLL_VEHICLE_DOWN, //}; // GLOBAL VARIABLES (OURS) // WANNE: //void CreateButtonsForScrolling(void); //void DeleteButtonsForScrolling(void); void BtnMessageUpMapScreenCallback( GUI_BUTTON *btn,INT32 reason ); BOOLEAN fScrollButtonsInitialized = FALSE; BOOLEAN fFlashAssignDone = FALSE; BOOLEAN fInMapMode = FALSE; BOOLEAN fMapPanelDirty=TRUE; BOOLEAN fTeamPanelDirty = TRUE; BOOLEAN fCharacterInfoPanelDirty = TRUE; BOOLEAN gfLoadPending = FALSE; BOOLEAN fReDrawFace=FALSE; BOOLEAN fFirstTimeInMapScreen = TRUE; BOOLEAN fShowInventoryFlag = FALSE; BOOLEAN fMapInventoryItem=FALSE; BOOLEAN fShowDescriptionFlag=FALSE; // are the graphics for mapscreen preloaded? BOOLEAN fPreLoadedMapGraphics = FALSE; BOOLEAN gfHotKeyEnterSector = FALSE; BOOLEAN fOneFrame = FALSE; BOOLEAN fShowFaceHightLight = FALSE; BOOLEAN fShowItemHighLight = FALSE; BOOLEAN gfAllowSkyriderTooFarQuote = FALSE; BOOLEAN fJustFinishedPlotting = FALSE; // for the flashing of the contract departure time...for when mercs are leaving in an hour or less BOOLEAN fFlashContractFlag = FALSE; BOOLEAN fShowTrashCanHighLight = FALSE; // the flags for display of pop up boxes/menus BOOLEAN fEndPlotting = FALSE; BOOLEAN gfInConfirmMapMoveMode = FALSE; BOOLEAN gfInChangeArrivalSectorMode = FALSE; // redraw character list BOOLEAN fDrawCharacterList = TRUE; // was the cursor set to the checkmark? BOOLEAN fCheckCursorWasSet = FALSE; BOOLEAN fShowingMapDisableBox = FALSE; BOOLEAN fShowFrameRate = FALSE; //BOOLEAN fMapExitDueToMessageBox = FALSE; BOOLEAN fEndShowInventoryFlag = FALSE; // draw the temp path BOOLEAN fDrawTempPath = TRUE; BOOLEAN gfCharacterListInited = FALSE; BOOLEAN gfGlowTimerExpired = FALSE; //not required to be saved. The flag is set to allow mapscreen to render once, then transition the //current tactical battle into autoresolve. BOOLEAN gfTransitionMapscreenToAutoResolve = FALSE; BOOLEAN gfSkyriderEmptyHelpGiven = FALSE; BOOLEAN gfRequestGiveSkyriderNewDestination = FALSE; BOOLEAN gfFirstMapscreenFrame = FALSE; BOOLEAN gfMapPanelWasRedrawn = FALSE; UINT8 gubMAP_HandInvDispText[ NUM_INV_SLOTS ]; // currently selected character's list index INT8 bSelectedInfoChar = -1; // map sort button images INT32 giMapSortButtonImage[ MAX_SORT_METHODS ] = { -1, -1, -1, -1, -1, -1 }; INT32 giMapSortButton[ MAX_SORT_METHODS ] = { -1, -1, -1, -1, -1, -1 }; INT32 giCharInfoButtonImage[ 2 ]; INT32 giCharInfoButton[ 2 ] = { -1, -1 }; INT32 giMapInvButtonDoneImage; INT32 giMapInvDoneButton = -1; INT32 giMapContractButton = -1; INT32 giMapContractButtonImage; //INT32 giMapInvButton = -1; //INT32 giMapInvButtonImage; INT32 giSortStateForMapScreenList = 0; INT32 giCommonGlowBaseTime = 0; INT32 giFlashAssignBaseTime = 0; INT32 giFlashContractBaseTime = 0; UINT32 guiFlashCursorBaseTime = 0; INT32 giPotCharPathBaseTime = 0; /* // next and prev INT32 giMapInvPrev; INT32 giMapInvNext; INT32 giMapInvPrevImage; INT32 giMapInvNextImage; */ extern UINT32 guiVObjectSize; extern UINT32 guiVSurfaceSize; extern UINT8 gubHandPos; extern UINT16 gusOldItemIndex; extern UINT16 gusNewItemIndex; extern BOOLEAN gfDeductPoints; extern void CleanUpStack( OBJECTTYPE * pObj, OBJECTTYPE * pCursorObj ); UINT32 guiCHARLIST; UINT32 guiCHARINFO; UINT32 guiSleepIcon; UINT32 guiCROSS; UINT32 guiMAPINV; UINT32 guiMapInvSecondHandBlockout; UINT32 guiULICONS; UINT32 guiNewMailIcons; UINT32 guiLEVELMARKER; // the white rectangle highlighting the current level on the map border // misc mouse regions MOUSE_REGION gCharInfoFaceRegion; MOUSE_REGION gCharInfoHandRegion; MOUSE_REGION gMPanelRegion; MOUSE_REGION gMapViewRegion; MOUSE_REGION gMapScreenMaskRegion; MOUSE_REGION gTrashCanRegion; // mouse regions for team info panel MOUSE_REGION gTeamListNameRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListAssignmentRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListSleepRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListLocationRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListDestinationRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListContractRegion[ MAX_CHARACTER_COUNT ]; OBJECTTYPE gItemPointer; SOLDIERTYPE *gpItemPointerSoldier; PathStPtr gpCharacterPreviousMercPath[ MAX_CHARACTER_COUNT ]; PathStPtr gpHelicopterPreviousMercPath = NULL; // GLOBAL VARIABLES (EXTERNAL) extern BOOLEAN fHoveringHelicopter; extern BOOLEAN fDeletedNode; extern BOOLEAN gfRenderPBInterface; extern BOOLEAN fMapScreenBottomDirty; extern BOOLEAN fResetTimerForFirstEntryIntoMapScreen; extern BOOLEAN gfStartedFromMapScreen; extern BOOLEAN gfUsePersistantPBI; extern BOOLEAN gfOneFramePauseOnExit; // the selected list of mercs extern BOOLEAN fSelectedListOfMercsForMapScreen[ MAX_CHARACTER_COUNT ]; extern INT32 iDialogueBox; extern INT32 giMapInvDescButton; extern UINT32 guiBrownBackgroundForTeamPanel; // the town mine info box extern INT32 ghTownMineBox; // border and bottom buttons extern INT32 giMapBorderButtons[]; extern UINT32 guiMapButtonInventory[]; // the mine icon extern UINT32 guiMINEICON; extern UINT32 guiSecItemHiddenVO; extern UINT32 guiUIMessageTimeDelay; extern PathStPtr pTempCharacterPath; extern PathStPtr pTempHelicopterPath; extern BOOLEAN gfAutoAIAware; extern void HandlePreBattleInterfaceStates(); // the title for the contract button on the character info panel in the upper left portion of the mapscreen extern STR16 pContractButtonString[]; extern STR16 pBullseyeStrings[]; extern OBJECTTYPE *gpItemDescObject; extern SOLDIERTYPE *pProcessingSoldier; // faces stuff extern FACETYPE *gpCurrentTalkingFace; //extern BOOLEAN gfFacePanelActive; // externs for highlighting of ammo/weapons extern UINT32 guiMouseOverItemTime; extern BOOLEAN gfCheckForMouseOverItem; extern INT8 gbCheckForMouseOverItemPos; //Autoresolve sets this variable which defaults to -1 when not needed. extern INT16 gsEnemyGainedControlOfSectorID; extern INT16 gsCiviliansEatenByMonsters; extern BOOLEAN gfFadeOutDone; extern UINT32 guiPendingScreen; extern CHAR16 gzUserDefinedButton1[ 128 ]; extern CHAR16 gzUserDefinedButton2[ 128 ]; extern BOOLEAN gfMilitiaPopupCreated; #ifdef JA2TESTVERSION extern INT16 MSYS_CurrentMX; extern INT16 MSYS_CurrentMY; #endif // PROTOTYPES // basic input void GetMapKeyboardInput( UINT32 *puiNewEvent ); void PollLeftButtonInMapView( UINT32 *puiNewEvent ); void PollRightButtonInMapView( UINT32 *puiNewEvent ); // background render void BlitBackgroundToSaveBuffer( void ); // Drawing the Map UINT32 HandleMapUI( ); void RenderMapCursorsIndexesAnims( void ); BOOLEAN GetMapXY( INT16 sX, INT16 sY, INT16 *psMapWorldX, INT16 *psMapWorldY ); BOOLEAN GetMouseMapXY( INT16 *psMapWorldX, INT16 *psMapWorldY ); void StartConfirmMapMoveMode( INT16 sMapY ); void EndConfirmMapMoveMode( void ); void CancelMapUIMessage( void ); void MonitorMapUIMessage( void ); void RenderMapHighlight( INT16 sMapX, INT16 sMapY, UINT16 usLineColor, BOOLEAN fStationary ); void ShadeMapElem( INT16 sMapX, INT16 sMapY ); void PopupText( UINT16 *pFontString, ... ); void DrawString(STR16 pString, UINT16 uiX, UINT16 uiY, UINT32 uiFont); // Clock void SetClock(STR16 pString); void SetClockMin(STR16, ...); void SetClockHour(STR16 pStringA, ...); void SetHourAlternate(STR16 pStringA, ...); void SetDayAlternate(STR16 pStringA, ...); void RenderIconsForUpperLeftCornerPiece( INT8 bCharNumber ); void RenderAttributeStringsForUpperLeftHandCorner( UINT32 uiBufferToRenderTo ); void DisplayThePotentialPathForCurrentDestinationCharacterForMapScreenInterface( INT16 sMapX, INT16 sMapY ); void HandleCursorOverRifleAmmo( ); void SetUpCursorForStrategicMap( void ); void HandleAnimatedCursorsForMapScreen( ); void CheckToSeeIfMouseHasLeftMapRegionDuringPathPlotting( ); // handle change in info char void HandleChangeOfInfoChar( void ); // update town mine pop up void UpdateTownMinePopUpDisplay( void ); // Map Buttons void GlowFace( void ); void ResetMapButtons(); //Drawing Strings void DrawName( STR16 pName, INT16 sRowIndex, INT32 iFont ); void DrawAssignment( INT16 sCharNumber, INT16 sRowIndex, INT32 iFont ); void DrawLocation( INT16 sCharNumber, INT16 sRowIndex, INT32 iFont ); void DrawDestination( INT16 sCharNumber, INT16 sRowIndex, INT32 iFont ); void DrawTimeRemaining( INT16 sCharNumber, INT32 iFont, UINT8 ubFontColor ); void HandleAssignmentsDoneAndAwaitingFurtherOrders( void ); void HandleCommonGlowTimer( void ); void CheckIfPlottingForCharacterWhileAirCraft( void ); // handle highlighting of team panel lines void HandleChangeOfHighLightedLine( void ); // automatically pause/unpause time compression during certain events void UpdatePausedStatesDueToTimeCompression( void ); // handle pre battle interface in relation to inventory void HandlePreBattleInterfaceWithInventoryPanelUp( void ); void CreateDestroyMapCharacterScrollButtons( void ); // sort buttons for team list void AddTeamPanelSortButtonsForMapScreen( void ); void RemoveTeamPanelSortButtonsForMapScreen( void ); void SortListOfMercsInTeamPanel( BOOLEAN fRetainSelectedMercs ); // Rendering void RenderCharacterInfoBackground( void ); void RenderTeamRegionBackground( void ); void RenderMapRegionBackground( void ); void HandleHighLightingOfLinesInTeamPanel( void ); void ClearTeamPanel(); void PlotTemporaryPaths( void ); void PlotPermanentPaths( void ); void RenderHandPosItem( void ); void ContractListRegionBoxGlow( UINT16 usCount ); void DisplayDestinationOfCurrentDestMerc( void ); void HandleCharBarRender( void ); // rebuild waypoints for selected character list void RebuildWayPointsForAllSelectedCharsGroups( void ); extern BOOLEAN HandleNailsVestFetish( SOLDIERTYPE *pSoldier, UINT32 uiHandPos, UINT16 usReplaceItem ); BOOLEAN CharacterIsInTransitAndHasItemPickedUp( INT8 bCharacterNumber ); void InterruptTimeForMenus( void ); // Pop Up Boxes void CreateAttributeBox( void ); void CreateVehicleBox( void ); void CreateContractBox( SOLDIERTYPE *pCharacter ); void CreateAssignmentsBox( void ); void CreateTrainingBox( void ); void CreateMercRemoveAssignBox( void ); void DetermineWhichAssignmentMenusCanBeShown( void ); void DetermineWhichMilitiaControlMenusCanBeShown( void ); //lal void DetermineIfContractMenuCanBeShown( void ); void ContractRegionBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ); void ContractRegionMvtCallback( MOUSE_REGION * pRegion, INT32 iReason ); void HandleShadingOfLinesForContractMenu( void ); void UpdateStatusOfMapSortButtons( void ); void DisplayIconsForMercsAsleep( void ); BOOLEAN CharacterIsInLoadedSectorAndWantsToMoveInventoryButIsNotAllowed( INT8 bCharId ); void HandlePostAutoresolveMessages(); // screen mask for pop up menus void ClearScreenMaskForMapScreenExit( void ); void ResetAllSelectedCharacterModes( void ); // The Mouse/Btn Creation/Destruction // destroy regions/buttons void DestroyMouseRegionsForTeamList( void ); // create new regions/buttons void CreateMouseRegionsForTeamList( void ); void EnableDisableTeamListRegionsAndHelpText( void ); // merc about to leave, flash contract time BOOLEAN AnyMercsLeavingRealSoon(); void HandleContractTimeFlashForMercThatIsAboutLeave( void ); // Mouse Region Callbacks // team list void TeamListInfoRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason ); void TeamListInfoRegionMvtCallBack(MOUSE_REGION *pRegion, INT32 iReason ); void TeamListAssignmentRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason ); void TeamListAssignmentRegionMvtCallBack(MOUSE_REGION *pRegion, INT32 iReason ); void TeamListDestinationRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason ); void TeamListDestinationRegionMvtCallBack(MOUSE_REGION *pRegion, INT32 iReason ); void TeamListContractRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason ); void TeamListContractRegionMvtCallBack( MOUSE_REGION *pRegion, INT32 iReason ); void TeamListSleepRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason ); void TeamListSleepRegionMvtCallBack( MOUSE_REGION *pRegion, INT32 iReason ); void FaceRegionBtnCallback( MOUSE_REGION *pRegion, INT32 iReason ); void FaceRegionMvtCallback( MOUSE_REGION *pRegion, INT32 iReason ); void ItemRegionBtnCallback( MOUSE_REGION *pRegion, INT32 iReason ); void ItemRegionMvtCallback( MOUSE_REGION *pRegion, INT32 iReason ); // mapscreen mouse region screen mask btn callback void MapScreenMarkRegionBtnCallback(MOUSE_REGION *pRegion, INT32 iReason ); // inventory mvt and click callbacks void MAPInvMoveCallback( MOUSE_REGION *pRegion, INT32 iReason ); void MAPInvClickCallback( MOUSE_REGION *pRegion, INT32 iReason ); void MAPInvClickCamoCallback( MOUSE_REGION *pRegion, INT32 iReason ); void MAPInvMoveCamoCallback( MOUSE_REGION *pRegion, INT32 iReason ); void InvmaskRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason ); void TrashCanBtnCallback( MOUSE_REGION *pRegion, INT32 iReason); extern void KeyRingItemPanelButtonCallback( MOUSE_REGION *pRegion, INT32 iReason ); // handle talking void HandleSpontanousTalking( void ); BOOLEAN ContinueDialogue(SOLDIERTYPE *pSoldier, BOOLEAN fDone ); extern void CreateDestroyMilitiaSectorButtons( void ); // mouse position test BOOLEAN IsCursorWithInRegion(INT16 sLeft, INT16 sRight, INT16 sTop, INT16 sBottom ); // pop up boxes void CreateVehicleBox( ); void TestMessageSystem( void ); BOOLEAN CheckIfClickOnLastSectorInPath( INT16 sX, INT16 sY ); //update any bad assignments..error checking void UpdateBadAssignments( void ); // hwo many on team, if less than 2, disable prev/next merc buttons void UpdateTheStateOfTheNextPrevMapScreenCharacterButtons( void ); // inventory void CreateDestroyTrashCanRegion( void ); void DoneInventoryMapBtnCallback( GUI_BUTTON *btn,INT32 reason ); // handle cursor for invenetory mode..update to object selected, if needed void HandleMapInventoryCursor( ); void MAPEndItemPointer( ); void MAPBeginItemPointer( SOLDIERTYPE *pSoldier, UINT8 ubHandPos ); // create/destroy inventory button as needed void CreateDestroyMapInvButton(); void PrevInventoryMapBtnCallback( GUI_BUTTON *btn, INT32 reason ); void NextInventoryMapBtnCallback( GUI_BUTTON *btn, INT32 reason ); // check if cursor needs to be set to checkmark or to the walking guy? void UpdateCursorIfInLastSector( void ); void ContractButtonCallback(GUI_BUTTON *btn,INT32 reason); void MapScreenDefaultOkBoxCallback( UINT8 bExitValue ); // blt inventory panel void BltCharInvPanel(); // show character information void DrawCharacterInfo(INT16 sCharNumber); void DisplayCharacterInfo( void ); void UpDateStatusOfContractBox( void ); // get which index in the mapscreen character list is this guy INT32 GetIndexForThisSoldier( SOLDIERTYPE *pSoldier ); void CheckForAndRenderNewMailOverlay(); BOOLEAN MapCharacterHasAccessibleInventory( INT8 bCharNumber ); void CheckForInventoryModeCancellation(); void ChangeMapScreenMaskCursor( UINT16 usCursor ); void CancelOrShortenPlottedPath( void ); BOOLEAN HandleCtrlOrShiftInTeamPanel( INT8 bCharNumber ); INT32 GetContractExpiryTime( SOLDIERTYPE *pSoldier ); void ConvertMinTimeToETADayHourMinString( UINT32 uiTimeInMin, STR16 sString ); INT32 GetGroundTravelTimeOfCharacter( INT8 bCharNumber ); INT16 CalcLocationValueForChar( INT32 iCounter ); void CancelChangeArrivalSectorMode( ); void MakeMapModesSuitableForDestPlotting( INT8 bCharNumber ); BOOLEAN AnyMovableCharsInOrBetweenThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); void SwapCharactersInList( INT32 iCharA, INT32 iCharB ); BOOLEAN CanChangeDestinationForCharSlot( INT8 bCharNumber, BOOLEAN fShowErrorMessage ); BOOLEAN RequestGiveSkyriderNewDestination( void ); void ExplainWhySkyriderCantFly( void ); UINT8 PlayerMercsInHelicopterSector( void ); void HandleNewDestConfirmation( INT16 sMapX, INT16 sMapY ); void RandomAwakeSelectedMercConfirmsStrategicMove( void ); void DestinationPlottingCompleted( void ); void HandleMilitiaRedistributionClick( void ); void StartChangeSectorArrivalMode( void ); BOOLEAN CanMoveBullseyeAndClickedOnIt( INT16 sMapX, INT16 sMapY ); void CreateBullsEyeOrChopperSelectionPopup( void ); void BullsEyeOrChopperSelectionPopupCallback( UINT8 ubExitValue ); void WakeUpAnySleepingSelectedMercsOnFootOrDriving( void ); void GetMapscreenMercAssignmentString( SOLDIERTYPE *pSoldier, CHAR16 sString[] ); void GetMapscreenMercLocationString( SOLDIERTYPE *pSoldier, CHAR16 sString[] ); void GetMapscreenMercDestinationString( SOLDIERTYPE *pSoldier, CHAR16 sString[] ); void GetMapscreenMercDepartureString( SOLDIERTYPE *pSoldier, CHAR16 sString[], UINT8 *pubFontColor ); void InitPreviousPaths( void ); void RememberPreviousPathForAllSelectedChars( void ); void RestorePreviousPaths( void ); void ClearPreviousPaths( void ); void SelectAllCharactersInSquad( INT8 bSquadNumber ); BOOLEAN CanDrawSectorCursor( void ); void RestoreMapSectorCursor( INT16 sMapX, INT16 sMapY ); void RequestToggleMercInventoryPanel( void ); void RequestContractMenu( void ); void ChangeCharacterListSortMethod( INT32 iValue ); void MapscreenMarkButtonsDirty(); extern BOOLEAN CanRedistributeMilitiaInSector( INT16 sClickedSectorX, INT16 sClickedSectorY, INT8 bClickedTownId ); extern INT32 GetNumberOfMercsInUpdateList( void ); void DeleteAllItemsInInventoryPool(); #ifdef JA2TESTVERSION void TestDumpStatChanges( void ); void DumpSectorDifficultyInfo( void ); void DumpItemsList( void ); #endif // the tries to select a mapscreen character by his soldier ID BOOLEAN SetInfoChar( UINT8 ubID ) { INT8 bCounter; for ( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++) { // skip invalid characters if ( gCharactersList[ bCounter ].fValid == TRUE ) { if ( gCharactersList[ bCounter ].usSolID == (UINT16)ubID ) { ChangeSelectedInfoChar( bCounter, TRUE ); return( TRUE ); } } } return ( FALSE ); } void DisplayDestinationOfCurrentDestMerc( void ) { // will display the dest of the current dest merc CHAR16 sString[ 32 ]; INT16 sX, sY; INT16 sSector; SetFont( MAP_SCREEN_FONT ); sSector = GetLastSectorIdInCharactersPath( &Menptr[gCharactersList[ bSelectedDestChar ].usSolID] ); SetBoxForeground(ghVehicleBox, FONT_LTGREEN); SetBoxBackground(ghVehicleBox, FONT_BLACK); swprintf( sString, L"%s%s", pMapVertIndex[ sSector / MAP_WORLD_X ], pMapHortIndex[ sSector % MAP_WORLD_X ] ); FindFontCenterCoordinates(DEST_PLOT_X, DEST_PLOT_Y ,70 ,GetFontHeight( MAP_SCREEN_FONT ) ,sString , MAP_SCREEN_FONT, &sX, &sY); RestoreExternBackgroundRect( DEST_PLOT_X, DEST_PLOT_Y ,70 ,GetFontHeight( MAP_SCREEN_FONT ) ); mprintf( sX, sY, sString ); } void ContractBoxGlow( void ) { /* Why not? static INT32 iColorNum=10; static BOOLEAN fDelta=FALSE; static BOOLEAN fOldContractGlow = FALSE; UINT16 usColor; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; // stopped glowing? if( ( fGlowContractRegion == FALSE )&&( ( fOldContractGlow == TRUE )||( fResetContractGlow== TRUE ) ) ) { // restore background // RestoreExternBackgroundRect( CONTRACT_X, CONTRACT_Y, CONTRACT_WIDTH+1, CONTRACT_HEIGHT+1 ); // reset old fOldContractGlow = FALSE; } // not glowing right now, leave if( ( fGlowContractRegion == FALSE )||( fResetContractGlow == TRUE ) ) { // reset color rotation iColorNum =0; fDelta = TRUE; // reset fResetContractGlow = FALSE; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; // change direction of glow? if((iColorNum==0)||(iColorNum==10)) { fDelta=!fDelta; } // increment color if(!fDelta) iColorNum++; else iColorNum--; usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480); RectangleDraw( TRUE, CONTRACT_X, CONTRACT_Y, CONTRACT_X+CONTRACT_WIDTH, CONTRACT_Y+CONTRACT_HEIGHT, usColor, pDestBuf ); InvalidateRegion(CONTRACT_X, CONTRACT_Y, CONTRACT_X+CONTRACT_WIDTH+1, CONTRACT_Y+CONTRACT_HEIGHT+1); UnLockVideoSurface( FRAME_BUFFER ); // restore background if((iColorNum==0)||(iColorNum==1)) RestoreExternBackgroundRect( CONTRACT_X, CONTRACT_Y, CONTRACT_WIDTH+1, CONTRACT_HEIGHT+1 ); */ } void ContractListRegionBoxGlow( UINT16 usCount ) { static INT32 iColorNum =10; static BOOLEAN fDelta=FALSE; UINT16 usColor; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; INT16 usY = 0; INT16 sYAdd = 0; INT16 sYStart = 0; INT16 usVehicleCount = 0; // if not glowing right now, leave if( ( giContractHighLine == -1 )||( fResetContractGlow == TRUE ) || fShowInventoryFlag ) { iColorNum = 0; fDelta = TRUE; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; // change direction of glow? if((iColorNum==0)||(iColorNum==10)) { fDelta=!fDelta; } // increment color if(!fDelta) iColorNum++; else iColorNum--; if( usCount >= FIRST_VEHICLE ) { usVehicleCount = usCount - FIRST_VEHICLE; sYStart = usVehicleY; usY=(Y_OFFSET*usVehicleCount-1)+(sYStart+(usVehicleCount*Y_SIZE)); } else { sYStart = Y_START; usY=(Y_OFFSET*usCount-1)+(sYStart+(usCount*Y_SIZE)); } // y start position of box //usY=(Y_OFFSET*usCount-1)+(Y_START+(usCount*Y_SIZE) + sYAdd ); //usY=(Y_OFFSET*usCount-1)+(sYStart+(usCount*Y_SIZE)); // glow contract box usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); RectangleDraw( TRUE, TIME_REMAINING_X, usY, TIME_REMAINING_X + TIME_REMAINING_WIDTH, usY + GetFontHeight( MAP_SCREEN_FONT ) + 2, usColor, pDestBuf ); InvalidateRegion(TIME_REMAINING_X - 1, usY, TIME_REMAINING_X + TIME_REMAINING_WIDTH + 1, usY + GetFontHeight( MAP_SCREEN_FONT ) + 3 ); UnLockVideoSurface( FRAME_BUFFER ); /* // restore background if((iColorNum==0)||(iColorNum==1)) RestoreExternBackgroundRect( CONTRACT_X, CONTRACT_Y, CONTRACT_WIDTH+1, CONTRACT_HEIGHT+1 ); */ } void GlowFace( void ) { static INT32 iColorNum =10; static BOOLEAN fDelta=FALSE; static BOOLEAN fOldFaceGlow = FALSE; UINT16 usColor; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; INT16 usY = 0; // not glowing right now, leave if( fShowFaceHightLight == FALSE ) { iColorNum =0; fDelta = TRUE; if( fOldFaceGlow == TRUE ) { RestoreExternBackgroundRect( 9, 18, ( UINT16 )( 61 - 9 ), ( UINT16 )( 64 - 18 ) ); } fOldFaceGlow = FALSE; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; fOldFaceGlow = TRUE; // change direction of glow? if((iColorNum==0)||(iColorNum==10)) { fDelta=!fDelta; } // increment color if(!fDelta) iColorNum++; else iColorNum--; // glow contract box usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); RectangleDraw( TRUE, 9, 18, 60, 63 , usColor, pDestBuf ); InvalidateRegion( 9, 18, 61, 64 ); UnLockVideoSurface( FRAME_BUFFER ); // restore background if((iColorNum==0)||(iColorNum==1)) RestoreExternBackgroundRect( 9, 18, ( UINT16 )( 61 - 9 ), ( UINT16 )( 64 - 18 ) ); } void GlowItem( void ) { static INT32 iColorNum =10; static BOOLEAN fDelta=FALSE; static BOOLEAN fOldItemGlow = FALSE; UINT16 usColor; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; INT16 usY = 0; // not glowing right now, leave if( fShowItemHighLight == FALSE ) { iColorNum =0; fDelta = TRUE; if( fOldItemGlow == TRUE ) { RestoreExternBackgroundRect( 3, 80, ( UINT16 )( 65 - 3 ), ( UINT16 )( 105 - 80 ) ); } fOldItemGlow = FALSE; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; fOldItemGlow = TRUE; // change direction of glow? if((iColorNum==0)||(iColorNum==10)) { fDelta=!fDelta; } // increment color if(!fDelta) iColorNum++; else iColorNum--; // restore background if((iColorNum==0)||(iColorNum==1)) { RestoreExternBackgroundRect( 3, 80, ( UINT16 )( 65 - 3 ), ( UINT16 )( 105 - 80 ) ); RenderHandPosItem(); } // glow contract box usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); RectangleDraw( TRUE, 3, 80, 64, 104 , usColor, pDestBuf ); InvalidateRegion( 3, 80, 65, 105 ); UnLockVideoSurface( FRAME_BUFFER ); } void GlowTrashCan( void ) { static INT32 iColorNum =10; static BOOLEAN fDelta=FALSE; static BOOLEAN fOldTrashCanGlow = FALSE; UINT16 usColor; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; INT16 usY = 0; if( fShowInventoryFlag == FALSE ) { fShowTrashCanHighLight = FALSE; } // not glowing right now, leave if( fShowTrashCanHighLight == FALSE ) { iColorNum =0; fDelta = TRUE; if( fOldTrashCanGlow == TRUE ) { RestoreExternBackgroundRect( TRASH_CAN_X, TRASH_CAN_Y, ( UINT16 )( TRASH_CAN_WIDTH + 2 ), ( UINT16 )( TRASH_CAN_HEIGHT + 2 ) ); } fOldTrashCanGlow = FALSE; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; fOldTrashCanGlow = TRUE; // glow contract box usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); RectangleDraw( TRUE, TRASH_CAN_X, TRASH_CAN_Y , TRASH_CAN_X + TRASH_CAN_WIDTH, TRASH_CAN_Y + TRASH_CAN_HEIGHT , usColor, pDestBuf ); InvalidateRegion( TRASH_CAN_X, TRASH_CAN_Y, TRASH_CAN_X + TRASH_CAN_WIDTH + 1, TRASH_CAN_Y + TRASH_CAN_HEIGHT + 1 ); UnLockVideoSurface( FRAME_BUFFER ); // restore background if((iColorNum==0)||(iColorNum==1)) RestoreExternBackgroundRect( TRASH_CAN_X, TRASH_CAN_Y, ( UINT16 )( TRASH_CAN_WIDTH + 2 ), ( UINT16 )( TRASH_CAN_HEIGHT + 2 ) ); } void DrawFace( INT16 sCharNumber ) { SOLDIERTYPE *pSoldier = NULL; static INT16 sOldId = -1; // draws the face of the currently selected merc, being displayed int he upper left hand corner // grab the soldier if( bSelectedInfoChar != -1 ) { if( gCharactersList[ bSelectedInfoChar ].fValid ) { GetSoldier( &pSoldier, gCharactersList[ bSelectedInfoChar ].usSolID ); } } if( pSoldier == NULL ) { return; } if( ( gCharactersList[ bSelectedInfoChar ].usSolID == sOldId )&&( fReDrawFace == FALSE ) ) { // are the same, return return; } // get old id value sOldId = gCharactersList[ bSelectedInfoChar ].usSolID; // reset redraw of face fReDrawFace = FALSE; // render their face RenderSoldierFace( pSoldier, SOLDIER_PIC_X, SOLDIER_PIC_Y, TRUE ); return; } void RenderHandPosItem( void ) { SOLDIERTYPE *pSoldier = NULL; // renders the inventory item in char's right hand // ARM: if already in the inventory panel, don't show the item again here, seeing it twice is confusing if ( fShowInventoryFlag ) { return; } // grab the soldier if( bSelectedInfoChar != -1 ) { if( gCharactersList[ bSelectedInfoChar ].fValid ) { GetSoldier( &pSoldier, gCharactersList[ bSelectedInfoChar ].usSolID ); } } if( pSoldier == NULL ) { return; } // check if still alive? if( pSoldier -> bLife == 0 ) { return; } SetFont(BLOCKFONT2); SetFontForeground(CHAR_INFO_PANEL_BLOCK_COLOR); SetFontBackground(FONT_BLACK); INVRenderItem( guiSAVEBUFFER, pSoldier, &(pSoldier->inv[HANDPOS]), SOLDIER_HAND_X, SOLDIER_HAND_Y, 58, 23, DIRTYLEVEL2, NULL, 0, FALSE, 0); } void RenderIconsForUpperLeftCornerPiece( INT8 bCharNumber ) { HVOBJECT hHandle; GetVideoObject(&hHandle, guiULICONS); // if merc is an AIM merc if( Menptr[ gCharactersList[ bCharNumber ].usSolID ].ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC ) { // finite contract length icon BltVideoObject( guiSAVEBUFFER, hHandle, 0, CHAR_ICON_X, CHAR_ICON_CONTRACT_Y, VO_BLT_SRCTRANSPARENCY, NULL ); } // if merc has life insurance if( Menptr[ gCharactersList[ bCharNumber ].usSolID ].usLifeInsurance > 0 ) { // draw life insurance icon BltVideoObject( guiSAVEBUFFER, hHandle, 2, CHAR_ICON_X, CHAR_ICON_CONTRACT_Y + CHAR_ICON_SPACING, VO_BLT_SRCTRANSPARENCY, NULL ); } // if merc has a medical deposit if( Menptr[ gCharactersList[ bCharNumber ].usSolID ].usMedicalDeposit > 0 ) { // draw medical deposit icon BltVideoObject( guiSAVEBUFFER, hHandle, 1, CHAR_ICON_X, CHAR_ICON_CONTRACT_Y + ( 2 * CHAR_ICON_SPACING ), VO_BLT_SRCTRANSPARENCY, NULL ); } } void DrawPay(INT16 sCharNumber) { // will draw the pay INT32 uiSalary; CHAR16 sString[7]; INT16 usX, usY; INT16 usMercProfileID; // get merc id usMercProfileID = MercPtrs[ gCharactersList[ sCharNumber ].usSolID ] -> ubProfile; // grab salary uiSalary=( ( UINT32 ) gMercProfiles[ usMercProfileID ].sSalary ); // font stuff SetFontForeground( CHAR_TITLE_FONT_COLOR ); SetFontBackground( FONT_BLACK ); // parse salary swprintf( sString, L"%d", uiSalary ); // right justify salary FindFontRightCoordinates(CHAR_PAY_X,CHAR_PAY_Y , CHAR_PAY_WID,CHAR_PAY_HEI ,sString , CHAR_FONT, &usX, &usY); // draw salary DrawString(sString,usX, usY, CHAR_FONT); } void DrawCharBars( void ) { UINT16 usSoldierID; SOLDIERTYPE *pSoldier; // will draw the heath, morale and breath bars for a character being displayed in the upper left hand corner if( ( bSelectedInfoChar == -1 )&&( bSelectedDestChar == -1 ) ) { // error, no character to display right now return; } else { // valid character if( bSelectedInfoChar != -1 ) { usSoldierID=gCharactersList[ bSelectedInfoChar ].usSolID; } else { usSoldierID=gCharactersList[ bSelectedDestChar ].usSolID; } // grab soldier's id number GetSoldier( &pSoldier, usSoldierID ); if( pSoldier == NULL ) { // no soldier return; } // skip POWs, dead guys if( ( pSoldier->bLife == 0 ) || ( pSoldier->bAssignment == ASSIGNMENT_DEAD ) || ( pSoldier->bAssignment == ASSIGNMENT_POW ) ) { return; } // current health DrawLifeUIBarEx( pSoldier, BAR_INFO_X, BAR_INFO_Y,3,42, TRUE, FRAME_BUFFER ); // robot doesn't have energy/fuel if ( !AM_A_ROBOT( pSoldier ) ) { // current energy/fuel DrawBreathUIBarEx( pSoldier, BAR_INFO_X + 6, BAR_INFO_Y,3,42, TRUE, FRAME_BUFFER ); } // vehicles and robot don't have morale if ( !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) && !AM_A_ROBOT( pSoldier ) ) { // draw morale bar DrawMoraleUIBarEx( pSoldier, BAR_INFO_X + 12, BAR_INFO_Y,3,42, TRUE, FRAME_BUFFER ); } } return; } void DrawCharStats( INT16 sCharNum ) { // will draw the characters stats, max life, strength, dex, and skills CHAR16 sString[9]; INT16 usX, usY; //HVOBJECT hCrossHandle; SOLDIERTYPE *pSoldier = NULL; pSoldier = &Menptr[gCharactersList[sCharNum].usSolID]; // set up font SetFont(CHAR_FONT); SetFontForeground(CHAR_TEXT_FONT_COLOR); SetFontBackground(FONT_BLACK); // strength swprintf( sString, L"%d", pSoldier->bStrength); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeStrengthTime)&& ( pSoldier->uiChangeStrengthTime != 0 ) ) { if( pSoldier->usValueGoneUp & STRENGTH_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(STR_X, STR_Y ,STAT_WID ,STAT_HEI ,sString, CHAR_FONT, &usX, &usY); DrawString(sString,usX, STR_Y,CHAR_FONT ); // dexterity swprintf( sString, L"%d", pSoldier->bDexterity ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeDexterityTime ) && ( pSoldier->uiChangeDexterityTime != 0 ) ) { if( pSoldier->usValueGoneUp & DEX_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(DEX_X,DEX_Y ,STAT_WID ,STAT_HEI ,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, DEX_Y,CHAR_FONT ); // agility swprintf( sString, L"%d", pSoldier->bAgility ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeAgilityTime)&& ( pSoldier->uiChangeAgilityTime != 0 ) ) { if( pSoldier->usValueGoneUp & AGIL_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(AGL_X,AGL_Y,STAT_WID ,STAT_HEI ,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, AGL_Y,CHAR_FONT ); // wisdom swprintf( sString, L"%d", pSoldier->bWisdom ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeWisdomTime )&&( pSoldier->uiChangeWisdomTime != 0 )) { if( pSoldier->usValueGoneUp & WIS_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates( WIS_X,WIS_Y,STAT_WID ,STAT_HEI,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, WIS_Y,CHAR_FONT ); // leadership swprintf( sString, L"%d", pSoldier->bLeadership ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeLeadershipTime ) && ( pSoldier->uiChangeLeadershipTime != 0 ) ) { if( pSoldier->usValueGoneUp & LDR_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(LDR_X,LDR_Y,STAT_WID,STAT_HEI, sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, LDR_Y,CHAR_FONT ); // experience level swprintf( sString, L"%d", pSoldier->bExpLevel ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeLevelTime)&&( pSoldier->uiChangeLevelTime != 0 ) ) { if( pSoldier->usValueGoneUp & LVL_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(LVL_X,LVL_Y,STAT_WID ,STAT_HEI,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, LVL_Y,CHAR_FONT ); // marksmanship swprintf( sString, L"%d", pSoldier->bMarksmanship ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeMarksmanshipTime) && ( pSoldier->uiChangeMarksmanshipTime != 0 ) ) { if( pSoldier->usValueGoneUp & MRK_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(MRK_X,MRK_Y,STAT_WID ,STAT_HEI,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, MRK_Y,CHAR_FONT ); // explosives swprintf( sString, L"%d", pSoldier->bExplosive ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeExplosivesTime)&& ( pSoldier->uiChangeExplosivesTime != 0 ) ) { if( pSoldier->usValueGoneUp & EXP_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(EXP_X,EXP_Y,STAT_WID ,STAT_HEI,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, EXP_Y,CHAR_FONT ); // mechanical swprintf( sString, L"%d", pSoldier->bMechanical ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeMechanicalTime )&& ( pSoldier->uiChangeMechanicalTime != 0 ) ) { if( pSoldier->usValueGoneUp & MECH_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(MEC_X,MEC_Y,STAT_WID ,STAT_HEI,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, MEC_Y,CHAR_FONT ); // medical swprintf( sString, L"%d", pSoldier->bMedical ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeMedicalTime)&& ( pSoldier->uiChangeMedicalTime != 0 ) ) { if( pSoldier->usValueGoneUp & MED_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // right justify FindFontRightCoordinates(MED_X,MED_Y,STAT_WID ,STAT_HEI,sString , CHAR_FONT, &usX, &usY); DrawString(sString,usX, MED_Y,CHAR_FONT ); SetFontForeground(CHAR_TEXT_FONT_COLOR); return; } void DrawCharHealth( INT16 sCharNum ) { UINT32 uiHealthPercent = 0; CHAR16 sString[9]; INT16 usX, usY; SOLDIERTYPE *pSoldier = NULL; pSoldier = &Menptr[gCharactersList[sCharNum].usSolID]; if( pSoldier->bAssignment != ASSIGNMENT_POW ) { // find starting X coordinate by centering all 3 substrings together, then print them separately (different colors)! swprintf( sString, L"%d/%d", pSoldier->bLife, pSoldier->bLifeMax ); FindFontCenterCoordinates(CHAR_HP_X, CHAR_HP_Y, CHAR_HP_WID, CHAR_HP_HEI, sString, CHAR_FONT, &usX, &usY); if ( pSoldier->bLifeMax > 0 ) { uiHealthPercent = ( pSoldier->bLife * 100 ) / pSoldier->bLifeMax; } // how is characters life? if (uiHealthPercent == 0) { // he's dead, Jim SetFontForeground(FONT_METALGRAY); } else if (uiHealthPercent < 25) { // very bad SetFontForeground(FONT_RED); } else if (uiHealthPercent < 50) { // not good SetFontForeground(FONT_YELLOW); } else { // ok SetFontForeground(CHAR_TEXT_FONT_COLOR); } // current life swprintf( sString, L"%d", pSoldier->bLife ); DrawString( sString, usX, CHAR_HP_Y, CHAR_FONT ); usX += StringPixLength( sString, CHAR_FONT ); // slash SetFontForeground(CHAR_TEXT_FONT_COLOR); wcscpy( sString, L"/" ); DrawString( sString, usX, CHAR_HP_Y, CHAR_FONT ); usX += StringPixLength( sString, CHAR_FONT ); if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->uiChangeHealthTime)&& ( pSoldier->uiChangeHealthTime != 0 ) ) { if( pSoldier->usValueGoneUp & HEALTH_INCREASE ) { SetFontForeground( FONT_LTGREEN ); } else { SetFontForeground( FONT_RED ); } } else { SetFontForeground(CHAR_TEXT_FONT_COLOR); } // maximum life swprintf( sString, L"%d", pSoldier->bLifeMax ); DrawString( sString, usX, CHAR_HP_Y, CHAR_FONT ); } else { // POW - health unknown SetFontForeground(CHAR_TEXT_FONT_COLOR); swprintf( sString, pPOWStrings[ 1 ] ); FindFontCenterCoordinates(CHAR_HP_X, CHAR_HP_Y, CHAR_HP_WID, CHAR_HP_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString, usX, CHAR_HP_Y, CHAR_FONT); } SetFontForeground(CHAR_TEXT_FONT_COLOR); } // "character" refers to hired people AND vehicles void DrawCharacterInfo(INT16 sCharNumber) { CHAR16 sString[80]; INT16 usX, usY; INT16 usMercProfileID; INT32 iTimeRemaining=0; INT8 bMorale =0; INT32 iDailyCost = 0; SOLDIERTYPE *pSoldier = NULL; UINT32 uiArrivalTime; if( gCharactersList[sCharNumber].fValid == FALSE ) { return; } pSoldier = MercPtrs[ gCharactersList[sCharNumber].usSolID ]; if( pSoldier->ubProfile == NO_PROFILE ) { return; } // draw particular info about a character that are neither attributes nor skills // get profile information usMercProfileID = pSoldier->ubProfile; // set font stuff SetFont(CHAR_FONT); SetFontForeground(CHAR_TEXT_FONT_COLOR); SetFontBackground(FONT_BLACK); // Nickname (beneath Picture) if( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { // vehicle wcscpy(sString, pShortVehicleStrings[ pVehicleList[ pSoldier->bVehicleID ].ubVehicleType ]); } else { // soldier wcscpy(sString, gMercProfiles[usMercProfileID].zNickname); } FindFontCenterCoordinates(PIC_NAME_X, PIC_NAME_Y, PIC_NAME_WID, PIC_NAME_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString, usX, usY, CHAR_FONT); // Full name (Top Box) if( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { // vehicle wcscpy(sString, pVehicleStrings[ pVehicleList[ pSoldier->bVehicleID ].ubVehicleType ]); } else { // soldier wcscpy(sString, gMercProfiles[usMercProfileID].zName); } FindFontCenterCoordinates(CHAR_NAME_X, CHAR_NAME_Y, CHAR_NAME_WID, CHAR_NAME_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString, usX, usY, CHAR_FONT); // Assignment if( pSoldier->bAssignment == VEHICLE ) { // show vehicle type wcscpy( sString, pShortVehicleStrings[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ] ); } else { wcscpy( sString, pAssignmentStrings[ pSoldier->bAssignment ] ); } FindFontCenterCoordinates( CHAR_ASSIGN_X, CHAR_ASSIGN1_Y, CHAR_ASSIGN_WID, CHAR_ASSIGN_HEI, sString, CHAR_FONT, &usX, &usY ); DrawString( sString, usX, usY, CHAR_FONT ); // second assignment line // train self / teammate / by other ? if( ( pSoldier->bAssignment == TRAIN_SELF ) || ( pSoldier->bAssignment == TRAIN_TEAMMATE ) || ( pSoldier->bAssignment == TRAIN_BY_OTHER ) ) { wcscpy(sString, pAttributeMenuStrings[pSoldier->bTrainStat]); } // train town? else if( pSoldier->bAssignment == TRAIN_TOWN ) { wcscpy(sString,pTownNames[GetTownIdForSector( pSoldier->sSectorX, pSoldier->sSectorY ) ] ); } // repairing? else if( pSoldier->bAssignment == REPAIR ) { if ( pSoldier->fFixingRobot ) { // robot wcscpy( sString, pRepairStrings[ 3 ] ); } /* else if ( pSoldier->fFixingSAMSite ) { // SAM site wcscpy( sString, pRepairStrings[ 1 ] ); } */ else if ( pSoldier->bVehicleUnderRepairID != -1 ) { // vehicle wcscpy( sString, pShortVehicleStrings[ pVehicleList[ pSoldier->bVehicleUnderRepairID ].ubVehicleType ] ); } else { // items wcscpy( sString, pRepairStrings[ 0 ] ); } } // in transit? else if( pSoldier->bAssignment == IN_TRANSIT ) { // show ETA ConvertMinTimeToETADayHourMinString( pSoldier->uiTimeSoldierWillArrive, sString ); } // traveling ? else if ( PlayerIDGroupInMotion( GetSoldierGroupId( pSoldier ) ) ) { // show ETA uiArrivalTime = GetWorldTotalMin( ) + CalculateTravelTimeOfGroupId( GetSoldierGroupId( pSoldier ) ); ConvertMinTimeToETADayHourMinString( uiArrivalTime, sString ); } else { // show location GetMapscreenMercLocationString( pSoldier, sString ); } if ( wcslen( sString ) > 0 ) { FindFontCenterCoordinates(CHAR_ASSIGN_X, CHAR_ASSIGN2_Y ,CHAR_ASSIGN_WID ,CHAR_ASSIGN_HEI ,sString , CHAR_FONT, &usX, &usY); DrawString(sString, usX, usY, CHAR_FONT ); } // draw health/condition DrawCharHealth( sCharNumber ); // if a vehicle or robot if( ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) || AM_A_ROBOT( pSoldier ) ) { // we're done - the remainder applies only to people return; } // draw attributes & skills for currently displayed character DrawCharStats(sCharNumber); // remaining contract length // dead? if( pSoldier->bLife <= 0 ) { swprintf( sString, L"%s", gpStrategicString[ STR_PB_NOTAPPLICABLE_ABBREVIATION ] ); } // what kind of merc else if(pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC || pSoldier->ubProfile == SLAY ) { FLOAT dTimeLeft = 0.0; // amount of time left on contract iTimeRemaining = pSoldier->iEndofContractTime-GetWorldTotalMin(); //if the merc is in transit if( pSoldier->bAssignment == IN_TRANSIT ) { //and if the ttime left on the cotract is greater then the contract time if( iTimeRemaining > (INT32)( pSoldier->iTotalContractLength * NUM_MIN_IN_DAY ) ) { iTimeRemaining = ( pSoldier->iTotalContractLength * NUM_MIN_IN_DAY ); } } if(iTimeRemaining >= ( 24 * 60 ) ) { //calculate the exact time left on the contract ( ex 1.8 days ) dTimeLeft = (FLOAT)(iTimeRemaining / (60*24.0) ); // more than a day, display in green iTimeRemaining /= (60*24); if( pSoldier->bLife > 0 ) { SetFontForeground(FONT_LTGREEN); } swprintf(sString, L"%.1f%s/%d%s", dTimeLeft, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ], pSoldier->iTotalContractLength, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ]); } else { // less than a day, display hours left in red if( iTimeRemaining > 5 ) { BOOLEAN fNeedToIncrement = FALSE; if( iTimeRemaining % 60 != 0 ) fNeedToIncrement = TRUE; iTimeRemaining /= 60; if( fNeedToIncrement ) iTimeRemaining++; } else { iTimeRemaining /= 60; } if( pSoldier->bLife > 0 ) { SetFontForeground(FONT_RED); } swprintf(sString, L"%d%s/%d%s",iTimeRemaining, gpStrategicString[ STR_PB_HOURS_ABBREVIATION ], pSoldier->iTotalContractLength, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ]); } } else if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC ) { INT32 iBeenHiredFor = ( GetWorldTotalMin( ) / NUM_MIN_IN_DAY ) - pSoldier->iStartContractTime; swprintf(sString, L"%d%s/%d%s",gMercProfiles[ pSoldier->ubProfile ].iMercMercContractLength, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ], iBeenHiredFor, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ] ); } else { swprintf( sString, L"%s", gpStrategicString[ STR_PB_NOTAPPLICABLE_ABBREVIATION ] ); } // set font stuff SetFontForeground(CHAR_TEXT_FONT_COLOR); SetFontBackground(FONT_BLACK); // center and draw FindFontCenterCoordinates(CHAR_TIME_REMAINING_X, CHAR_TIME_REMAINING_Y, CHAR_TIME_REMAINING_WID, CHAR_TIME_REMAINING_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString,usX,usY, CHAR_FONT); // salary if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC ) { // daily rate if( pSoldier->bTypeOfLastContract == CONTRACT_EXTEND_2_WEEK ) { iDailyCost = ( gMercProfiles[ pSoldier->ubProfile ].uiBiWeeklySalary / 14 ); } if( pSoldier->bTypeOfLastContract == CONTRACT_EXTEND_1_WEEK ) { iDailyCost = ( gMercProfiles[ pSoldier->ubProfile ].uiWeeklySalary / 7 ); } else { iDailyCost = gMercProfiles[ pSoldier->ubProfile ].sSalary; } } else { iDailyCost = gMercProfiles[ pSoldier->ubProfile ].sSalary; } swprintf(sString, L"%d", iDailyCost ); // insert commas and dollar sign InsertCommasForDollarFigure( sString ); InsertDollarSignInToString( sString ); FindFontRightCoordinates(CHAR_SALARY_X, CHAR_SALARY_Y, CHAR_SALARY_WID, CHAR_SALARY_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString,usX,usY, CHAR_FONT); // medical deposit if( gMercProfiles[ Menptr[ gCharactersList[ sCharNumber ].usSolID ].ubProfile ].sMedicalDepositAmount > 0 ) { swprintf(sString, L"%d", gMercProfiles[ Menptr[ gCharactersList[ sCharNumber ].usSolID ].ubProfile ].sMedicalDepositAmount ); // insert commas and dollar sign InsertCommasForDollarFigure( sString ); InsertDollarSignInToString( sString ); FindFontRightCoordinates(CHAR_MEDICAL_X, CHAR_MEDICAL_Y, CHAR_MEDICAL_WID, CHAR_MEDICAL_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString,usX,CHAR_MEDICAL_Y, CHAR_FONT); } /* // life insurance swprintf(sString, L"%d", Menptr[ gCharactersList[ sCharNumber ].usSolID ].usLifeInsuranceAmount ); InsertCommasForDollarFigure( sString ); InsertDollarSignInToString( sString ); FindFontRightCoordinates(CHAR_LIFE_INSUR_X, CHAR_LIFE_INSUR_Y, CHAR_LIFE_INSUR_WID, CHAR_LIFE_INSUR_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString,usX,usY, CHAR_FONT); */ // morale if( pSoldier->bAssignment != ASSIGNMENT_POW ) { if ( pSoldier->bLife != 0 ) { GetMoraleString( MercPtrs[gCharactersList[sCharNumber].usSolID], sString ); } else { wcscpy( sString, L"" ); } } else { // POW - morale unknown swprintf( sString, pPOWStrings[ 1 ] ); } FindFontCenterCoordinates(CHAR_MORALE_X, CHAR_MORALE_Y, CHAR_MORALE_WID, CHAR_MORALE_HEI, sString, CHAR_FONT, &usX, &usY); DrawString(sString,usX,CHAR_MORALE_Y, CHAR_FONT); return; } // this character is in transit has an item picked up BOOLEAN CharacterIsInTransitAndHasItemPickedUp( INT8 bCharacterNumber ) { // valid character? if( bCharacterNumber == -1 ) { // nope return( FALSE ); } // second validity check if( gCharactersList[ bCharacterNumber ].fValid == FALSE ) { // nope return( FALSE ); } // character in transit? if( Menptr[ gCharactersList[ bCharacterNumber ].usSolID ].bAssignment != IN_TRANSIT ) { // nope return( FALSE ); } // item picked up? if( gMPanelRegion.Cursor != EXTERN_CURSOR) { return( FALSE ); } return( TRUE ); } void DisplayCharacterInfo( void ) { Assert( bSelectedInfoChar < MAX_CHARACTER_COUNT ); Assert( gCharactersList[ bSelectedInfoChar ].fValid ); // set font buffer SetFontDestBuffer( guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); // draw character info and face DrawCharacterInfo( bSelectedInfoChar ); RenderHandPosItem(); SetFontDestBuffer( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); RenderIconsForUpperLeftCornerPiece( bSelectedInfoChar ); // mark all pop ups as dirty MarkAllBoxesAsAltered( ); } INT32 GetPathTravelTimeDuringPlotting( PathStPtr pPath ) { INT32 iTravelTime = 0; WAYPOINT pCurrent; WAYPOINT pNext; GROUP *pGroup; UINT8 ubGroupId = 0; BOOLEAN fSkipFirstNode = FALSE; if( ( bSelectedDestChar == -1 ) && ( fPlotForHelicopter == FALSE ) ) { return( 0 ); } if( fTempPathAlreadyDrawn == FALSE ) { return( 0 ); } if( pPath == NULL ) { return( 0 ); } pPath = MoveToBeginningOfPathList( pPath ); if( fPlotForHelicopter == FALSE ) { // plotting for a character... if( Menptr[gCharactersList[bSelectedDestChar].usSolID].bAssignment == VEHICLE ) { ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].iVehicleId ].ubMovementGroup; pGroup = GetGroup( ubGroupId ); if( pGroup == NULL ) { SetUpMvtGroupForVehicle( &( Menptr[gCharactersList[bSelectedDestChar].usSolID] ) ); // get vehicle id ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].iVehicleId ].ubMovementGroup; pGroup = GetGroup( ubGroupId ); } } else if( Menptr[gCharactersList[bSelectedDestChar].usSolID].uiStatusFlags & SOLDIER_VEHICLE ) { ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].bVehicleID ].ubMovementGroup; pGroup = GetGroup( ubGroupId ); if( pGroup == NULL ) { SetUpMvtGroupForVehicle( &( Menptr[gCharactersList[bSelectedDestChar].usSolID] ) ); // get vehicle id ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].bVehicleID ].ubMovementGroup; pGroup = GetGroup( ubGroupId ); } } else { ubGroupId = Menptr[gCharactersList[bSelectedDestChar].usSolID].ubGroupID; pGroup = GetGroup( ( UINT8 )( ubGroupId ) ); } } else { ubGroupId = pVehicleList[ iHelicopterVehicleId ].ubMovementGroup; pGroup = GetGroup( ubGroupId ); } Assert(pGroup); // if between sectors if ( pGroup->fBetweenSectors ) { // arrival time should always be legal! Assert( pGroup->uiArrivalTime >= GetWorldTotalMin( ) ); // start with time to finish arriving in any traversal already in progress iTravelTime = pGroup->uiArrivalTime - GetWorldTotalMin(); fSkipFirstNode = TRUE; } else { iTravelTime = 0; } while( pPath->pNext ) { if ( !fSkipFirstNode ) { // grab the current location pCurrent.x = ( UINT8 )( pPath->uiSectorId % MAP_WORLD_X ); pCurrent.y = ( UINT8 )( pPath->uiSectorId / MAP_WORLD_X ); // grab the next location pNext.x = ( UINT8 )( pPath->pNext->uiSectorId % MAP_WORLD_X ); pNext.y = ( UINT8 )( pPath->pNext->uiSectorId / MAP_WORLD_X ); iTravelTime += FindTravelTimeBetweenWaypoints( &pCurrent, &pNext, pGroup ); } else { fSkipFirstNode = FALSE; } pPath = pPath->pNext; } return( iTravelTime ); } void DisplayGroundEta( void ) { UINT32 iTotalTime = 0; if( fPlotForHelicopter == TRUE ) { return; } if( bSelectedDestChar == -1 ) { return; } if( !gCharactersList[bSelectedDestChar].fValid ) { return; } iTotalTime = GetGroundTravelTimeOfCharacter( bSelectedDestChar ); // now display it SetFont( ETA_FONT ); SetFontForeground( FONT_LTGREEN ); SetFontBackground( FONT_BLACK ); mprintf( CLOCK_ETA_X, CLOCK_Y_START, pEtaString[ 0 ] ); // if less than one day if( ( iTotalTime / ( 60 * 24 ) ) < 1 ) { // show hours and minutes SetClockMin( L"%d", iTotalTime % 60 ); SetClockHour(L"%d", iTotalTime / 60); } else { // show days and hours SetHourAlternate(L"%d", ( iTotalTime / 60 ) % 24 ); SetDayAlternate( L"%d", iTotalTime / ( 60 * 24 ) ); } } void HighLightAssignLine() { UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; UINT16 usColor; static INT32 iColorNum = STARTING_COLOR_NUM; static BOOLEAN fDelta=FALSE; static INT32 uiOldHighlight = MAX_CHARACTER_COUNT + 1; INT16 usCount = 0; UINT16 usX; UINT16 usY; INT16 usVehicleCount = 0; // is this a valid line? if( ( giAssignHighLine == -1 ) || fShowInventoryFlag ) { uiOldHighlight = MAX_CHARACTER_COUNT + 1; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; // check if we have moved lines, if so, reset if( uiOldHighlight != giAssignHighLine ) { iColorNum = STARTING_COLOR_NUM; fDelta = FALSE; uiOldHighlight = giAssignHighLine; } if((iColorNum==0)||(iColorNum==10)) { fDelta=!fDelta; } if(!fDelta) iColorNum++; else iColorNum--; pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); for( usCount = 0; usCount < MAX_CHARACTER_COUNT; usCount++ ) { if( IsCharacterSelectedForAssignment( usCount ) == TRUE ) { usX=ASSIGN_X; //usY=Y_START+(giHighLine*GetFontHeight((MAP_SCREEN_FONT))); usY=(Y_OFFSET*usCount-1)+(Y_START+(usCount*Y_SIZE)); if( usCount >= FIRST_VEHICLE ) { usVehicleCount = usCount - FIRST_VEHICLE; usY = (Y_OFFSET*usVehicleCount-1)+(usVehicleY+(usVehicleCount*Y_SIZE)); } usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); LineDraw(TRUE, usX, usY, usX, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); LineDraw(TRUE, usX+ASSIGN_WIDTH, usY, usX+ASSIGN_WIDTH, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); if( ( usCount == 0 ) || ( usCount != 0 ? !( IsCharacterSelectedForAssignment( ( UINT16 )( usCount - 1 ) ) ) : 0 ) || ( usCount == FIRST_VEHICLE ) ) { LineDraw( TRUE, usX, usY, usX+ASSIGN_WIDTH, usY, usColor,pDestBuf); } if( ( ( usCount == MAX_CHARACTER_COUNT - 1 ) ) || ( usCount != ( MAX_CHARACTER_COUNT - 1 ) ? !( IsCharacterSelectedForAssignment( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) ) { LineDraw(TRUE, usX, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX+ASSIGN_WIDTH, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); } InvalidateRegion( usX, usY, usX+ASSIGN_WIDTH+1, usY+GetFontHeight(MAP_SCREEN_FONT)+3); } } UnLockVideoSurface( FRAME_BUFFER ); } void HighLightDestLine() { UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; UINT16 usColor; static INT32 iColorNum = STARTING_COLOR_NUM; static BOOLEAN fDelta=FALSE; static INT32 uiOldHighlight = MAX_CHARACTER_COUNT + 1; UINT16 usCount = 0; UINT16 usX; UINT16 usY; UINT16 usVehicleCont = 0; if( ( giDestHighLine == -1 ) || fShowInventoryFlag ) { uiOldHighlight = MAX_CHARACTER_COUNT + 1; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; // check if we have moved lines, if so, reset if( uiOldHighlight != giDestHighLine ) { iColorNum = STARTING_COLOR_NUM; fDelta = FALSE; uiOldHighlight = giDestHighLine; } if((iColorNum==0)||(iColorNum==10)) { fDelta=!fDelta; } if(!fDelta) iColorNum++; else iColorNum--; pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); for( usCount = 0; usCount < MAX_CHARACTER_COUNT; usCount++ ) { if( CharacterIsGettingPathPlotted( usCount ) == TRUE ) { usX=DEST_ETA_X-4; usY=(Y_OFFSET*usCount-1)+(Y_START+(usCount*Y_SIZE)); if( usCount >= FIRST_VEHICLE ) { usVehicleCont = usCount - FIRST_VEHICLE; usY=(Y_OFFSET*usVehicleCont-1)+(usVehicleY+(usVehicleCont*Y_SIZE)); } usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); if( ( usCount == 0 ) || ( usCount != 0 ? !( CharacterIsGettingPathPlotted( ( UINT16 )( usCount - 1 ) ) ) : 0 ) || ( usCount == FIRST_VEHICLE ) ) { LineDraw( TRUE, usX+4, usY, usX+DEST_ETA_WIDTH+4, usY, usColor,pDestBuf); } if( ( ( usCount == MAX_CHARACTER_COUNT - 1 ) ) || ( usCount != ( MAX_CHARACTER_COUNT - 1 ) ? !( CharacterIsGettingPathPlotted( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) ) { LineDraw(TRUE, usX+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX+DEST_ETA_WIDTH+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); } LineDraw(TRUE, usX+4, usY, usX+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); LineDraw(TRUE, usX+DEST_ETA_WIDTH+4, usY, usX+DEST_ETA_WIDTH+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); InvalidateRegion( usX, usY, usX + DEST_ETA_WIDTH + 5, usY + GetFontHeight(MAP_SCREEN_FONT)+3 ); } } //InvalidateRegion( usX+4, usY, DEST_ETA_WIDTH-10, usY+GetFontHeight(MAP_SCREEN_FONT)+3); //InvalidateRegion( usX+10, usY, usX+ASSIGN_WIDTH, usY+GetFontHeight(MAP_SCREEN_FONT)+3); UnLockVideoSurface( FRAME_BUFFER ); } void HighLightSleepLine() { UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; UINT16 usColor; static INT32 iColorNum = STARTING_COLOR_NUM; static BOOLEAN fDelta=FALSE; static INT32 uiOldHighlight = MAX_CHARACTER_COUNT + 1; UINT16 usCount = 0; UINT16 usX, usX2; UINT16 usY; UINT16 usVehicleCount = 0; // is this a valid line? if( ( giSleepHighLine == -1 ) || fShowInventoryFlag ) { uiOldHighlight = MAX_CHARACTER_COUNT + 1; return; } // if not ready to change glow phase yet, leave if ( !gfGlowTimerExpired ) return; // check if we have moved lines, if so, reset if( uiOldHighlight != giSleepHighLine ) { iColorNum = STARTING_COLOR_NUM; fDelta = FALSE; uiOldHighlight = giSleepHighLine; } if((iColorNum==0)||(iColorNum==10)) { fDelta=!fDelta; } if(!fDelta) iColorNum++; else iColorNum--; pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); for( usCount = 0; usCount < MAX_CHARACTER_COUNT; usCount++ ) { if( IsCharacterSelectedForSleep( usCount ) == TRUE ) { usX=SLEEP_X-4; usX2 = SLEEP_X + SLEEP_WIDTH; usY=(Y_OFFSET*usCount-1)+(Y_START+(usCount*Y_SIZE)); if( usCount >= FIRST_VEHICLE ) { usVehicleCount = usCount - FIRST_VEHICLE; usY=(Y_OFFSET*usVehicleCount-1)+(usVehicleY+(usVehicleCount*Y_SIZE)); } usColor=Get16BPPColor( FROMRGB( GlowColorsA[iColorNum].ubRed, GlowColorsA[iColorNum].ubGreen, GlowColorsA[iColorNum].ubBlue ) ); if( ( usCount == 0 ) || ( usCount != 0 ? !( IsCharacterSelectedForSleep( ( UINT16 )( usCount - 1 ) ) ) : 0 ) || ( usCount == FIRST_VEHICLE ) ) { LineDraw( TRUE, usX+4, usY, usX2, usY, usColor,pDestBuf); } if( ( ( usCount == MAX_CHARACTER_COUNT - 1 ) ) || ( usCount != ( MAX_CHARACTER_COUNT - 1 ) ? !( IsCharacterSelectedForSleep( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) ) { LineDraw(TRUE, usX+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX2, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); } LineDraw(TRUE, usX+ 4, usY, usX + 4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); LineDraw(TRUE, usX2, usY, usX2, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); InvalidateRegion( usX, usY, usX2 + 5, usY + GetFontHeight(MAP_SCREEN_FONT)+3 ); } } UnLockVideoSurface( FRAME_BUFFER ); } void AddCharacter( SOLDIERTYPE *pCharacter ) { UINT16 usCount=0; UINT16 usVehicleCount = 0, usVehicleLoop = 0; // is character valid? if( pCharacter == NULL) { // not valid, leave return; } // valid character? if( pCharacter -> bActive == FALSE ) { return; } // adding a vehicle? if( pCharacter->uiStatusFlags & SOLDIER_VEHICLE ) { while( usVehicleLoop < MAX_CHARACTER_COUNT ) { if ( gCharactersList[ usVehicleLoop ].fValid ) { if ( Menptr[ usVehicleLoop ].uiStatusFlags & SOLDIER_VEHICLE ) { usVehicleCount++; } } usVehicleLoop++; } usCount = FIRST_VEHICLE + usVehicleCount; } else { // go through character list until a blank is reached while( (gCharactersList[usCount].fValid)&&(usCount < MAX_CHARACTER_COUNT) ) { usCount++; } } Assert( usCount < MAX_CHARACTER_COUNT ); if (usCount >= MAX_CHARACTER_COUNT ) { return; } // copy over soldier id value gCharactersList[usCount].usSolID = ( UINT16 )pCharacter -> ubID; // valid character gCharactersList[usCount].fValid = TRUE; return; } /* void MoveCharacter(UINT16 uiInitialPosition, UINT16 uiFinalPosition) { if (!gCharactersList[uiInitialPosition].fValid) return; else memcpy(&gCharactersList[uiFinalPosition], &gCharactersList[uiInitialPosition], sizeof(MapScreenCharacterSt)); } void SwapCharacters(UINT16 uiInitialPosition, UINT16 uiFinalPosition) { MapScreenCharacterSt pTempChar; memcpy(&pTempChar, &gCharactersList[uiInitialPosition], sizeof(MapScreenCharacterSt)); memcpy(&gCharactersList[uiInitialPosition], &gCharactersList[uiFinalPosition], sizeof(MapScreenCharacterSt)); memcpy(&gCharactersList[uiFinalPosition], &pTempChar, sizeof(MapScreenCharacterSt)); } void RemoveCharacter(UINT16 uiCharPosition) { memset(&gCharactersList[uiCharPosition], 0, sizeof( MapScreenCharacterSt )); } */ void LoadCharacters( void ) { UINT16 uiCount=0; SOLDIERTYPE *pSoldier, *pTeamSoldier; INT32 cnt=0; pSoldier = MercPtrs[ 0 ]; // fills array with pressence of player controlled characters for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; cnt++,pTeamSoldier++) { if(pTeamSoldier->bActive) { AddCharacter( pTeamSoldier ); uiCount++; } } // set info char if no selected if( bSelectedInfoChar == -1 ) { if( DialogueActive() == FALSE ) { ChangeSelectedInfoChar( 0, TRUE ); } } // check if ANYONE was available if( uiCount == 0 ) { // no one to show ChangeSelectedInfoChar( -1, TRUE ); bSelectedDestChar = -1; bSelectedAssignChar = -1; bSelectedContractChar = -1; fPlotForHelicopter = FALSE; } } void DisplayCharacterList() { INT16 sCount=0; UINT8 ubForegroundColor = 0; if( ( fShowAssignmentMenu == TRUE ) && ( fTeamPanelDirty == FALSE ) ) { SetFontDestBuffer(FRAME_BUFFER ,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,FALSE); return; } // set dest buffer SetFontDestBuffer(guiSAVEBUFFER,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,FALSE); SetFont( MAP_SCREEN_FONT ); SetFontBackground(FONT_BLACK); for (sCount = 0; sCount < MAX_CHARACTER_COUNT; sCount++) { // skip invalid characters if ( gCharactersList[sCount].fValid == TRUE ) { if( sCount == ( INT16 ) giHighLine ) { ubForegroundColor = FONT_WHITE; } // check to see if character is still alive else if( Menptr[gCharactersList[sCount].usSolID].bLife == 0 ) { ubForegroundColor = FONT_METALGRAY; } else if( CharacterIsGettingPathPlotted( sCount ) == TRUE ) { ubForegroundColor = FONT_LTBLUE; } // in current sector? else if( ( Menptr[gCharactersList[sCount].usSolID].sSectorX == sSelMapX ) && ( Menptr[gCharactersList[sCount].usSolID].sSectorY == sSelMapY ) && ( Menptr[gCharactersList[sCount].usSolID].bSectorZ == iCurrentMapSectorZ ) ) { // mobile ? if( ( Menptr[gCharactersList[sCount].usSolID].bAssignment < ON_DUTY ) || ( Menptr[gCharactersList[sCount].usSolID].bAssignment == VEHICLE ) ) ubForegroundColor = FONT_YELLOW; else ubForegroundColor = FONT_MAP_DKYELLOW; } else { // not in current sector ubForegroundColor = 5; } SetFontForeground( ubForegroundColor ); DrawName( Menptr[gCharactersList[sCount].usSolID].name, sCount, MAP_SCREEN_FONT); DrawLocation(sCount, sCount, MAP_SCREEN_FONT); DrawDestination(sCount, sCount, MAP_SCREEN_FONT); DrawAssignment(sCount, sCount, MAP_SCREEN_FONT); DrawTimeRemaining(sCount, MAP_SCREEN_FONT, ubForegroundColor ); } } HandleDisplayOfSelectedMercArrows( ); SetFontDestBuffer(FRAME_BUFFER ,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,FALSE); EnableDisableTeamListRegionsAndHelpText( ); // mark all pop ups as dirty, so that any open assigment menus get reblitted over top of the team list MarkAllBoxesAsAltered( ); return; } // THIS IS STUFF THAT RUNS *ONCE* DURING APPLICATION EXECUTION, AT INITIAL STARTUP UINT32 MapScreenInit(void) { VOBJECT_DESC VObjectDesc; SetUpBadSectorsList( ); // setup message box system InitGlobalMessageList( ); // init palettes for big map InitializePalettesForMap( ); // set up mapscreen fast help text SetUpMapScreenFastHelpText( ); // set up leave list arrays for dismissed mercs InitLeaveList( ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\group_confirm.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiUpdatePanel ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\group_confirm_tactical.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiUpdatePanelTactical ) ); return TRUE; } UINT32 MapScreenShutdown(void) { // destroy some popup boxes fShowAssignmentMenu = FALSE; CreateDestroyAssignmentPopUpBoxes( ); fShowContractMenu = FALSE; DetermineIfContractMenuCanBeShown( ); RemoveBox(ghContractBox); ghContractBox = -1; if ( ghRemoveMercAssignBox != -1 ) { fShowRemoveMenu = FALSE; RemoveBox( ghRemoveMercAssignBox ); ghRemoveMercAssignBox = -1; } // free up alloced mapscreen messages FreeGlobalMessageList( ); ShutDownPalettesForMap( ); // free memory for leave list arrays for dismissed mercs ShutDownLeaveList( ); DeleteVideoObjectFromIndex(guiUpdatePanel ); DeleteVideoObjectFromIndex(guiUpdatePanelTactical); return TRUE; } UINT32 MapScreenHandle(void) { UINT32 uiNewScreen; INT32 found=FALSE; UINT32 uiMins=0; UINT32 uiHours=0; UINT32 uiDays=0; VSURFACE_DESC vs_desc; VOBJECT_DESC VObjectDesc; // static BOOLEAN fSecondFrame = FALSE; INT32 iCounter = 0; SOLDIERTYPE *pSoldier = NULL; //DO NOT MOVE THIS FUNCTION CALL!!! //This determines if the help screen should be active if( ShouldTheHelpScreenComeUp( HelpScreenDetermineWhichMapScreenHelpToShow(), FALSE ) ) { // handle the help screen HelpScreenHandler(); return( MAP_SCREEN ); } MoveRadarScreen(); // shaded screen, leave if ( gfLoadPending == 2 ) { gfLoadPending = FALSE; // Load Sector // BigCheese if ( !SetCurrentWorldSector( sSelMapX, sSelMapY , ( INT8 )iCurrentMapSectorZ ) ) { // Cannot load! } else { CreateDestroyMapInvButton(); // define our progress bar //CreateProgressBar( 0, 118, 183, 522, 202 ); } return( MAP_SCREEN ); } // WANNE: /*if (fShowInventoryFlag == TRUE) { DeleteButtonsForScrolling(); } else { CreateButtonsForScrolling(); }*/ // if ( (fInMapMode == FALSE ) && ( fMapExitDueToMessageBox == FALSE ) ) if ( !fInMapMode ) { gfFirstMapscreenFrame = TRUE; InitPreviousPaths(); // if arrival sector is invalid, reset to A9 if ( ( gsMercArriveSectorX < 1 ) || ( gsMercArriveSectorY < 1 ) || ( gsMercArriveSectorX > 16 ) || ( gsMercArriveSectorY > 16 ) ) { gsMercArriveSectorX = 9; gsMercArriveSectorY = 1; } gfInConfirmMapMoveMode = FALSE; gfInChangeArrivalSectorMode = FALSE; fLeavingMapScreen = FALSE; fResetTimerForFirstEntryIntoMapScreen = TRUE; fFlashAssignDone = FALSE; gfEnteringMapScreen = 0; guiTacticalInterfaceFlags |= INTERFACE_MAPSCREEN; // fDisabledMapBorder = FALSE; // handle the sort buttons AddTeamPanelSortButtonsForMapScreen( ); // load bottom graphics LoadMapScreenInterfaceBottom( ); MoveToEndOfMapScreenMessageList( ); // if the current time compression mode is something legal in mapscreen, keep it if ( ( giTimeCompressMode >= TIME_COMPRESS_5MINS ) && ( giTimeCompressMode <= TIME_COMPRESS_60MINS ) ) { // leave the current time compression mode set, but DO stop it StopTimeCompression(); } else { // set compressed mode to X0 (which also stops time compression) SetGameTimeCompressionLevel( TIME_COMPRESS_X0 ); } // disable video overlay for tactical scroll messages EnableDisableScrollStringVideoOverlay( FALSE ); CreateDestroyInsuranceMouseRegionForMercs( TRUE ); // ATE: Init tactical interface interface ( always to team panel ) //SetCurrentInterfacePanel( TEAM_PANEL ); // Do some things to this now that it's initialized //MSYS_DisableRegion( &gViewportRegion ); //MSYS_DisableRegion( &gRadarRegion ); //Disable all faces SetAllAutoFacesInactive( ); if(fPreLoadedMapGraphics == FALSE ) { // load border graphics LoadMapBorderGraphics( ); //fInterfacePanelDirty=DIRTYLEVEL2; //RenderTacticalInterface(); vs_desc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE; // Grab the Map image strcpy(vs_desc.ImageFile, "INTERFACE\\b_map.pcx"); CHECKF(AddVideoSurface(&vs_desc, &guiBIGMAP)); strcpy(vs_desc.ImageFile, "INTERFACE\\popupbackground.pcx"); CHECKF(AddVideoSurface(&vs_desc, &guiPOPUPTEX)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\SAM.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSAMICON)); // VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; // FilenameForBPP("INTERFACE\\s_map.sti", VObjectDesc.ImageFile); // CHECKF( AddVideoObject( &VObjectDesc, &guiMAP ) ); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mapcursr.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMAPCURSORS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Mine_1.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSubLevel1)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Mine_2.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSubLevel2)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Mine_3.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSubLevel3)); //VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; //FilenameForBPP("INTERFACE\\addonslcp.sti", VObjectDesc.ImageFile); //CHECKF(AddVideoObject(&VObjectDesc, &guiCORNERADDONS)); //VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; //FilenameForBPP("INTERFACE\\mapborder.sti", VObjectDesc.ImageFile); //CHECKF(AddVideoObject(&VObjectDesc, &guiMAPBORDER)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\sleepicon.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSleepIcon)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\charinfo.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARINFO)); /*strcpy(vs_desc.ImageFile, "INTERFACE\\playlist3.pcx"); CHECKF(AddVideoSurface( &vs_desc, &guiCHARLIST ));*/ VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; if (iResolution == 0) { FilenameForBPP("INTERFACE\\newgoldpiece3.sti", VObjectDesc.ImageFile ); } else if (iResolution == 1) { FilenameForBPP("INTERFACE\\newgoldpiece3_800x600.sti", VObjectDesc.ImageFile ); } else if (iResolution == 2) { FilenameForBPP("INTERFACE\\newgoldpiece3_1024x768.sti", VObjectDesc.ImageFile ); } CHECKF(AddVideoObject(&VObjectDesc, &guiCHARLIST)); //VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; //FilenameForBPP("INTERFACE\\mapbordercorner.sti", VObjectDesc.ImageFile); //CHECKF(AddVideoObject(&VObjectDesc, &guiMAPCORNER)); // VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; // FilenameForBPP("INTERFACE\\popup.sti", VObjectDesc.ImageFile); // CHECKF(AddVideoObject(&VObjectDesc, &guiPOPUPBORDERS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\boxes.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARICONS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\incross.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCROSS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mapinv.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMAPINV)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\map_inv_2nd_gun_cover.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMapInvSecondHandBlockout)); // the upper left corner piece icons VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\top_left_corner_icons.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiULICONS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\map_item.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiORTAICON)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\prison.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiTIXAICON)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\merc_between_sector_icons.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARBETWEENSECTORICONS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\merc_mvt_green_arrows.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARBETWEENSECTORICONSCLOSE)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\GreenArr.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiLEVELMARKER)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Helicop.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiHelicopterIcon)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\eta_pop_up.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMapBorderEtaPopUp)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\pos2.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMapBorderHeliSectors)); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\secondary_gun_hidden.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiSecItemHiddenVO ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\selectedchararrow.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiSelectedCharArrow ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mine.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiMINEICON ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; sprintf( VObjectDesc.ImageFile, "INTERFACE\\hilite.sti" ); AddVideoObject( &VObjectDesc, &guiSectorLocatorGraphicID ); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\BullsEye.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiBULLSEYE)); HandleLoadOfMapBottomGraphics( ); // load the militia pop up box LoadMilitiaPopUpBox( ); // graphic for pool inventory LoadInventoryPoolGraphic( ); //Kris: Added this because I need to blink the icons button. VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; sprintf( VObjectDesc.ImageFile, "INTERFACE\\newemail.sti" ); AddVideoObject( &VObjectDesc, &guiNewMailIcons ); } // create buttons CreateButtonsForMapBorder( ); // create mouse regions for level markers CreateMouseRegionsForLevelMarkers( ); // change selected sector/level if necessary // NOTE: Must come after border buttons are created, since it may toggle them! if( AnyMercsHired( ) == FALSE ) { // select starting sector (A9 - Omerta) ChangeSelectedMapSector( 9, 1, 0 ); } else if( ( gWorldSectorX > 0 ) && ( gWorldSectorY > 0 ) && ( gbWorldSectorZ != -1 ) ) { // select currently loaded sector as the map sector ChangeSelectedMapSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); } else // no loaded sector { // only select A9 - Omerta IF there is no current selection, otherwise leave it as is if ( ( sSelMapX == 0 ) || ( sSelMapY == 0 ) || ( iCurrentMapSectorZ == -1 ) ) { ChangeSelectedMapSector( 9, 1, 0 ); } } VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Bars.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiBrownBackgroundForTeamPanel ) ); // we are in fact in the map, do not repeat this sequence fInMapMode = TRUE; // dirty map fMapPanelDirty=TRUE; // dirty team region fTeamPanelDirty = TRUE; // dirty info region fCharacterInfoPanelDirty = TRUE; // direty map bottom region fMapScreenBottomDirty = TRUE; // tactical scroll of messages not allowed to beep until new message is added in tactical fOkToBeepNewMessage = FALSE; // not in laptop, not about to go there either fLapTop=FALSE; // reset show aircraft flag //fShowAircraftFlag = FALSE; // reset fact we are showing white bounding box around face fShowFaceHightLight = FALSE; fShowItemHighLight = FALSE; // reset all selected character flags ResetAllSelectedCharacterModes( ); if( fFirstTimeInMapScreen == TRUE ) { fFirstTimeInMapScreen = FALSE; // fShowMapScreenHelpText = TRUE; } fShowMapInventoryPool = FALSE; // init character list - set all values in the list to 0 InitalizeVehicleAndCharacterList( ); // deselect all entries ResetSelectedListForMapScreen( ); LoadCharacters(); // set up regions MSYS_DefineRegion( &gMapViewRegion, MAP_VIEW_START_X + MAP_GRID_X, MAP_VIEW_START_Y + MAP_GRID_Y,MAP_VIEW_START_X + MAP_VIEW_WIDTH+MAP_GRID_X-1, MAP_VIEW_START_Y + MAP_VIEW_HEIGHT-1 + 8, MSYS_PRIORITY_HIGH - 3, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK ); MSYS_DefineRegion( &gCharInfoHandRegion, ((INT16)( 4 )), ((INT16)( 81 )) ,((INT16)(62)), ((INT16)(103)), MSYS_PRIORITY_HIGH, MSYS_NO_CURSOR, ItemRegionMvtCallback , ItemRegionBtnCallback ); MSYS_DefineRegion( &gCharInfoFaceRegion, (INT16) PLAYER_INFO_FACE_START_X, (INT16) PLAYER_INFO_FACE_START_Y, (INT16) PLAYER_INFO_FACE_END_X, (INT16) PLAYER_INFO_FACE_END_Y, MSYS_PRIORITY_HIGH, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, FaceRegionBtnCallback ); MSYS_DefineRegion(&gMPanelRegion, INV_REGION_X, INV_REGION_Y, INV_REGION_X+INV_REGION_WIDTH, INV_REGION_Y+INV_REGION_HEIGHT, MSYS_PRIORITY_HIGH, MSYS_NO_CURSOR, MSYS_NO_CALLBACK,InvmaskRegionBtnCallBack); // screen mask for animated cursors MSYS_DefineRegion( &gMapScreenMaskRegion, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_LOW, CURSOR_NORMAL, MSYS_NO_CALLBACK, MapScreenMarkRegionBtnCallback); // set help text for item glow region SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] ); // init the timer menus InitTimersForMoveMenuMouseRegions( ); giMapContractButtonImage = LoadButtonImage( "INTERFACE\\contractbutton.sti" ,-1,0,-1,1,-1 ); // buttonmake giMapContractButton= QuickCreateButton( giMapContractButtonImage, CONTRACT_X + 5, CONTRACT_Y - 1, BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 5, (GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)ContractButtonCallback); SpecifyButtonText( giMapContractButton, pContractButtonString[ 0 ] ); SpecifyButtonFont( giMapContractButton, MAP_SCREEN_FONT ); SpecifyButtonUpTextColors( giMapContractButton, CHAR_TEXT_FONT_COLOR, FONT_BLACK ); SpecifyButtonDownTextColors( giMapContractButton, CHAR_TEXT_FONT_COLOR, FONT_BLACK ); // create mouse region for pause clock CreateMouseRegionForPauseOfClock( CLOCK_REGION_START_X, CLOCK_REGION_START_Y ); if (iResolution == 0) { usVehicleY = 319; } else if (iResolution == 1) { usVehicleY = 414; } else if (iResolution == 2) { usVehicleY = 549; } // create mouse regions CreateMouseRegionsForTeamList( ); ReBuildCharactersList( ); // create status bar region CreateMapStatusBarsRegion( ); // Add region MSYS_AddRegion( &gMapViewRegion); MSYS_AddRegion( &gCharInfoFaceRegion); MSYS_AddRegion( &gMPanelRegion); if ( !gfFadeOutDone && !gfFadeIn ) { MSYS_SetCurrentCursor(SCREEN_CURSOR); } MSYS_DisableRegion(&gMPanelRegion); // create contract box CreateContractBox( NULL ); // create the permanent boxes for assignment and its submenus fShowAssignmentMenu = TRUE; CreateDestroyAssignmentPopUpBoxes( ); fShowAssignmentMenu = FALSE; // create merc remove box CreateMercRemoveAssignBox( ); // test message // TestMessageSystem( ); // fill in ColorFillVideoSurfaceArea( guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, Get16BPPColor( RGB_NEAR_BLACK ) ); ColorFillVideoSurfaceArea( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, Get16BPPColor( RGB_NEAR_BLACK ) ); if( ( fFirstTimeInMapScreen == TRUE ) && ( AnyMercsHired( ) == FALSE ) ) { // render both panels for the restore RenderMapRegionBackground( ); RenderTeamRegionBackground( ); // now do the warning box DoMapMessageBox( MSG_BOX_BASIC_STYLE, pMapErrorString[ 4 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } fFirstTimeInMapScreen = FALSE; if( gpCurrentTalkingFace != NULL ) { // GO FROM GAMESCREEN TO MAPSCREEN // REMOVE OLD UI // Set face inactive! //gpCurrentTalkingFace->fCanHandleInactiveNow = TRUE; //SetAutoFaceInActive( gpCurrentTalkingFace->iID ); //gfFacePanelActive = FALSE; // make him continue talking ContinueDialogue( MercPtrs[ gpCurrentTalkingFace -> ubSoldierID ], FALSE ); // reset diabled flag //gpCurrentTalkingFace->fDisabled = FALSE; // Continue his talking! } fOneFrame = FALSE; if( fEnterMapDueToContract == TRUE ) { if( pContractReHireSoldier ) { FindAndSetThisContractSoldier( pContractReHireSoldier ); } fEnterMapDueToContract = FALSE; } } // if not going anywhere else if ( guiPendingScreen == NO_PENDING_SCREEN ) { if ( HandleFadeOutCallback( ) ) { // force mapscreen to be reinitialized even though we're already in it EndMapScreen( TRUE ); return( MAP_SCREEN ); } if ( HandleBeginFadeOut( MAP_SCREEN ) ) { return( MAP_SCREEN ); } } // check to see if we need to rebuild the characterlist for map screen HandleRebuildingOfMapScreenCharacterList( ); HandleStrategicTurn( ); /* // update cursor based on state if( ( bSelectedDestChar == -1 ) && ( fPlotForHelicopter == FALSE ) && ( gfInChangeArrivalSectorMode == FALSE ) ) { // reset cursor if ( !gfFadeIn ) { ChangeMapScreenMaskCursor( CURSOR_NORMAL ); } } */ // check if we are going to create or destroy map border graphics? CreateDestroyMapInventoryPoolButtons( FALSE ); // set up buttons for mapscreen scroll // HandleMapScrollButtonStates( ); // don't process any input until we've been through here once if( gfFirstMapscreenFrame == FALSE ) { // Handle Interface uiNewScreen = HandleMapUI( ); if ( uiNewScreen != MAP_SCREEN ) { return( MAP_SCREEN ); } } // handle flashing of contract column for any mercs leaving very soon HandleContractTimeFlashForMercThatIsAboutLeave( ); if( ( fShownAssignmentMenu == FALSE ) && ( fShowAssignmentMenu == TRUE ) ) { // need a one frame pause fShownAssignmentMenu = fShowAssignmentMenu; fShowAssignmentMenu = FALSE; fOneFrame = TRUE; } else if( ( fShownContractMenu == FALSE ) && ( fShowContractMenu == TRUE ) ) { fShownContractMenu = fShowContractMenu; fShowContractMenu = FALSE; fOneFrame = TRUE; } else if( fOneFrame ) { // one frame passed fShowContractMenu = fShownContractMenu; fShowAssignmentMenu = fShownAssignmentMenu; fOneFrame = FALSE; } if( ( fShownAssignmentMenu == FALSE ) && ( fShowAssignmentMenu == FALSE ) ) { bSelectedAssignChar = -1; } HandlePostAutoresolveMessages(); // UpdateLevelButtonStates( ); // NOTE: This must happen *before* UpdateTheStateOfTheNextPrevMapScreenCharacterButtons() CreateDestroyMapCharacterScrollButtons( ); // update the prev next merc buttons UpdateTheStateOfTheNextPrevMapScreenCharacterButtons( ); // handle for inventory HandleCursorOverRifleAmmo( ); // check contract times, update screen if they do change CheckAndUpdateBasedOnContractTimes( ); // handle flashing of assignment strings when merc's assignment is done HandleAssignmentsDoneAndAwaitingFurtherOrders( ); // handle timing for the various glowing higlights HandleCommonGlowTimer( ); // are we attempting to plot a foot/vehicle path during aircraft mode..if so, stop it CheckIfPlottingForCharacterWhileAirCraft( ); // check to see if helicopter is available //CheckIfHelicopterAvailable( ); if( fShowMapInventoryPool ) { HandleFlashForHighLightedItem( ); } // CreateDestroyMovementBox( 0,0,0 ); // Deque all game events DequeAllGameEvents( TRUE ); // Handle Interface Stuff SetUpInterface( ); // reset time compress has occured ResetTimeCompressHasOccured( ); // handle change in info char HandleChangeOfInfoChar( ); // update status of contract box UpDateStatusOfContractBox( ); // error check of assignments UpdateBadAssignments( ); // if cursor has left map..will need to update temp path plotting and cursor CheckToSeeIfMouseHasLeftMapRegionDuringPathPlotting( ); // update assignment menus and submenus HandleShadingOfLinesForAssignmentMenus( ); // check which menus can be shown right now DetermineWhichAssignmentMenusCanBeShown( ); DetermineWhichMilitiaControlMenusCanBeShown( ); //lal // determine if contract menu can be shown DetermineIfContractMenuCanBeShown( ); // if pre battle and inventory up?..get rid of inventory HandlePreBattleInterfaceWithInventoryPanelUp( ); // create destroy trash can region CreateDestroyTrashCanRegion( ); // update these buttons UpdateStatusOfMapSortButtons( ); // if in inventory mode, make sure it's still ok CheckForInventoryModeCancellation(); // restore background rects RestoreBackgroundRects( ); InterruptTimeForMenus( ); // place down background BlitBackgroundToSaveBuffer( ); if( fLeavingMapScreen == TRUE ) { return( MAP_SCREEN ); } if( fDisableDueToBattleRoster == FALSE ) { /* // ATE: OK mark is rendering the item every frame - which isn't good // however, don't want to break the world here.. // this line was added so that when the ItemGlow() is on, // we're not rendering also, else glow looks bad if ( !fShowItemHighLight ) { RenderHandPosItem(); } */ if( fDrawCharacterList ) { if ( !fShowInventoryFlag ) { // if we are not in inventory mode, show character list HandleHighLightingOfLinesInTeamPanel( ); DisplayCharacterList(); } fDrawCharacterList = FALSE; } } if( !fShowMapInventoryPool && !gfPauseDueToPlayerGamePause && !IsMapScreenHelpTextUp( ) /* && !fDisabledMapBorder */ ) { RenderMapCursorsIndexesAnims( ); } if( fDisableDueToBattleRoster == FALSE ) { // render status bar HandleCharBarRender( ); } if( fShowInventoryFlag || fDisableDueToBattleRoster ) { for( iCounter = 0; iCounter < MAX_SORT_METHODS; iCounter++ ) { UnMarkButtonDirty( giMapSortButton[ iCounter ] ); } } if( fShowContractMenu || fDisableDueToBattleRoster ) { UnMarkButtonDirty( giMapContractButton ); } // handle any old messages ScrollString( ); HandleSpontanousTalking( ); if( ( fDisableDueToBattleRoster == FALSE ) ) { // remove the move box once user leaves it CreateDestroyMovementBox( 0,0,0 ); // this updates the move box contents when changes took place ReBuildMoveBox( ); } if( ( fDisableDueToBattleRoster == FALSE )&&( ( fShowAssignmentMenu == TRUE )||( fShowContractMenu == TRUE ) ) ) { // highlight lines? HandleHighLightingOfLinesInTeamPanel( ); // render glow for contract region ContractBoxGlow( ); GlowTrashCan( ); // handle changing of highlighted lines HandleChangeOfHighLightedLine( ); } if( fDisableDueToBattleRoster == FALSE ) { // render face of current info char, for animation DrawFace( bSelectedInfoChar ); // handle autofaces HandleAutoFaces( ); HandleTalkingAutoFaces( ); /* GlowFace( ); GlowItem( ); */ } // automatically turns off mapscreen ui overlay messages when appropriate MonitorMapUIMessage( ); // if heli is around, show it if( fHelicopterAvailable && fShowAircraftFlag && ( iCurrentMapSectorZ == 0 ) && !fShowMapInventoryPool ) { // this is done on EVERY frame, I guess it beats setting entire map dirty all the time while he's moving... DisplayPositionOfHelicopter( ); } // display town info DisplayTownInfo( sSelMapX, sSelMapY, ( INT8 ) iCurrentMapSectorZ ); if( fShowTownInfo == TRUE ) { // force update of town mine info boxes ForceUpDateOfBox( ghTownMineBox ); MapscreenMarkButtonsDirty(); } // update town mine pop up display UpdateTownMinePopUpDisplay( ); if( fShowAttributeMenu ) { // mark all popups as dirty MarkAllBoxesAsAltered( ); } // if plotting path if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { // plot out paths PlotPermanentPaths( ); PlotTemporaryPaths( ); // show ETA RenderMapBorderEtaPopUp( ); DisplayGroundEta(); //DisplayDestinationOfCurrentDestMerc( ); } HandleContractRenewalSequence( ); // handle dialog HandleDialogue( ); // now the border corner piece // RenderMapBorderCorner( ); // handle display of inventory pop up HandleDisplayOfItemPopUpForSector( 9, 1, 0 ); // Display Framerate DisplayFrameRate( ); // update paused states UpdatePausedStatesDueToTimeCompression( ); // is there a description to be displayed? RenderItemDescriptionBox( ); // render clock // WANNE: Renders the clock in the strategy screen RenderClock(CLOCK_X, CLOCK_Y); #ifdef JA2TESTVERSION if( !gfWorldLoaded ) { SetFont( FONT10ARIAL ); if( GetJA2Clock() % 1000 < 500 ) SetFontForeground( FONT_DKRED ); else SetFontForeground( FONT_RED ); mprintf( SCREEN_WIDTH - 110, 2, L"TESTVERSION MSG" ); if( GetJA2Clock() % 1000 < 500 ) SetFontForeground( FONT_DKYELLOW ); else SetFontForeground( FONT_YELLOW ); mprintf( SCREEN_WIDTH - 110, 12, L"NO WORLD LOADED" ); InvalidateRegion( SCREEN_WIDTH - 110, 2, SCREEN_WIDTH, 23 ); } #endif if( fEndShowInventoryFlag == TRUE ) { if( InKeyRingPopup( ) == TRUE ) { DeleteKeyRingPopup( ); } else { fShowInventoryFlag = FALSE; // set help text for item glow region SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] ); } fTeamPanelDirty = TRUE; fEndShowInventoryFlag = FALSE; } // handle animated cursor update if ( !gfFadeIn ) { HandleAnimatedCursorsForMapScreen( ); } // if inventory is being manipulated, update cursor HandleMapInventoryCursor(); if( fShowDescriptionFlag == TRUE ) { // unmark done button if( gpItemDescObject->usItem == MONEY ) { MapscreenMarkButtonsDirty(); } if( Item[ gpItemDescObject->usItem ].usItemClass & IC_GUN ) { MapscreenMarkButtonsDirty(); } UnMarkButtonDirty( giMapInvDoneButton ); //UnMarkButtonDirty( giCharInfoButton[ 0 ] ); //UnMarkButtonDirty( giCharInfoButton[ 1 ] ); MarkAButtonDirty( giMapInvDescButton ); } else { if( fShowInventoryFlag == TRUE ) { MarkAButtonDirty( giMapInvDoneButton ); MarkAButtonDirty( giCharInfoButton[ 1 ] ); MarkAButtonDirty( giCharInfoButton[ 0 ] ); } } DrawMilitiaPopUpBox( ); if( fDisableDueToBattleRoster == FALSE ) { CreateDestroyTheUpdateBox( ); DisplaySoldierUpdateBox( ); } // pop up display boxes DisplayBoxes(FRAME_BUFFER); // render buttons RenderButtons( ); if( fShowMapScreenMovementList ) { // redisplay Movement box to blit it over any border buttons, since if long enough it can overlap them ForceUpDateOfBox( ghMoveBox ); DisplayOnePopupBox( ghMoveBox, FRAME_BUFFER ); } if( fShowContractMenu ) { // redisplay Contract box to blit it over any map sort buttons, since they overlap ForceUpDateOfBox( ghContractBox ); DisplayOnePopupBox( ghContractBox, FRAME_BUFFER ); } //If we have new email, blink the email icon on top of the laptop button. CheckForAndRenderNewMailOverlay(); // handle video overlays ExecuteVideoOverlays( ); if ( InItemStackPopup( ) ) { RenderItemStackPopup( FALSE ); } if( InKeyRingPopup() ) { RenderKeyRingPopup( FALSE ); } CheckForMeanwhileOKStart( ); // save background rects // ATE: DO this BEFORE rendering help text.... SaveBackgroundRects( ); if( ( fDisableDueToBattleRoster == FALSE ) && ( fShowAssignmentMenu == FALSE )&&( fShowContractMenu == FALSE ) ) { // highlight lines? HandleHighLightingOfLinesInTeamPanel( ); // render glow for contract region ContractBoxGlow( ); GlowTrashCan( ); // handle changing of highlighted lines HandleChangeOfHighLightedLine( ); GlowFace( ); GlowItem( ); } if( fShowMapScreenHelpText ) { // display map screen fast help DisplayMapScreenFastHelpList( ); } else { // render help RenderButtonsFastHelp( ); } /* if( fSecondFrame ) { if( gTacticalStatus.fDidGameJustStart ) { // game just started, check what state player is in...... HandlePlayerEnteringMapScreenBeforeGoingToTactical( ); } } fSecondFrame = FALSE; */ // execute dirty ExecuteBaseDirtyRectQueue( ); // update cursor UpdateCursorIfInLastSector( ); // about to leave for new map if ( gfLoadPending == 1 ) { gfLoadPending++; // Shade this frame! // Remove cursor SetCurrentCursorFromDatabase( VIDEO_NO_CURSOR ); //Shadow area ShadowVideoSurfaceRect( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); InvalidateScreen( ); } //InvalidateRegion( 0,0, 640, 480); EndFrameBufferRender( ); // if not going anywhere else if ( guiPendingScreen == NO_PENDING_SCREEN ) { if ( HandleFadeInCallback( ) ) { // force mapscreen to be reinitialized even though we're already in it EndMapScreen( TRUE ); } if ( HandleBeginFadeIn( MAP_SCREEN ) ) { } } HandlePreBattleInterfaceStates(); if( gfHotKeyEnterSector ) { gfHotKeyEnterSector = FALSE; ActivatePreBattleEnterSectorAction(); } #ifdef JA2BETAVERSION DebugValidateSoldierData( ); #endif if ( gfRequestGiveSkyriderNewDestination ) { RequestGiveSkyriderNewDestination(); gfRequestGiveSkyriderNewDestination = FALSE; } if( gfFirstMapscreenFrame ) { // fSecondFrame = TRUE; gfFirstMapscreenFrame = FALSE; } else { // handle exiting from mapscreen due to both exit button clicks and keyboard equivalents HandleExitsFromMapScreen( ); } return( MAP_SCREEN ); } void DrawString(STR16 pString, UINT16 uiX, UINT16 uiY, UINT32 uiFont) { // draw monochrome string SetFont(uiFont); gprintfdirty(uiX,uiY,pString); mprintf(uiX,uiY,pString); } void SetDayAlternate(STR16 pStringA, ...) { // this sets the clock counter, unwind loop UINT16 uiX=0; UINT16 uiY=0; CHAR16 String[80]; va_list argptr; va_start(argptr, pStringA); // Set up variable argument pointer vswprintf(String, pStringA, argptr); // process gprintf string (get output str) va_end(argptr); if (String[1]==0) { String[1]=String[0]; String[0]=L' '; } String[2]=gsTimeStrings[ 3 ][ 0 ]; String[3]=L' '; String[4]=0; uiX=CLOCK_HOUR_X_START-9; uiY=CLOCK_Y_START; SetFont( ETA_FONT ); SetFontForeground( FONT_LTGREEN ); SetFontBackground( FONT_BLACK ); //RestoreExternBackgroundRect( uiX, uiY, 20 ,GetFontHeight( ETA_FONT ) ); mprintf( uiX, uiY, String ); } void SetHourAlternate(STR16 pStringA, ...) { // this sets the clock counter, unwind loop UINT16 uiX=0; UINT16 uiY=0; CHAR16 String[80]; va_list argptr; va_start(argptr, pStringA); // Set up variable argument pointer vswprintf(String, pStringA, argptr); // process gprintf string (get output str) va_end(argptr); if (String[1]==0) { String[1]=String[0]; String[0]=L' '; } String[2]=gsTimeStrings[ 0 ][ 0 ]; String[3]=L' '; String[4]= 0; uiX=CLOCK_MIN_X_START-5; uiY=CLOCK_Y_START; DrawString(String, uiX, uiY, ETA_FONT); SetFont( ETA_FONT ); SetFontForeground( FONT_LTGREEN ); SetFontBackground( FONT_BLACK ); //RestoreExternBackgroundRect( uiX, uiY, 20 ,GetFontHeight( ETA_FONT ) ); mprintf( uiX, uiY, String ); } void SetClockHour(STR16 pStringA, ...) { // this sets the clock counter, unwind loop UINT16 uiX=0; UINT16 uiY=0; CHAR16 String[80]; va_list argptr; va_start(argptr, pStringA); // Set up variable argument pointer vswprintf(String, pStringA, argptr); // process gprintf string (get output str) va_end(argptr); if (String[1]==0) { String[1]=String[0]; String[0]=L' '; } String[2]=gsTimeStrings[ 0 ][ 0 ]; String[3]=L' '; String[4]=0; uiX=CLOCK_HOUR_X_START-8; uiY=CLOCK_Y_START; SetFont( ETA_FONT ); SetFontForeground( FONT_LTGREEN ); SetFontBackground( FONT_BLACK ); //RestoreExternBackgroundRect( uiX, uiY, 20 ,GetFontHeight( ETA_FONT ) ); mprintf( uiX, uiY, String ); } void SetClockMin(STR16 pStringA, ...) { // this sets the clock counter, unwind loop CHAR16 String[10]; va_list argptr; va_start(argptr, pStringA); // Set up variable argument pointer vswprintf(String, pStringA, argptr); // process gprintf string (get output str) va_end(argptr); if (String[1]==0) { String[1]=String[0]; String[0]=L' '; } String[2]=gsTimeStrings[ 1 ][ 0 ]; String[3]=L' '; String[4]=0; SetFont( ETA_FONT ); SetFontForeground( FONT_LTGREEN ); SetFontBackground( FONT_BLACK ); //RestoreExternBackgroundRect( CLOCK_MIN_X_START - 5, CLOCK_Y_START, 20 ,GetFontHeight( ETA_FONT ) ); mprintf( CLOCK_MIN_X_START-5, CLOCK_Y_START, String ); } void DrawName(STR16 pName, INT16 sRowIndex, INT32 iFont) { INT16 usX=0; INT16 usY=0; // mercs if( sRowIndex < FIRST_VEHICLE ) { FindFontCenterCoordinates((short)NAME_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE)), (short)NAME_WIDTH, (short)Y_SIZE, pName, (long)iFont, &usX, &usY); } // vehicles else { sRowIndex = sRowIndex - FIRST_VEHICLE; //FindFontCenterCoordinates((short)NAME_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE) + 6), (short)NAME_WIDTH, (short)Y_SIZE, pName, (long)iFont, &usX, &usY); FindFontCenterCoordinates((short)NAME_X + 1, (short)(usVehicleY+(sRowIndex*Y_SIZE)), (short)NAME_WIDTH, (short)Y_SIZE, pName, (long)iFont, &usX, &usY); } //RestoreExternBackgroundRect(NAME_X, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), NAME_WIDTH, Y_SIZE); DrawString( pName, (UINT16)usX, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), iFont); } void DrawAssignment(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont) { INT16 usX=0; INT16 usY=0; CHAR16 sString[32]; GetMapscreenMercAssignmentString( MercPtrs[ gCharactersList[ sCharNumber ].usSolID ], sString ); if( sRowIndex < FIRST_VEHICLE ) { FindFontCenterCoordinates((short)ASSIGN_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE)), (short)ASSIGN_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } else { sRowIndex = sRowIndex - FIRST_VEHICLE; //FindFontCenterCoordinates((short)ASSIGN_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE) + 6), (short)ASSIGN_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); FindFontCenterCoordinates((short)ASSIGN_X + 1, (short)(usVehicleY+(sRowIndex*Y_SIZE)), (short)ASSIGN_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } if( fFlashAssignDone == TRUE ) { if( Menptr[gCharactersList[sCharNumber].usSolID].fDoneAssignmentAndNothingToDoFlag ) { SetFontForeground( FONT_RED ); } } //RestoreExternBackgroundRect(ASSIGN_X-2, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), ASSIGN_WIDTH+2, Y_SIZE); DrawString(sString, (UINT16)usX, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), iFont); } void DrawLocation(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont) { INT16 usX=0; INT16 usY=0; CHAR16 sString[32]; GetMapscreenMercLocationString( MercPtrs[ gCharactersList[ sCharNumber ].usSolID ], sString ); if( sRowIndex < FIRST_VEHICLE ) { // center FindFontCenterCoordinates((short)LOC_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE)), (short)LOC_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } else { //FindFontCenterCoordinates((short)LOC_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE) + 6), (short)LOC_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); sRowIndex = sRowIndex - FIRST_VEHICLE; FindFontCenterCoordinates((short)LOC_X + 1, (short)(usVehicleY+(sRowIndex*Y_SIZE)), (short)LOC_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } // restore background //RestoreExternBackgroundRect(LOC_X, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), LOC_WIDTH, Y_SIZE); // draw string DrawString( sString,((UINT16)(usX)), ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), ((UINT32)iFont)); } void DrawDestination(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont) { INT16 usX=0; INT16 usY=0; CHAR16 sString[32]; GetMapscreenMercDestinationString( MercPtrs[ gCharactersList[ sCharNumber ].usSolID ], sString ); if ( wcslen( sString ) == 0 ) { return; } if( sRowIndex < FIRST_VEHICLE ) { FindFontCenterCoordinates((short)DEST_ETA_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE)), (short)DEST_ETA_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } else { sRowIndex = sRowIndex - FIRST_VEHICLE; //FindFontCenterCoordinates((short)DEST_ETA_X + 1, (short)(Y_START+(sRowIndex*Y_SIZE) + 6 ), (short)DEST_ETA_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); FindFontCenterCoordinates((short)DEST_ETA_X + 1, (short)(usVehicleY+(sRowIndex*Y_SIZE)), (short)DEST_ETA_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } //RestoreExternBackgroundRect(DEST_ETA_X+1, ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), DEST_ETA_WIDTH-1, Y_SIZE); // ShowDestinationOfPlottedPath( sString ); DrawString( sString,((UINT16)(usX)), ((UINT16)(usY+(Y_OFFSET*sRowIndex+1))), ((UINT32)iFont)); } void DrawTimeRemaining( INT16 sCharNumber, INT32 iFont, UINT8 ubFontColor ) { INT16 usX=0; INT16 usY=0; CHAR16 sString[32]; GetMapscreenMercDepartureString( MercPtrs[ gCharactersList[ sCharNumber ].usSolID ], sString, &ubFontColor ); // if merc is highlighted, override the color decided above with bright white if( sCharNumber == ( INT16 ) giHighLine ) { ubFontColor = FONT_WHITE; } SetFont(iFont); SetFontForeground( ubFontColor ); if( sCharNumber < FIRST_VEHICLE ) { FindFontCenterCoordinates((short)TIME_REMAINING_X + 1, (short)(Y_START+(sCharNumber*Y_SIZE)), (short)TIME_REMAINING_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } else { sCharNumber = sCharNumber - FIRST_VEHICLE; //FindFontCenterCoordinates((short)TIME_REMAINING_X + 1, (short)(Y_START+(sCharNumber*Y_SIZE) + 6 ), (short)TIME_REMAINING_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); FindFontCenterCoordinates((short)TIME_REMAINING_X + 1, (short)(usVehicleY+(sCharNumber*Y_SIZE)), (short)TIME_REMAINING_WIDTH, (short)Y_SIZE, sString, (long)iFont, &usX, &usY); } //RestoreExternBackgroundRect(TIME_REMAINING_X, ((UINT16)(usY+(Y_OFFSET*sCharNumber+1))), TIME_REMAINING_WIDTH, Y_SIZE); DrawString(sString,((UINT16)(usX)), ((UINT16)(usY+(Y_OFFSET*sCharNumber+1))), ((UINT32)iFont)); } void RenderMapCursorsIndexesAnims( ) { BOOLEAN fSelectedSectorHighlighted = FALSE; BOOLEAN fSelectedCursorIsYellow = TRUE; UINT16 usCursorColor; UINT32 uiDeltaTime; static INT16 sPrevHighlightedMapX = -1, sPrevHighlightedMapY = -1; static INT16 sPrevSelectedMapX = -1, sPrevSelectedMapY = -1; static BOOLEAN fFlashCursorIsYellow = FALSE; BOOLEAN fDrawCursors; BOOLEAN fHighlightChanged = FALSE; HandleAnimationOfSectors( ); if( gfBlitBattleSectorLocator ) { HandleBlitOfSectorLocatorIcon( gubPBSectorX, gubPBSectorY, gubPBSectorZ, LOCATOR_COLOR_RED ); } fDrawCursors = CanDrawSectorCursor( ); // if mouse cursor is over a map sector if ( fDrawCursors && ( GetMouseMapXY( &gsHighlightSectorX, &gsHighlightSectorY ) ) ) { // handle highlighting of sector pointed at ( WHITE ) // if we're over a different sector than when we previously blitted this if ( ( gsHighlightSectorX != sPrevHighlightedMapX ) || ( gsHighlightSectorY != sPrevHighlightedMapY ) || gfMapPanelWasRedrawn ) { if ( sPrevHighlightedMapX != -1 && sPrevHighlightedMapY != -1 ) { RestoreMapSectorCursor( sPrevHighlightedMapX, sPrevHighlightedMapY ); } // draw WHITE highlight rectangle RenderMapHighlight( gsHighlightSectorX, gsHighlightSectorY, Get16BPPColor( RGB_WHITE ), FALSE ); sPrevHighlightedMapX = gsHighlightSectorX; sPrevHighlightedMapY = gsHighlightSectorY; fHighlightChanged = TRUE; } } else { // nothing now highlighted gsHighlightSectorX = -1; gsHighlightSectorY = -1; if ( sPrevHighlightedMapX != -1 && sPrevHighlightedMapY != -1 ) { RestoreMapSectorCursor( sPrevHighlightedMapX, sPrevHighlightedMapY ); fHighlightChanged = TRUE; } sPrevHighlightedMapX = -1; sPrevHighlightedMapY = -1; } // handle highlighting of selected sector ( YELLOW ) - don't show it while plotting movement if ( fDrawCursors && ( bSelectedDestChar == -1 ) && ( fPlotForHelicopter == FALSE ) ) { // if mouse cursor is over the currently selected sector if( ( gsHighlightSectorX == sSelMapX ) && ( gsHighlightSectorY == sSelMapY ) ) { fSelectedSectorHighlighted = TRUE; // do we need to flash the cursor? get the delta in time uiDeltaTime = GetJA2Clock( ) - guiFlashCursorBaseTime; if ( uiDeltaTime > 300 ) { guiFlashCursorBaseTime = GetJA2Clock(); fFlashCursorIsYellow = !fFlashCursorIsYellow; fHighlightChanged = TRUE; } } if ( !fSelectedSectorHighlighted || fFlashCursorIsYellow ) { // draw YELLOW highlight rectangle usCursorColor = Get16BPPColor( RGB_YELLOW ); } else { // draw WHITE highlight rectangle usCursorColor = Get16BPPColor( RGB_WHITE ); // index letters will also be white instead of yellow so that they flash in synch with the cursor fSelectedCursorIsYellow = FALSE; } // always render this one, it's too much of a pain detecting overlaps with the white cursor otherwise RenderMapHighlight( sSelMapX, sSelMapY, usCursorColor, TRUE ); if ( ( sPrevSelectedMapX != sSelMapX ) || ( sPrevSelectedMapY != sSelMapY ) ) { sPrevSelectedMapX = sSelMapX; sPrevSelectedMapY = sSelMapY; fHighlightChanged = TRUE; } } else { // erase yellow highlight cursor if ( sPrevSelectedMapX != -1 && sPrevSelectedMapY != -1 ) { RestoreMapSectorCursor( sPrevSelectedMapX, sPrevSelectedMapY ); fHighlightChanged = TRUE; } sPrevSelectedMapX = -1; sPrevSelectedMapY = -1; } if ( fHighlightChanged || gfMapPanelWasRedrawn ) { // redraw sector index letters and numbers /* if( fZoomFlag ) DrawMapIndexSmallMap( fSelectedCursorIsYellow ); else */ DrawMapIndexBigMap( fSelectedCursorIsYellow ); } } UINT32 HandleMapUI( ) { UINT32 uiNewEvent = MAP_EVENT_NONE; INT16 sMapX = 0, sMapY = 0; INT8 bMapZ = 0; INT16 sX, sY; UINT8 ubCount=0; PathStPtr pNode=NULL; BOOLEAN fVehicle=FALSE; POINT MousePos; UINT32 uiNewScreen = MAP_SCREEN; BOOLEAN fWasAlreadySelected; // Get Input from keyboard GetMapKeyboardInput( &uiNewEvent ); CreateDestroyMapInvButton(); // Get mouse PollLeftButtonInMapView( &uiNewEvent ); PollRightButtonInMapView( &uiNewEvent ); // Switch on event switch( uiNewEvent ) { case MAP_EVENT_NONE: break; case MAP_EVENT_PLOT_PATH: GetMouseMapXY(&sMapX, &sMapY); /* // translate screen values to map grid values for zoomed in if(fZoomFlag) { sMapX=(UINT16)iZoomX/MAP_GRID_X+sMapX; sMapX=sMapX/2; sMapY=(UINT16)iZoomY/MAP_GRID_Y+sMapY; sMapY=sMapY/2; } */ // plotting for the chopper? if( fPlotForHelicopter == TRUE ) { /* if( IsSectorOutOfTheWay( sMapX, sMapY ) == TRUE ) { if( gfAllowSkyriderTooFarQuote == TRUE ) { SkyRiderTalk( DESTINATION_TOO_FAR ); } return( MAP_SCREEN ); } */ PlotPathForHelicopter( sMapX, sMapY ); fTeamPanelDirty = TRUE; } else { // plot for character // check for valid character Assert ( bSelectedDestChar != -1 ); if ( bSelectedDestChar == -1 ) break; // check if last sector in character's path is same as where mouse is if( GetLastSectorIdInCharactersPath( &Menptr[gCharactersList[bSelectedDestChar].usSolID] ) != ( sMapX + ( sMapY * MAP_WORLD_X ) ) ) { sX = ( GetLastSectorIdInCharactersPath( &Menptr[gCharactersList[bSelectedDestChar].usSolID] ) % MAP_WORLD_X ); sY = ( GetLastSectorIdInCharactersPath( &Menptr[gCharactersList[bSelectedDestChar].usSolID] ) / MAP_WORLD_X ); GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! RestoreBackgroundForMapGrid( sX, sY ); // fMapPanelDirty = TRUE; } //SetFontDestBuffer( FRAME_BUFFER, 0, 0, 640, 480, FALSE ); if( ( IsTheCursorAllowedToHighLightThisSector( sMapX, sMapY ) == TRUE ) && ( SectorInfo[ ( SECTOR( sMapX, sMapY ) ) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] != GROUNDBARRIER ) ) { // Can we get go there? (NULL temp character path) if ( GetLengthOfPath( pTempCharacterPath ) > 0 ) { PlotPathForCharacter( &Menptr[gCharactersList[bSelectedDestChar].usSolID], sMapX, sMapY, FALSE ); // copy the path to every other selected character CopyPathToAllSelectedCharacters( GetSoldierMercPathPtr( MercPtrs[ gCharactersList[ bSelectedDestChar ].usSolID ] ) ); StartConfirmMapMoveMode( sMapY ); fMapPanelDirty = TRUE; fTeamPanelDirty = TRUE; // update team panel desinations } else { // means it's a vehicle and we've clicked an off-road sector MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pMapErrorString[ 40 ] ); } } } break; case MAP_EVENT_CANCEL_PATH: CancelOrShortenPlottedPath( ); break; /* case MAP_EVENT_SELECT_SECTOR: // will select the sector the selected merc is in sMapX=Menptr[gCharactersList[bSelectedInfoChar].usSolID].sSectorX; sMapY=Menptr[gCharactersList[bSelectedInfoChar].usSolID].sSectorY; bMapZ=Menptr[gCharactersList[bSelectedInfoChar].usSolID].bSectorZ; if( ( sSelMapX != sMapX || sSelMapY != sMapY || iCurrentMapSectorZ != bMapZ ) && ( gTacticalStatus.fDidGameJustStart == FALSE ) && ( gfPreBattleInterfaceActive == FALSE ) ) { ChangeSelectedMapSector( sMapX, sMapY, bMapZ ); fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; bSelectedDestChar=-1; } break; */ case MAP_EVENT_CLICK_SECTOR: // Get Current mouse position if ( GetMouseMapXY( &sMapX, &sMapY) ) { /* if( fZoomFlag == TRUE ) { // convert to zoom out coords from screen coords sMapX = ( INT16 )( iZoomX / MAP_GRID_X + sMapX ) / 2; sMapY = ( INT16 )( iZoomY / MAP_GRID_Y + sMapY ) / 2; //sMapX = ( INT16 ) ( ( ( iZoomX ) / ( MAP_GRID_X * 2) ) + sMapX / 2 ); //sMapX = ( INT16 ) ( ( ( iZoomY ) / ( MAP_GRID_Y * 2) ) + sMapY / 2 ); } */ // not zoomed out, make sure this is a valid sector if( IsTheCursorAllowedToHighLightThisSector( sMapX, sMapY ) == FALSE ) { // do nothing, return return( MAP_SCREEN ); } // while item in hand if ( fMapInventoryItem ) { // if not showing item counts on the map if ( !fShowItemsFlag ) { // turn that on ToggleItemsFilter( ); } // if item's owner is known if ( gpItemPointerSoldier != NULL ) { // make sure it's the owner's sector that's selected if ( ( gpItemPointerSoldier->sSectorX != sSelMapX ) || ( gpItemPointerSoldier->sSectorY != sSelMapY ) || ( gpItemPointerSoldier->bSectorZ != iCurrentMapSectorZ ) ) { ChangeSelectedMapSector( gpItemPointerSoldier->sSectorX, gpItemPointerSoldier->sSectorY, gpItemPointerSoldier->bSectorZ ); } } // if not already in sector inventory if ( !fShowMapInventoryPool ) { // start it up ( NOTE: for the item OWNER'S sector, regardless of which sector player clicks ) fShowMapInventoryPool = TRUE; CreateDestroyMapInventoryPoolButtons( TRUE ); } return( MAP_SCREEN ); } // don't permit other click handling while item is in cursor (entering PBI would permit item teleports, etc.) Assert( !fMapInventoryItem ); // this doesn't change selected sector if ( gfInChangeArrivalSectorMode ) { if( SectorInfo[ ( SECTOR( sMapX, sMapY ) ) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] != GROUNDBARRIER ) { // if it's not enemy air controlled if ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( sMapX, sMapY ) ].fEnemyAirControlled == FALSE ) { CHAR16 sMsgString[ 128 ], sMsgSubString[ 64 ]; // move the landing zone over here gsMercArriveSectorX = sMapX; gsMercArriveSectorY = sMapY; // change arrival sector for all mercs currently in transit who are showing up at the landing zone UpdateAnyInTransitMercsWithGlobalArrivalSector(); // we're done, cancel this mode CancelChangeArrivalSectorMode(); // get the name of the sector GetSectorIDString( sMapX, sMapY, 0, sMsgSubString, FALSE ); // now build the string swprintf( sMsgString, pBullseyeStrings[ 1 ], sMsgSubString ); // confirm the change with overlay message MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, sMsgString ); // update destination column for any mercs in transit fTeamPanelDirty = TRUE; } else { // message: not allowed, don't have airspace secured MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pBullseyeStrings[ 2 ] ); } } return( MAP_SCREEN ); } else // not already changing arrival sector { if ( CanMoveBullseyeAndClickedOnIt( sMapX, sMapY ) ) { // if the click is ALSO over the helicopter icon // NOTE: The helicopter icon is NOT necessarily directly over the helicopter's current sector!!! if( CheckForClickOverHelicopterIcon( sMapX, sMapY ) == TRUE ) { CreateBullsEyeOrChopperSelectionPopup(); } else { StartChangeSectorArrivalMode(); } return( MAP_SCREEN ); } } // if new map sector was clicked on if( ( sSelMapX != sMapX ) || ( sSelMapY != sMapY ) ) { fWasAlreadySelected = FALSE; // select the clicked sector, retaining the same sublevel depth ChangeSelectedMapSector( sMapX, sMapY, ( INT8 )iCurrentMapSectorZ ); } else { fWasAlreadySelected = TRUE; } // if showing item counts on the map, and not already in sector inventory if ( fShowItemsFlag && !fShowMapInventoryPool ) { // show sector inventory for this clicked sector ChangeSelectedMapSector( sMapX, sMapY, ( INT8 ) iCurrentMapSectorZ ); fShowMapInventoryPool = TRUE; CreateDestroyMapInventoryPoolButtons( TRUE ); return( MAP_SCREEN ); } if( gfBlitBattleSectorLocator && sMapX == gubPBSectorX && sMapY == gubPBSectorY && iCurrentMapSectorZ == gubPBSectorZ ) { //Bring up a non-persistant version of mapscreen if the user clicks on the sector where a //battle is taking place. InitPreBattleInterface( NULL, FALSE ); return( MAP_SCREEN ); } // if we're in airspace mode if( fShowAircraftFlag == TRUE ) { // if not moving soldiers, and not yet plotting the helicopter if ( ( bSelectedDestChar == -1 ) && ( fPlotForHelicopter == FALSE ) ) { // if we're on the surface level, and the click is over the helicopter icon // NOTE: The helicopter icon is NOT necessarily directly over the helicopter's current sector!!! if( ( iCurrentMapSectorZ == 0 ) && CheckForClickOverHelicopterIcon( sMapX, sMapY ) == TRUE ) { RequestGiveSkyriderNewDestination( ); return( MAP_SCREEN ); } } } else // not in airspace mode { // sector must be already selected to initiate movement plotting! This is to allow selecting sectors with // mercs in them without necessarily initiating movement right away. if( fWasAlreadySelected ) { // if there are any movable characters here if ( AnyMovableCharsInOrBetweenThisSector( sMapX, sMapY, ( INT8 )iCurrentMapSectorZ ) ) { // if showing the surface level map if( iCurrentMapSectorZ == 0 ) { TurnOnShowTeamsMode( ); // NOTE: must allow move box to come up, since there may be movable characters between sectors which are // unaffected by combat / hostiles / air raid in the sector proper itself!! // This also allows all strategic movement error handling to be centralized in CanCharacterMoveInStrategic() // start the move box menu SetUpMovingListsForSector( sMapX, sMapY, ( INT16 )iCurrentMapSectorZ ); } else { // no strategic movement is possible from underground sectors DoMapMessageBox( MSG_BOX_BASIC_STYLE, pMapErrorString[ 1 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); return( MAP_SCREEN ); } } } } } break; //Kris -- added hook so I can access AIView in non-release mode. #ifdef JA2BETAVERSION case MAP_EVENT_VIEWAI: SetPendingNewScreen( AIVIEWER_SCREEN ); CreateDestroyMapInvButton(); break; #endif } // if we pressed something that will cause a screen change if ( guiPendingScreen != NO_PENDING_SCREEN ) { uiNewScreen = guiPendingScreen; } return( uiNewScreen ); } void GetMapKeyboardInput( UINT32 *puiNewEvent ) { InputAtom InputEvent; POINT MousePos; INT8 bSquadNumber; UINT8 ubGroupId = 0; BOOLEAN fCtrl, fAlt; INT16 sMapX, sMapY; fCtrl = _KeyDown( CTRL ); fAlt = _KeyDown( ALT ); while( DequeueEvent( &InputEvent ) ) // while( DequeueSpecificEvent( &InputEvent, KEY_DOWN ) ) // doesn't work for some reason { GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! // 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; case RIGHT_BUTTON_REPEAT: MouseSystemHook(RIGHT_BUTTON_REPEAT, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); break; case LEFT_BUTTON_REPEAT: MouseSystemHook(LEFT_BUTTON_REPEAT, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); break; } if( InputEvent.usEvent == KEY_DOWN ) { // if game is paused because of player, unpause with any key if ( gfPauseDueToPlayerGamePause ) { HandlePlayerPauseUnPauseOfGame( ); continue; } if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); continue; } // handle for fast help text for interface stuff if( IsTheInterfaceFastHelpTextActive() ) { ShutDownUserDefineHelpTextRegions( ); } switch( InputEvent.usParam ) { case ESC: gfDontStartTransitionFromLaptop = TRUE; if( gfPreBattleInterfaceActive && !gfPersistantPBI ) { //Non persistant PBI. Allow ESC to close it and return to mapscreen. KillPreBattleInterface(); gpBattleGroup = NULL; return; } if ( gfInChangeArrivalSectorMode ) { CancelChangeArrivalSectorMode( ); MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pBullseyeStrings[ 3 ] ); } // ESC cancels MAP UI messages, unless we're in confirm map move mode else if( ( giUIMessageOverlay != -1 ) && !gfInConfirmMapMoveMode ) { CancelMapUIMessage( ); } else if( IsMapScreenHelpTextUp( ) ) { StopMapScreenHelpText( ); } else if ( gpCurrentTalkingFace != NULL && gpCurrentTalkingFace->fTalking ) { // ATE: We want to stop speech if somebody is talking... StopAnyCurrentlyTalkingSpeech( ); } else if( fShowUpdateBox ) { if( fShowUpdateBox ) { EndUpdateBox( FALSE ); // stop time compression } } else if(fShowDescriptionFlag) { DeleteItemDescriptionBox( ); } // plotting movement? else if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); } else if( fShowAssignmentMenu ) { // dirty region fTeamPanelDirty = TRUE; fMapPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; // stop showing current assignment box if( fShowAttributeMenu == TRUE ) { fShowAttributeMenu = FALSE; fMapPanelDirty = TRUE; } else if( fShowTrainingMenu == TRUE ) { fShowTrainingMenu = FALSE; } else if( fShowSquadMenu == TRUE ) { fShowSquadMenu = FALSE; } else if( fShowRepairMenu == TRUE ) { fShowRepairMenu = FALSE; } else { fShowAssignmentMenu = FALSE; } giAssignHighLine = -1; // restore background to glow region RestoreBackgroundForAssignmentGlowRegionList( ); } else if( fShowContractMenu == TRUE ) { fShowContractMenu = FALSE; // restore contract glow region RestoreBackgroundForContractGlowRegionList( ); fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; giContractHighLine = -1; } // in militia popup? else if( ( sSelectedMilitiaTown != 0 ) && ( sGreensOnCursor == 0 ) && ( sRegularsOnCursor == 0 ) && ( sElitesOnCursor == 0 ) ) { sSelectedMilitiaTown = 0; fMapPanelDirty = TRUE; } else if( fShowTownInfo == TRUE ) { fShowTownInfo = FALSE; CreateDestroyScreenMaskForAssignmentAndContractMenus( ); } else if( fShowDescriptionFlag ) { if( gMPanelRegion.Cursor != EXTERN_CURSOR ) { DeleteItemDescriptionBox( ); } } else if( InKeyRingPopup( ) == TRUE ) { DeleteKeyRingPopup( ); fTeamPanelDirty = TRUE; } else if( fShowInventoryFlag == TRUE ) { if ( gMPanelRegion.Cursor != EXTERN_CURSOR && !InItemStackPopup() ) { fEndShowInventoryFlag = TRUE; } } else if( MultipleCharacterListEntriesSelected( ) ) { ResetSelectedListForMapScreen( ); if( bSelectedInfoChar != -1 ) { SetEntryInSelectedCharacterList( bSelectedInfoChar ); } fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; } else { RequestTriggerExitFromMapscreen( MAP_EXIT_TO_TACTICAL ); } break; // end of ESC case PAUSE: // Pause game! HandlePlayerPauseUnPauseOfGame( ); break; case LEFTARROW: // previous character GoToPrevCharacterInList( ); break; case RIGHTARROW: // next character GoToNextCharacterInList( ); break; case UPARROW: // up a line MapScreenMsgScrollUp( 1 ); break; case DNARROW: // down a line MapScreenMsgScrollDown( 1 ); break; case PGUP: // up a page MapScreenMsgScrollUp( MAX_MESSAGES_ON_MAP_BOTTOM ); break; case PGDN: // down a page MapScreenMsgScrollDown( MAX_MESSAGES_ON_MAP_BOTTOM ); break; case HOME: // jump to top of message list ChangeCurrentMapscreenMessageIndex( 0 ); break; case END: // jump to bottom of message list MoveToEndOfMapScreenMessageList(); break; case INSERT: // up one sublevel GoUpOneLevelInMap( ); break; case DEL: // show the inventory pool? if( fShowMapInventoryPool && _KeyDown( CTRL ) ) { DeleteAllItemsInInventoryPool(); break; } // down one sublevel GoDownOneLevelInMap( ); break; case ENTER: RequestToggleMercInventoryPanel(); break; case BACKSPACE: StopAnyCurrentlyTalkingSpeech( ); break; case F1: case F2: case F3: case F4: case F5: case F6: ChangeCharacterListSortMethod( InputEvent.usParam - F1 ); break; case F7: #ifdef JA2TESTVERSION if( fAlt ) { if ( bSelectedInfoChar != -1 ) { SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]; if ( pSoldier->inv[ HANDPOS ].usItem != 0 ) { pSoldier->inv[ HANDPOS ].ItemData.Generic.bStatus[ 0 ] = 2; } } } if( fCtrl ) { if ( bSelectedInfoChar != -1 ) { SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]; if ( pSoldier->inv[ HANDPOS ].usItem != 0 ) { pSoldier->inv[ HANDPOS ].usItem = GUN_BARREL_EXTENDER; } } } #endif break; case F8: #ifdef JA2TESTVERSION if( fAlt ) { // reduce balance to $500 AddTransactionToPlayersBook( PAYMENT_TO_NPC, SKYRIDER, GetWorldTotalMin( ), - ( LaptopSaveInfo.iCurrentBalance - 500 ) ); } #endif break; case F9: #ifdef JA2TESTVERSION if( fAlt ) { UINT8 ubSamIndex; // ALT-F9: Reveal all SAM sites for( ubSamIndex = 0; ubSamIndex < NUMBER_OF_SAMS; ubSamIndex++ ) { SetSAMSiteAsFound( ubSamIndex ); } } #endif break; case F10: #ifdef JA2TESTVERSION if( fAlt ) { if ( bSelectedInfoChar != -1 ) { // ALT-F10: force selected character asleep (ignores breathmax) PutMercInAsleepState( MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ] ); } } #endif break; /* case F11: #ifdef JA2TESTVERSION if( fAlt ) { // ALT-F11: make all sectors player controlled ClearMapControlledFlags( ); fMapPanelDirty = TRUE; } #endif break; */ case F12: #ifdef JA2BETAVERSION *puiNewEvent = MAP_EVENT_VIEWAI; #endif break; case '+': case '=': if ( CommonTimeCompressionChecks() == FALSE ) RequestIncreaseInTimeCompression(); break; case '-': case '_': if ( CommonTimeCompressionChecks() == FALSE ) RequestDecreaseInTimeCompression(); break; case SPACE: if( fShowUpdateBox ) { EndUpdateBox( TRUE ); // restart time compression } else { // toggle time compression if ( CommonTimeCompressionChecks() == FALSE ) RequestToggleTimeCompression(); } break; case '`': #ifdef JA2TESTVERSION if( fCtrl ) { if( bSelectedInfoChar != -1 ) { TownMilitiaTrainingCompleted( &Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ], sSelMapX, sSelMapY ); } } #endif break; case '\\': #ifdef JA2TESTVERSION if (fAlt) { } else if( fCtrl ) { DumpItemsList(); } #endif break; case '>': #ifdef JA2TESTVERSION if( fCtrl ) { // free } #endif break; case '?': #ifdef JA2TESTVERSION if( fCtrl ) MapScreenMessage( 0, MSG_DEBUG, L"JA2Clock = %d", GetJA2Clock() ); else MapScreenMessage( 0, MSG_DEBUG, L"Mouse X,Y = %d,%d", MSYS_CurrentMX, MSYS_CurrentMY ); #endif break; case '/': #ifdef JA2TESTVERSION if( fAlt ) { if( bSelectedInfoChar != -1 ) { StatChange( &Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ], EXPERAMT, 1000, FROM_SUCCESS ); } } #endif break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // multi-selects all characters in that squad. SHIFT key and 1-0 for squads 11-20 bSquadNumber = ( INT8 ) ( InputEvent.usParam - '1' ); // internal squad #s start at 0 SelectAllCharactersInSquad( bSquadNumber ); break; case '0': SelectAllCharactersInSquad( 9 ); // internal squad #s start at 0 break; case '!': SelectAllCharactersInSquad( 10 ); // internal squad #s start at 0 break; case '@': SelectAllCharactersInSquad( 11 ); // internal squad #s start at 0 break; case '#': SelectAllCharactersInSquad( 12 ); // internal squad #s start at 0 break; case '$': SelectAllCharactersInSquad( 13 ); // internal squad #s start at 0 break; case '%': SelectAllCharactersInSquad( 14 ); // internal squad #s start at 0 break; case '^': SelectAllCharactersInSquad( 15 ); // internal squad #s start at 0 break; case '&': SelectAllCharactersInSquad( 16 ); // internal squad #s start at 0 break; case '*': SelectAllCharactersInSquad( 17 ); // internal squad #s start at 0 break; case '(': SelectAllCharactersInSquad( 18 ); // internal squad #s start at 0 break; case ')': SelectAllCharactersInSquad( 19 ); // internal squad #s start at 0 break; case 'a': if( fAlt ) { if( giHighLine != -1 ) { if( gCharactersList[ giHighLine ].fValid == TRUE ) { bSelectedAssignChar = ( INT8 )giHighLine; RebuildAssignmentsBox( ); ChangeSelectedInfoChar( ( INT8 ) giHighLine, FALSE ); fShowAssignmentMenu = TRUE; } } else if( bSelectedInfoChar != -1 ) { if( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) { bSelectedAssignChar = ( INT8 )bSelectedInfoChar; RebuildAssignmentsBox( ); fShowAssignmentMenu = TRUE; } } } else if( fCtrl ) { if( CHEATER_CHEAT_LEVEL( ) ) { if( gfAutoAmbush ^= 1 ) ScreenMsg( FONT_WHITE, MSG_TESTVERSION, L"Enemy ambush test mode enabled." ); else ScreenMsg( FONT_WHITE, MSG_TESTVERSION, L"Enemy ambush test mode disabled." ); } } else { if( gfPreBattleInterfaceActive ) { //activate autoresolve in prebattle interface. ActivatePreBattleAutoresolveAction(); } else { // only handle border button keyboard equivalents if the button is visible! if ( !fShowMapInventoryPool ) { ToggleAirspaceMode(); } } } break; case 'b': /* // CTRL-B: make player's perception of all sectors correct! if( ( fCtrl )&&( CHEATER_CHEAT_LEVEL( ) ) ) { for ( sMapX = 1; sMapX <= 16; sMapX++ ) { for ( sMapY = 1; sMapY <= 16; sMapY++ ) { MakePlayerPerceptionOfSectorControlCorrect( sMapX, sMapY, 0 ); } } } */ break; case 'c': RequestContractMenu(); break; case 'd': #ifdef JA2TESTVERSION if( fAlt ) { // prints out a text file in C:\TEMP telling you how many stat change chances/successes each profile merc got TestDumpStatChanges(); } #endif break; case 'e': if( gfPreBattleInterfaceActive ) { //activate enter sector in prebattle interface. gfHotKeyEnterSector = TRUE; } break; case 'f': #ifdef JA2TESTVERSION // CTRL-F: Refuel vehicle if( ( fCtrl ) && ( bSelectedInfoChar != -1 ) ) { SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]; if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { pSoldier->sBreathRed = 10000; pSoldier->bBreath = 100; ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"Vehicle refueled" ); fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; } } #endif if( fAlt ) { if ( INFORMATION_CHEAT_LEVEL( ) ) { //Toggle Frame Rate Display gbFPSDisplay = !gbFPSDisplay; DisableFPSOverlay( (BOOLEAN)!gbFPSDisplay ); } } break; case 'h': #ifdef JA2TESTVERSION if( fAlt ) { // set up the helicopter over Omerta (if it's not already set up) SetUpHelicopterForPlayer( 9,1 ); // raise Drassen loyalty to minimum that will allow Skyrider to fly if ( gTownLoyalty[ DRASSEN ].fStarted && ( gTownLoyalty[ DRASSEN ].ubRating < LOYALTY_LOW_THRESHOLD ) ) { SetTownLoyalty( DRASSEN, LOYALTY_LOW_THRESHOLD ); } TurnOnAirSpaceMode( ); } else #endif { // ARM: Feb01/98 - Cancel out of mapscreen movement plotting if Help subscreen is coming up if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); } ShouldTheHelpScreenComeUp( HELP_SCREEN_MAPSCREEN, TRUE ); } // fShowMapScreenHelpText = TRUE; break; case 'i': #ifdef JA2TESTVERSION /* if( fAlt ) { InitializeMines(); fMapPanelDirty = TRUE; } else */ if( fCtrl ) { fDisableJustForIan = ! fDisableJustForIan; } else { // only handle border button keyboard equivalents if the button is visible! if ( !fShowMapInventoryPool ) { ToggleItemsFilter(); } } #else // only handle border button keyboard equivalents if the button is visible! if ( !fShowMapInventoryPool ) { ToggleItemsFilter(); } #endif break; case 'l': if( fAlt ) { // although we're not actually going anywhere, we must still be in a state where this is permitted if ( AllowedToExitFromMapscreenTo( MAP_EXIT_TO_LOAD ) ) { DoQuickLoad(); } } else if( fCtrl ) { // go to LOAD screen gfSaveGame = FALSE; RequestTriggerExitFromMapscreen( MAP_EXIT_TO_LOAD ); } else { // go to LAPTOP RequestTriggerExitFromMapscreen( MAP_EXIT_TO_LAPTOP ); } break; case 'm': // only handle border button keyboard equivalents if the button is visible! if ( !fShowMapInventoryPool ) { // toggle show mines flag ToggleShowMinesMode(); } break; case 'n': #ifdef JA2TESTVERSION if( fAlt ) { static UINT16 gQuoteNum = 0; // Get Soldier TacticalCharacterDialogue( MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ], gQuoteNum ); gQuoteNum++; } else if( fCtrl ) { static UINT16 gQuoteNum = 0; // Get Soldier if ( giHighLine != -1 ) { TacticalCharacterDialogue( MercPtrs[ gCharactersList[ giHighLine ].usSolID ], gQuoteNum ); gQuoteNum++; } } #endif break; case 'o': if( fAlt ) { // toggle if Orta & Tixa have been found #ifdef JA2TESTVERSION fFoundOrta = !fFoundOrta; fFoundTixa = !fFoundTixa; fMapPanelDirty = TRUE; #endif } else { // go to OPTIONS screen RequestTriggerExitFromMapscreen( MAP_EXIT_TO_OPTIONS ); } break; case 'p': #ifdef JA2TESTVERSION if( fCtrl ) { // CTRL-P: Display player's highest progress percentage DumpSectorDifficultyInfo(); } #endif #ifdef JA2TESTVERSION // ALT-P: Make the selected character a POW! if( ( fAlt ) && ( bSelectedInfoChar != -1 ) ) { SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]; EnemyCapturesPlayerSoldier( pSoldier ); if ( pSoldier->bInSector ) { RemoveSoldierFromTacticalSector( pSoldier, TRUE ); } fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; fMapPanelDirty = TRUE; } #endif break; case 'q': #ifdef JA2TESTVERSION if( fAlt ) { // initialize miners if not already done so (fakes entering Drassen mine first) HandleQuestCodeOnSectorEntry( 13, 4, 0); // test miner quote system IssueHeadMinerQuote( (INT8) (1 + Random(MAX_NUMBER_OF_MINES - 1)), (UINT8) (1 + Random(2))); } #endif break; case 'r': if( gfPreBattleInterfaceActive ) { //activate autoresolve in prebattle interface. ActivatePreBattleRetreatAction(); } break; case 's': if( fAlt ) { // although we're not actually going anywhere, we must still be in a state where this is permitted if ( AllowedToExitFromMapscreenTo( MAP_EXIT_TO_SAVE ) ) { //if the game CAN be saved if( CanGameBeSaved() ) { guiPreviousOptionScreen = guiCurrentScreen; DoQuickSave(); } else { //Display a message saying the player cant save now DoMapMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[ TCTL_MSG__IRON_MAN_CANT_SAVE_NOW ], MAP_SCREEN, MSG_BOX_FLAG_OK, NULL ); } } } else if( fCtrl ) { // go to SAVE screen gfSaveGame = TRUE; RequestTriggerExitFromMapscreen( MAP_EXIT_TO_SAVE ); } break; case 't': // Teleport: CTRL-T if( ( fCtrl )&&( CHEATER_CHEAT_LEVEL( ) ) ) { // check if selected dest char, if( ( bSelectedDestChar != -1 ) && ( fPlotForHelicopter == FALSE ) && ( iCurrentMapSectorZ == 0 ) && ( GetMouseMapXY( &sMapX, &sMapY ) ) ) { INT16 sDeltaX, sDeltaY; INT16 sPrevX, sPrevY; SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ bSelectedDestChar ].usSolID ]; // can't teleport to where we already are if ( ( sMapX == pSoldier->sSectorX ) && ( sMapY == pSoldier->sSectorY ) ) break; /* if( fZoomFlag == TRUE ) { // convert to zoom out coords from screen coords sMapX = ( INT16 )( iZoomX / MAP_GRID_X + sMapX ) / 2; sMapY = ( INT16 )( iZoomY / MAP_GRID_Y + sMapY ) / 2; } */ // cancel movement plotting AbortMovementPlottingMode( ); // nuke the UI message generated by this CancelMapUIMessage( ); // clear their strategic movement (mercpaths and waypoints) ClearMvtForThisSoldierAndGang( pSoldier ); // select this sector ChangeSelectedMapSector( sMapX, sMapY, 0 ); // check to see if this person is moving, if not...then assign them to mvt group if( pSoldier->ubGroupID == 0 ) { ubGroupId = CreateNewPlayerGroupDepartingFromSector( ( INT8 ) ( pSoldier->sSectorX ) , ( INT8 ) ( pSoldier->sSectorY ) ); // assign to a group AddPlayerToGroup( ubGroupId, pSoldier ); } // figure out where they would've come from sDeltaX = sMapX - pSoldier->sSectorX; sDeltaY = sMapY - pSoldier->sSectorY; if ( abs( sDeltaX ) >= abs( sDeltaY ) ) { // use East or West if( sDeltaX > 0 ) { // came in from the West sPrevX = sMapX - 1; sPrevY = sMapY; } else { // came in from the East sPrevX = sMapX + 1; sPrevY = sMapY; } } else { // use North or South if( sDeltaY > 0 ) { // came in from the North sPrevX = sMapX; sPrevY = sMapY - 1; } else { // came in from the South sPrevX = sMapX; sPrevY = sMapY + 1; } } // set where they are, were/are going, then make them arrive there and check for battle PlaceGroupInSector( pSoldier->ubGroupID, sPrevX, sPrevY, sMapX, sMapY, 0, TRUE ); // unload the sector they teleported out of CheckAndHandleUnloadingOfCurrentWorld(); } } else { // only handle border button keyboard equivalents if the button is visible! if ( !fShowMapInventoryPool ) { // Toggle show teams flag ToggleShowTeamsMode(); } } break; case 'u': #ifdef JA2TESTVERSION { if( fAlt ) { UINT32 uiCnt; // initialize miners if not already done so (fakes entering Drassen mine first) HandleQuestCodeOnSectorEntry( 13, 4, 0); // test running out for (uiCnt = 0; uiCnt < 10; uiCnt++) { HandleIncomeFromMines(); } } } #endif break; case 'v': if( fCtrl ) { #ifdef SGP_VIDEO_DEBUGGING ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VObjects: %d", guiVObjectSize ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VSurfaces: %d", guiVSurfaceSize ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SGPVideoDump.txt updated..." ); PerformVideoInfoDumpIntoFile( "SGPVideoDump.txt", TRUE ); #endif } else { DisplayGameSettings( ); } break; case 'w': // only handle border button keyboard equivalents if the button is visible! if ( !fShowMapInventoryPool ) { // toggle show towns filter ToggleShowTownsMode(); } break; case 'x': if( fAlt ) { HandleShortCutExitState( ); } break; case 'y': // ALT-Y: toggles SAM sites disable if( fAlt ) { #ifdef JA2TESTVERSION fSAMSitesDisabledFromAttackingPlayer = !fSAMSitesDisabledFromAttackingPlayer; #endif } break; case 'z': // only handle border button keyboard equivalents if the button is visible! if( fCtrl ) { if( CHEATER_CHEAT_LEVEL( ) ) { if( gfAutoAIAware ^= 1 ) ScreenMsg( FONT_WHITE, MSG_TESTVERSION, L"Strategic AI awareness maxed." ); else ScreenMsg( FONT_WHITE, MSG_TESTVERSION, L"Strategic AI awareness normal." ); } } else if ( !fShowMapInventoryPool ) { // Toggle Show Militia ON/OFF ToggleShowMilitiaMode(); } break; } } else if( InputEvent.usEvent == KEY_REPEAT ) { switch( InputEvent.usParam ) { case LEFTARROW: // previous character GoToPrevCharacterInList( ); break; case RIGHTARROW: // next character GoToNextCharacterInList( ); break; case UPARROW: // up a line MapScreenMsgScrollUp( 1 ); break; case DNARROW: // down a line MapScreenMsgScrollDown( 1 ); break; case PGUP: // up a page MapScreenMsgScrollUp( MAX_MESSAGES_ON_MAP_BOTTOM ); break; case PGDN: // down a page MapScreenMsgScrollDown( MAX_MESSAGES_ON_MAP_BOTTOM ); break; } } } } void EndMapScreen( BOOLEAN fDuringFade ) { if ( fInMapMode == FALSE ) { // shouldn't be here return; } /* // exit is called due to message box, leave if( fMapExitDueToMessageBox ) { fMapExitDueToMessageBox = FALSE; return; } */ fLeavingMapScreen = FALSE; SetRenderFlags( RENDER_FLAG_FULL ); //MSYS_EnableRegion( &gViewportRegion ); //MSYS_EnableRegion( &gRadarRegion ); // ATE: Shutdown tactical interface panel // ShutdownCurrentPanel( ); if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } // still plotting movement? if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); } DestroyMouseRegionsForTeamList( ); MSYS_RemoveRegion( &gMapViewRegion ); MSYS_RemoveRegion( &gCharInfoFaceRegion); MSYS_RemoveRegion( &gCharInfoHandRegion ); MSYS_RemoveRegion( &gMPanelRegion); MSYS_RemoveRegion( &gMapScreenMaskRegion ); fInMapMode = FALSE; // remove team panel sort button RemoveTeamPanelSortButtonsForMapScreen( ); // for th merc insurance help text CreateDestroyInsuranceMouseRegionForMercs( FALSE ); // gonna need to remove the screen mask regions CreateDestroyMouseRegionMasksForTimeCompressionButtons( ); UnloadButtonImage( giMapContractButtonImage ); RemoveButton( giMapContractButton ); HandleShutDownOfMapScreenWhileExternfaceIsTalking( ); fShowInventoryFlag = FALSE; CreateDestroyMapInvButton(); // no longer can we show assignments menu fShowAssignmentMenu = FALSE; // clear out mouse regions for pop up boxes DetermineWhichAssignmentMenusCanBeShown( ); DetermineWhichMilitiaControlMenusCanBeShown( ); //lal sSelectedMilitiaTown = 0; CreateDestroyMilitiaPopUPRegions( ); CreateDestroyMilitiaSectorButtons( ); // stop showing contract menu fShowContractMenu = FALSE; // clear out contract menu DetermineIfContractMenuCanBeShown( ); // remove contract pop up box (always created upon mapscreen entry) RemoveBox(ghContractBox); ghContractBox = -1; CreateDestroyAssignmentPopUpBoxes( ); CreateDestroyMilitiaControlPopUpBoxes( ); //lal // shutdown movement box if ( fShowMapScreenMovementList ) { fShowMapScreenMovementList = FALSE; CreateDestroyMovementBox( 0, 0, 0 ); } // the remove merc from team box RemoveBox( ghRemoveMercAssignBox ); ghRemoveMercAssignBox = -1; // clear screen mask if needed ClearScreenMaskForMapScreenExit( ); // get rid of pause clock area RemoveMouseRegionForPauseOfClock( ); // get rid of pop up for town info, if being shown fShowTownInfo = FALSE; CreateDestroyTownInfoBox( ); // build squad list RebuildCurrentSquad( ); DeleteMouseRegionsForLevelMarkers( ); // WANNE: //DeleteButtonsForScrolling(); if( fShowMapInventoryPool == FALSE ) { // delete buttons DeleteMapBorderButtons( ); } if(fShowDescriptionFlag) { DeleteItemDescriptionBox( ); } fShowInventoryFlag = FALSE; CreateDestroyTrashCanRegion( ); if ( !fDuringFade ) { MSYS_SetCurrentCursor(SCREEN_CURSOR); } if(fPreLoadedMapGraphics == FALSE ) { DeleteMapBottomGraphics( ); DeleteVideoObjectFromIndex(guiSubLevel1); DeleteVideoObjectFromIndex(guiSubLevel2); DeleteVideoObjectFromIndex(guiSubLevel3); DeleteVideoObjectFromIndex( guiSleepIcon ); DeleteVideoObjectFromIndex(guiMAPCURSORS); //DeleteVideoObjectFromIndex(guiMAPBORDER); DeleteVideoObjectFromIndex(guiCHARLIST); //DeleteVideoObjectFromIndex(guiCORNERADDONS); //DeleteVideoObjectFromIndex(guiMAPCORNER); //DeleteVideoObjectFromIndex(guiPOPUPBORDERS); DeleteVideoObjectFromIndex(guiCHARINFO); DeleteVideoObjectFromIndex(guiCHARICONS); DeleteVideoObjectFromIndex(guiCROSS); DeleteVideoSurfaceFromIndex(guiBIGMAP); // DeleteVideoSurfaceFromIndex(guiPOPUPTEX); DeleteVideoObjectFromIndex(guiSAMICON); DeleteVideoObjectFromIndex(guiMAPINV); DeleteVideoObjectFromIndex(guiMapInvSecondHandBlockout); DeleteVideoObjectFromIndex(guiULICONS); DeleteVideoObjectFromIndex(guiORTAICON); DeleteVideoObjectFromIndex(guiTIXAICON); DeleteVideoObjectFromIndex( guiCHARBETWEENSECTORICONS ); DeleteVideoObjectFromIndex( guiCHARBETWEENSECTORICONSCLOSE ); DeleteVideoObjectFromIndex( guiLEVELMARKER ); DeleteVideoObjectFromIndex( guiMapBorderEtaPopUp ); DeleteVideoObjectFromIndex( guiSecItemHiddenVO ); DeleteVideoObjectFromIndex( guiSelectedCharArrow ); DeleteVideoObjectFromIndex( guiMapBorderHeliSectors ); DeleteVideoObjectFromIndex( guiHelicopterIcon ); DeleteVideoObjectFromIndex( guiMINEICON ); DeleteVideoObjectFromIndex( guiSectorLocatorGraphicID ); DeleteVideoObjectFromIndex( guiBULLSEYE ); // remove the militia pop up box RemoveMilitiaPopUpBox( ); // remove inventory pool graphic RemoveInventoryPoolGraphic( ); // get rid of border stuff DeleteMapBorderGraphics( ); //Kris: Remove the email icons. DeleteVideoObjectFromIndex( guiNewMailIcons ); } DeleteVideoObjectFromIndex( guiBrownBackgroundForTeamPanel ); RemoveMapStatusBarsRegion( ); fShowUpdateBox = FALSE; CreateDestroyTheUpdateBox( ); // get rid of mapscreen bottom DeleteMapScreenInterfaceBottom( ); // shutdown any mapscreen UI overlay message CancelMapUIMessage( ); CreateDestroyMapCharacterScrollButtons( ); // if time was ever compressed while we were in mapscreen if ( HasTimeCompressOccured( ) ) { // make sure everything tactical got cleared out ClearTacticalStuffDueToTimeCompression(); } CancelSectorInventoryDisplayIfOn( TRUE ); SetAllAutoFacesInactive( ); if(fLapTop) { StopAnyCurrentlyTalkingSpeech( ); guiCurrentScreen=LAPTOP_SCREEN; } else { guiCurrentScreen = GAME_SCREEN; // remove the progress bar RemoveProgressBar( 0 ); // enable scroll string video overlays EnableDisableScrollStringVideoOverlay( TRUE ); } // if going to tactical next if ( guiPendingScreen == GAME_SCREEN ) { // set compressed mode to Normal (X1) SetGameTimeCompressionLevel( TIME_COMPRESS_X1 ); } else // going to another screen (options, laptop, save/load) { StopTimeCompression(); } // update paused states, we are exiting...need to reset for any pathing or menus displayed UnLockPauseState( ); UpdatePausedStatesDueToTimeCompression( ); if( !gfDontStartTransitionFromLaptop ) { VOBJECT_DESC VObjectDesc; UINT32 uiLaptopOn; //Load a tiny graphic of the on screen and draw it to the buffer. PlayJA2SampleFromFile( "SOUNDS\\Initial Power Up (8-11).wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; sprintf( VObjectDesc.ImageFile, "INTERFACE\\LaptopOn.sti" ); if( !AddVideoObject( &VObjectDesc, &uiLaptopOn ) ) AssertMsg( 0, "Failed to load data\\Interface\\LaptopOn.sti" ); BltVideoObjectFromIndex( FRAME_BUFFER, uiLaptopOn, 0, 465, 417, VO_BLT_SRCTRANSPARENCY, NULL ); InvalidateRegion( 465, 417, 480, 427 ); ExecuteBaseDirtyRectQueue( ); EndFrameBufferRender( ); DeleteVideoObjectFromIndex( uiLaptopOn ); RefreshScreen( NULL ); } //Kris: Removes the pre battle interface, but only if it exists. // It is internally considered. KillPreBattleInterface(); // cancel request if we somehow leave first gfRequestGiveSkyriderNewDestination = FALSE; } BOOLEAN GetMouseMapXY( INT16 *psMapWorldX, INT16 *psMapWorldY ) { POINT MousePos; if( IsMapScreenHelpTextUp( ) ) { // don't show highlight while global help text is up return( FALSE ); } GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! if(fZoomFlag) { if(MousePos.x >MAP_GRID_X+MAP_VIEW_START_X) MousePos.x-=MAP_GRID_X; if(MousePos.x >MAP_VIEW_START_X+MAP_VIEW_WIDTH) MousePos.x=-1; if(MousePos.y > MAP_GRID_Y+MAP_VIEW_START_Y) MousePos.y-=MAP_GRID_Y; if(MousePos.y >MAP_VIEW_START_Y+MAP_VIEW_HEIGHT-11) MousePos.y=-11; if(MousePos.y < MAP_VIEW_START_Y) MousePos.y=-1; } return( GetMapXY( (INT16)MousePos.x, (INT16)MousePos.y, psMapWorldX, psMapWorldY ) ); } BOOLEAN GetMapXY( INT16 sX, INT16 sY, INT16 *psMapWorldX, INT16 *psMapWorldY ) { INT16 sMapX, sMapY; // Subtract start of map view sMapX = sX - MAP_VIEW_START_X;//+2*MAP_GRID_X; sMapY = sY - MAP_VIEW_START_Y; if(!fZoomFlag) { if ( sMapX < MAP_GRID_X || sMapY < MAP_GRID_Y ) { return( FALSE ); } } if ( sMapX < 0 || sMapY < 0 ) { return( FALSE ); } if ( sMapX > MAP_VIEW_WIDTH+MAP_GRID_X-1 || sMapY > MAP_VIEW_HEIGHT+7/* +MAP_VIEW_HEIGHT */ ) { return( FALSE ); } if(sMapX < 1 || sMapY <1) { return (FALSE); } *psMapWorldX = ( sMapX / MAP_GRID_X ); *psMapWorldY = ( sMapY / MAP_GRID_Y ); return( TRUE ); } void RenderMapHighlight( INT16 sMapX, INT16 sMapY, UINT16 usLineColor, BOOLEAN fStationary ) { INT16 sScreenX, sScreenY; UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; Assert( ( sMapX >= 1 ) && ( sMapX <= 16 ) ); Assert( ( sMapY >= 1 ) && ( sMapY <= 16 ) ); /* if((fZoomFlag)&&((sMapX > MAP_WORLD_X-1)||(sMapY> MAP_WORLD_Y-1))) return; */ // if we are not allowed to highlight, leave if( ( IsTheCursorAllowedToHighLightThisSector( sMapX, sMapY ) == FALSE )&&( fZoomFlag == FALSE ) ) { return; } /* else if( ( IsTheCursorAllowedToHighLightThisSector( sMapX , sMapY ) == FALSE )&&( fZoomFlag == TRUE ) && ( fStationary == TRUE ) ) { return; } else if( ( IsTheCursorAllowedToHighLightThisSector( ( INT16 ) ( ( ( iZoomX ) / ( MAP_GRID_X * 2 ) ) + sMapX / 2 ) ,( INT16 ) ( ( ( iZoomY ) / ( MAP_GRID_Y * 2 ) ) + sMapY / 2 ) ) == FALSE ) && ( fZoomFlag == TRUE ) &&( fStationary == FALSE ) ) { return; } */ // if((!fStationary)||(!fZoomFlag)) { GetScreenXYFromMapXY( sMapX, sMapY, &sScreenX, &sScreenY ); } /* else { GetScreenXYFromMapXYStationary( sMapX, sMapY, &sScreenX, &sScreenY ); } */ // blit in the highlighted sector pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); // clip to view region ClipBlitsToMapViewRegionForRectangleAndABit( uiDestPitchBYTES ); if(gbPixelDepth==16) { // DB Need to add a radar color for 8-bit /* if (fZoomFlag) { // draw rectangle for zoom in RectangleDraw( TRUE, sScreenX-MAP_GRID_X, sScreenY-MAP_GRID_Y - 1, sScreenX + MAP_GRID_ZOOM_X - MAP_GRID_X, sScreenY + MAP_GRID_ZOOM_Y - MAP_GRID_Y - 1, usLineColor, pDestBuf ); InvalidateRegion( sScreenX-MAP_GRID_X - 3, sScreenY-MAP_GRID_Y - 4, sScreenX + DMAP_GRID_ZOOM_X - MAP_GRID_X, sScreenY + DMAP_GRID_ZOOM_Y - MAP_GRID_Y - 1 ); } else */ { // draw rectangle for zoom out RectangleDraw( TRUE, sScreenX, sScreenY - 1, sScreenX + MAP_GRID_X, sScreenY + MAP_GRID_Y - 1, usLineColor, pDestBuf ); InvalidateRegion( sScreenX, sScreenY - 2, sScreenX + DMAP_GRID_X + 1, sScreenY + DMAP_GRID_Y - 1 ); } } RestoreClipRegionToFullScreenForRectangle( uiDestPitchBYTES ); UnLockVideoSurface( FRAME_BUFFER ); } void PollLeftButtonInMapView( UINT32 *puiNewEvent ) { static BOOLEAN fLBBeenPressedInMapView = FALSE; INT16 sMapX, sMapY; // if the mouse is currently over the MAP area if ( gMapViewRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { // if L-button is down at the moment if ( gMapViewRegion.ButtonState & MSYS_LEFT_BUTTON ) { if ( !fLBBeenPressedInMapView ) { fLBBeenPressedInMapView = TRUE; RESETCOUNTER( LMOUSECLICK_DELAY_COUNTER ); gfAllowSkyriderTooFarQuote = FALSE; } } else // L-button is NOT down at the moment { if ( fLBBeenPressedInMapView ) { fLBBeenPressedInMapView = FALSE; RESETCOUNTER( LMOUSECLICK_DELAY_COUNTER ); // if we are showing help text in mapscreen if( fShowMapScreenHelpText ) { fShowMapScreenHelpText = FALSE; fCharacterInfoPanelDirty = TRUE; fMapPanelDirty = TRUE; return; } // if in militia redistribution popup if ( sSelectedMilitiaTown != 0 ) { // ignore clicks outside the box return; } // left click cancels MAP UI messages, unless we're in confirm map move mode if( ( giUIMessageOverlay != -1 ) && !gfInConfirmMapMoveMode ) { CancelMapUIMessage( ); // return unless moving the bullseye if ( !gfInChangeArrivalSectorMode ) return; } // ignore left clicks in the map screen if: // game just started or we're in the prebattle interface or if we are about to hit pre-battle if ( ( gTacticalStatus.fDidGameJustStart == TRUE ) || ( gfPreBattleInterfaceActive == TRUE ) || ( fDisableMapInterfaceDueToBattle == TRUE ) ) { return; } // if in "plot route" mode if ( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { fEndPlotting = FALSE; GetMouseMapXY(&sMapX, &sMapY); /* // translate screen values to map grid values for zoomed in if(fZoomFlag) { sMapX=(UINT16)iZoomX/MAP_GRID_X+sMapX; sMapX=sMapX/2; sMapY=(UINT16)iZoomY/MAP_GRID_Y+sMapY; sMapY=sMapY/2; } */ // if he clicked on the last sector in his current path if( CheckIfClickOnLastSectorInPath( sMapX, sMapY ) ) { DestinationPlottingCompleted(); } else // clicked on a new sector { gfAllowSkyriderTooFarQuote = TRUE; // draw new map route *puiNewEvent = MAP_EVENT_PLOT_PATH; } } else // not plotting movement { // if not plotting a path if( ( fEndPlotting == FALSE ) && ( fJustFinishedPlotting == FALSE ) ) { // make this sector selected / trigger movement box / start helicopter plotting / changing arrival sector *puiNewEvent = MAP_EVENT_CLICK_SECTOR; } fEndPlotting = FALSE; } // reset town info flag fShowTownInfo = FALSE; } } } fJustFinishedPlotting = FALSE; } void PollRightButtonInMapView( UINT32 *puiNewEvent ) { static BOOLEAN fRBBeenPressedInMapView = FALSE; INT16 sMapX, sMapY; // if the mouse is currently over the MAP area if ( gMapViewRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { // if R-button is down at the moment if ( gMapViewRegion.ButtonState & MSYS_RIGHT_BUTTON ) { if ( !fRBBeenPressedInMapView ) { fRBBeenPressedInMapView = TRUE; RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER ); } } else // R-button is NOT down at the moment { if ( fRBBeenPressedInMapView ) { fRBBeenPressedInMapView = FALSE; RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER ); // if we are showing help text in mapscreen if( fShowMapScreenHelpText ) { fShowMapScreenHelpText = FALSE; fCharacterInfoPanelDirty = TRUE; fMapPanelDirty = TRUE; return; } // if in militia redistribution popup if ( sSelectedMilitiaTown != 0 ) { // ignore clicks outside the box return; } if ( gfInChangeArrivalSectorMode ) { CancelChangeArrivalSectorMode( ); MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pBullseyeStrings[ 3 ] ); return; } // right click cancels MAP UI messages, unless we're in confirm map move mode if( ( giUIMessageOverlay != -1 ) && !gfInConfirmMapMoveMode ) { CancelMapUIMessage( ); return; } // ignore right clicks in the map area if: // game just started or we're in the prebattle interface or if we are about to hit pre-battle if ( ( gTacticalStatus.fDidGameJustStart == TRUE ) || ( gfPreBattleInterfaceActive == TRUE ) || ( fDisableMapInterfaceDueToBattle == TRUE ) ) { return; } if ( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { // cancel/shorten the path *puiNewEvent = MAP_EVENT_CANCEL_PATH; } else { if ( GetMouseMapXY( &sMapX, &sMapY ) ) { /* if(fZoomFlag) { sMapX=(UINT16)iZoomX/MAP_GRID_X+sMapX; sMapX=sMapX/2; sMapY=(UINT16)iZoomY/MAP_GRID_Y+sMapY; sMapY=sMapY/2; } */ if( ( sSelMapX != sMapX ) || ( sSelMapY != sMapY ) ) { ChangeSelectedMapSector( sMapX, sMapY, ( INT8 )iCurrentMapSectorZ ); } } // sector must be selected to bring up militia or town info boxes for it if ( ( sMapX == sSelMapX ) && ( sSelMapY == sMapY ) ) { if ( fShowMilitia == TRUE ) { HandleMilitiaRedistributionClick(); } else // show militia is OFF { // if on the surface, or a real underground sector (we've visited it) if ( ( iCurrentMapSectorZ == 0 ) || ( GetSectorFlagStatus( sMapX, sMapY, ( UINT8 ) iCurrentMapSectorZ, SF_ALREADY_VISITED ) == TRUE ) ) { // toggle sector info for this sector fShowTownInfo = !fShowTownInfo; fMapPanelDirty = TRUE; } } // fMapScreenBottomDirty = TRUE; CreateDestroyScreenMaskForAssignmentAndContractMenus( ); if( fShowTownInfo == FALSE ) { // destroy town info box CreateDestroyTownInfoBox( ); } } } } } } } void PopupText( STR16 pFontString, ... ) { UINT8 *pDestBuf; UINT32 uiDestPitchBYTES; va_list argptr; INT16 sX, sY; CHAR16 PopupString[512]; va_start(argptr, pFontString); // Set up variable argument pointer vswprintf(PopupString, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); FindFontCenterCoordinates( 0, 0, SCREEN_WIDTH, INTERFACE_START_Y, PopupString, LARGEFONT1, &sX, &sY ); BltVideoSurface( FRAME_BUFFER, guiINTEXT, 0, 85, 160, VS_BLT_FAST | VS_BLT_USECOLORKEY, NULL ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES); SetFont( LARGEFONT1 ); SetFontBackground( FONT_MCOLOR_BLACK ); SetFontForeground( FONT_MCOLOR_DKGRAY ); mprintf_buffer( pDestBuf, uiDestPitchBYTES, LARGEFONT1, sX, sY, PopupString ); UnLockVideoSurface( FRAME_BUFFER ); InvalidateScreen( ); } /* void BtnINVCallback(GUI_BUTTON *btn,INT32 reason) { if (!(btn->uiFlags & BUTTON_ENABLED)) return; if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { if(fMapInventoryItem) return; if(!(btn->uiFlags & BUTTON_CLICKED_ON)) { fCharacterInfoPanelDirty = TRUE; } btn->uiFlags|=(BUTTON_CLICKED_ON); } else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { if(btn->uiFlags & BUTTON_CLICKED_ON) { btn->uiFlags&= ~(BUTTON_CLICKED_ON); if(!fMapInventoryItem) { fShowInventoryFlag = FALSE; } // set help text for item glow region if( fShowInventoryFlag ) { SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 2 ] ); } else { SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] ); } fTeamPanelDirty = TRUE; } } } */ void CreateDestroyMapInvButton() { static BOOLEAN fOldShowInventoryFlag=FALSE; if( fShowInventoryFlag && !fOldShowInventoryFlag ) { // create inventory button fOldShowInventoryFlag=TRUE; //giMapInvButtonImage= LoadButtonImage( "INTERFACE\\mapinv.sti" ,-1,1,-1,2,-1 ); //giMapInvButton= QuickCreateButton( giMapInvButtonImage, INV_BTN_X-1, INV_BTN_Y, // BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, // BUTTON_NO_CALLBACK, (GUI_CALLBACK)BtnINVCallback); // disable allmouse regions in this space fTeamPanelDirty=TRUE; InitInvSlotInterface( gMapScreenInvPocketXY, &gSCamoXY, MAPInvMoveCallback, MAPInvClickCallback, MAPInvMoveCamoCallback, MAPInvClickCamoCallback, FALSE ); MSYS_EnableRegion(&gMPanelRegion); // switch hand region help text to "Exit Inventory" SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 2 ] ); // reset inventory item help text memset( gubMAP_HandInvDispText, 0, sizeof( gubMAP_HandInvDispText ) ); // dirty character info panel ( Why? ARM ) fCharacterInfoPanelDirty=TRUE; } else if( !fShowInventoryFlag && fOldShowInventoryFlag ) { // destroy inventory button ShutdownInvSlotInterface( ); fOldShowInventoryFlag=FALSE; //RemoveButton( giMapInvButton ); //UnloadButtonImage( giMapInvButtonImage ); fTeamPanelDirty=TRUE; MSYS_DisableRegion(&gMPanelRegion); // switch hand region help text to "Enter Inventory" SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] ); // force immediate reblit of item in HANDPOS now that it's not blitted while in inventory mode fCharacterInfoPanelDirty=TRUE; } } void BltCharInvPanel() { UINT32 uiDestPitchBYTES; UINT16 *pDestBuf; HVOBJECT hCharListHandle; SOLDIERTYPE *pSoldier; CHAR16 sString[ 32 ]; INT16 usX, usY; INT32 iCounter = 0; // make sure we're here legally Assert( MapCharacterHasAccessibleInventory( bSelectedInfoChar ) ); GetSoldier( &pSoldier, gCharactersList[bSelectedInfoChar].usSolID ); pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); GetVideoObject(&hCharListHandle, guiMAPINV); Blt8BPPDataTo16BPPBufferTransparent( pDestBuf, uiDestPitchBYTES, hCharListHandle, PLAYER_INFO_X, PLAYER_INFO_Y, 0); UnLockVideoSurface( guiSAVEBUFFER ); Assert( pSoldier ); CreateDestroyMapInvButton(); if( gbCheckForMouseOverItemPos != -1 ) { if( HandleCompatibleAmmoUIForMapScreen( pSoldier, (INT32)gbCheckForMouseOverItemPos, TRUE, TRUE ) == TRUE ) { fMapPanelDirty = TRUE; } } if( ( fShowMapInventoryPool ) ) { if( iCurrentlyHighLightedItem != -1 ) { HandleCompatibleAmmoUIForMapScreen( pSoldier, (INT32)( iCurrentlyHighLightedItem + ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) ) , TRUE, FALSE ); } } RenderInvBodyPanel(pSoldier, INV_BODY_X, INV_BODY_Y ); // reset font destination buffer to the save buffer SetFontDestBuffer( guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); // render items in each of chars slots HandleRenderInvSlots( pSoldier, DIRTYLEVEL2 ); // reset font destination buffer SetFontDestBuffer( FRAME_BUFFER, 0,0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); SetFont( BLOCKFONT2 ); // Render Values for stats! // Set font drawing to saved buffer SetFontDestBuffer( guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); SetFontBackground( FONT_MCOLOR_BLACK ); SetFontForeground( MAP_INV_STATS_TITLE_FONT_COLOR ); // print armor/weight/camo labels mprintf( MAP_ARMOR_LABEL_X, MAP_ARMOR_LABEL_Y, pInvPanelTitleStrings[ 0 ] ); mprintf( MAP_ARMOR_PERCENT_X, MAP_ARMOR_PERCENT_Y, L"%%" ); mprintf( MAP_WEIGHT_LABEL_X, MAP_WEIGHT_LABEL_Y, pInvPanelTitleStrings[ 1 ] ); mprintf( MAP_WEIGHT_PERCENT_X, MAP_WEIGHT_PERCENT_Y, L"%%" ); mprintf( MAP_CAMMO_LABEL_X, MAP_CAMMO_LABEL_Y, pInvPanelTitleStrings[ 2 ] ); mprintf( MAP_CAMMO_PERCENT_X, MAP_CAMMO_PERCENT_Y, L"%%" ); // display armor value swprintf( sString, L"%3d", ArmourPercent( pSoldier ) ); FindFontRightCoordinates(MAP_ARMOR_X, MAP_ARMOR_Y, MAP_PERCENT_WIDTH, MAP_PERCENT_HEIGHT, sString, BLOCKFONT2, &usX, &usY); mprintf( usX, usY, sString ); // Display weight value swprintf( sString, L"%3d", CalculateCarriedWeight( pSoldier ) ); FindFontRightCoordinates(MAP_WEIGHT_X, MAP_WEIGHT_Y, MAP_PERCENT_WIDTH, MAP_PERCENT_HEIGHT, sString, BLOCKFONT2, &usX, &usY); mprintf( usX, usY, sString ); // Display camo value swprintf( sString, L"%3d", max(0, min ((pSoldier->bCamo + pSoldier->wornCamo + pSoldier->urbanCamo+pSoldier->wornUrbanCamo+pSoldier->desertCamo+pSoldier->wornDesertCamo+pSoldier->snowCamo+pSoldier->wornSnowCamo ),100 )) ); FindFontRightCoordinates(MAP_CAMMO_X, MAP_CAMMO_Y, MAP_PERCENT_WIDTH, MAP_PERCENT_HEIGHT, sString, BLOCKFONT2, &usX, &usY); mprintf( usX, usY, sString ); if( InKeyRingPopup( ) ) { // shade the background ShadowVideoSurfaceRect( guiSAVEBUFFER , PLAYER_INFO_X, PLAYER_INFO_Y, PLAYER_INFO_X + 261, PLAYER_INFO_Y + ( 359 - 107 )); } else { // blit gold key on top of key ring if key ring is not empty } SetFontDestBuffer( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); } // check for and highlight any ammo void HandleCursorOverRifleAmmo( ) { if( fShowInventoryFlag == FALSE ) { return; } if( gbCheckForMouseOverItemPos == -1 ) { return; } if ( gfCheckForMouseOverItem ) { if ( HandleCompatibleAmmoUI( &Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ], (INT8)gbCheckForMouseOverItemPos, TRUE ) ) { if ( ( GetJA2Clock( ) - guiMouseOverItemTime ) > 100 ) { fTeamPanelDirty = TRUE; } } } } void MAPInvClickCamoCallback( MOUSE_REGION *pRegion, INT32 iReason ) { } void MAPInvMoveCamoCallback( MOUSE_REGION *pRegion, INT32 iReason ) { } // this is Map Screen's version of SMInvMoveCallback() void MAPInvMoveCallback( MOUSE_REGION *pRegion, INT32 iReason ) { SOLDIERTYPE *pSoldier; UINT32 uiHandPos; if (iReason & MSYS_CALLBACK_REASON_INIT) { return; } // make sure we're here legally Assert( MapCharacterHasAccessibleInventory( bSelectedInfoChar ) ); GetSoldier( &pSoldier, gCharactersList[ bSelectedInfoChar ].usSolID ); uiHandPos = MSYS_GetRegionUserData( pRegion, 0 ); //gbCheckForMouseOverItemPos = -1; if ( pSoldier->inv[ uiHandPos ].usItem == NOTHING ) return; if (iReason == MSYS_CALLBACK_REASON_MOVE) { } else if (iReason == MSYS_CALLBACK_REASON_GAIN_MOUSE ) // if( ( iReason == MSYS_CALLBACK_REASON_MOVE ) || ( iReason == MSYS_CALLBACK_REASON_GAIN_MOUSE ) ) { gubMAP_HandInvDispText[ uiHandPos ] = 2; guiMouseOverItemTime = GetJA2Clock( ); gfCheckForMouseOverItem = TRUE; HandleCompatibleAmmoUI( pSoldier, (INT8)uiHandPos, FALSE ); gbCheckForMouseOverItemPos = (INT8)uiHandPos; } if (iReason == MSYS_CALLBACK_REASON_LOST_MOUSE ) { gubMAP_HandInvDispText[ uiHandPos ] = 1; HandleCompatibleAmmoUI( pSoldier, (INT8)uiHandPos, FALSE ); gfCheckForMouseOverItem = FALSE; fTeamPanelDirty = TRUE; gbCheckForMouseOverItemPos = -1; } } // mapscreen wrapper to init the item description box BOOLEAN MAPInternalInitItemDescriptionBox( OBJECTTYPE *pObject, UINT8 ubStatusIndex, SOLDIERTYPE *pSoldier ) { BOOLEAN fRet; fRet = InternalInitItemDescriptionBox( pObject, MAP_ITEMDESC_START_X, MAP_ITEMDESC_START_Y, ubStatusIndex, pSoldier ); fShowDescriptionFlag=TRUE; fTeamPanelDirty=TRUE; fInterfacePanelDirty = DIRTYLEVEL2; return( fRet ); } // this is Map Screen's version of SMInvClickCallback() void MAPInvClickCallback( MOUSE_REGION *pRegion, INT32 iReason ) { SOLDIERTYPE *pSoldier; UINT32 uiHandPos; UINT16 usOldItemIndex, usNewItemIndex; static BOOLEAN fRightDown = FALSE; if (iReason & MSYS_CALLBACK_REASON_INIT) { return; } // make sure we're here legally Assert( MapCharacterHasAccessibleInventory( bSelectedInfoChar ) ); GetSoldier( &pSoldier, gCharactersList[ bSelectedInfoChar ].usSolID ); uiHandPos = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { // If we do not have an item in hand, start moving it if ( gpItemPointer == NULL ) { // Return if empty if ( pSoldier->inv[ uiHandPos ].usItem == NOTHING ) { return; } //ATE: Put this here to handle Nails refusal.... if ( HandleNailsVestFetish( pSoldier, uiHandPos, NOTHING ) ) { return; } if ( _KeyDown(CTRL) ) { CleanUpStack( &( pSoldier->inv[ uiHandPos ] ), NULL ); } // remember what it was usOldItemIndex = pSoldier->inv[ uiHandPos ].usItem; // pick it up MAPBeginItemPointer( pSoldier, (UINT8)uiHandPos ); // remember which gridno the object came from sObjectSourceGridNo = pSoldier->sGridNo; HandleTacticalEffectsOfEquipmentChange( pSoldier, uiHandPos, usOldItemIndex, NOTHING ); fInterfacePanelDirty = DIRTYLEVEL2; fCharacterInfoPanelDirty = TRUE; } else // item in cursor { // can we pass this part due to booby traps if( ContinuePastBoobyTrapInMapScreen( gpItemPointer, pSoldier ) == FALSE ) { return; } usOldItemIndex = pSoldier->inv[ uiHandPos ].usItem; usNewItemIndex = gpItemPointer->usItem; //ATE: Put this here to handle Nails refusal.... if ( HandleNailsVestFetish( pSoldier, uiHandPos, usNewItemIndex ) ) { return; } if ( _KeyDown(CTRL) ) { CleanUpStack( &( pSoldier->inv[ uiHandPos ] ), gpItemPointer ); if ( gpItemPointer->ubNumberOfObjects == 0 ) { MAPEndItemPointer( ); } return; } // !!! ATTACHING/MERGING ITEMS IN MAP SCREEN IS NOT SUPPORTED !!! if ( uiHandPos == HANDPOS || uiHandPos == SECONDHANDPOS || uiHandPos == HELMETPOS || uiHandPos == VESTPOS || uiHandPos == LEGPOS ) { //if ( ValidAttachmentClass( usNewItemIndex, usOldItemIndex ) ) if ( ValidAttachment( usNewItemIndex, usOldItemIndex ) ) { // it's an attempt to attach; bring up the inventory panel if ( !InItemDescriptionBox( ) ) { MAPInternalInitItemDescriptionBox( &(pSoldier->inv[ uiHandPos ]), 0, pSoldier ); } return; } else if ( ValidMerge( usNewItemIndex, usOldItemIndex ) ) { // bring up merge requestor // TOO PAINFUL TO DO!! --CC if ( !InItemDescriptionBox( ) ) { MAPInternalInitItemDescriptionBox( &(pSoldier->inv[ uiHandPos ]), 0, pSoldier ); } /* gubHandPos = (UINT8) uiHandPos; gusOldItemIndex = usOldItemIndex; gusNewItemIndex = usNewItemIndex; gfDeductPoints = fDeductPoints; DoScreenIndependantMessageBox( Message[ STR_MERGE_ITEMS ], MSG_BOX_FLAG_YESNO, MergeMessageBoxCallBack ); return; */ } // else handle normally } // Else, try to place here if ( PlaceObject( pSoldier, (UINT8)uiHandPos, gpItemPointer ) ) { HandleTacticalEffectsOfEquipmentChange( pSoldier, uiHandPos, usOldItemIndex, usNewItemIndex ); // Dirty fInterfacePanelDirty = DIRTYLEVEL2; fCharacterInfoPanelDirty = TRUE; fMapPanelDirty = TRUE; // Check if cursor is empty now if ( gpItemPointer->ubNumberOfObjects == 0 ) { MAPEndItemPointer( ); } else // items swapped { // Update mouse cursor guiExternVo = GetInterfaceGraphicForItem( &(Item[ gpItemPointer->usItem ]) ); gusExternVoSubIndex = Item[ gpItemPointer->usItem ].ubGraphicNum; MSYS_ChangeRegionCursor( &gMPanelRegion , EXTERN_CURSOR ); MSYS_SetCurrentCursor( EXTERN_CURSOR ); fMapInventoryItem=TRUE; fTeamPanelDirty=TRUE; // remember which gridno the object came from sObjectSourceGridNo = pSoldier->sGridNo; // and who owned it last gpItemPointerSoldier = pSoldier; ReevaluateItemHatches( pSoldier, FALSE ); } // re-evaluate repairs gfReEvaluateEveryonesNothingToDo = TRUE; // if item came from another merc if ( gpItemPointerSoldier != pSoldier ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_ITEM_PASSED_TO_MERC ], ShortItemNames[ usNewItemIndex ], pSoldier->name ); } } } } else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_DWN) { // if there is a map UI message being displayed if( giUIMessageOverlay != -1 ) { CancelMapUIMessage( ); return; } fRightDown = TRUE; } else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP && fRightDown ) { fRightDown = FALSE; // Return if empty if (pSoldier->inv[ uiHandPos ].usItem == NOTHING ) { return; } // Some global stuff here - for esc, etc // Check for # of slots in item if ( ( pSoldier->inv[ uiHandPos ].ubNumberOfObjects > 1 ) && ( ItemSlotLimit( pSoldier->inv[ uiHandPos ].usItem, (UINT8)uiHandPos ) > 0 ) ) { if ( !InItemStackPopup( ) ) { InitItemStackPopup( pSoldier, (UINT8)uiHandPos, 0, INV_REGION_Y, 261, 248 ); fTeamPanelDirty=TRUE; fInterfacePanelDirty = DIRTYLEVEL2; } } else { if ( !InItemDescriptionBox( ) ) { InitItemDescriptionBox( pSoldier, (UINT8)uiHandPos, MAP_ITEMDESC_START_X, MAP_ITEMDESC_START_Y, 0 ); fShowDescriptionFlag=TRUE; fTeamPanelDirty=TRUE; fInterfacePanelDirty = DIRTYLEVEL2; } } } else if (iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { fRightDown = FALSE; } } void InternalMAPBeginItemPointer( SOLDIERTYPE *pSoldier ) { // If not null return if ( gpItemPointer != NULL ) { return; } // Set global indicator gpItemPointer = &gItemPointer; gpItemPointerSoldier = pSoldier; // Set mouse guiExternVo = GetInterfaceGraphicForItem( &(Item[ gpItemPointer->usItem ]) ); gusExternVoSubIndex = Item[ gpItemPointer->usItem ].ubGraphicNum; MSYS_ChangeRegionCursor( &gMPanelRegion , EXTERN_CURSOR ); MSYS_SetCurrentCursor( EXTERN_CURSOR ); fMapInventoryItem=TRUE; fTeamPanelDirty=TRUE; // hatch out incompatible inventory slots ReevaluateItemHatches( pSoldier, FALSE ); // re-evaluate repairs gfReEvaluateEveryonesNothingToDo = TRUE; } void MAPBeginItemPointer( SOLDIERTYPE *pSoldier, UINT8 ubHandPos ) { BOOLEAN fOk; // If not null return if ( gpItemPointer != NULL ) { return; } if (_KeyDown( SHIFT )) { // Remove all from soldier's slot fOk = RemoveObjectFromSlot( pSoldier, ubHandPos, &gItemPointer ); } else { GetObjFrom( &(pSoldier->inv[ubHandPos]), 0, &gItemPointer ); fOk = (gItemPointer.ubNumberOfObjects == 1); } if ( fOk ) { InternalMAPBeginItemPointer( pSoldier ); } } void MAPBeginKeyRingItemPointer( SOLDIERTYPE *pSoldier, UINT8 uiKeySlot ) { // If not null return if ( gpItemPointer != NULL ) { return; } // Set mouse guiExternVo = GetInterfaceGraphicForItem( &(Item[ gpItemPointer->usItem ]) ); gusExternVoSubIndex = Item[ gpItemPointer->usItem ].ubGraphicNum; MSYS_ChangeRegionCursor( &gMPanelRegion , EXTERN_CURSOR ); MSYS_SetCurrentCursor( EXTERN_CURSOR ); fMapInventoryItem=TRUE; fTeamPanelDirty=TRUE; } void MAPEndItemPointer( ) { if ( gpItemPointer != NULL ) { gpItemPointer = NULL; MSYS_ChangeRegionCursor( &gMPanelRegion , CURSOR_NORMAL ); MSYS_SetCurrentCursor( CURSOR_NORMAL ); fMapInventoryItem=FALSE; fTeamPanelDirty=TRUE; if ( fShowMapInventoryPool ) { HandleButtonStatesWhileMapInventoryActive(); } if ( fShowInventoryFlag && bSelectedInfoChar >= 0 ) { ReevaluateItemHatches( MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ], FALSE ); } } } void HandleMapInventoryCursor() { if(fMapInventoryItem) MSYS_SetCurrentCursor( EXTERN_CURSOR ); return; } // will place down the upper left hand corner attribute strings void RenderAttributeStringsForUpperLeftHandCorner( UINT32 uiBufferToRenderTo ) { INT32 iCounter = 0; SOLDIERTYPE *pSoldier = NULL; if ( ( bSelectedInfoChar != - 1) && ( gCharactersList[ bSelectedInfoChar ].fValid ) ) { pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]; } SetFont( CHAR_FONT ); SetFontForeground( CHAR_TITLE_FONT_COLOR ); SetFontBackground( FONT_BLACK ); SetFontDestBuffer( uiBufferToRenderTo, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); // assignment strings DrawString( pUpperLeftMapScreenStrings[ 0 ], (UINT16)(220 - StringPixLength( pUpperLeftMapScreenStrings[0], CHAR_FONT)/2), 6, CHAR_FONT); // vehicles and robot don't have attributes, contracts, or morale if ( ( pSoldier == NULL ) || ( !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) && !AM_A_ROBOT( pSoldier ) ) ) { // health DrawString(pUpperLeftMapScreenStrings[ 2 ], 87, 80, CHAR_FONT); for( iCounter = 0; iCounter < 5; iCounter++ ) { DrawString(pShortAttributeStrings[ iCounter ], 88, ( INT16 )( 22 + iCounter * 10 ) ,CHAR_FONT ); DrawString(pShortAttributeStrings[ iCounter + 5 ] ,133, ( INT16 )( 22 + iCounter * 10 ), CHAR_FONT ); } // contract //DrawString(pUpperLeftMapScreenStrings[ 1 ], 194, 52, CHAR_FONT); // morale DrawString(pUpperLeftMapScreenStrings[ 3 ], 87, 94, CHAR_FONT); } else { // condition DrawString(pUpperLeftMapScreenStrings[ 4 ], 96, 80, CHAR_FONT); } // restore buffer SetFontDestBuffer( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); } void DisplayThePotentialPathForCurrentDestinationCharacterForMapScreenInterface(INT16 sMapX, INT16 sMapY ) { // simply check if we want to refresh the screen to display path static INT8 bOldDestChar = -1; static INT16 sPrevMapX, sPrevMapY; INT32 iDifference = 0; if( bOldDestChar != bSelectedDestChar ) { bOldDestChar = bSelectedDestChar; giPotCharPathBaseTime = GetJA2Clock( ); sPrevMapX = sMapX; sPrevMapY = sMapY; fTempPathAlreadyDrawn = FALSE; fDrawTempPath = FALSE; } if( ( sMapX != sPrevMapX) || ( sMapY != sPrevMapY ) ) { giPotCharPathBaseTime = GetJA2Clock( ); sPrevMapX = sMapX; sPrevMapY = sMapY; // path was plotted and we moved, re draw map..to clean up mess if( fTempPathAlreadyDrawn == TRUE ) { fMapPanelDirty = TRUE; } fTempPathAlreadyDrawn = FALSE; fDrawTempPath = FALSE; } iDifference = GetJA2Clock( ) - giPotCharPathBaseTime ; if( fTempPathAlreadyDrawn == TRUE ) { return; } if( iDifference > MIN_WAIT_TIME_FOR_TEMP_PATH ) { fDrawTempPath = TRUE; giPotCharPathBaseTime = GetJA2Clock( ); fTempPathAlreadyDrawn = TRUE; } return; } void SetUpCursorForStrategicMap( void ) { if ( gfInChangeArrivalSectorMode == FALSE ) { // check if character is in destination plotting mode if( fPlotForHelicopter == FALSE ) { if( bSelectedDestChar == -1 ) { // no plot mode, reset cursor to normal ChangeMapScreenMaskCursor( CURSOR_NORMAL ); } else // yes - by character { // set cursor based on foot or vehicle if( ( Menptr[gCharactersList[ bSelectedDestChar ].usSolID].bAssignment != VEHICLE ) && !( Menptr[gCharactersList[ bSelectedDestChar ].usSolID].uiStatusFlags & SOLDIER_VEHICLE ) ) { ChangeMapScreenMaskCursor( CURSOR_STRATEGIC_FOOT ); } else { ChangeMapScreenMaskCursor( CURSOR_STRATEGIC_VEHICLE ); } } } else // yes - by helicopter { // set cursor to chopper ChangeMapScreenMaskCursor( CURSOR_CHOPPER ); } } else { // set cursor to bullseye ChangeMapScreenMaskCursor( CURSOR_STRATEGIC_BULLSEYE ); } } void HandleAnimatedCursorsForMapScreen( ) { if ( COUNTERDONE( CURSORCOUNTER ) ) { RESETCOUNTER( CURSORCOUNTER ); UpdateAnimatedCursorFrames( gMapScreenMaskRegion.Cursor ); SetCurrentCursorFromDatabase( gMapScreenMaskRegion.Cursor ); } } void AbortMovementPlottingMode( void ) { // invalid if we're not plotting movement Assert( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ); // make everybody go back to where they were going before this plotting session started RestorePreviousPaths(); // don't need the previous paths any more ClearPreviousPaths(); // clear the character's temporary path (this is the route being constantly updated on the map) if( pTempCharacterPath ) { // make sure we're at the beginning pTempCharacterPath = MoveToBeginningOfPathList( pTempCharacterPath ); pTempCharacterPath = ClearStrategicPathList( pTempCharacterPath, 0 ); } // clear the helicopter's temporary path (this is the route being constantly updated on the map) if( pTempHelicopterPath ) { // make sure we're at the beginning pTempHelicopterPath = MoveToBeginningOfPathList( pTempHelicopterPath ); pTempHelicopterPath = ClearStrategicPathList( pTempHelicopterPath, 0 ); } EndConfirmMapMoveMode( ); // cancel destination line highlight giDestHighLine = -1; // cancel movement mode bSelectedDestChar = -1; fPlotForHelicopter = FALSE; // tell player the route was UNCHANGED MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pMapPlotStrings[ 2 ] ); // reset cursors ChangeMapScreenMaskCursor( CURSOR_NORMAL ); SetUpCursorForStrategicMap( ); // restore glow region RestoreBackgroundForDestinationGlowRegionList( ); // we might be on the map, redraw to remove old path stuff fMapPanelDirty = TRUE; fTeamPanelDirty = TRUE; gfRenderPBInterface = TRUE; } void CheckToSeeIfMouseHasLeftMapRegionDuringPathPlotting( ) { static BOOLEAN fInArea = FALSE; if ( ( gMapViewRegion.uiFlags & MSYS_MOUSE_IN_AREA ) == 0 ) { if( fInArea == TRUE ) { fInArea = FALSE; // plotting path, clean up if( ( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) || ( fDrawTempHeliPath == TRUE ) ) && ( fTempPathAlreadyDrawn == TRUE ) ) { fDrawTempHeliPath = FALSE; fMapPanelDirty = TRUE; gfRenderPBInterface = TRUE; // clear the temp path if( pTempCharacterPath ) { pTempCharacterPath = ClearStrategicPathList( pTempCharacterPath, 0 ); } } // reset fact temp path has been drawn fTempPathAlreadyDrawn = FALSE; } } else { fInArea = TRUE; } return; } void BlitBackgroundToSaveBuffer( void ) { INT8 bTempDestChar = -1; // render map RenderMapRegionBackground( ); if( fDisableDueToBattleRoster == FALSE ) { // render team RenderTeamRegionBackground( ); // render character info RenderCharacterInfoBackground( ); } else if( gfPreBattleInterfaceActive ) { // WANNE: //DeleteButtonsForScrolling(); ForceButtonUnDirty( giMapContractButton ); ForceButtonUnDirty( giCharInfoButton[ 0 ] ); ForceButtonUnDirty( giCharInfoButton[ 1 ] ); RenderPreBattleInterface(); } // now render lower panel RenderMapScreenInterfaceBottom( ); } void CreateMouseRegionsForTeamList( void ) { // will create mouse regions for assignments, path plotting, character info selection INT16 sCounter = 0; //INT16 sYAdd = 0; INT16 sYStart = 0; INT16 sOffsetCounter = 0; // the info region...is the background for the list itself for( sCounter = 0; sCounter < MAX_CHARACTER_COUNT; sCounter++ ) { if( sCounter >= FIRST_VEHICLE ) { //sYAdd = 6; sOffsetCounter = sCounter - FIRST_VEHICLE; sYStart = usVehicleY; } else { sOffsetCounter = sCounter; sYStart = Y_START; //sYAdd = 0; } // name region MSYS_DefineRegion( &gTeamListNameRegion[ sCounter ] , NAME_X, ( INT16 )( sYStart + ( sOffsetCounter ) * ( Y_SIZE + 2 )), NAME_X + NAME_WIDTH, ( INT16 )( (sYStart + 10) + ( sOffsetCounter + 1 ) * ( Y_SIZE + 2 )), MSYS_PRIORITY_NORMAL, MSYS_NO_CURSOR, TeamListInfoRegionMvtCallBack, TeamListInfoRegionBtnCallBack ); // assignment region MSYS_DefineRegion( &gTeamListAssignmentRegion[ sCounter ] ,ASSIGN_X , ( INT16 )( sYStart + ( sOffsetCounter ) * ( Y_SIZE + 2 )), ASSIGN_X + ASSIGN_WIDTH, ( INT16 )( (sYStart + 10) + ( sOffsetCounter + 1 ) * ( Y_SIZE + 2 )), MSYS_PRIORITY_NORMAL + 1, MSYS_NO_CURSOR, TeamListAssignmentRegionMvtCallBack, TeamListAssignmentRegionBtnCallBack ); // location region (same function as name regions, so uses the same callbacks) MSYS_DefineRegion( &gTeamListLocationRegion[ sCounter ] , LOC_X, ( INT16 )( sYStart + ( sOffsetCounter ) * ( Y_SIZE + 2 )), LOC_X + LOC_WIDTH, ( INT16 )( (sYStart + 10) + ( sOffsetCounter + 1 ) * ( Y_SIZE + 2 )), MSYS_PRIORITY_NORMAL + 1, MSYS_NO_CURSOR, TeamListInfoRegionMvtCallBack, TeamListInfoRegionBtnCallBack ); // destination region MSYS_DefineRegion( &gTeamListDestinationRegion[ sCounter ] ,DEST_ETA_X , ( INT16 )( sYStart + ( sOffsetCounter ) * ( Y_SIZE + 2 )), DEST_ETA_X + DEST_ETA_WIDTH, ( INT16 )( (sYStart + 10) + ( sOffsetCounter + 1 ) * ( Y_SIZE + 2 )), MSYS_PRIORITY_NORMAL + 1, MSYS_NO_CURSOR, TeamListDestinationRegionMvtCallBack, TeamListDestinationRegionBtnCallBack ); // contract region MSYS_DefineRegion( &gTeamListContractRegion[ sCounter ] ,TIME_REMAINING_X , ( INT16 )( sYStart + ( sOffsetCounter ) * ( Y_SIZE + 2 )), TIME_REMAINING_X + TIME_REMAINING_WIDTH, ( INT16 )( (sYStart + 10) + ( sOffsetCounter + 1 ) * ( Y_SIZE + 2 )), MSYS_PRIORITY_NORMAL + 1, MSYS_NO_CURSOR, TeamListContractRegionMvtCallBack, TeamListContractRegionBtnCallBack ); // contract region MSYS_DefineRegion( &gTeamListSleepRegion[ sCounter ] ,SLEEP_X, ( INT16 )( sYStart + ( sOffsetCounter ) * ( Y_SIZE + 2 )), SLEEP_X + SLEEP_WIDTH, ( INT16 )( (sYStart + 10) + ( sOffsetCounter + 1 ) * ( Y_SIZE + 2 )), MSYS_PRIORITY_NORMAL + 1, MSYS_NO_CURSOR, TeamListSleepRegionMvtCallBack, TeamListSleepRegionBtnCallBack ); //// name region //MSYS_DefineRegion( &gTeamListNameRegion[ sCounter ] , NAME_X, ( INT16 )( Y_START + ( sCounter ) * ( Y_SIZE + 2 ) + sYAdd ), NAME_X + NAME_WIDTH, ( INT16 )( 145 + ( sCounter + 1 ) * ( Y_SIZE + 2 ) + sYAdd ), MSYS_PRIORITY_NORMAL, // MSYS_NO_CURSOR, TeamListInfoRegionMvtCallBack, TeamListInfoRegionBtnCallBack ); //// assignment region //MSYS_DefineRegion( &gTeamListAssignmentRegion[ sCounter ] ,ASSIGN_X , ( INT16 )( Y_START + ( sCounter ) * ( Y_SIZE + 2 ) + sYAdd), ASSIGN_X + ASSIGN_WIDTH, ( INT16 )( 145 + ( sCounter + 1 ) * ( Y_SIZE + 2 ) + sYAdd ), MSYS_PRIORITY_NORMAL + 1, // MSYS_NO_CURSOR, TeamListAssignmentRegionMvtCallBack, TeamListAssignmentRegionBtnCallBack ); //// location region (same function as name regions, so uses the same callbacks) //MSYS_DefineRegion( &gTeamListLocationRegion[ sCounter ] , LOC_X, ( INT16 )( Y_START + ( sCounter ) * ( Y_SIZE + 2 ) + sYAdd ), LOC_X + LOC_WIDTH, ( INT16 )( 145 + ( sCounter + 1 ) * ( Y_SIZE + 2 ) + sYAdd ), MSYS_PRIORITY_NORMAL + 1, // MSYS_NO_CURSOR, TeamListInfoRegionMvtCallBack, TeamListInfoRegionBtnCallBack ); //// destination region //MSYS_DefineRegion( &gTeamListDestinationRegion[ sCounter ] ,DEST_ETA_X , ( INT16 )( Y_START + ( sCounter ) * ( Y_SIZE + 2 ) + sYAdd ), DEST_ETA_X + DEST_ETA_WIDTH, ( INT16 )( 145 + ( sCounter + 1 ) * ( Y_SIZE + 2 ) + sYAdd ), MSYS_PRIORITY_NORMAL + 1, // MSYS_NO_CURSOR, TeamListDestinationRegionMvtCallBack, TeamListDestinationRegionBtnCallBack ); //// contract region //MSYS_DefineRegion( &gTeamListContractRegion[ sCounter ] ,TIME_REMAINING_X , ( INT16 )( Y_START + ( sCounter ) * ( Y_SIZE + 2 ) + sYAdd), TIME_REMAINING_X + TIME_REMAINING_WIDTH, ( INT16 )( 145 + ( sCounter + 1 ) * ( Y_SIZE + 2 ) + sYAdd ), MSYS_PRIORITY_NORMAL + 1, // MSYS_NO_CURSOR, TeamListContractRegionMvtCallBack, TeamListContractRegionBtnCallBack ); //// contract region //MSYS_DefineRegion( &gTeamListSleepRegion[ sCounter ] ,SLEEP_X, ( INT16 )( Y_START + ( sCounter ) * ( Y_SIZE + 2 ) + sYAdd), SLEEP_X + SLEEP_WIDTH, ( INT16 )( 145 + ( sCounter + 1 ) * ( Y_SIZE + 2 ) + sYAdd ), MSYS_PRIORITY_NORMAL + 1, // MSYS_NO_CURSOR, TeamListSleepRegionMvtCallBack, TeamListSleepRegionBtnCallBack ); MSYS_SetRegionUserData(&gTeamListNameRegion[sCounter],0,sCounter); MSYS_SetRegionUserData(&gTeamListAssignmentRegion[sCounter],0,sCounter); MSYS_SetRegionUserData(&gTeamListSleepRegion[sCounter],0,sCounter); MSYS_SetRegionUserData(&gTeamListLocationRegion[sCounter],0,sCounter); MSYS_SetRegionUserData(&gTeamListDestinationRegion[sCounter],0,sCounter); MSYS_SetRegionUserData(&gTeamListContractRegion[sCounter],0,sCounter); // set up help boxes SetRegionFastHelpText( &gTeamListNameRegion[sCounter], pMapScreenMouseRegionHelpText[ 0 ] ); SetRegionFastHelpText( &gTeamListAssignmentRegion[sCounter], pMapScreenMouseRegionHelpText[ 1 ] ); SetRegionFastHelpText( &gTeamListSleepRegion[sCounter], pMapScreenMouseRegionHelpText[ 5 ] ); SetRegionFastHelpText( &gTeamListLocationRegion[sCounter], pMapScreenMouseRegionHelpText[ 4 ] ); SetRegionFastHelpText( &gTeamListDestinationRegion[sCounter], pMapScreenMouseRegionHelpText[ 2 ] ); SetRegionFastHelpText( &gTeamListContractRegion[sCounter], pMapScreenMouseRegionHelpText[ 3 ] ); } return; } void DestroyMouseRegionsForTeamList( void ) { // will destroy mouse regions overlaying the team list area INT32 sCounter = 0; for( sCounter = 0; sCounter < MAX_CHARACTER_COUNT; sCounter++ ) { MSYS_RemoveRegion( &gTeamListNameRegion[ sCounter ]); MSYS_RemoveRegion( &gTeamListAssignmentRegion[ sCounter ]); MSYS_RemoveRegion( &gTeamListSleepRegion[ sCounter ]); MSYS_RemoveRegion( &gTeamListDestinationRegion[ sCounter ]); MSYS_RemoveRegion( &gTeamListLocationRegion[ sCounter ]); MSYS_RemoveRegion( &gTeamListContractRegion[ sCounter ]); } } // mask for mapscreen region void MapScreenMarkRegionBtnCallback(MOUSE_REGION *pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { // reset selected characters ResetAllSelectedCharacterModes( ); } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { // reset selected characters ResetAllSelectedCharacterModes( ); } } void ContractButtonCallback(GUI_BUTTON *btn,INT32 reason) { if( ( iDialogueBox != -1 ) ) { return; } if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); } /* if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); return; } */ // redraw region if( btn->Area.uiFlags & MSYS_HAS_BACKRECT ) { fCharacterInfoPanelDirty = TRUE; } btn->uiFlags|=(BUTTON_CLICKED_ON); } else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); } if (btn->uiFlags & BUTTON_CLICKED_ON) { btn->uiFlags&= ~(BUTTON_CLICKED_ON); RequestContractMenu( ); } } else if(reason & MSYS_CALLBACK_REASON_RBUTTON_DWN ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); } } } void TeamListInfoRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = 0; SOLDIERTYPE *pSoldier = NULL; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { // set to new info character...make sure is valid if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( gCharactersList[ iValue ].fValid == TRUE ) { if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) ) { return; } ChangeSelectedInfoChar( ( INT8 ) iValue, TRUE ); pSoldier = &Menptr[ gCharactersList[ iValue ].usSolID ]; // highlight giDestHighLine = -1; // reset character bSelectedAssignChar = -1; bSelectedDestChar = -1; bSelectedContractChar = -1; fPlotForHelicopter = FALSE; // if not dead or POW, select his sector if( ( pSoldier->bLife > 0 ) && ( pSoldier->bAssignment != ASSIGNMENT_POW ) ) { ChangeSelectedMapSector( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); } // unhilight contract line giContractHighLine = -1; // can't assign highlight line giAssignHighLine = -1; // dirty team and map regions fTeamPanelDirty = TRUE; fMapPanelDirty = TRUE; //fMapScreenBottomDirty = TRUE; gfRenderPBInterface = TRUE; } else { // reset selected characters ResetAllSelectedCharacterModes( ); } } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( gCharactersList[ iValue ].fValid == TRUE ) { pSoldier = &Menptr[ gCharactersList[ iValue ].usSolID ]; // select this character ChangeSelectedInfoChar( ( INT8 ) iValue, TRUE ); RequestToggleMercInventoryPanel(); // highlight giDestHighLine = -1; // reset character bSelectedAssignChar = -1; bSelectedDestChar = -1; bSelectedContractChar = -1; fPlotForHelicopter = FALSE; // if not dead or POW, select his sector if( ( pSoldier->bLife > 0 ) && ( pSoldier->bAssignment != ASSIGNMENT_POW ) ) { ChangeSelectedMapSector( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); } // unhilight contract line giContractHighLine = -1; // can't assign highlight line giAssignHighLine = -1; // dirty team and map regions fTeamPanelDirty = TRUE; fMapPanelDirty = TRUE; // fMapScreenBottomDirty = TRUE; gfRenderPBInterface = TRUE; } } } void TeamListInfoRegionMvtCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = 0; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_MOVE) { if( gCharactersList[ iValue ].fValid == TRUE ) { giHighLine = iValue; } else { giHighLine = -1; } } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { giHighLine = -1; } } void TeamListAssignmentRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = 0; SOLDIERTYPE *pSoldier = NULL; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { // set to new info character...make sure is valid if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( gCharactersList[ iValue ].fValid == TRUE ) { if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) ) { return; } // reset list if the clicked character isn't also selected ChangeSelectedInfoChar( ( INT8 ) iValue, ( BOOLEAN )( IsEntryInSelectedListSet( ( INT8 ) iValue ) == FALSE ) ); pSoldier = &Menptr[ gCharactersList[ iValue ].usSolID ]; // if alive (dead guys keep going, use remove menu instead), // and it's between sectors and it can be reassigned (non-vehicles) if ( ( pSoldier->bAssignment != ASSIGNMENT_DEAD ) && ( pSoldier->bLife > 0 ) && ( pSoldier->fBetweenSectors ) && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) { // can't reassign mercs while between sectors DoScreenIndependantMessageBox( pMapErrorString[ 41 ], MSG_BOX_FLAG_OK, NULL ); return; } bSelectedAssignChar = ( INT8 ) iValue; RebuildAssignmentsBox( ); // reset dest character bSelectedDestChar = -1; fPlotForHelicopter = FALSE; // reset contract char bSelectedContractChar = -1; giContractHighLine = -1; // can't highlight line, anymore..if we were giDestHighLine = -1; // dirty team and map regions fTeamPanelDirty = TRUE; fMapPanelDirty = TRUE; gfRenderPBInterface = TRUE; // if this thing can be re-assigned if( !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) { giAssignHighLine = iValue; fShowAssignmentMenu = TRUE; if( ( pSoldier->bLife == 0 ) || ( pSoldier->bAssignment == ASSIGNMENT_POW ) ) { fShowRemoveMenu = TRUE; } } else { // can't highlight line giAssignHighLine = -1; // we can't highlight this line // giHighLine = -1; } } else { // reset selected characters ResetAllSelectedCharacterModes( ); } } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { // reset selected characters ResetAllSelectedCharacterModes( ); } } void TeamListAssignmentRegionMvtCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = 0; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_MOVE) { if( gCharactersList[ iValue ].fValid == TRUE ) { giHighLine = iValue; if( !( Menptr[ gCharactersList[ iValue ].usSolID ].uiStatusFlags & SOLDIER_VEHICLE ) ) { giAssignHighLine = iValue; } else { giAssignHighLine = -1; } } else { // can't highlight line giHighLine = -1; giAssignHighLine = -1; } } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { giHighLine = -1; if( bSelectedAssignChar == -1 ) { giAssignHighLine = -1; } // restore background RestoreBackgroundForAssignmentGlowRegionList( ); } else if( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { if( ( gCharactersList[ iValue ].fValid == TRUE ) && !( Menptr[ gCharactersList[ iValue ].usSolID ].uiStatusFlags & SOLDIER_VEHICLE ) ) { // play click PlayGlowRegionSound( ); } } } void TeamListDestinationRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = 0; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive || fShowMapInventoryPool ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( gCharactersList[ iValue ].fValid == TRUE ) { if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) ) { return; } // reset list if the clicked character isn't also selected ChangeSelectedInfoChar( ( INT8 ) iValue, ( BOOLEAN )( IsEntryInSelectedListSet( ( INT8 ) iValue ) == FALSE ) ); // deselect any characters/vehicles that can't accompany the clicked merc DeselectSelectedListMercsWhoCantMoveWithThisGuy( &( Menptr[ gCharactersList[ iValue ].usSolID ] ) ); // select all characters/vehicles that MUST accompany the clicked merc (same squad/vehicle) SelectUnselectedMercsWhoMustMoveWithThisGuy( ); // Find out if this guy and everyone travelling with him is allowed to move strategically // NOTE: errors are reported within... if ( CanChangeDestinationForCharSlot( ( INT8 ) iValue, TRUE ) ) { // turn off sector inventory, turn on show teams filter, etc. MakeMapModesSuitableForDestPlotting( ( INT8 ) iValue ); // check if person is in a vehicle if( Menptr[gCharactersList[ iValue ].usSolID].bAssignment == VEHICLE ) { // if he's in the helicopter if( Menptr[gCharactersList[ iValue ].usSolID].iVehicleId == iHelicopterVehicleId ) { TurnOnAirSpaceMode( ); if( RequestGiveSkyriderNewDestination( ) == FALSE ) { // not allowed to change destination of the helicopter return; } } } // select this character as the one plotting strategic movement bSelectedDestChar = ( INT8 )iValue; // remember the current paths for all selected characters so we can restore them if need be RememberPreviousPathForAllSelectedChars(); // check each person in this mvt group, if any bleeding, have them complain //CheckMembersOfMvtGroupAndComplainAboutBleeding( &( Menptr[ gCharactersList[ bSelectedDestChar ].usSolID ] ) ); // highlight giDestHighLine = iValue; // can't assign highlight line giAssignHighLine = -1; // reset assign character bSelectedAssignChar = -1; // reset contract char bSelectedContractChar = -1; giContractHighLine = -1; // dirty team and map regions fTeamPanelDirty = TRUE; fMapPanelDirty = TRUE; gfRenderPBInterface = TRUE; // set cursor SetUpCursorForStrategicMap( ); } else // problem - this guy can't move { // cancel destination highlight giDestHighLine = -1; } } else // empty char list slot { // reset selected characters ResetAllSelectedCharacterModes( ); } } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { MakeMapModesSuitableForDestPlotting( ( INT8 ) iValue ); // reset list if the clicked character isn't also selected ChangeSelectedInfoChar( ( INT8 ) iValue, ( BOOLEAN )( IsEntryInSelectedListSet( ( INT8 ) iValue ) == FALSE ) ); CancelPathsOfAllSelectedCharacters(); // reset selected characters ResetAllSelectedCharacterModes( ); } } void TeamListDestinationRegionMvtCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = -1; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_MOVE) { if( gCharactersList[ iValue ].fValid == TRUE ) { giHighLine = iValue; giDestHighLine = iValue; } else { // can't highlight line giHighLine = -1; giDestHighLine = -1; } } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { giHighLine = -1; if( bSelectedDestChar == -1 ) { giDestHighLine = -1; } // restore background RestoreBackgroundForDestinationGlowRegionList( ); } else if( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { if( gCharactersList[ iValue ].fValid == TRUE ) { // play click PlayGlowRegionSound( ); } } } void TeamListSleepRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = 0; SOLDIERTYPE *pSoldier = NULL; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { // set to new info character...make sure is valid.. not in transit and alive and concious if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( ( gCharactersList[ iValue ].fValid == TRUE ) ) { if ( HandleCtrlOrShiftInTeamPanel( ( INT8 ) iValue ) ) { return; } // reset list if the clicked character isn't also selected ChangeSelectedInfoChar( ( INT8 ) iValue, ( BOOLEAN )( IsEntryInSelectedListSet( ( INT8 ) iValue ) == FALSE ) ); // if this slot's sleep status can be changed if ( CanChangeSleepStatusForCharSlot( (INT8) iValue ) ) { pSoldier = &Menptr[ gCharactersList[ iValue ].usSolID ]; if( pSoldier->fMercAsleep == TRUE ) { // try to wake him up if( SetMercAwake( pSoldier, TRUE, FALSE ) ) { // propagate HandleSelectedMercsBeingPutAsleep( TRUE, TRUE ); return; } else { HandleSelectedMercsBeingPutAsleep( TRUE, FALSE ); } } else // awake { // try to put him to sleep if( SetMercAsleep( pSoldier, TRUE ) ) { // propagate HandleSelectedMercsBeingPutAsleep( FALSE, TRUE ); return; } else { HandleSelectedMercsBeingPutAsleep( FALSE, FALSE ); } } } } else { // reset selected characters ResetAllSelectedCharacterModes( ); } } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { // reset selected characters ResetAllSelectedCharacterModes( ); } } void TeamListSleepRegionMvtCallBack( MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = -1; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_MOVE) { if( gCharactersList[ iValue ].fValid == TRUE ) { giHighLine = iValue; if ( CanChangeSleepStatusForCharSlot( (INT8) iValue ) ) { giSleepHighLine = iValue; } else { giSleepHighLine = -1; } } else { // can't highlight line giHighLine = -1; giSleepHighLine = -1; } } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { giHighLine = -1; giSleepHighLine = -1; // restore background RestoreBackgroundForSleepGlowRegionList( ); } else if( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { if ( CanChangeSleepStatusForCharSlot( (INT8) iValue ) ) { // play click PlayGlowRegionSound( ); } } } void TeamListContractRegionBtnCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = 0; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if( gCharactersList[ iValue ].fValid == TRUE ) { if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { // select ONLY this dude ChangeSelectedInfoChar( ( INT8 ) iValue, TRUE ); // reset character giDestHighLine = -1; bSelectedAssignChar = -1; bSelectedDestChar = -1; bSelectedContractChar = -1; fPlotForHelicopter = FALSE; fTeamPanelDirty = TRUE; } ContractRegionBtnCallback( pRegion, iReason ); } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { // reset selected characters ResetAllSelectedCharacterModes( ); } } void TeamListContractRegionMvtCallBack(MOUSE_REGION *pRegion, INT32 iReason ) { INT32 iValue = -1; if( fLockOutMapScreenInterface || gfPreBattleInterfaceActive ) { return; } iValue = MSYS_GetRegionUserData( pRegion, 0 ); if (iReason & MSYS_CALLBACK_REASON_MOVE) { if( gCharactersList[ iValue ].fValid == TRUE ) { giHighLine = iValue; if( CanExtendContractForCharSlot( (INT8) iValue ) ) { giContractHighLine = iValue; } else { giContractHighLine = -1; } } else { // can't highlight line giHighLine = -1; giContractHighLine = -1; } } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { giHighLine = -1; // no longer valid char?...reset display of highlight boxes if( fShowContractMenu == FALSE ) { giContractHighLine = -1; } // restore background RestoreBackgroundForContractGlowRegionList( ); } else if( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { if( CanExtendContractForCharSlot( (INT8) iValue ) ) { // play click PlayGlowRegionSound( ); } } } INT32 GetIndexForThisSoldier( SOLDIERTYPE *pSoldier ) { INT32 iLastGuy; INT32 iIndex = 0; INT32 iCounter = 0; // get the index into the characters list for this soldier type iLastGuy = gTacticalStatus.Team[ OUR_TEAM ].bLastID; for( iCounter = 0; iCounter < iLastGuy; iCounter++ ) { if( gCharactersList[ iCounter ].fValid == TRUE ) { if( ( &Menptr[ gCharactersList[ iCounter ].usSolID ] ) == pSoldier ) { iIndex = iCounter; iCounter = iLastGuy; } } } return( iIndex ); } BOOLEAN IsCursorWithInRegion(INT16 sLeft, INT16 sRight, INT16 sTop, INT16 sBottom ) { POINT MousePos; // get cursor position GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! // is it within region? if( ( sLeft < MousePos.x ) && ( sRight > MousePos.x) && (sTop < MousePos.y ) && ( sBottom > MousePos.y ) ) { return ( TRUE ); } else { return ( FALSE ); } } void HandleHighLightingOfLinesInTeamPanel( void ) { if ( fShowInventoryFlag ) { return; } // will highlight or restore backgrounds to highlighted lines // restore backgrounds, if need be RestoreBackgroundForAssignmentGlowRegionList( ); RestoreBackgroundForDestinationGlowRegionList( ); RestoreBackgroundForContractGlowRegionList( ); RestoreBackgroundForSleepGlowRegionList( ); HighLightAssignLine( /*(UINT16)giAssignHighLine*/ ); // doesn't take parameters (jonathanl) HighLightDestLine( /*(UINT16)giDestHighLine */); // doesn't take parameters (jonathanl) HighLightSleepLine( /*(UINT16)giSleepHighLine */); // doesn't take parameters (jonathanl) // contracts? if( giContractHighLine != -1 ) { ContractListRegionBoxGlow( ( UINT16 ) giContractHighLine ); } } void PlotPermanentPaths( void ) { if( fPlotForHelicopter == TRUE ) { DisplayHelicopterPath( ); } else if( bSelectedDestChar != -1 ) { DisplaySoldierPath( &Menptr[ gCharactersList[ bSelectedDestChar ].usSolID ] ); } } void PlotTemporaryPaths( void ) { INT16 sMapX, sMapY; // check to see if we have in fact moved are are plotting a path? if ( GetMouseMapXY( &sMapX, &sMapY ) ) { if ( fPlotForHelicopter == TRUE ) { Assert( fShowAircraftFlag == TRUE ); /* if( fZoomFlag ) { sMapX = ( INT16 )( ( ( iZoomX ) / ( WORLD_MAP_X ) ) + sMapX ); sMapX /= 2; sMapY = ( INT16 )( ( ( iZoomY ) / ( WORLD_MAP_X ) ) + sMapY ); sMapY /= 2; } */ // plot temp path PlotATemporaryPathForHelicopter( sMapX, sMapY); // check if potential path is allowed DisplayThePotentialPathForHelicopter( sMapX, sMapY ); if( fDrawTempHeliPath == TRUE ) { // clip region ClipBlitsToMapViewRegion( ); // display heli temp path DisplayHelicopterTempPath( ); //restore RestoreClipRegionToFullScreen( ); } } else // dest char has been selected, if( bSelectedDestChar != -1 ) { /* if( fZoomFlag ) { sMapX = ( INT16 )( ( ( iZoomX ) / ( MAP_GRID_X ) ) + sMapX ); sMapX /= 2; sMapY = ( INT16 )( ( ( iZoomY ) / ( MAP_GRID_Y ) ) + sMapY ); sMapY /= 2; } */ PlotATemporaryPathForCharacter( &Menptr[ gCharactersList[ bSelectedDestChar ].usSolID ], sMapX, sMapY ); // check to see if we are drawing path DisplayThePotentialPathForCurrentDestinationCharacterForMapScreenInterface( sMapX, sMapY ); // if we need to draw path, do it if( fDrawTempPath == TRUE ) { // clip region ClipBlitsToMapViewRegion( ); // blit DisplaySoldierTempPath( &Menptr[ gCharactersList[ bSelectedDestChar ].usSolID ] ); // restore RestoreClipRegionToFullScreen( ); } } } } void RenderMapRegionBackground( void ) { // renders to save buffer when dirty flag set if( fMapPanelDirty == FALSE ) { gfMapPanelWasRedrawn = FALSE; // not dirty, leave return; } // don't bother if showing sector inventory instead of the map!!! if( !fShowMapInventoryPool ) { // draw map DrawMap( ); } // blit in border RenderMapBorder( ); if ( ghAttributeBox != - 1 ) { ForceUpDateOfBox( ghAttributeBox ); } if ( ghTownMineBox != - 1 ) { // force update of town mine info boxes ForceUpDateOfBox( ghTownMineBox ); } MapscreenMarkButtonsDirty(); //RestoreExternBackgroundRect( 261, 0, 379, 359 ); RestoreExternBackgroundRect( 261, 0, SCREEN_WIDTH - 261, SCREEN_HEIGHT - 121 ); // don't bother if showing sector inventory instead of the map!!! if( !fShowMapInventoryPool ) { // if Skyrider can and wants to talk to us if( IsHelicopterPilotAvailable( ) ) { // see if Skyrider has anything new to tell us CheckAndHandleSkyriderMonologues( ); } } // reset dirty flag fMapPanelDirty = FALSE; gfMapPanelWasRedrawn = TRUE; return; } void RenderTeamRegionBackground( void ) { HVOBJECT hHandle; // renders to save buffer when dirty flag set if( fTeamPanelDirty == FALSE ) { // not dirty, leave return; } // show inventory or the team list? if(fShowInventoryFlag == FALSE ) { GetVideoObject(&hHandle, guiCHARLIST); BltVideoObject( guiSAVEBUFFER , hHandle, 0,PLAYER_INFO_X, PLAYER_INFO_Y , VO_BLT_SRCTRANSPARENCY,NULL ); } else { BltCharInvPanel(); } if ( !fShowInventoryFlag ) { // if we are not in inventory mode, show character list HandleHighLightingOfLinesInTeamPanel( ); DisplayCharacterList(); } fDrawCharacterList = FALSE; // display arrows by selected people HandleDisplayOfSelectedMercArrows( ); DisplayIconsForMercsAsleep( ); // reset dirty flag fTeamPanelDirty = FALSE; gfRenderPBInterface = TRUE; // mark all pop ups as dirty MarkAllBoxesAsAltered( ); // restore background for area RestoreExternBackgroundRect( 0, 107, 261, SCREEN_HEIGHT - 106 - 121 ); MapscreenMarkButtonsDirty(); return; } void RenderCharacterInfoBackground( void ) { HVOBJECT hHandle; // will render the background for the character info panel if( fCharacterInfoPanelDirty == FALSE ) { // not dirty, leave return; } // the upleft hand corner character info panel GetVideoObject(&hHandle, guiCHARINFO); BltVideoObject( guiSAVEBUFFER , hHandle, 0,TOWN_INFO_X, TOWN_INFO_Y , VO_BLT_SRCTRANSPARENCY,NULL ); UpdateHelpTextForMapScreenMercIcons( ); if( ( bSelectedInfoChar != -1) && ( fDisableDueToBattleRoster == FALSE ) ) { // valid char to display DisplayCharacterInfo(); } if( ( fDisableDueToBattleRoster == FALSE ) ) { // draw attributes RenderAttributeStringsForUpperLeftHandCorner( guiSAVEBUFFER ); } // reset dirty flag fCharacterInfoPanelDirty = FALSE; // redraw face fReDrawFace = TRUE; MapscreenMarkButtonsDirty(); // mark all pop ups as dirty MarkAllBoxesAsAltered( ); // restore background for area RestoreExternBackgroundRect( 0, 0, 261, 107 ); } void DetermineIfContractMenuCanBeShown( void ) { if( fShowContractMenu == FALSE ) { // destroy menus for contract region CreateDestroyMouseRegionsForContractMenu( ); // hide all boxes HideBox( ghContractBox ); // make sure, absolutly sure we want to hide this box if( fShowAssignmentMenu == FALSE ) { HideBox( ghRemoveMercAssignBox ); } return; } // create mask, if needed CreateDestroyScreenMaskForAssignmentAndContractMenus( ); // create mouse regions for contract region CreateDestroyMouseRegionsForContractMenu( ); // determine which lines selectable HandleShadingOfLinesForContractMenu( ); if( Menptr[gCharactersList[ bSelectedInfoChar ].usSolID].bLife == 0 ) { // show basic assignment menu ShowBox( ghRemoveMercAssignBox ); } else { // show basic contract menu ShowBox( ghContractBox ); } } void CheckIfPlottingForCharacterWhileAirCraft( void ) { // if we are in aircraft mode and plotting for character, reset plotting character if( fShowAircraftFlag == TRUE ) { // if plotting, but not for heli if ( ( bSelectedDestChar != -1 ) && ( fPlotForHelicopter == FALSE ) ) { // abort AbortMovementPlottingMode(); } } else // not in airspace mode { if( fPlotForHelicopter == TRUE ) { // abort AbortMovementPlottingMode(); } } } void ContractRegionBtnCallback( MOUSE_REGION *pRegion, INT32 iReason ) { SOLDIERTYPE *pSoldier = NULL; // btn callback handler for contract region if( ( iDialogueBox != -1 ) ) { return; } if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( CanExtendContractForCharSlot( bSelectedInfoChar ) ) { pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]; // create RebuildContractBoxForMerc( pSoldier ); // reset selected characters ResetAllSelectedCharacterModes( ); bSelectedContractChar = bSelectedInfoChar; giContractHighLine = bSelectedContractChar; // if not triggered internally if ( CheckIfSalaryIncreasedAndSayQuote( pSoldier, TRUE ) == FALSE ) { // show contract box fShowContractMenu = TRUE; // stop any active dialogue StopAnyCurrentlyTalkingSpeech( ); } //fCharacterInfoPanelDirty = TRUE; } else { // reset selected characters ResetAllSelectedCharacterModes( ); } } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { // reset selected characters ResetAllSelectedCharacterModes( ); } } void ContractRegionMvtCallback( MOUSE_REGION *pRegion, INT32 iReason ) { // mvt callback handler for contract region if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { if( fGlowContractRegion == TRUE ) { // not showing box and lost mouse?..stop glowing if( fShowContractMenu == FALSE ) { fGlowContractRegion = FALSE; fCharacterInfoPanelDirty = TRUE; giContractHighLine = -1; // reset glow fResetContractGlow = TRUE; } } } else if( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { if( bSelectedInfoChar != -1 ) { if( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) { if( fShowContractMenu == FALSE ) { // glow region fGlowContractRegion = TRUE; giContractHighLine = bSelectedInfoChar; PlayGlowRegionSound( ); } } } } } void HandleShadingOfLinesForContractMenu( void ) { SOLDIERTYPE *pSoldier; MERCPROFILESTRUCT *pProfile; if( ( fShowContractMenu == FALSE ) || ( ghContractBox == - 1 ) ) { return; } // error check, return if not a valid character if( bSelectedContractChar == -1 ) { return; } // check if this character is a valid character if( gCharactersList[ bSelectedContractChar ].fValid == FALSE ) { return; } Assert( CanExtendContractForCharSlot( bSelectedContractChar ) ); // grab the character pSoldier = &Menptr[ gCharactersList[ bSelectedContractChar ].usSolID ]; // is guy in AIM? and well enough to talk and make such decisions? if( ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC ) && ( pSoldier->bLife >= OKLIFE ) ) { pProfile = &( gMercProfiles[ pSoldier->ubProfile ] ); // one day if( pProfile->sSalary > LaptopSaveInfo.iCurrentBalance ) { ShadeStringInBox( ghContractBox, CONTRACT_MENU_DAY ); } else { UnShadeStringInBox( ghContractBox, CONTRACT_MENU_DAY ); } // one week if( ( INT32 )( pProfile->uiWeeklySalary ) > LaptopSaveInfo.iCurrentBalance ) { ShadeStringInBox( ghContractBox, CONTRACT_MENU_WEEK ); } else { UnShadeStringInBox( ghContractBox, CONTRACT_MENU_WEEK ); } // two weeks if( ( INT32 )( pProfile->uiBiWeeklySalary ) > LaptopSaveInfo.iCurrentBalance ) { ShadeStringInBox( ghContractBox, CONTRACT_MENU_TWO_WEEKS ); } else { UnShadeStringInBox( ghContractBox, CONTRACT_MENU_TWO_WEEKS ); } } else { // can't extend contract duration ShadeStringInBox( ghContractBox, CONTRACT_MENU_DAY ); ShadeStringInBox( ghContractBox, CONTRACT_MENU_WEEK ); ShadeStringInBox( ghContractBox, CONTRACT_MENU_TWO_WEEKS ); } // if THIS soldier is involved in a fight (dismissing in a hostile sector IS ok...) if( ( gTacticalStatus.uiFlags & INCOMBAT ) && pSoldier->bInSector ) { ShadeStringInBox( ghContractBox, CONTRACT_MENU_TERMINATE ); } else { UnShadeStringInBox( ghContractBox, CONTRACT_MENU_TERMINATE ); } } void ReBuildCharactersList( void ) { // rebuild character's list INT16 sCount = 0; // add in characters for ( sCount = 0; sCount < MAX_CHARACTER_COUNT; sCount++) { // clear this slot gCharactersList[ sCount ].fValid = FALSE; gCharactersList[ sCount ].usSolID = 0; } for ( sCount = 0; sCount < MAX_CHARACTER_COUNT; sCount++) { // add character into the cleared slot AddCharacter( &Menptr[ gTacticalStatus.Team[ OUR_TEAM ].bFirstID + sCount ] ); } // sort them according to current sorting method SortListOfMercsInTeamPanel( FALSE ); // if nobody is selected, or the selected merc has somehow become invalid if ( ( bSelectedInfoChar == -1 ) || ( !gCharactersList[ bSelectedInfoChar ].fValid ) ) { // is the first character in the list valid? if ( gCharactersList[ 0 ].fValid ) { // select him ChangeSelectedInfoChar( 0, TRUE ); } else { // select no one ChangeSelectedInfoChar( -1, TRUE ); } } // exit inventory mode fShowInventoryFlag = FALSE; // switch hand region help text to "Enter Inventory" SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] ); } void HandleChangeOfInfoChar( void ) { static INT8 bOldInfoChar = -1; if( bSelectedInfoChar != bOldInfoChar ) { // set auto faces inactive // valid character? if( bOldInfoChar != -1 ) { if( gCharactersList[ bOldInfoChar ].fValid == TRUE ) { // set face in active SetAutoFaceInActiveFromSoldier( Menptr[ gCharactersList[ bOldInfoChar ].usSolID ].ubID ); } } // stop showing contract box //fShowContractMenu = FALSE; // update old info char value bOldInfoChar = bSelectedInfoChar; } } void RebuildContractBoxForMerc( SOLDIERTYPE *pCharacter ) { // rebuild contractbox for this merc RemoveBox( ghContractBox ); ghContractBox = -1; // recreate CreateContractBox( pCharacter ); return; } void TestMessageSystem( void ) { INT32 iCounter = 0; for( iCounter = 0; iCounter < 300; iCounter++ ) { MapScreenMessage( FONT_MCOLOR_DKRED, MSG_INTERFACE, L"%d", iCounter ); } MapScreenMessage( FONT_MCOLOR_DKRED, MSG_INTERFACE, L"%d", iCounter ); return; } void EnableDisableTeamListRegionsAndHelpText( void ) { // check if valid character here, if so, then do nothing..other wise set help text timer to a gazillion INT8 bCharNum; for( bCharNum = 0; bCharNum < MAX_CHARACTER_COUNT; bCharNum++ ) { if( gCharactersList[ bCharNum ].fValid == FALSE ) { // disable regions in all team list columns MSYS_DisableRegion( &gTeamListNameRegion[ bCharNum ] ); MSYS_DisableRegion( &gTeamListAssignmentRegion[ bCharNum ] ); MSYS_DisableRegion( &gTeamListLocationRegion[ bCharNum ] ); MSYS_DisableRegion( &gTeamListSleepRegion[ bCharNum ] ); MSYS_DisableRegion( &gTeamListDestinationRegion[ bCharNum ] ); MSYS_DisableRegion( &gTeamListContractRegion[ bCharNum ] ); } else { // always enable Name and Location regions MSYS_EnableRegion( &gTeamListNameRegion[ bCharNum ] ); MSYS_EnableRegion( &gTeamListLocationRegion[ bCharNum ] ); // valid character. If it's a vehicle, however if ( Menptr[ gCharactersList[ bCharNum ].usSolID ].uiStatusFlags & SOLDIER_VEHICLE ) { // Can't change assignment for vehicles MSYS_DisableRegion( &gTeamListAssignmentRegion[ bCharNum ] ); } else { MSYS_EnableRegion( &gTeamListAssignmentRegion[ bCharNum ] ); // POW or dead ? if ( ( Menptr[ gCharactersList[ bCharNum ].usSolID ].bAssignment == ASSIGNMENT_POW ) || ( Menptr[ gCharactersList[ bCharNum ].usSolID ].bLife == 0 ) ) { // "Remove Merc" SetRegionFastHelpText( &gTeamListAssignmentRegion[ bCharNum ], pRemoveMercStrings[ 0 ] ); SetRegionFastHelpText( &gTeamListDestinationRegion[ bCharNum ], L"" ); } else { // "Assign Merc" SetRegionFastHelpText( &gTeamListAssignmentRegion[ bCharNum ], pMapScreenMouseRegionHelpText[ 1 ] ); // "Plot Travel Route" SetRegionFastHelpText( &gTeamListDestinationRegion[ bCharNum ], pMapScreenMouseRegionHelpText[ 2 ] ); } } if ( CanExtendContractForCharSlot( bCharNum ) ) { MSYS_EnableRegion( &gTeamListContractRegion[ bCharNum ] ); } else { MSYS_DisableRegion( &gTeamListContractRegion[ bCharNum ] ); } if ( CanChangeSleepStatusForCharSlot( bCharNum ) ) { MSYS_EnableRegion( &gTeamListSleepRegion[ bCharNum ] ); } else { MSYS_DisableRegion( &gTeamListSleepRegion[ bCharNum ] ); } // destination region is always enabled for all valid character slots. // if the character can't move at this time, then the region handler must be able to tell the player why not MSYS_EnableRegion( &gTeamListDestinationRegion[ bCharNum ] ); } } } void ResetAllSelectedCharacterModes( void ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } // if in militia redistribution popup if ( sSelectedMilitiaTown != 0 ) { sSelectedMilitiaTown = 0; } // cancel destination line highlight giDestHighLine = -1; // cancel assign line highlight giAssignHighLine = -1; // unhilight contract line giContractHighLine = -1; // if we were plotting movement if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode(); } // reset assign character bSelectedAssignChar = -1; // reset contract character bSelectedContractChar = -1; // reset map cursor to normal if ( !gfFadeOutDone && !gfFadeIn ) { SetUpCursorForStrategicMap( ); } return; } void UpdatePausedStatesDueToTimeCompression( void ) { // this executes every frame, so keep it optimized for speed! // if time is being compressed if( IsTimeBeingCompressed() ) { // but it shouldn't be if ( !AllowedToTimeCompress( ) ) { // pause game to (temporarily) stop time compression PauseGame( ); } } else // time is NOT being compressed { // but the player would like it to be compressing if ( IsTimeCompressionOn() && !gfPauseDueToPlayerGamePause ) { // so check if it's legal to start time compressing again if ( AllowedToTimeCompress( ) ) { // unpause game to restart time compresssion UnPauseGame( ); } } } return; } BOOLEAN ContinueDialogue(SOLDIERTYPE *pSoldier, BOOLEAN fDone ) { // continue this grunts dialogue, restore when done static INT8 bOldSelectedInfoChar = -1; static BOOLEAN fTalkingingGuy = FALSE; INT8 bCounter = 0; if( fDone == TRUE ) { if( fTalkingingGuy == TRUE ) { /* // done, restore if( bOldSelectedInfoChar != -1 ) { ChangeSelectedInfoChar( bOldSelectedInfoChar, TRUE ); SetAutoFaceInActive( MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]->iFaceIndex ); } */ fCharacterInfoPanelDirty = TRUE; fTalkingingGuy = FALSE; } return( TRUE ); } // check if valid character talking? if( pSoldier == NULL ) { return FALSE; } // otherwise, find this character for( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++ ) { if( gCharactersList[bCounter].fValid == TRUE ) { if( ( &Menptr[gCharactersList[bCounter].usSolID]) == pSoldier ) { if( bSelectedInfoChar != bCounter ) { bOldSelectedInfoChar = bSelectedInfoChar; ChangeSelectedInfoChar( bCounter, TRUE ); } fTalkingingGuy = TRUE; return ( FALSE ); } } } return ( FALSE ); } void HandleSpontanousTalking( ) { // simply polls if the talking guy is done, if so...send an end command to continue dialogue if( DialogueActive() == FALSE ) { if( ( bSelectedInfoChar != -1 ) && ( bSelectedInfoChar < MAX_CHARACTER_COUNT ) ) { ContinueDialogue( ( &Menptr[gCharactersList[bSelectedInfoChar].usSolID] ), TRUE ); } } return; } BOOLEAN CheckIfClickOnLastSectorInPath( INT16 sX, INT16 sY ) { PathStPtr *ppMovePath = NULL; BOOLEAN fLastSectorInPath = FALSE; INT32 iVehicleId = -1; PathStPtr pPreviousMercPath = NULL; // see if we have clicked on the last sector in the characters path // check if helicopter if( fPlotForHelicopter == TRUE ) { if( sX + ( sY * MAP_WORLD_X ) == GetLastSectorOfHelicoptersPath( ) ) { // helicopter route confirmed - take off TakeOffHelicopter( ); // rebuild waypoints - helicopter ppMovePath = &( pVehicleList[ iHelicopterVehicleId ].pMercPath ); RebuildWayPointsForGroupPath( *ppMovePath, pVehicleList[ iHelicopterVehicleId ].ubMovementGroup ); // pointer to previous helicopter path pPreviousMercPath = gpHelicopterPreviousMercPath; fLastSectorInPath = TRUE; } } else // not doing helicopter movement { // if not doing a soldier either, we shouldn't be here! if( bSelectedDestChar == -1 ) { return( FALSE ); } // invalid soldier? we shouldn't be here! if( gCharactersList[ bSelectedDestChar ].fValid == FALSE ) { bSelectedDestChar = -1; return( FALSE ); } if( sX + ( sY * MAP_WORLD_X ) == GetLastSectorIdInCharactersPath( ( &Menptr[ gCharactersList[ bSelectedDestChar ].usSolID ] ) ) ) { // clicked on last sector, reset plotting mode // if he's IN a vehicle or IS a vehicle if( ( Menptr[gCharactersList[ bSelectedDestChar ].usSolID].bAssignment == VEHICLE ) || ( Menptr[gCharactersList[ bSelectedDestChar ].usSolID].uiStatusFlags & SOLDIER_VEHICLE ) ) { if( Menptr[gCharactersList[ bSelectedDestChar ].usSolID].bAssignment == VEHICLE ) { // IN a vehicle iVehicleId = Menptr[gCharactersList[ bSelectedDestChar ].usSolID].iVehicleId; } else { // IS a vehicle iVehicleId = Menptr[gCharactersList[ bSelectedDestChar ].usSolID].bVehicleID; } // rebuild waypoints - vehicles ppMovePath = &( pVehicleList[ iVehicleId ].pMercPath ); } else { // rebuild waypoints - mercs on foot ppMovePath = &( Menptr[gCharactersList[ bSelectedDestChar ].usSolID].pMercPath ); } RebuildWayPointsForAllSelectedCharsGroups( ); // pointer to previous character path pPreviousMercPath = gpCharacterPreviousMercPath[ bSelectedDestChar ]; fLastSectorInPath = TRUE; } } // if the click was over the last sector if ( fLastSectorInPath ) { // route has been confirmed EndConfirmMapMoveMode( ); // if we really did plot a path (this will skip message if left click on current sector with no path) if ( GetLengthOfPath( *ppMovePath ) > 0 ) { // then verbally confirm this destination! HandleNewDestConfirmation( sX, sY ); } else // NULL path confirmed { // if previously there was a path if ( pPreviousMercPath != NULL ) { // then this means we've CANCELED it MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pMapPlotStrings[ 3 ] ); } else // no previous path { // then it means the route was UNCHANGED MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pMapPlotStrings[ 2 ] ); } } } return( fLastSectorInPath ); } void RebuildWayPointsForAllSelectedCharsGroups( void ) { // rebuild the waypoints for everyone in the selected character list INT32 iCounter = 0; BOOLEAN fGroupIDRebuilt[ 256 ]; SOLDIERTYPE *pSoldier = NULL; INT32 iVehicleId; PathStPtr *ppMovePath = NULL; UINT8 ubGroupId; memset( fGroupIDRebuilt, FALSE, sizeof( fGroupIDRebuilt ) ); for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) ) { pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; // if he's IN a vehicle or IS a vehicle if( ( pSoldier->bAssignment == VEHICLE ) || ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) { if( pSoldier->bAssignment == VEHICLE ) { // IN a vehicle iVehicleId = pSoldier->iVehicleId; } else { // IS a vehicle iVehicleId = pSoldier->bVehicleID; } // vehicles ppMovePath = &( pVehicleList[ iVehicleId ].pMercPath ); ubGroupId = pVehicleList[ iVehicleId ].ubMovementGroup; } else { // mercs on foot ppMovePath = &( Menptr[gCharactersList[ bSelectedDestChar ].usSolID].pMercPath ); ubGroupId = pSoldier->ubGroupID; } // if we haven't already rebuilt this group if ( !fGroupIDRebuilt[ ubGroupId ] ) { // rebuild it now RebuildWayPointsForGroupPath( *ppMovePath, ubGroupId ); // mark it as rebuilt fGroupIDRebuilt[ ubGroupId ] = TRUE; } } } } void UpdateCursorIfInLastSector( void ) { INT16 sMapX = 0, sMapY = 0; // check to see if we are plotting a path, if so, see if we are highlighting the last sector int he path, if so, change the cursor if ( ( bSelectedDestChar != -1) || ( fPlotForHelicopter == TRUE ) ) { GetMouseMapXY(&sMapX, &sMapY); // translate screen values to map grid values for zoomed in if(fZoomFlag) { sMapX=(UINT16)iZoomX/MAP_GRID_X+sMapX; sMapX=sMapX/2; sMapY=(UINT16)iZoomY/MAP_GRID_Y+sMapY; sMapY=sMapY/2; } if( fShowAircraftFlag == FALSE ) { if( bSelectedDestChar != -1 ) { //c heck if we are in the last sector of the characters path? if( sMapX + ( sMapY * MAP_WORLD_X ) == GetLastSectorIdInCharactersPath( ( &Menptr[ gCharactersList[ bSelectedDestChar ].usSolID ] ) ) ) { // set cursor to checkmark ChangeMapScreenMaskCursor( CURSOR_CHECKMARK ); } else if( fCheckCursorWasSet ) { // reset to walking guy/vehicle SetUpCursorForStrategicMap( ); } } } else { // check for helicopter if( fPlotForHelicopter ) { if( sMapX + ( sMapY * MAP_WORLD_X ) == GetLastSectorOfHelicoptersPath( ) ) { // set cursor to checkmark ChangeMapScreenMaskCursor( CURSOR_CHECKMARK ); } else if( fCheckCursorWasSet ) { // reset to walking guy/vehicle SetUpCursorForStrategicMap( ); } } else { // reset to walking guy/vehicle SetUpCursorForStrategicMap( ); } } } return; } void FaceRegionBtnCallback( MOUSE_REGION *pRegion, INT32 iReason ) { // error checking, make sure someone is there if( bSelectedInfoChar == -1 ) { return; } else if( gCharactersList[ bSelectedInfoChar ].fValid == FALSE ) { return; } if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( gfPreBattleInterfaceActive == TRUE ) { return; } // now stop any dialogue in progress StopAnyCurrentlyTalkingSpeech( ); } if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { RequestToggleMercInventoryPanel(); } } void FaceRegionMvtCallback( MOUSE_REGION *pRegion, INT32 iReason ) { if( bSelectedInfoChar == -1 ) { fShowFaceHightLight = FALSE; return; } else if( gCharactersList[ bSelectedInfoChar ].fValid == FALSE ) { fShowFaceHightLight = FALSE; return; } if( ( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) ) { fShowFaceHightLight = TRUE; } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { fShowFaceHightLight = FALSE; } } void ItemRegionBtnCallback( MOUSE_REGION *pRegion, INT32 iReason ) { // left AND right button are handled the same way if (iReason & ( MSYS_CALLBACK_REASON_RBUTTON_UP | MSYS_CALLBACK_REASON_LBUTTON_UP ) ) { RequestToggleMercInventoryPanel(); } } void ItemRegionMvtCallback( MOUSE_REGION *pRegion, INT32 iReason ) { if ( !CanToggleSelectedCharInventory() ) { fShowItemHighLight = FALSE; return; } if( ( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) ) { fShowItemHighLight = TRUE; } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { fShowItemHighLight = FALSE; } } void HandleChangeOfHighLightedLine( void ) { static INT32 iOldHighLine; if ( fShowInventoryFlag ) { return; } // check if change in highlight line if( giHighLine != iOldHighLine ) { iOldHighLine = giHighLine; if( giHighLine == -1 ) { giSleepHighLine = -1; giAssignHighLine = -1; giContractHighLine = -1; giSleepHighLine = -1; // don't do during plotting, allowing selected character to remain highlighted and their destination column to glow! if( ( bSelectedDestChar == -1 ) && ( fPlotForHelicopter == FALSE ) ) { giDestHighLine = -1; } } fDrawCharacterList = TRUE; } } void UpdateTownMinePopUpDisplay( void ) { if ( gMapViewRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { ForceUpDateOfBox( ghTownMineBox ); MapscreenMarkButtonsDirty(); } } void HandleCharBarRender( void ) { // check if the panel is disbled, if so, do not render if( ( bSelectedInfoChar !=-1) && ( fDisableDueToBattleRoster == FALSE ) ) { // valid character?...render if( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) { //if( !( ( fShowContractMenu)||( fShowAssignmentMenu ) ) ) //{ // draw bars for them DrawCharBars( ); UpdateCharRegionHelpText( ); //} } } } // update the status of the contract box void UpDateStatusOfContractBox( void ) { if( fShowContractMenu == TRUE ) { ForceUpDateOfBox( ghContractBox ); if( ( Menptr[gCharactersList[ bSelectedInfoChar ].usSolID].bLife == 0 )||( Menptr[gCharactersList[bSelectedInfoChar].usSolID].bAssignment == ASSIGNMENT_POW ) ) { ForceUpDateOfBox( ghRemoveMercAssignBox ); } } return; } void DestroyTheItemInCursor( ) { // actually destroy this item // End Item pickup MAPEndItemPointer( ); gpItemPointer = NULL; } void TrashItemMessageBoxCallBack( UINT8 bExitValue ) { if( bExitValue == MSG_BOX_RETURN_YES ) { // find the item and get rid of it DestroyTheItemInCursor( ); // reset cursor MSYS_ChangeRegionCursor( &gSMPanelRegion , CURSOR_NORMAL ); SetCurrentCursorFromDatabase( CURSOR_NORMAL ); HandleButtonStatesWhileMapInventoryActive( ); } } void TrashCanBtnCallback( MOUSE_REGION *pRegion, INT32 iReason) { if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } // check if an item is in the cursor, if so, warn player if( gpItemPointer != NULL ) { // set up for mapscreen if( gpItemPointer -> ubMission ) { DoMapMessageBox( MSG_BOX_BASIC_STYLE, pTrashItemText[ 1 ], MAP_SCREEN, MSG_BOX_FLAG_YESNO, TrashItemMessageBoxCallBack ); } else { DoMapMessageBox( MSG_BOX_BASIC_STYLE, pTrashItemText[ 0 ], MAP_SCREEN, MSG_BOX_FLAG_YESNO, TrashItemMessageBoxCallBack ); } } } } void TrashCanMoveCallback( MOUSE_REGION *pRegion, INT32 iReason) { if (iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { if( gMPanelRegion.Cursor == EXTERN_CURSOR ) { fShowTrashCanHighLight = TRUE; } } else if( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) { fShowTrashCanHighLight = FALSE; } } void MapInvDoneButtonfastHelpCall( ) { SetPendingNewScreen( LAPTOP_SCREEN ); } void UpdateStatusOfMapSortButtons( void ) { INT32 iCounter = 0; static BOOLEAN fShownLastTime = FALSE; if( ( gfPreBattleInterfaceActive ) || fShowInventoryFlag ) { if ( fShownLastTime ) { for( iCounter = 0; iCounter < MAX_SORT_METHODS; iCounter++ ) { HideButton( giMapSortButton[ iCounter ] ); } if ( gfPreBattleInterfaceActive ) { HideButton( giCharInfoButton[ 0 ] ); HideButton( giCharInfoButton[ 1 ] ); } fShownLastTime = FALSE; } } else { if ( !fShownLastTime ) { for( iCounter = 0; iCounter < MAX_SORT_METHODS; iCounter++ ) { ShowButton( giMapSortButton[ iCounter ] ); } ShowButton( giCharInfoButton[ 0 ] ); ShowButton( giCharInfoButton[ 1 ] ); fShownLastTime = TRUE; } } } INT8 GetLastValidCharacterInTeamPanelList( void ) { INT8 iCounter = 0, iValue = 0; // run through the list and find the last valid guy in the list for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( gCharactersList[ iCounter ].fValid == TRUE ) { if(( Menptr[ gCharactersList[ iCounter ].usSolID ].bLife >= OKLIFE ) ) { if( fShowMapInventoryPool ) { if( Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorX == sSelMapX && Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorY == sSelMapY && Menptr[ gCharactersList[ iCounter ].usSolID ].bSectorZ == ( INT8 )( iCurrentMapSectorZ ) ) { iValue = iCounter; } } else { if( fShowInventoryFlag && ( gMPanelRegion.Cursor == EXTERN_CURSOR ) ) { if( bSelectedInfoChar != -1 ) { if( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) { if( Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorX == Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].sSectorX && Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorY == Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].sSectorY && Menptr[ gCharactersList[ iCounter ].usSolID ].bSectorZ ==Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].bSectorZ ) { iValue = iCounter; } } } } else { iValue = iCounter; } } } } } // return the character return( iValue ); } /* // NB These functions weren't being called anywhere! Use GoToNextCharacterInList etc instead INT8 GetPrevValidCharacterInTeamPanelList( INT8 bCurrentIndex ) { INT8 iCounter = bCurrentIndex, iValue = 0; // run through the list and find the last valid guy in the list for( iCounter = bCurrentIndex; iCounter > 0; iCounter-- ) { if( gCharactersList[ iCounter ].fValid == TRUE ) { if( ( Menptr[ gCharactersList[ iCounter ].usSolID ].bLife >= OKLIFE ) ) { if( fShowMapInventoryPool ) { if( Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorX == sSelMapX && Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorY == sSelMapY && Menptr[ gCharactersList[ iCounter ].usSolID ].bSectorZ == ( INT8 )( iCurrentMapSectorZ ) ) { iValue = iCounter; } } else { if( fShowInventoryFlag && ( gMPanelRegion.Cursor == EXTERN_CURSOR ) ) { if( bSelectedInfoChar != -1 ) { if( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) { if( Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorX == Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].sSectorX && Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorY == Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].sSectorY && Menptr[ gCharactersList[ iCounter ].usSolID ].bSectorZ ==Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].bSectorZ ) { iValue = iCounter; iCounter = 0; } } } } else { iValue = iCounter; } } } } } // return the character return( iValue ); } INT8 GetNextValidCharacterInTeamPanelList( INT8 bCurrentIndex ) { INT8 iCounter = bCurrentIndex, iValue = 0; // run through the list and find the last valid guy in the list for( iCounter = bCurrentIndex; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( gCharactersList[ iCounter ].fValid == TRUE ) { if( ( Menptr[ gCharactersList[ iCounter ].usSolID ].bLife >= OKLIFE ) ) { if( fShowMapInventoryPool ) { if( Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorX == sSelMapX && Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorY == sSelMapY && Menptr[ gCharactersList[ iCounter ].usSolID ].bSectorZ == ( INT8 )( iCurrentMapSectorZ ) ) { iValue = iCounter; } } else { if( fShowInventoryFlag && ( gMPanelRegion.Cursor == EXTERN_CURSOR ) ) { if( bSelectedInfoChar != -1 ) { if( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) { if( Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorX == Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].sSectorX && Menptr[ gCharactersList[ iCounter ].usSolID ].sSectorY == Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].sSectorY && Menptr[ gCharactersList[ iCounter ].usSolID ].bSectorZ ==Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ].bSectorZ ) { iValue = iCounter; } } } } else { iValue = iCounter; } } } } } // return the character return( iValue ); } */ void CreateDestroyTrashCanRegion( void ) { static BOOLEAN fCreated = FALSE; if( fShowInventoryFlag && ( fCreated == FALSE ) ) { fCreated = TRUE; // trash can MSYS_DefineRegion( &gTrashCanRegion, TRASH_CAN_X, TRASH_CAN_Y, TRASH_CAN_X + TRASH_CAN_WIDTH, TRASH_CAN_Y + TRASH_CAN_HEIGHT , MSYS_PRIORITY_HIGHEST - 4 , MSYS_NO_CURSOR, TrashCanMoveCallback, TrashCanBtnCallback ); // done inventory button define giMapInvButtonDoneImage = LoadButtonImage( "INTERFACE\\done_button2.sti" ,-1,0,-1,1,-1 ); giMapInvDoneButton = QuickCreateButton( giMapInvButtonDoneImage, INV_BTN_X, INV_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, ( GUI_CALLBACK )BtnGenericMouseMoveButtonCallback, ( GUI_CALLBACK)DoneInventoryMapBtnCallback ); SetButtonFastHelpText( giMapInvDoneButton ,pMiscMapScreenMouseRegionHelpText[ 2 ] ); SetRegionFastHelpText( &gTrashCanRegion, pMiscMapScreenMouseRegionHelpText[ 1 ] ); InitMapKeyRingInterface( KeyRingItemPanelButtonCallback ); /* giMapInvNextImage= LoadButtonImage( "INTERFACE\\inventory_buttons.sti" ,-1,20,-1,22,-1 ); giMapInvNext= QuickCreateButton( giMapInvNextImage, ( 2 ), ( 79 ) , BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, ( GUI_CALLBACK )BtnGenericMouseMoveButtonCallback, ( GUI_CALLBACK)NextInventoryMapBtnCallback ); giMapInvPrevImage= LoadButtonImage( "INTERFACE\\inventory_buttons.sti" ,-1,21,-1,23,-1 ); giMapInvPrev= QuickCreateButton( giMapInvPrevImage, ( 30 ) , ( 79 ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, ( GUI_CALLBACK )BtnGenericMouseMoveButtonCallback, ( GUI_CALLBACK)PrevInventoryMapBtnCallback ); */ // reset the compatable item array at this point ResetCompatibleItemArray( ); } else if( ( fShowInventoryFlag == FALSE ) && ( fCreated == TRUE ) ) { // trash can region fCreated = FALSE; MSYS_RemoveRegion( &gTrashCanRegion ); // map inv done button RemoveButton( giMapInvDoneButton ); // get rid of button image UnloadButtonImage( giMapInvButtonDoneImage ); ShutdownKeyRingInterface( ); if( fShowDescriptionFlag == TRUE ) { // kill description DeleteItemDescriptionBox( ); } } } void InvmaskRegionBtnCallBack( MOUSE_REGION *pRegion, INT32 iReason ) { // CJC, December 15 1998: do NOTHING for clicks here } void DoneInventoryMapBtnCallback( GUI_BUTTON *btn, INT32 reason ) { // prevent inventory from being closed while stack popup up! if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { btn->uiFlags|=(BUTTON_CLICKED_ON); } else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { if (btn->uiFlags & BUTTON_CLICKED_ON) { btn->uiFlags&= ~(BUTTON_CLICKED_ON); if ( gMPanelRegion.Cursor != EXTERN_CURSOR && !InItemStackPopup() ) { fEndShowInventoryFlag = TRUE; } } } } void StartConfirmMapMoveMode( INT16 sMapY ) { UINT8 ubPosition = ( sMapY < 8 ) ? MSG_MAP_UI_POSITION_LOWER : MSG_MAP_UI_POSITION_UPPER; // tell player what to do - to click again to confirm move MapScreenMessage( FONT_MCOLOR_LTYELLOW, ubPosition, pMapPlotStrings[ 0 ] ); gfInConfirmMapMoveMode = TRUE; } void EndConfirmMapMoveMode( void ) { CancelMapUIMessage( ); gfInConfirmMapMoveMode = FALSE; } void CancelMapUIMessage( void ) { // and kill the message overlay EndUIMessage( ); fMapPanelDirty = TRUE; } // automatically turns off mapscreen ui overlay messages when appropriate void MonitorMapUIMessage( void ) { // if there is a map UI message being displayed if( giUIMessageOverlay != -1 ) { // and if we're not in the middle of the "confirm move" sequence // if( !gfInConfirmMapMoveMode || bSelectedDestChar == -1 ) { // and we've now exceed its period of maximum persistance (without user input) if ( ( GetJA2Clock( ) - guiUIMessageTime ) > guiUIMessageTimeDelay ) { // then cancel the message now CancelMapUIMessage( ); } } } } void HandlePreBattleInterfaceWithInventoryPanelUp( void ) { if( ( gfPreBattleInterfaceActive == TRUE ) && ( fShowInventoryFlag == TRUE ) ) { if( fShowDescriptionFlag == TRUE ) { // kill description DeleteItemDescriptionBox( ); } // kill inventory panel fShowInventoryFlag = FALSE; CreateDestroyMapInvButton(); } } // this puts anyone who is on NO_ASSIGNMENT onto a free squad void UpdateBadAssignments( void ) { UINT32 iCounter; for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( gCharactersList[ iCounter ].fValid == TRUE ) { CheckIfSoldierUnassigned( &Menptr[ gCharactersList[ iCounter ].usSolID ] ); } } return; } void InterruptTimeForMenus( void ) { if( ( fShowAssignmentMenu == TRUE )||( fShowContractMenu == TRUE ) ) { InterruptTime( ); PauseTimeForInterupt( ); } else if( fOneFrame ) { InterruptTime( ); PauseTimeForInterupt( ); } return; } void HandleContractTimeFlashForMercThatIsAboutLeave( void ) { INT32 iCurrentTime; // grab the current time iCurrentTime = GetJA2Clock(); // only bother checking once flash interval has elapsed if( ( iCurrentTime - giFlashContractBaseTime ) >= DELAY_PER_FLASH_FOR_DEPARTING_PERSONNEL ) { // update timer so that we only run check so often giFlashContractBaseTime = iCurrentTime; fFlashContractFlag = !fFlashContractFlag; // don't redraw unless we have to! if ( AnyMercsLeavingRealSoon() ) { // redraw character list fDrawCharacterList = TRUE; } } } BOOLEAN AnyMercsLeavingRealSoon() { UINT32 uiCounter = 0; UINT32 uiTimeInMin = GetWorldTotalMin(); BOOLEAN fFoundOne = FALSE; for( uiCounter = 0; uiCounter < MAX_CHARACTER_COUNT; uiCounter++ ) { if( gCharactersList[ uiCounter ].fValid == TRUE ) { if( ( Menptr[gCharactersList[uiCounter].usSolID].iEndofContractTime - uiTimeInMin ) <= MINS_TO_FLASH_CONTRACT_TIME ) { fFoundOne = TRUE; break; } } } return( fFoundOne ); } BOOLEAN HandlePreloadOfMapGraphics( void ) { // check amt of memory, if above required amt...use it VSURFACE_DESC vs_desc; VOBJECT_DESC VObjectDesc; fPreLoadedMapGraphics = TRUE; vs_desc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE; strcpy(vs_desc.ImageFile, "INTERFACE\\b_map.pcx"); CHECKF(AddVideoSurface(&vs_desc, &guiBIGMAP)); //strcpy(vs_desc.ImageFile, "INTERFACE\\popupbackground.pcx"); //CHECKF(AddVideoSurface(&vs_desc, &guiPOPUPTEX)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mapcursr.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMAPCURSORS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\SAM.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSAMICON)); // VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; // FilenameForBPP("INTERFACE\\s_map.sti", VObjectDesc.ImageFile); // CHECKF( AddVideoObject( &VObjectDesc, &guiMAP ) ); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mapcursr.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMAPCURSORS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\sleepicon.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSleepIcon)); //VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; //FilenameForBPP("INTERFACE\\addonslcp.sti", VObjectDesc.ImageFile); //CHECKF(AddVideoObject(&VObjectDesc, &guiCORNERADDONS)); //VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; //FilenameForBPP("INTERFACE\\mapborder.sti", VObjectDesc.ImageFile); //CHECKF(AddVideoObject(&VObjectDesc, &guiMAPBORDER)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\charinfo.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARINFO)); /*strcpy(vs_desc.ImageFile, "INTERFACE\\playlist3.pcx"); CHECKF(AddVideoSurface( &vs_desc, &guiCHARLIST ));*/ VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; if (iResolution == 0) { FilenameForBPP("INTERFACE\\newgoldpiece3.sti", VObjectDesc.ImageFile ); } else if (iResolution == 1) { FilenameForBPP("INTERFACE\\newgoldpiece3_800x600.sti", VObjectDesc.ImageFile ); } else if (iResolution == 2) { FilenameForBPP("INTERFACE\\newgoldpiece3_1024x768.sti", VObjectDesc.ImageFile ); } CHECKF(AddVideoObject(&VObjectDesc, &guiCHARLIST)); //VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; //FilenameForBPP("INTERFACE\\mapbordercorner.sti", VObjectDesc.ImageFile); //CHECKF(AddVideoObject(&VObjectDesc, &guiMAPCORNER)); // VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; // FilenameForBPP("INTERFACE\\popup.sti", VObjectDesc.ImageFile); // CHECKF(AddVideoObject(&VObjectDesc, &guiPOPUPBORDERS)); // the sublevels VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Mine_1.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSubLevel1)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Mine_2.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSubLevel2)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Mine_3.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSubLevel3)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\boxes.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARICONS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\incross.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCROSS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mapinv.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMAPINV)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\map_inv_2nd_gun_cover.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMapInvSecondHandBlockout)); // the upper left corner piece icons VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\top_left_corner_icons.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiULICONS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\prison.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiTIXAICON)); HandleLoadOfMapBottomGraphics( ); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\map_item.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiORTAICON)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mapcursr.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMAPCURSORS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\merc_between_sector_icons.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARBETWEENSECTORICONS)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\merc_mvt_green_arrows.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiCHARBETWEENSECTORICONSCLOSE)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\GreenArr.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiLEVELMARKER)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\Helicop.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiHelicopterIcon)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\eta_pop_up.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMapBorderEtaPopUp)); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\pos2.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMapBorderHeliSectors)); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\secondary_gun_hidden.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiSecItemHiddenVO ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\selectedchararrow.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiSelectedCharArrow ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\mine.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &guiMINEICON ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; sprintf( VObjectDesc.ImageFile, "INTERFACE\\hilite.sti" ); AddVideoObject( &VObjectDesc, &guiSectorLocatorGraphicID ); //Kris: Added this because I need to blink the icons button. VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; sprintf( VObjectDesc.ImageFile, "INTERFACE\\newemail.sti" ); AddVideoObject( &VObjectDesc, &guiNewMailIcons ); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\BullsEye.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiBULLSEYE)); // graphic for pool inventory LoadInventoryPoolGraphic( ); // load border graphics LoadMapBorderGraphics( ); // load the pop up for the militia pop up box LoadMilitiaPopUpBox( ); return( TRUE ); } void HandleRemovalOfPreLoadedMapGraphics( void ) { if( fPreLoadedMapGraphics == TRUE ) { DeleteMapBottomGraphics( ); DeleteVideoObjectFromIndex( guiMAPCURSORS ); DeleteVideoObjectFromIndex( guiSleepIcon ); //DeleteVideoObjectFromIndex(guiMAPBORDER); DeleteVideoObjectFromIndex(guiCHARLIST); //DeleteVideoObjectFromIndex(guiCORNERADDONS); //DeleteVideoObjectFromIndex(guiMAPCORNER); // DeleteVideoObjectFromIndex(guiPOPUPBORDERS); DeleteVideoObjectFromIndex(guiCHARINFO); DeleteVideoObjectFromIndex(guiCHARICONS); DeleteVideoObjectFromIndex(guiCROSS); DeleteVideoSurfaceFromIndex(guiBIGMAP); DeleteVideoObjectFromIndex(guiSubLevel1); DeleteVideoObjectFromIndex(guiSubLevel2); DeleteVideoObjectFromIndex(guiSubLevel3); // DeleteVideoSurfaceFromIndex(guiPOPUPTEX); DeleteVideoObjectFromIndex(guiSAMICON); DeleteVideoObjectFromIndex(guiMAPINV); DeleteVideoObjectFromIndex(guiMapInvSecondHandBlockout); DeleteVideoObjectFromIndex(guiULICONS); DeleteVideoObjectFromIndex(guiORTAICON); DeleteVideoObjectFromIndex(guiTIXAICON); DeleteVideoObjectFromIndex( guiCHARBETWEENSECTORICONS ); DeleteVideoObjectFromIndex( guiCHARBETWEENSECTORICONSCLOSE ); DeleteVideoObjectFromIndex( guiLEVELMARKER ); DeleteVideoObjectFromIndex( guiMapBorderEtaPopUp ); DeleteVideoObjectFromIndex( guiSecItemHiddenVO ); DeleteVideoObjectFromIndex( guiSelectedCharArrow ); DeleteVideoObjectFromIndex( guiMapBorderHeliSectors ); DeleteVideoObjectFromIndex( guiHelicopterIcon ); DeleteVideoObjectFromIndex( guiMINEICON ); DeleteVideoObjectFromIndex( guiSectorLocatorGraphicID ); //Kris: Remove the email icons. DeleteVideoObjectFromIndex( guiNewMailIcons ); DeleteVideoObjectFromIndex( guiBULLSEYE ); // remove the graphic for the militia pop up box RemoveMilitiaPopUpBox( ); // remove inventory pool graphic RemoveInventoryPoolGraphic( ); // get rid of border stuff DeleteMapBorderGraphics( ); } return; } BOOLEAN CharacterIsInLoadedSectorAndWantsToMoveInventoryButIsNotAllowed( INT8 bCharId ) { UINT16 usSoldierId = 0; // invalid char id if( bCharId == -1 ) { return( FALSE ); } // valid char? if( gCharactersList[ bCharId ].fValid == FALSE ) { return( FALSE ); } // get the soldier id usSoldierId = gCharactersList[ bCharId ].usSolID; // char is in loaded sector if( Menptr[ usSoldierId ].sSectorX != gWorldSectorX || Menptr[ usSoldierId ].sSectorY != gWorldSectorY || Menptr[ usSoldierId ].bSectorZ != gbWorldSectorZ ) { return( FALSE ); } // not showing inventory? if( fShowInventoryFlag == FALSE ) { // nope return( FALSE ); } // picked something up? if( gMPanelRegion.Cursor != EXTERN_CURSOR ) { // nope return( FALSE ); } // only disallow when enemies in sector if ( !gTacticalStatus.fEnemyInSector ) { return( FALSE ); } return( TRUE ); } void UpdateTheStateOfTheNextPrevMapScreenCharacterButtons( void ) { if( gfPreBattleInterfaceActive ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); } } else if( bSelectedInfoChar == -1 ) { DisableButton( giCharInfoButton[ 0 ] ); DisableButton( giCharInfoButton[ 1 ] ); DisableButton( giMapContractButton ); } /* ARM: Commented out at KM's request, it won't reenabled them when coming back from PBI, on Feb. 22, 99 else if ( fShowInventoryFlag == FALSE ) // make sure that we are in fact showing the mapscreen inventory { return; } */ else { // standard checks if ( ( GetNumberOfPeopleInCharacterList( ) < 2 ) || ( CharacterIsInLoadedSectorAndWantsToMoveInventoryButIsNotAllowed( bSelectedInfoChar ) ) || ( CharacterIsInTransitAndHasItemPickedUp( bSelectedInfoChar ) ) || ( fShowDescriptionFlag ) ) { DisableButton( giCharInfoButton[ 0 ] ); DisableButton( giCharInfoButton[ 1 ] ); } else { EnableButton( giCharInfoButton[ 0 ] ); EnableButton( giCharInfoButton[ 1 ] ); } } } void PrevInventoryMapBtnCallback( 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 ) { if (btn->uiFlags & BUTTON_CLICKED_ON) { btn->uiFlags&= ~(BUTTON_CLICKED_ON); GoToPrevCharacterInList( ); } } } void NextInventoryMapBtnCallback( 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 ) { if (btn->uiFlags & BUTTON_CLICKED_ON) { btn->uiFlags&= ~(BUTTON_CLICKED_ON); GoToNextCharacterInList( ); } } } // WANNE: //void BtnMercsUpMapScreenCallback( GUI_BUTTON *btn,INT32 reason ) //{ // // WANNE: See Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback) // int i = 10; //} // //void BtnMercsDownMapScreenCallback( GUI_BUTTON *btn,INT32 reason ) //{ // // WANNE: See Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback) // int i = 10; //} // //void BtnVehicleUpMapScreenCallback( GUI_BUTTON *btn,INT32 reason ) //{ // // WANNE: See Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback) // int i = 10; //} // //void BtnVehicleDownMapScreenCallback( GUI_BUTTON *btn,INT32 reason ) //{ // // WANNE: See Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback) // int i = 10; //} // WANNE: //void DeleteButtonsForScrolling(void) //{ // if (fScrollButtonsInitialized == TRUE) // { // // mercs scroll buttons // RemoveButton( guiMapMercsScrollButtons[ 0 ]); // RemoveButton( guiMapMercsScrollButtons[ 1 ]); // UnloadButtonImage( guiMapMercsScrollButtonsImage[ 0 ] ); // UnloadButtonImage( guiMapMercsScrollButtonsImage[ 1 ] ); // // RemoveButton( guiMapVehicleScrollButtons[ 0 ]); // RemoveButton( guiMapVehicleScrollButtons[ 1 ]); // UnloadButtonImage( guiMapVehicleScrollButtonsImage[ 0 ] ); // UnloadButtonImage( guiMapVehicleScrollButtonsImage[ 1 ] ); // // fScrollButtonsInitialized = FALSE; // } //} // WANNE: // Create the scrolling arrows //void CreateButtonsForScrolling( void ) //{ // if (fScrollButtonsInitialized == FALSE) // { // INT32 iXPos = 247; // INT32 iMercUpY = -1; // INT32 iVehicleUpY = -1; // // if (iResolution == 0) // { // iMercUpY = 207; // iVehicleUpY = 321; // } // else if (iResolution == 1) // { // iMercUpY = 256; // iVehicleUpY = 429; // } // else if (iResolution == 2) // { // iMercUpY = 328; // iVehicleUpY = 579; // } // // // merc - scroll up // guiMapMercsScrollButtonsImage[ MAP_SCROLL_MERCS_UP ]= LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti" ,11,4,-1,6,-1 ); // guiMapMercsScrollButtons[ MAP_SCROLL_MERCS_UP ] = QuickCreateButton( guiMapMercsScrollButtonsImage[ MAP_SCROLL_MERCS_UP ], iXPos, iMercUpY, // BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, // (GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMercsUpMapScreenCallback); // // // merc - scroll down // guiMapMercsScrollButtonsImage[ MAP_SCROLL_MERCS_DOWN ]= LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti" ,12,5,-1,7,-1 ); // guiMapMercsScrollButtons[ MAP_SCROLL_MERCS_DOWN ] = QuickCreateButton( guiMapMercsScrollButtonsImage[ MAP_SCROLL_MERCS_DOWN ], iXPos, iMercUpY + 17, // BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, // (GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMercsDownMapScreenCallback); // // // vehicle - scroll up // guiMapVehicleScrollButtonsImage[ MAP_SCROLL_VEHICLE_UP ]= LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti" ,11,4,-1,6,-1 ); // guiMapVehicleScrollButtons[ MAP_SCROLL_VEHICLE_UP ] = QuickCreateButton( guiMapVehicleScrollButtonsImage[ MAP_SCROLL_VEHICLE_UP ], iXPos, iVehicleUpY, // BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, // (GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnVehicleUpMapScreenCallback); // // // vehicle - scroll down // guiMapVehicleScrollButtonsImage[ MAP_SCROLL_VEHICLE_DOWN ]= LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti" ,12,5,-1,7,-1 ); // guiMapVehicleScrollButtons[ MAP_SCROLL_VEHICLE_DOWN ] = QuickCreateButton( guiMapVehicleScrollButtonsImage[ MAP_SCROLL_VEHICLE_DOWN ], iXPos, iVehicleUpY + 17, // BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1, // (GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnVehicleDownMapScreenCallback); // // fScrollButtonsInitialized = TRUE; // } //} void CreateDestroyMapCharacterScrollButtons( void ) { static BOOLEAN fCreated = FALSE; if( ( fInMapMode == TRUE ) && ( fCreated == FALSE ) ) { // set the button image giCharInfoButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti" ,11,4,-1,6,-1 ); // set the button value giCharInfoButton[ 0 ] = QuickCreateButton( giCharInfoButtonImage[ 0 ], 67, 69, BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 5, BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)PrevInventoryMapBtnCallback ); // set the button image giCharInfoButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti" ,12,5,-1,7,-1 ); // set the button value giCharInfoButton[ 1 ] = QuickCreateButton( giCharInfoButtonImage[ 1 ], 67, 87, BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 5, BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)NextInventoryMapBtnCallback ); SetButtonFastHelpText( giCharInfoButton[ 0 ], pMapScreenPrevNextCharButtonHelpText[ 0 ] ); SetButtonFastHelpText( giCharInfoButton[ 1 ], pMapScreenPrevNextCharButtonHelpText[ 1 ] ); fCreated = TRUE; } else if( ( ( fInMapMode == FALSE ) ) && ( fCreated == TRUE ) ) { UnloadButtonImage( giCharInfoButtonImage[ 0 ] ); UnloadButtonImage( giCharInfoButtonImage[ 1 ] ); RemoveButton( giCharInfoButton[ 0 ]); RemoveButton( giCharInfoButton[ 1 ]); fCreated = FALSE; } } void TellPlayerWhyHeCantCompressTime( void ) { // if we're locked into paused time compression by some event that enforces that if ( PauseStateLocked() ) { #ifdef JA2BETAVERSION ScreenMsg( FONT_MCOLOR_RED, MSG_BETAVERSION, L"(BETA) Can't compress time, pause state locked (reason %d). OK unless permanent.", guiLockPauseStateLastReasonId ); ScreenMsg( FONT_MCOLOR_RED, MSG_BETAVERSION, L"(BETA) If permanent, take screenshot now, send with *previous* save & describe what happened since."); #endif } else if( gfAtLeastOneMercWasHired == FALSE ) { // no mercs hired, ever DoMapMessageBox( MSG_BOX_BASIC_STYLE, pMapScreenJustStartedHelpText[ 0 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } else if ( !AnyUsableRealMercenariesOnTeam() ) { // no usable mercs left on team DoMapMessageBox( MSG_BOX_BASIC_STYLE, pMapErrorString[ 39 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } else if ( ActiveTimedBombExists() ) { // can't time compress when a bomb is about to go off! DoMapMessageBox( MSG_BOX_BASIC_STYLE, gzLateLocalizedString[ 2 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } else if ( gfContractRenewalSquenceOn ) { #ifdef JA2BETAVERSION ScreenMsg( FONT_MCOLOR_RED, MSG_BETAVERSION, L"(BETA) Can't compress time while contract renewal sequence is on."); #endif } else if( fDisableMapInterfaceDueToBattle ) { #ifdef JA2BETAVERSION ScreenMsg( FONT_MCOLOR_RED, MSG_BETAVERSION, L"(BETA) Can't compress time while disabled due to battle."); #endif } else if( fDisableDueToBattleRoster ) { #ifdef JA2BETAVERSION ScreenMsg( FONT_MCOLOR_RED, MSG_BETAVERSION, L"(BETA) Can't compress time while in battle roster."); #endif } else if ( fMapInventoryItem ) { #ifdef JA2BETAVERSION ScreenMsg( FONT_MCOLOR_RED, MSG_BETAVERSION, L"(BETA) Can't compress time while still holding an inventory item."); #endif } else if( fShowMapInventoryPool ) { DoMapMessageBox( MSG_BOX_BASIC_STYLE, gzLateLocalizedString[ 55 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } // ARM: THIS TEST SHOULD BE THE LAST ONE, BECAUSE IT ACTUALLY RESULTS IN SOMETHING HAPPENING NOW. // KM: Except if we are in a creature lair and haven't loaded the sector yet (no battle yet) else if( gTacticalStatus.uiFlags & INCOMBAT || gTacticalStatus.fEnemyInSector ) { if( OnlyHostileCivsInSector() ) { CHAR16 str[ 256 ]; CHAR16 pSectorString[ 128 ]; GetSectorIDString( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, pSectorString, TRUE ); swprintf( str, gzLateLocalizedString[ 27 ], pSectorString ); DoMapMessageBox( MSG_BOX_BASIC_STYLE, str, MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } else { //The NEW non-persistant PBI is used instead of a dialog box explaining why we can't compress time. InitPreBattleInterface( NULL, FALSE ); } } else if( PlayerGroupIsInACreatureInfestedMine() ) { DoMapMessageBox( MSG_BOX_BASIC_STYLE, gzLateLocalizedString[ 28 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } } void MapScreenDefaultOkBoxCallback( UINT8 bExitValue ) { // yes, load the game if( bExitValue == MSG_BOX_RETURN_OK ) { fMapPanelDirty = TRUE; fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; } return; } void MapSortBtnCallback( GUI_BUTTON *btn, INT32 reason ) { INT32 iValue = 0; // grab the button index value for the sort buttons iValue = MSYS_GetBtnUserData( btn, 0 ); if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } btn->uiFlags|=(BUTTON_CLICKED_ON); } else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { if (btn->uiFlags & BUTTON_CLICKED_ON) { btn->uiFlags &= ~(BUTTON_CLICKED_ON); ChangeCharacterListSortMethod( iValue ); } } } void AddTeamPanelSortButtonsForMapScreen( void ) { INT32 iCounter = 0; SGPFILENAME filename; INT32 iImageIndex[ MAX_SORT_METHODS ] = { 0, 1, 5, 2, 3, 4 }; // sleep image is out or order (last) GetMLGFilename( filename, MLG_GOLDPIECEBUTTONS ); for( iCounter = 0; iCounter < MAX_SORT_METHODS; iCounter++ ) { giMapSortButtonImage[ iCounter ] = LoadButtonImage( filename, -1, iImageIndex[ iCounter ] , -1, iImageIndex[ iCounter ] + 6 , -1 ); // buttonmake giMapSortButton[ iCounter ]= QuickCreateButton( giMapSortButtonImage[ iCounter ], ( INT16 )( gMapSortButtons[ iCounter ].iX ), ( INT16 )( gMapSortButtons[ iCounter ].iY ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 5, (GUI_CALLBACK)BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)MapSortBtnCallback ); MSYS_SetBtnUserData(giMapSortButton[ iCounter ], 0, iCounter ); SetButtonFastHelpText( giMapSortButton[ iCounter ], wMapScreenSortButtonHelpText[ iCounter ] ); } return; } void SortListOfMercsInTeamPanel( BOOLEAN fRetainSelectedMercs ) { INT32 iCounter = 0, iCounterA = 0; INT16 sEndSectorA, sEndSectorB; INT32 iExpiryTime, iExpiryTimeA; BOOLEAN fEntrySelected = FALSE; SOLDIERTYPE *pSelectedSoldier[ MAX_CHARACTER_COUNT ]; SOLDIERTYPE *pCurrentSoldier = NULL; SOLDIERTYPE *pPreviousSelectedInfoChar = NULL; if ( fRetainSelectedMercs ) { // if we have anyone valid selected if ( ( bSelectedInfoChar != -1 ) && ( gCharactersList[ bSelectedInfoChar ].fValid ) ) { pPreviousSelectedInfoChar = &Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ]; } for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { // set current entry to null pSelectedSoldier[ iCounter ] = NULL; // is this entry even valid if( gCharactersList[ iCounter ].fValid == FALSE ) { continue; } // get soldier assoc. with entry pCurrentSoldier = &Menptr[ gCharactersList[ iCounter ].usSolID ]; // check if soldier is active if( pCurrentSoldier->bActive == FALSE ) { continue; } // are they selected?... if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) { // yes, store pointer to them pSelectedSoldier[ iCounter ] = pCurrentSoldier; } } } // do the sort for( iCounter = 1; iCounter < FIRST_VEHICLE ; iCounter++ ) { // have we gone too far if( gCharactersList[ iCounter ].fValid == FALSE ) { break; } switch( giSortStateForMapScreenList ) { case( 0 ): // by name for( iCounterA = 0; iCounterA < FIRST_VEHICLE; iCounterA++ ) { if( gCharactersList[ iCounterA ].fValid == FALSE ) { break; } if( ( wcscmp( Menptr[ gCharactersList[ iCounterA ].usSolID ].name, Menptr[ gCharactersList[ iCounter ].usSolID ].name ) > 0 ) && ( iCounterA < iCounter ) ) { SwapCharactersInList( iCounter, iCounterA ); } } break; case( 1 ): // by assignment for( iCounterA = 0; iCounterA < FIRST_VEHICLE; iCounterA++ ) { if( gCharactersList[ iCounterA ].fValid == FALSE ) { break; } if( ( Menptr[ gCharactersList[ iCounterA ].usSolID ].bAssignment > Menptr[ gCharactersList[ iCounter ].usSolID ].bAssignment ) && ( iCounterA < iCounter ) ) { SwapCharactersInList( iCounter, iCounterA ); } else if( ( Menptr[ gCharactersList[ iCounterA ].usSolID ].bAssignment == Menptr[ gCharactersList[ iCounter ].usSolID ].bAssignment ) && ( iCounterA < iCounter ) ) { // same assignment // if it's in a vehicle if( Menptr[ gCharactersList[ iCounterA ].usSolID ].bAssignment == VEHICLE ) { // then also compare vehicle IDs if( ( Menptr[ gCharactersList[ iCounterA ].usSolID ].iVehicleId > Menptr[ gCharactersList[ iCounter ].usSolID ].iVehicleId ) && ( iCounterA < iCounter ) ) { SwapCharactersInList( iCounter, iCounterA ); } } } } break; case( 2 ): // by sleep status for( iCounterA = 0; iCounterA < FIRST_VEHICLE; iCounterA++ ) { if( gCharactersList[ iCounterA ].fValid == FALSE ) { break; } if( ( Menptr[ gCharactersList[ iCounterA ].usSolID ].fMercAsleep == TRUE ) && ( Menptr[ gCharactersList[ iCounter ].usSolID ].fMercAsleep == FALSE ) && ( iCounterA < iCounter ) ) { SwapCharactersInList( iCounter, iCounterA ); } } break; case( 3 ): //by location sEndSectorA = CalcLocationValueForChar( iCounter ); for( iCounterA = 0; iCounterA < FIRST_VEHICLE; iCounterA++ ) { if( gCharactersList[ iCounterA ].fValid == FALSE ) { break; } sEndSectorB = CalcLocationValueForChar( iCounterA ); if( ( sEndSectorB > sEndSectorA ) && ( iCounterA < iCounter ) ) { SwapCharactersInList( iCounter, iCounterA ); } } break; case( 4 ): // by destination sector if( GetLengthOfMercPath( MercPtrs[ gCharactersList[ iCounter ].usSolID ] ) == 0 ) { sEndSectorA = 9999; } else { sEndSectorA = GetLastSectorIdInCharactersPath( &Menptr[ gCharactersList[ iCounter ].usSolID ] ); } for( iCounterA = 0; iCounterA < FIRST_VEHICLE; iCounterA++ ) { if( gCharactersList[ iCounterA ].fValid == FALSE ) { break; } if( GetLengthOfMercPath( MercPtrs[ gCharactersList[ iCounterA ].usSolID ] ) == 0 ) { sEndSectorB = 9999; } else { sEndSectorB = GetLastSectorIdInCharactersPath( &Menptr[ gCharactersList[ iCounterA ].usSolID ] ); } if( ( sEndSectorB > sEndSectorA ) && ( iCounterA < iCounter ) ) { SwapCharactersInList( iCounter, iCounterA ); } } break; case( 5 ): iExpiryTime = GetContractExpiryTime( &( Menptr[ gCharactersList[ iCounter ].usSolID ] ) ); //by contract expiry for( iCounterA = 0; iCounterA < FIRST_VEHICLE; iCounterA++ ) { if( gCharactersList[ iCounterA ].fValid == FALSE ) { break; } iExpiryTimeA = GetContractExpiryTime( &( Menptr[ gCharactersList[ iCounterA ].usSolID ] ) ); if( ( iExpiryTimeA > iExpiryTime ) && ( iCounterA < iCounter ) ) { SwapCharactersInList( iCounter, iCounterA ); } } break; default: Assert(0); return; } } if ( fRetainSelectedMercs ) { // select nobody & reset the selected list ChangeSelectedInfoChar( -1, TRUE ); // now select all the soldiers that were selected before for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( pSelectedSoldier[ iCounter ] ) { for( iCounterA = 0; iCounterA < MAX_CHARACTER_COUNT; iCounterA++ ) { // is this entry even valid if( gCharactersList[ iCounterA ].fValid == FALSE ) { continue; } // grab current soldier pCurrentSoldier = &Menptr[ gCharactersList[ iCounterA ].usSolID ]; // check if soldier is active if( pCurrentSoldier->bActive == FALSE ) { continue; } // this guy is selected if( pSelectedSoldier[ iCounter ] == pCurrentSoldier ) { SetEntryInSelectedCharacterList( ( INT8 ) iCounterA ); } // update who the currently selected info guy is if( pPreviousSelectedInfoChar == pCurrentSoldier ) { ChangeSelectedInfoChar( ( INT8 ) iCounterA, FALSE ); } } } } } else { // keep currently selected merc, but reset the selected list (which isn't saved/restored, that's why) ResetSelectedListForMapScreen( ); } // reset blinking animations SetAllAutoFacesInactive( ); // dirty the screen parts affected fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; } void SwapCharactersInList( INT32 iCharA, INT32 iCharB ) { UINT16 usTempSoldID; // swap usTempSoldID = gCharactersList[ iCharA ].usSolID; gCharactersList[ iCharA ].usSolID = gCharactersList[ iCharB ].usSolID; gCharactersList[ iCharB ].usSolID = usTempSoldID; } void RemoveTeamPanelSortButtonsForMapScreen( void ) { INT32 iCounter = 0; for( iCounter = 0; iCounter < MAX_SORT_METHODS; iCounter++ ) { UnloadButtonImage( giMapSortButtonImage[ iCounter ] ); RemoveButton( giMapSortButton[ iCounter ] ); giMapSortButtonImage[ iCounter ] = -1; giMapSortButton[ iCounter ] = -1; } return; } void HandleCommonGlowTimer( ) { INT32 iCurrentTime = 0; // grab the current time iCurrentTime = GetJA2Clock(); // only bother checking once flash interval has elapsed if( ( iCurrentTime - giCommonGlowBaseTime ) >= GLOW_DELAY ) { // update timer so that we only run check so often giCommonGlowBaseTime = iCurrentTime; // set flag to trigger glow higlight updates gfGlowTimerExpired = TRUE; } else { gfGlowTimerExpired = FALSE; } } void HandleAssignmentsDoneAndAwaitingFurtherOrders( void ) { // run through list of grunts and handle awating further orders INT32 iCounter = 0, iCurrentTime = 0; SOLDIERTYPE *pSoldier = NULL; // update "nothing to do" flags if necessary if ( gfReEvaluateEveryonesNothingToDo ) { ReEvaluateEveryonesNothingToDo(); } // grab the current time iCurrentTime = GetJA2Clock(); // only bother checking once flash interval has elapsed if( ( iCurrentTime - giFlashAssignBaseTime ) >= ASSIGNMENT_DONE_FLASH_TIME ) { // update timer so that we only run check so often giFlashAssignBaseTime = iCurrentTime; for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( gCharactersList[ iCounter ].fValid == FALSE ) { break; } pSoldier = &( Menptr[ gCharactersList[ iCounter ].usSolID ] ); // toggle and redraw if flash was left ON even though the flag is OFF if( pSoldier->fDoneAssignmentAndNothingToDoFlag || fFlashAssignDone ) { fFlashAssignDone = !fFlashAssignDone; fDrawCharacterList = TRUE; // only need to find one break; } } } } void DisplayIconsForMercsAsleep( void ) { // run throught he list of grunts to see who is asleep and who isn't HVOBJECT hHandle; INT32 iCounter; SOLDIERTYPE *pSoldier; // if we are in inventory if( fShowInventoryFlag == TRUE ) { return; } GetVideoObject(&hHandle, guiSleepIcon ); for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( gCharactersList[ iCounter ].fValid == TRUE ) { pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; if( pSoldier->bActive && pSoldier->fMercAsleep && CanChangeSleepStatusForSoldier( pSoldier ) ) { //BltVideoObject( guiSAVEBUFFER , hHandle, 0, 125, ( INT16 )( Y_START+(iCounter * ( Y_SIZE + 2 ) ) ) , VO_BLT_SRCTRANSPARENCY,NULL ); BltVideoObject( guiSAVEBUFFER , hHandle, 0, SLEEP_X + 2, ( INT16 )( Y_START+(iCounter * ( Y_SIZE + 2 ) ) ) , VO_BLT_SRCTRANSPARENCY,NULL ); } } } return; } //Kris: Added this function to blink the email icon on top of the laptop button whenever we are in // mapscreen and we have new email to read. void CheckForAndRenderNewMailOverlay() { if( fNewMailFlag ) { if( GetJA2Clock() % 1000 < 667 ) { if( ButtonList[ guiMapBottomExitButtons[ MAP_EXIT_TO_LAPTOP ] ]->uiFlags & BUTTON_CLICKED_ON ) { //button is down, so offset the icon //BltVideoObjectFromIndex( FRAME_BUFFER, guiNewMailIcons, 1, 465, 418, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObjectFromIndex( FRAME_BUFFER, guiNewMailIcons, 1, (SCREEN_WIDTH - 175), (SCREEN_HEIGHT - 62), VO_BLT_SRCTRANSPARENCY, NULL ); //InvalidateRegion( 465, 418, 480, 428 ); InvalidateRegion( (SCREEN_WIDTH - 175), (SCREEN_HEIGHT - 62), (SCREEN_WIDTH - 160), (SCREEN_HEIGHT - 52 )); } else { //button is up, so draw the icon normally //BltVideoObjectFromIndex( FRAME_BUFFER, guiNewMailIcons, 0, 464, 417, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObjectFromIndex( FRAME_BUFFER, guiNewMailIcons, 0, (SCREEN_WIDTH - 176), (SCREEN_HEIGHT - 63), VO_BLT_SRCTRANSPARENCY, NULL ); if( !(ButtonList[ guiMapBottomExitButtons[ MAP_EXIT_TO_LAPTOP ] ]->uiFlags & BUTTON_ENABLED ) ) { UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; SGPRect area = { (SCREEN_WIDTH - 177), (SCREEN_HEIGHT - 63), (SCREEN_WIDTH - 163), (SCREEN_HEIGHT - 55) }; pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); Blt16BPPBufferHatchRect( (UINT16*)pDestBuf, uiDestPitchBYTES, &area ); UnLockVideoSurface( FRAME_BUFFER ); } InvalidateRegion( (SCREEN_WIDTH - 177), (SCREEN_HEIGHT - 63), (SCREEN_WIDTH - 159), (SCREEN_HEIGHT - 50) ); } } else { //The blink is now off, so mark the button dirty so that it'll render next frame. MarkAButtonDirty( guiMapBottomExitButtons[ MAP_EXIT_TO_LAPTOP ] ); } } } BOOLEAN CanToggleSelectedCharInventory( void ) { SOLDIERTYPE *pSoldier = NULL; if( gfPreBattleInterfaceActive == TRUE ) { return(FALSE); } // already in inventory and an item picked up? if( fShowInventoryFlag && ( gMPanelRegion.Cursor == EXTERN_CURSOR ) ) { return(FALSE); } // nobody selected? if( bSelectedInfoChar == -1 ) { return(FALSE); } // does the selected guy have inventory and can we get at it? if ( !MapCharacterHasAccessibleInventory( bSelectedInfoChar ) ) { return(FALSE); } pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ]; // if not in inventory, and holding an item from sector inventory if( !fShowInventoryFlag && ( ( gMPanelRegion.Cursor == EXTERN_CURSOR ) || gpItemPointer || fMapInventoryItem ) && ( gpItemPointerSoldier == NULL ) ) { // make sure he's in that sector if ( ( pSoldier->sSectorX != sSelMapX ) || ( pSoldier->sSectorY != sSelMapY ) || ( pSoldier->bSectorZ != iCurrentMapSectorZ ) || pSoldier->fBetweenSectors ) { return(FALSE); } } // passed! return(TRUE); } BOOLEAN MapCharacterHasAccessibleInventory( INT8 bCharNumber ) { SOLDIERTYPE *pSoldier = NULL; Assert( bCharNumber >= 0 ); Assert( bCharNumber < MAX_CHARACTER_COUNT ); // invalid character slot selected? if( gCharactersList[ bCharNumber ].fValid == FALSE ) { return(FALSE); } pSoldier = MercPtrs[ gCharactersList[ bCharNumber ].usSolID ]; if( ( pSoldier->bAssignment == IN_TRANSIT ) || ( pSoldier->bAssignment == ASSIGNMENT_POW ) || // Kaiden: Vehicle Inventory change - Commented the following line // ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) || // And added this instead: ( (!gGameExternalOptions.fVehicleInventory) && (pSoldier->uiStatusFlags & SOLDIER_VEHICLE) ) || ( AM_A_ROBOT( pSoldier ) ) || ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__EPC ) || ( pSoldier->bLife < OKLIFE ) ) { return(FALSE); } return( TRUE ); } void CheckForInventoryModeCancellation() { if ( fShowInventoryFlag || fShowDescriptionFlag ) { // can't bail while player has an item in hand... if( gMPanelRegion.Cursor == EXTERN_CURSOR ) { return; } if ( !CanToggleSelectedCharInventory( ) ) { // get out of inventory mode if it's on! (could have just bled below OKLIFE) if ( fShowInventoryFlag ) { fShowInventoryFlag = FALSE; SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] ); fTeamPanelDirty = TRUE; } // get out of inventory description if it's on! if ( fShowDescriptionFlag ) { DeleteItemDescriptionBox( ); } } } } void ChangeSelectedMapSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) { // ignore while map inventory pool is showing, or else items can be replicated, since sector inventory always applies // only to the currently selected sector!!! if( fShowMapInventoryPool ) return; if ( gfPreBattleInterfaceActive ) return; if( !IsTheCursorAllowedToHighLightThisSector( sMapX, sMapY ) ) return; // disallow going underground while plotting (surface) movement if ( ( bMapZ != 0 ) && ( ( bSelectedDestChar != -1 ) || fPlotForHelicopter ) ) return; sSelMapX = sMapX; sSelMapY = sMapY; iCurrentMapSectorZ = bMapZ; // if going underground while in airspace mode if ( ( bMapZ > 0 ) && ( fShowAircraftFlag == TRUE ) ) { // turn off airspace mode ToggleAirspaceMode( ); } fMapPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; // also need this, to update the text coloring of mercs in this sector fTeamPanelDirty = TRUE; } BOOLEAN CanChangeDestinationForCharSlot( INT8 bCharNumber, BOOLEAN fShowErrorMessage ) { SOLDIERTYPE *pSoldier = NULL; INT8 bErrorNumber = -1; if ( bCharNumber == -1 ) return( FALSE ); if ( gCharactersList[ bCharNumber ].fValid == FALSE ) return (FALSE); pSoldier = MercPtrs[ gCharactersList[ bCharNumber ].usSolID ]; // valid soldier? Assert( pSoldier ); Assert( pSoldier->bActive ); if ( CanEntireMovementGroupMercIsInMove( pSoldier, &bErrorNumber ) ) { return( TRUE ); } else { // function may fail without returning any specific error # (-1). // if it gave us the # of an error msg, and we were told to display it if ( ( bErrorNumber != -1 ) && fShowErrorMessage ) { ReportMapScreenMovementError( bErrorNumber ); } return( FALSE ); } } BOOLEAN CanExtendContractForCharSlot( INT8 bCharNumber ) { SOLDIERTYPE *pSoldier = NULL; if ( bCharNumber == -1 ) return( FALSE ); if ( gCharactersList[ bCharNumber ].fValid == FALSE ) return (FALSE); pSoldier = MercPtrs[ gCharactersList[ bCharNumber ].usSolID ]; // valid soldier? Assert( pSoldier ); Assert( pSoldier->bActive ); // if a vehicle, in transit, or a POW if( /*( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ||*/ ( pSoldier->bAssignment == IN_TRANSIT ) || ( pSoldier->bAssignment == ASSIGNMENT_POW ) ) { // can't extend contracts at this time return (FALSE); } // if a vehicle has passengers if ( (pSoldier->uiStatusFlags & SOLDIER_VEHICLE) && (DoesVehicleHaveAnyPassengers(pSoldier->bVehicleID) ) ) { // then restrict contract menu return (FALSE); } // mercs below OKLIFE, M.E.R.C. mercs, EPCs, and the Robot use the Contract menu so they can be DISMISSED/ABANDONED! // everything OK return( TRUE ); } BOOLEAN CanChangeSleepStatusForCharSlot( INT8 bCharNumber ) { SOLDIERTYPE *pSoldier = NULL; if ( bCharNumber == -1 ) return( FALSE ); if ( gCharactersList[ bCharNumber ].fValid == FALSE ) return (FALSE); pSoldier = MercPtrs[ gCharactersList[ bCharNumber ].usSolID ]; return( CanChangeSleepStatusForSoldier( pSoldier ) ); } BOOLEAN CanChangeSleepStatusForSoldier( SOLDIERTYPE *pSoldier ) { // valid soldier? Assert( pSoldier ); Assert( pSoldier->bActive ); // if a vehicle, robot, in transit, or a POW if( ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) || AM_A_ROBOT( pSoldier ) || ( pSoldier->bAssignment == IN_TRANSIT ) || ( pSoldier->bAssignment == ASSIGNMENT_POW ) ) { // can't change the sleep status of such mercs return ( FALSE ); } // if dead if( ( pSoldier->bLife <= 0 ) || ( pSoldier->bAssignment == ASSIGNMENT_DEAD ) ) { return ( FALSE ); } // this merc MAY be able to sleep/wake up - we'll allow player to click and find out return( TRUE ); } void ChangeMapScreenMaskCursor( UINT16 usCursor ) { MSYS_SetCurrentCursor( usCursor ); MSYS_ChangeRegionCursor( &gMapScreenMaskRegion, usCursor ); if ( usCursor == CURSOR_CHECKMARK ) fCheckCursorWasSet = TRUE; else fCheckCursorWasSet = FALSE; if ( usCursor == CURSOR_NORMAL ) { if ( !InItemStackPopup( ) ) { // cancel mouse restriction FreeMouseCursor(); } } else { // restrict mouse cursor to the map area RestrictMouseCursor( &MapScreenRect ); } } void CancelOrShortenPlottedPath( void ) { INT16 sMapX, sMapY; UINT32 uiReturnValue; GetMouseMapXY(&sMapX, &sMapY); /* // translate zoom in to zoom out coords if(fZoomFlag) { sMapX=(UINT16)iZoomX/MAP_GRID_X+sMapX; sMapX=sMapX/2; sMapY=(UINT16)iZoomY/MAP_GRID_Y+sMapY; sMapY=sMapY/2; } */ // check if we are in aircraft mode if( fShowAircraftFlag == TRUE ) { // check for helicopter path being plotted if( !fPlotForHelicopter ) return; // if player can't redirect it if ( CanHelicopterFly( ) == FALSE ) { // explain & ignore ExplainWhySkyriderCantFly(); return; } // try to delete portion of path AFTER the current sector for the helicopter uiReturnValue = ClearPathAfterThisSectorForHelicopter( sMapX, sMapY ); } else { // check for character path being plotted if( bSelectedDestChar == -1 ) return; // try to delete portion of path AFTER the current sector for the helicopter uiReturnValue = ClearPathAfterThisSectorForCharacter( &Menptr[gCharactersList[bSelectedDestChar].usSolID], sMapX, sMapY ); } switch ( uiReturnValue ) { case ABORT_PLOTTING: AbortMovementPlottingMode( ); break; case PATH_CLEARED: // movement was canceled // message was already issued when path was cleared DestinationPlottingCompleted(); break; case PATH_SHORTENED: // route was shortened but isn't completely gone // display "route shortened" message MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pMapPlotStrings[ 4 ] ); break; default: Assert( FALSE ); break; } // this triggers the path node animation to reset itself back to the first node fDeletedNode = TRUE; fMapPanelDirty = TRUE; fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; // to update ETAs if path reversed or shortened } BOOLEAN HandleCtrlOrShiftInTeamPanel( INT8 bCharNumber ) { // check if shift or ctrl held down, if so, set values in list if (_KeyDown(CTRL)) { ToggleEntryInSelectedList( bCharNumber ); fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; return( TRUE); } else if( _KeyDown(SHIFT) ) { // build a list from the bSelectedInfoChar To here, reset everyone //empty the list ResetSelectedListForMapScreen( ); // rebuild the list BuildSelectedListFromAToB( bSelectedInfoChar, bCharNumber ); fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; return( TRUE ); } return( FALSE ); } INT32 GetContractExpiryTime( SOLDIERTYPE *pSoldier ) { if( ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC ) || ( pSoldier->ubProfile == SLAY ) ) { return ( pSoldier->iEndofContractTime ); } else { // never - really high number return ( 999999 ); } } void ChangeSelectedInfoChar( INT8 bCharNumber, BOOLEAN fResetSelectedList ) { Assert( ( bCharNumber >= -1 ) && ( bCharNumber < MAX_CHARACTER_COUNT ) ); if( ( bCharNumber != -1 ) && ( gCharactersList[ bCharNumber ].fValid == FALSE ) ) return; // if holding an item if ( ( gMPanelRegion.Cursor == EXTERN_CURSOR ) || gpItemPointer || fMapInventoryItem ) { // make sure we can give it to this guy, otherwise don't allow the change if ( !MapscreenCanPassItemToCharNum( bCharNumber ) ) { return; } } if ( fResetSelectedList ) { // reset selections of all listed characters. Do this even if this guy is already selected. // NOTE: this keeps the currently selected info char selected ResetSelectedListForMapScreen( ); } // if this is really a change if ( bSelectedInfoChar != bCharNumber ) { // if resetting, and another guy was selected if ( fResetSelectedList && ( bSelectedInfoChar != -1 ) ) { // deselect previously selected character ResetEntryForSelectedList( bSelectedInfoChar ); } bSelectedInfoChar = bCharNumber; if ( bCharNumber != -1 ) { // the selected guy must always be ON in the list of selected chars SetEntryInSelectedCharacterList( bCharNumber ); } // if we're in the inventory panel if ( fShowInventoryFlag ) { // and we're changing to nobody or a guy whose inventory can't be accessed if ( ( bCharNumber == -1 ) || !MapCharacterHasAccessibleInventory( bCharNumber ) ) { // then get out of inventory mode fShowInventoryFlag = FALSE; } } fCharacterInfoPanelDirty = TRUE; // if showing sector inventory if ( fShowMapInventoryPool ) { // redraw right side to update item hatches fMapPanelDirty = TRUE; } } fTeamPanelDirty = TRUE; } void CopyPathToAllSelectedCharacters( PathStPtr pPath ) { INT32 iCounter = 0; SOLDIERTYPE *pSoldier = NULL; // run through list and copy paths for each selected character for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) { pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; // skip itself! if ( GetSoldierMercPathPtr( pSoldier ) != pPath ) { if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { pVehicleList[ pSoldier->bVehicleID ].pMercPath = CopyPaths( pPath, pVehicleList[ pSoldier->bVehicleID ].pMercPath ); } else if( pSoldier->bAssignment == VEHICLE ) { pVehicleList[ pSoldier->iVehicleId ].pMercPath = CopyPaths( pPath, pVehicleList[ pSoldier->iVehicleId ].pMercPath ); } else { pSoldier->pMercPath = CopyPaths( pPath, pSoldier->pMercPath ); } // don't use CopyPathToCharactersSquadIfInOne(), it will whack the original pPath by replacing that merc's path! } } } } void CancelPathsOfAllSelectedCharacters() { INT8 bCounter = 0; SOLDIERTYPE *pSoldier = NULL; BOOLEAN fSkyriderMsgShown = FALSE; // cancel destination for the clicked and ALL other valid & selected characters with a route set for( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++ ) { // if we've clicked on a selected valid character if( ( gCharactersList[ bCounter ].fValid == TRUE ) && IsEntryInSelectedListSet( bCounter ) ) { pSoldier = MercPtrs[ gCharactersList[ bCounter ].usSolID ]; // and he has a route set if ( GetLengthOfMercPath( pSoldier ) > 0 ) { // if he's in the chopper, but player can't redirect it if ( ( pSoldier->bAssignment == VEHICLE ) && ( pSoldier->iVehicleId == iHelicopterVehicleId ) && ( CanHelicopterFly( ) == FALSE ) ) { if ( !fSkyriderMsgShown ) { // explain ExplainWhySkyriderCantFly(); fSkyriderMsgShown = TRUE; } // don't cancel, ignore continue; } // cancel the entire path (also clears vehicles for any passengers selected, and handles reversing directions) if( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { CancelPathForVehicle( &( pVehicleList[ pSoldier->bVehicleID ] ), FALSE ); } else { CancelPathForCharacter( pSoldier ); } } } } } void ConvertMinTimeToETADayHourMinString( UINT32 uiTimeInMin, STR16 sString ) { UINT32 uiDay, uiHour, uiMin; uiDay = ( uiTimeInMin / NUM_MIN_IN_DAY ); uiHour = ( uiTimeInMin - ( uiDay * NUM_MIN_IN_DAY ) ) / NUM_MIN_IN_HOUR; uiMin = uiTimeInMin - ( ( uiDay * NUM_MIN_IN_DAY ) + ( uiHour * NUM_MIN_IN_HOUR ) ); // there ain't enough room to show both the day and ETA: and without ETA it's confused as the current time // swprintf( sString, L"%s %s %d, %02d:%02d", pEtaString[ 0 ], pDayStrings[ 0 ], uiDay, uiHour, uiMin ); // swprintf( sString, L"%s %d, %02d:%02d", pDayStrings[ 0 ], uiDay, uiHour, uiMin ); swprintf( sString, L"%s %02d:%02d", pEtaString[ 0 ], uiHour, uiMin ); } INT32 GetGroundTravelTimeOfCharacter( INT8 bCharNumber ) { INT32 iTravelTime = 0; if( bCharNumber == -1 ) return(0); if ( !gCharactersList[ bCharNumber ].fValid ) return(0); // get travel time for the last path segment (stored in pTempCharacterPath) iTravelTime = GetPathTravelTimeDuringPlotting( pTempCharacterPath ); // add travel time for any prior path segments (stored in the selected character's mercpath, but waypoints aren't built) iTravelTime += GetPathTravelTimeDuringPlotting( GetSoldierMercPathPtr( MercPtrs[ gCharactersList[ bCharNumber ].usSolID ] ) ); return( iTravelTime ); } INT16 CalcLocationValueForChar( INT32 iCounter ) { SOLDIERTYPE *pSoldier = NULL; INT16 sLocValue = 0; Assert( iCounter < MAX_CHARACTER_COUNT ); if( gCharactersList[ iCounter ].fValid == FALSE ) return( sLocValue ); pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; // don't reveal location of POWs! if( pSoldier->bAssignment != ASSIGNMENT_POW ) { sLocValue = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ); // underground: add 1000 per sublevel sLocValue += 1000 * ( pSoldier->bSectorZ ); } return( sLocValue ); } void CancelChangeArrivalSectorMode( ) { // "put him in change arrival sector" mode gfInChangeArrivalSectorMode = FALSE; // change the cursor to that mode SetUpCursorForStrategicMap(); fMapPanelDirty = TRUE; } void MakeMapModesSuitableForDestPlotting( INT8 bCharNumber ) { SOLDIERTYPE *pSoldier = NULL; if( gCharactersList[ bCharNumber ].fValid == TRUE ) { pSoldier = MercPtrs[ gCharactersList[ bCharNumber ].usSolID ]; CancelSectorInventoryDisplayIfOn( FALSE ); TurnOnShowTeamsMode( ); if ( ( pSoldier->bAssignment == VEHICLE ) && ( pSoldier->iVehicleId == iHelicopterVehicleId ) ) { if ( fShowAircraftFlag == FALSE ) { // turn on airspace mode automatically ToggleAirspaceMode(); } } else { if ( fShowAircraftFlag == TRUE ) { // turn off airspace mode automatically ToggleAirspaceMode(); } } // if viewing a different sublevel if ( iCurrentMapSectorZ != pSoldier->bSectorZ ) { // switch to that merc's sublevel JumpToLevel( pSoldier->bSectorZ ); } } } BOOLEAN AnyMovableCharsInOrBetweenThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) { INT32 iFirstId = 0, iLastId = 0; INT32 iCounter = 0; SOLDIERTYPE *pSoldier = NULL; // to speed it up a little? iFirstId = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; iLastId = gTacticalStatus.Team[ OUR_TEAM ].bLastID; for( iCounter = iFirstId; iCounter <= iLastId; iCounter++ ) { // get the soldier pSoldier = &Menptr[ iCounter ]; // is the soldier active if( pSoldier->bActive == FALSE ) { continue; } // POWs, dead guys, guys in transit can't move if ( ( pSoldier->bAssignment == IN_TRANSIT ) || ( pSoldier->bAssignment == ASSIGNMENT_POW ) || ( pSoldier->bAssignment == ASSIGNMENT_DEAD ) || ( pSoldier->bLife == 0 ) ) { continue; } // don't count mercs aboard Skyrider if ( ( pSoldier->bAssignment == VEHICLE ) && ( pSoldier->iVehicleId == iHelicopterVehicleId ) ) { continue; } // don't count vehicles - in order for them to move, somebody must be in the sector with them if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { continue; } // is he here? if( ( pSoldier->sSectorX == sSectorX ) && ( pSoldier->sSectorY == sSectorY ) && ( pSoldier->bSectorZ == bSectorZ ) ) { // NOTE that we consider mercs between sectors, mercs < OKLIFE, and sleeping mercs to be "movable". // This lets CanCharacterMoveInStrategic() itself report the appropriate error message when character is clicked return( TRUE ); } } return( FALSE ); } BOOLEAN RequestGiveSkyriderNewDestination( void ) { // should we allow it? if( CanHelicopterFly( ) == TRUE ) { // if not warned already, and chopper empty, but mercs are in this sector if ( !gfSkyriderEmptyHelpGiven && ( GetNumberOfPassengersInHelicopter() == 0 ) && ( PlayerMercsInHelicopterSector() > 0 ) ) { DoMapMessageBox( MSG_BOX_BASIC_STYLE, pSkyriderText[ 6 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); gfSkyriderEmptyHelpGiven = TRUE; return( FALSE ); } // say Yo! if(gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE) SkyRiderTalk( SKYRIDER_SAYS_HI ); // start plotting helicopter movement fPlotForHelicopter = TRUE; // change cursor to the helicopter SetUpCursorForStrategicMap(); // remember the helicopter's current path so we can restore it if need be gpHelicopterPreviousMercPath = CopyPaths( pVehicleList[ iHelicopterVehicleId ].pMercPath, gpHelicopterPreviousMercPath ); // affects Skyrider's dialogue SetFactTrue( FACT_SKYRIDER_USED_IN_MAPSCREEN ); return( TRUE ); } else // not allowed to reroute the chopper right now { // tell player why not ExplainWhySkyriderCantFly(); return( FALSE ); } } void ExplainWhySkyriderCantFly( void ) { // do we owe him money? if( gMercProfiles[ SKYRIDER ].iBalance < 0 ) { // overdue cash SkyRiderTalk( OWED_MONEY_TO_SKYRIDER ); return; } // is he returning to base? if( fHeliReturnStraightToBase ) { // returning to base SkyRiderTalk( RETURN_TO_BASE ); return; } // grounded by enemies in sector? if ( CanHelicopterTakeOff() == FALSE ) { SkyRiderTalk( CHOPPER_NOT_ACCESSIBLE ); // DoMapMessageBox( MSG_BOX_BASIC_STYLE, pSkyriderText[ 4 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); return; } // Drassen too disloyal to wanna help player? if ( CheckFact( FACT_LOYALTY_LOW, SKYRIDER ) ) { SkyRiderTalk( DOESNT_WANT_TO_FLY ); return; } // no explainable reason } UINT8 PlayerMercsInHelicopterSector( void ) { GROUP *pGroup = NULL; Assert( iHelicopterVehicleId != -1); pGroup = GetGroup( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup ); if ( pGroup->fBetweenSectors ) { return( 0 ); } return( PlayerMercsInSector( pGroup->ubSectorX, pGroup->ubSectorY, 0 ) ); } void HandleNewDestConfirmation( INT16 sMapX, INT16 sMapY ) { UINT8 ubCurrentProgress; // if moving the chopper itself, or moving a character aboard the chopper if( fPlotForHelicopter ) { // if there are no enemies in destination sector, or we don't know if ( ( NumEnemiesInSector( sMapX, sMapY ) == 0 ) || ( WhatPlayerKnowsAboutEnemiesInSector( sMapX, sMapY ) == KNOWS_NOTHING ) ) { // no problem // get current player progress ubCurrentProgress = CurrentPlayerProgressPercentage(); // if we're doing a lot better than last time he said anything if ( ( ubCurrentProgress > gubPlayerProgressSkyriderLastCommentedOn ) && ( ( ubCurrentProgress - gubPlayerProgressSkyriderLastCommentedOn ) >= MIN_PROGRESS_FOR_SKYRIDER_QUOTE_DOING_WELL ) ) { // kicking ass! SkyRiderTalk( THINGS_ARE_GOING_WELL ); gubPlayerProgressSkyriderLastCommentedOn = ubCurrentProgress; } // if we're doing noticably worse than last time he said anything else if ( ( ubCurrentProgress < gubPlayerProgressSkyriderLastCommentedOn ) && ( ( gubPlayerProgressSkyriderLastCommentedOn - ubCurrentProgress ) >= MIN_REGRESS_FOR_SKYRIDER_QUOTE_DOING_BADLY ) ) { // sucking rocks! SkyRiderTalk( THINGS_ARE_GOING_BADLY ); gubPlayerProgressSkyriderLastCommentedOn = ubCurrentProgress; } else { // ordinary confirmation quote if(gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE) SkyRiderTalk( CONFIRM_DESTINATION ); } } else { // ok, but... you know there are enemies there... SkyRiderTalk( BELIEVED_ENEMY_SECTOR ); } } else { RandomAwakeSelectedMercConfirmsStrategicMove( ); // tell player the route was CONFIRMED // NOTE: We don't this this for the helicopter any more, since it clashes with Skyrider's own confirmation msg MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pMapPlotStrings[ 1 ] ); // wake up anybody who needs to be awake to travel WakeUpAnySleepingSelectedMercsOnFootOrDriving(); } } void RandomAwakeSelectedMercConfirmsStrategicMove( void ) { SOLDIERTYPE *pSoldier = NULL; INT32 iCounter; UINT8 ubSelectedMercID[ 20 ]; UINT8 ubSelectedMercIndex[ 20 ]; UINT8 ubNumMercs = 0; UINT8 ubChosenMerc; for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) ) { pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; if ( pSoldier->bLife >= OKLIFE && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) && !AM_A_ROBOT( pSoldier ) && !AM_AN_EPC( pSoldier ) && !pSoldier->fMercAsleep ) { ubSelectedMercID[ ubNumMercs ] = pSoldier->ubID; ubSelectedMercIndex[ ubNumMercs ] = (UINT8)iCounter; ubNumMercs++; } } } if ( ubNumMercs > 0 ) { ubChosenMerc = (UINT8)Random( ubNumMercs ); // select that merc so that when he speaks we're showing his portrait and not someone else ChangeSelectedInfoChar( ubSelectedMercIndex[ ubChosenMerc ], FALSE ); DoMercBattleSound( MercPtrs[ ubSelectedMercID[ ubChosenMerc ] ], ( UINT8 ) ( Random(2) ? BATTLE_SOUND_OK1 : BATTLE_SOUND_OK2 ) ); //TacticalCharacterDialogue( MercPtrs[ ubSelectedMercID[ ubChosenMerc ] ], ubQuoteNum ); } } void DestinationPlottingCompleted( void ) { // clear previous paths for selected characters and helicopter ClearPreviousPaths(); fPlotForHelicopter = FALSE; bSelectedDestChar = - 1; giDestHighLine = -1; fMapPanelDirty = TRUE; // reset cursor SetUpCursorForStrategicMap( ); fJustFinishedPlotting = TRUE; fEndPlotting = TRUE; } void HandleMilitiaRedistributionClick( void ) { INT8 bTownId; BOOLEAN fTownStillHidden; CHAR16 sString[ 128 ]; // if on the surface if ( iCurrentMapSectorZ == 0 ) { bTownId = GetTownIdForSector( sSelMapX, sSelMapY ); fTownStillHidden = ( ( bTownId == TIXA ) && !fFoundTixa ) || ( ( bTownId == ORTA ) && !fFoundOrta ); if( ( bTownId != BLANK_SECTOR ) && !fTownStillHidden ) { if ( MilitiaTrainingAllowedInSector( sSelMapX, sSelMapY, ( INT8 )iCurrentMapSectorZ ) ) { if( fShowTownInfo == TRUE ) { fShowTownInfo = FALSE; } fMapPanelDirty = TRUE; // check if there's combat in any of the town's sectors if ( CanRedistributeMilitiaInSector( sSelMapX, sSelMapY, bTownId ) ) { // Nope, ok, set selected militia town sSelectedMilitiaTown = bTownId; } else { // can't redistribute militia during combat! DoScreenIndependantMessageBox( pMilitiaString[ 2 ], MSG_BOX_FLAG_OK, NULL ); } } else { // can't have militia in this town swprintf( sString, pMapErrorString[ 31 ], pTownNames [ bTownId ] ); DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL ); } } else if( IsThisSectorASAMSector( sSelMapX, sSelMapY, 0 ) && fSamSiteFound[ GetSAMIdFromSector( sSelMapX, sSelMapY, 0 ) ] ) { // can't move militia around sam sites DoScreenIndependantMessageBox( pMapErrorString[ 30 ], MSG_BOX_FLAG_OK, NULL ); } } } #ifdef JA2TESTVERSION void DumpSectorDifficultyInfo( void ) { // NOTE: This operates on the selected map sector! CHAR16 wSectorName[ 128 ]; ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Playing Difficulty: %s", gzGIOScreenText[ GIO_DIF_LEVEL_TEXT + gGameOptions.ubDifficultyLevel ] ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Highest Progress (0-100) = %d%%", HighestPlayerProgressPercentage() ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Player Kills = %d", gStrategicStatus.usPlayerKills ); GetSectorIDString( sSelMapX, sSelMapY, ( INT8 ) iCurrentMapSectorZ, wSectorName, TRUE ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"SECTOR: %s", wSectorName ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Pyth. Distance From Meduna (0-20) = %d", GetPythDistanceFromPalace( sSelMapX, sSelMapY ) ); if ( ( gWorldSectorX == sSelMapX ) && ( gWorldSectorY == sSelMapY ) && ( gbWorldSectorZ == iCurrentMapSectorZ ) ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Enemy Difficulty Factor (0 to 100) = %d%%", CalcDifficultyModifier( SOLDIER_CLASS_ARMY ) ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Avg Regular Enemy Exp. Level (2-6) = %d", 2 + ( CalcDifficultyModifier( SOLDIER_CLASS_ARMY ) / 20 ) ); } else { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"--Must load sector to calculate difficulty--" ); } } #endif void StartChangeSectorArrivalMode( void ) { // "put him in change arrival sector" mode gfInChangeArrivalSectorMode = TRUE; // redraw map with bullseye removed fMapPanelDirty = TRUE; // change the cursor to that mode SetUpCursorForStrategicMap(); // give instructions as overlay message MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pBullseyeStrings[ 0 ] ); } BOOLEAN CanMoveBullseyeAndClickedOnIt( INT16 sMapX, INT16 sMapY ) { // if in airspace mode, and not plotting paths if( ( fShowAircraftFlag == TRUE ) && ( bSelectedDestChar == -1 ) && ( fPlotForHelicopter == FALSE ) ) { // don't allow moving bullseye until after initial arrival if ( gTacticalStatus.fDidGameJustStart == FALSE ) { // if he clicked on the bullseye, and we're on the surface level if ( ( sMapX == gsMercArriveSectorX ) && ( sMapY == gsMercArriveSectorY ) && ( iCurrentMapSectorZ == 0 ) ) { return( TRUE ); } } } return( FALSE ); } void CreateBullsEyeOrChopperSelectionPopup( void ) { wcscpy( gzUserDefinedButton1, pHelicopterEtaStrings[ 8 ] ); wcscpy( gzUserDefinedButton2, pHelicopterEtaStrings[ 9 ] ); // do a BULLSEYE/CHOPPER message box DoScreenIndependantMessageBox( pHelicopterEtaStrings[ 7 ], MSG_BOX_FLAG_GENERIC, BullsEyeOrChopperSelectionPopupCallback ); } void BullsEyeOrChopperSelectionPopupCallback( UINT8 ubExitValue ) { // button 1 pressed? if ( ubExitValue == MSG_BOX_RETURN_YES ) { // chose chopper // have to set a flag 'cause first call to RequestGiveSkyriderNewDestination() triggers another msg box & won't work gfRequestGiveSkyriderNewDestination = TRUE; } // button 2 pressed? else if( ubExitValue == MSG_BOX_RETURN_NO ) { // chose bullseye StartChangeSectorArrivalMode(); } } // wake up anybody who needs to be awake to travel void WakeUpAnySleepingSelectedMercsOnFootOrDriving( void ) { SOLDIERTYPE *pSoldier = NULL; INT32 iCounter; BOOLEAN fSuccess = FALSE; for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) ) { pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; // if asleep if ( pSoldier->fMercAsleep ) { // and on foot or driving if ( ( pSoldier->bAssignment < ON_DUTY ) || ( ( pSoldier->bAssignment == VEHICLE ) && SoldierMustDriveVehicle( pSoldier, pSoldier->iVehicleId, FALSE ) ) ) { // we should be guaranteed that he CAN wake up to get this far, so report errors, but don't force it fSuccess = SetMercAwake( pSoldier, TRUE, FALSE ); Assert( fSuccess ); } } } } } void HandlePostAutoresolveMessages() { //KM: Autoresolve sets up this global sector value whenever the enemy gains control of a sector. As soon as //we leave autoresolve and enter mapscreen, then this gets called and handles ownership change for the sector. //It also brings up a dialog stating to the player what happened, however, the internals of those functions //breaks autoresolve and the game crashes after autoresolve is finished. The value doesn't need to be saved. // //An additional case is when creatures kill all opposition in the sector. For each surviving monster, civilians //are "virtually" murdered and loyalty hits will be processed. if( gsCiviliansEatenByMonsters >= 1 ) { AdjustLoyaltyForCivsEatenByMonsters( (UINT8)SECTORX( gsEnemyGainedControlOfSectorID ), (UINT8)SECTORY( gsEnemyGainedControlOfSectorID ), (UINT8)gsCiviliansEatenByMonsters ); gsCiviliansEatenByMonsters = -2; } else if( gsCiviliansEatenByMonsters == -2 ) { fMapPanelDirty = TRUE; gsCiviliansEatenByMonsters = -1; gsEnemyGainedControlOfSectorID = -1; } else if( gsEnemyGainedControlOfSectorID >= 0 ) { //bring up the dialog box SetThisSectorAsEnemyControlled( (UINT8)SECTORX( gsEnemyGainedControlOfSectorID ), (UINT8)SECTORY( gsEnemyGainedControlOfSectorID ), 0, TRUE ); gsEnemyGainedControlOfSectorID = -2; } else if( gsEnemyGainedControlOfSectorID == -2 ) { //dirty the mapscreen after the dialog box goes away. fMapPanelDirty = TRUE; gsEnemyGainedControlOfSectorID = -1; } else if( gbMilitiaPromotions ) { CHAR16 str[ 512 ]; BuildMilitiaPromotionsString( str ); DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); } } void GetMapscreenMercAssignmentString( SOLDIERTYPE *pSoldier, CHAR16 sString[] ) { if( pSoldier->bAssignment != VEHICLE ) { wcscpy(sString, pAssignmentStrings[ pSoldier->bAssignment ] ); } else { wcscpy( sString, pShortVehicleStrings[ pVehicleList[ pSoldier->iVehicleId ].ubVehicleType ] ); } } void GetMapscreenMercLocationString( SOLDIERTYPE *pSoldier, CHAR16 sString[] ) { CHAR16 pTempString[32]; if( pSoldier->bAssignment == IN_TRANSIT ) { // show blank wcscpy( sString, L"--" ); } else { if( pSoldier->bAssignment == ASSIGNMENT_POW ) { // POW - location unknown swprintf( sString, L"%s", pPOWStrings[ 1 ] ); } else { swprintf( pTempString, L"%s%s%s", pMapVertIndex[ pSoldier->sSectorY ], pMapHortIndex[ pSoldier->sSectorX ], pMapDepthIndex[ pSoldier->bSectorZ ] ); if ( pSoldier->fBetweenSectors ) { // put brackets around it when he's between sectors! swprintf( sString, L"(%s)", pTempString ); } else { wcscpy( sString, pTempString ); } } } } void GetMapscreenMercDestinationString( SOLDIERTYPE *pSoldier, CHAR16 sString[] ) { INT32 iSectorX, iSectorY; INT16 sSector=0; GROUP *pGroup = NULL; // by default, show nothing wcscpy( sString, L"" ); // if dead or POW - has no destination (no longer part of a group, for that matter) if( ( pSoldier->bAssignment == ASSIGNMENT_DEAD ) || ( pSoldier->bAssignment == ASSIGNMENT_POW ) || ( pSoldier->bLife == 0 ) ) { return; } if( pSoldier->bAssignment == IN_TRANSIT ) { // show the sector he'll be arriving in iSectorX = gsMercArriveSectorX; iSectorY = gsMercArriveSectorY; } else { // if he's going somewhere if ( GetLengthOfMercPath( pSoldier ) > 0 ) { sSector = GetLastSectorIdInCharactersPath( pSoldier ); // convert iSectorX = sSector % MAP_WORLD_X; iSectorY = sSector / MAP_WORLD_Y; } else // no movement path is set... { if ( pSoldier->fBetweenSectors ) { // he must be returning to his previous (reversed so as to be the next) sector, so show that as his destination // individual soldiers don't store previous/next sector coordinates, must go to his group for that pGroup = GetGroup( GetSoldierGroupId( pSoldier ) ); Assert( pGroup ); iSectorX = pGroup->ubNextX; iSectorY = pGroup->ubNextY; } else { // show nothing return; } } } swprintf( sString, L"%s%s", pMapVertIndex[ iSectorY ], pMapHortIndex[ iSectorX ] ); } void GetMapscreenMercDepartureString( SOLDIERTYPE *pSoldier, CHAR16 sString[], UINT8 *pubFontColor ) { INT32 iMinsRemaining = 0; INT32 iDaysRemaining = 0; INT32 iHoursRemaining = 0; if( ( pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__AIM_MERC && pSoldier->ubProfile != SLAY ) || pSoldier->bLife == 0 ) { swprintf( sString, L"%s", gpStrategicString[ STR_PB_NOTAPPLICABLE_ABBREVIATION ] ); } else { iMinsRemaining = pSoldier->iEndofContractTime - GetWorldTotalMin(); //if the merc is in transit if( pSoldier->bAssignment == IN_TRANSIT ) { //and if the time left on the cotract is greater then the contract time if( iMinsRemaining > (INT32)( pSoldier->iTotalContractLength * NUM_MIN_IN_DAY ) ) { iMinsRemaining = ( pSoldier->iTotalContractLength * NUM_MIN_IN_DAY ); } } // if 3 or more days remain if( iMinsRemaining >= MAP_TIME_UNDER_THIS_DISPLAY_AS_HOURS ) { iDaysRemaining = iMinsRemaining / (24*60); *pubFontColor = FONT_LTGREEN; swprintf(sString, L"%d%s", iDaysRemaining, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ] ); } else // less than 3 days { if( iMinsRemaining > 5 ) { iHoursRemaining = ( iMinsRemaining + 59 ) / 60; } else { iHoursRemaining = 0; } // last 3 days is Red, last 4 hours start flashing red/white! if( ( iMinsRemaining <= MINS_TO_FLASH_CONTRACT_TIME ) && ( fFlashContractFlag == TRUE ) ) { *pubFontColor = FONT_WHITE; } else { *pubFontColor = FONT_RED; } swprintf(sString, L"%d%s", iHoursRemaining, gpStrategicString[ STR_PB_HOURS_ABBREVIATION ] ); } } } void InitPreviousPaths( void ) { INT32 iCounter = 0; // init character previous paths for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { gpCharacterPreviousMercPath[ iCounter ] = NULL; } // init helicopter previous path gpHelicopterPreviousMercPath = NULL; } void RememberPreviousPathForAllSelectedChars( void ) { INT32 iCounter = 0; SOLDIERTYPE *pSoldier = NULL; for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) { pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; // remember his previous path by copying it to his slot in the array kept for that purpose gpCharacterPreviousMercPath[ iCounter ] = CopyPaths( GetSoldierMercPathPtr( MercPtrs[ gCharactersList[ iCounter ].usSolID ] ), gpCharacterPreviousMercPath[ iCounter ] ); } } } void RestorePreviousPaths( void ) { INT32 iCounter = 0; SOLDIERTYPE *pSoldier = NULL; PathStPtr *ppMovePath = NULL; UINT8 ubGroupId = 0; BOOLEAN fPathChanged = FALSE; // invalid if we're not plotting movement Assert( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ); if ( fPlotForHelicopter == TRUE ) { ppMovePath = &( pVehicleList[ iHelicopterVehicleId ].pMercPath ); ubGroupId = pVehicleList[ iHelicopterVehicleId ].ubMovementGroup; // if the helicopter had a previous path if( gpHelicopterPreviousMercPath != NULL ) { gpHelicopterPreviousMercPath = MoveToBeginningOfPathList( gpHelicopterPreviousMercPath ); // clear current path *ppMovePath = ClearStrategicPathList( *ppMovePath, ubGroupId ); // replace it with the previous one *ppMovePath = CopyPaths( gpHelicopterPreviousMercPath, *ppMovePath ); // will need to rebuild waypoints fPathChanged = TRUE; } else // no previous path { // if he currently has a path if( *ppMovePath ) { // wipe it out! *ppMovePath = MoveToBeginningOfPathList( *ppMovePath ); *ppMovePath = ClearStrategicPathList( *ppMovePath, ubGroupId ); // will need to rebuild waypoints fPathChanged = TRUE; } } if ( fPathChanged ) { // rebuild waypoints RebuildWayPointsForGroupPath( *ppMovePath, ubGroupId ); // copy his path to all selected characters CopyPathToAllSelectedCharacters( *ppMovePath ); } } else // character(s) plotting { for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { // if selected if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) { pSoldier = MercPtrs[ gCharactersList[ iCounter ].usSolID ]; if( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { ppMovePath = &( pVehicleList[ pSoldier->bVehicleID ].pMercPath ); ubGroupId = pVehicleList[ pSoldier->bVehicleID ].ubMovementGroup; } else if( pSoldier->bAssignment == VEHICLE ) { ppMovePath = &( pVehicleList[ pSoldier->iVehicleId ].pMercPath ); ubGroupId = pVehicleList[ pSoldier->iVehicleId ].ubMovementGroup; } else if( pSoldier->bAssignment < ON_DUTY ) { ppMovePath = &( pSoldier->pMercPath ); ubGroupId = pSoldier->ubGroupID; } else { // invalid pSoldier - that guy can't possibly be moving, he's on a non-vehicle assignment! Assert( 0 ); continue; } fPathChanged = FALSE; // if we have the previous path stored for the dest char if( gpCharacterPreviousMercPath[ iCounter ] ) { gpCharacterPreviousMercPath[ iCounter ] = MoveToBeginningOfPathList( gpCharacterPreviousMercPath[ iCounter ] ); // clear current path *ppMovePath = ClearStrategicPathList( *ppMovePath, ubGroupId ); // replace it with the previous one *ppMovePath = CopyPaths( gpCharacterPreviousMercPath[ iCounter ], *ppMovePath ); // will need to rebuild waypoints fPathChanged = TRUE; } else // no previous path stored { // if he has one now, wipe it out if( *ppMovePath ) { // wipe it out! *ppMovePath = MoveToBeginningOfPathList( *ppMovePath ); *ppMovePath = ClearStrategicPathList( *ppMovePath, ubGroupId ); // will need to rebuild waypoints fPathChanged = TRUE; } } if ( fPathChanged ) { // rebuild waypoints RebuildWayPointsForGroupPath( *ppMovePath, ubGroupId ); } } } } } void ClearPreviousPaths( void ) { INT32 iCounter = 0; for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) { if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) { gpCharacterPreviousMercPath[ iCounter ] = ClearStrategicPathList( gpCharacterPreviousMercPath[ iCounter ], 0 ); } } gpHelicopterPreviousMercPath = ClearStrategicPathList( gpHelicopterPreviousMercPath, 0 ); } void SelectAllCharactersInSquad( INT8 bSquadNumber ) { INT8 bCounter; BOOLEAN fFirstOne = TRUE; SOLDIERTYPE *pSoldier; // ignore if that squad is empty if( SquadIsEmpty( bSquadNumber ) == TRUE ) { return; } // select nobody & reset the selected list ChangeSelectedInfoChar( -1, TRUE ); // now select all the soldiers that are in this squad for( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++ ) { // is this entry is valid if( gCharactersList[ bCounter ].fValid == TRUE ) { pSoldier = MercPtrs[ gCharactersList[ bCounter ].usSolID ]; // if this guy is on that squad or in a vehicle which is assigned to that squad // NOTE: There's no way to select everyone aboard Skyrider with this function... if ( ( pSoldier->bAssignment == bSquadNumber ) || IsSoldierInThisVehicleSquad( pSoldier, bSquadNumber ) ) { if ( fFirstOne ) { // make the first guy in the list who is in this squad the selected info char ChangeSelectedInfoChar( bCounter, FALSE ); // select his sector ChangeSelectedMapSector( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); fFirstOne = FALSE; } SetEntryInSelectedCharacterList( bCounter ); } } } } BOOLEAN CanDrawSectorCursor( void ) { if( /*( fCursorIsOnMapScrollButtons == FALSE ) && */ ( fShowTownInfo == FALSE ) && ( ghTownMineBox == -1 ) && ( fShowUpdateBox == FALSE ) && ( GetNumberOfMercsInUpdateList() == 0 ) && ( sSelectedMilitiaTown == 0 ) && ( gfMilitiaPopupCreated == FALSE ) && ( gfStartedFromMapScreen == FALSE ) && ( fShowMapScreenMovementList == FALSE ) && ( ghMoveBox == - 1 ) && ( fMapInventoryItem == FALSE ) ) { return( TRUE ); } return( FALSE ); } void RestoreMapSectorCursor( INT16 sMapX, INT16 sMapY ) { INT16 sScreenX, sScreenY; Assert( ( sMapX >= 1 ) && ( sMapX <= 16 ) ); Assert( ( sMapY >= 1 ) && ( sMapY <= 16 ) ); GetScreenXYFromMapXY( sMapX, sMapY, &sScreenX, &sScreenY ); sScreenY -= 1; /* if(fZoomFlag) RestoreExternBackgroundRect( ((INT16)( sScreenX - MAP_GRID_X )), ((INT16)( sScreenY - MAP_GRID_Y )), DMAP_GRID_ZOOM_X, DMAP_GRID_ZOOM_Y); else */ RestoreExternBackgroundRect( sScreenX, sScreenY, DMAP_GRID_X, DMAP_GRID_Y ); } void RequestToggleMercInventoryPanel( void ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); } if ( !CanToggleSelectedCharInventory() ) { return; } if( fShowDescriptionFlag == TRUE ) { // turn off item description DeleteItemDescriptionBox( ); } else { // toggle inventory mode fShowInventoryFlag = !fShowInventoryFlag; // set help text for item glow region if( fShowInventoryFlag ) { SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 2 ] ); } else { SetRegionFastHelpText( &gCharInfoHandRegion, pMiscMapScreenMouseRegionHelpText[ 0 ] ); } } fTeamPanelDirty = TRUE; } void RequestContractMenu( void ) { if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( gfPreBattleInterfaceActive == TRUE ) { return; } if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); } // in case we have multiple guys selected, turn off everyone but the guy we're negotiating with ChangeSelectedInfoChar( bSelectedInfoChar, TRUE ); if ( CanExtendContractForCharSlot( bSelectedInfoChar ) ) { // create RebuildContractBoxForMerc( &Menptr[ gCharactersList[ bSelectedInfoChar ].usSolID ] ); // reset selected characters ResetAllSelectedCharacterModes( ); bSelectedContractChar = bSelectedInfoChar; giContractHighLine = bSelectedContractChar; // if not triggered internally if ( CheckIfSalaryIncreasedAndSayQuote( MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ], TRUE ) == FALSE ) { // show contract box fShowContractMenu = TRUE; // stop any dialogue by character StopAnyCurrentlyTalkingSpeech( ); } //fCharacterInfoPanelDirty = TRUE; } else { // reset selected characters ResetAllSelectedCharacterModes( ); } } void ChangeCharacterListSortMethod( INT32 iValue ) { Assert( iValue >= 0 ); Assert( iValue < MAX_SORT_METHODS ); if( IsMapScreenHelpTextUp() ) { // stop mapscreen text StopMapScreenHelpText( ); return; } if( gfPreBattleInterfaceActive == TRUE ) { return; } if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); } giSortStateForMapScreenList = iValue; SortListOfMercsInTeamPanel( TRUE ); } void MapscreenMarkButtonsDirty() { // redraw buttons MarkButtonsDirty( ); // if border buttons are created if( !fShowMapInventoryPool ) { // if the attribute assignment menu is showing if ( fShowAttributeMenu ) { // don't redraw the town button, it would wipe out a chunk of the attribute menu UnMarkButtonDirty( giMapBorderButtons[ MAP_BORDER_TOWN_BTN ] ); } } }