mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Added missing #includes Added LUA scripting and console Changed the way tracers are visualized, so they work more like real tracers instead of a light fountain Fixed signedness of many grid variables used in GetMouseMapPos calls Fixed enemy weapon choosing: Sometimes a mortar is chosen but later rejected, but the grenade class was not reset. Caused assertion failure Added checks so enemies don't try to chuck RPG grenades with their hands Now possible to shoot a someone in the head if he's in water Fixed InitSightArrays to also clear soldier interrupt duel points. This was causing an assertion failure elsewhere in the code because the interrupt list still had soldiers on it sometimes when this function was called. Soldiers are much less willing to forfeit their turn over an attempt to use more APs than they have Removed early setting of muzzle flash. This would allow enemies to get an interrupt before you even fired. Fixed item dropping by AI. If AI tried to drop something while standing it would cause deadlock Change to greatly speed up closing the sector inventory window in an unloaded sector Added conditional compile flag to always give robot weapon ready advantage, even for 360 degree sighting Check builddefines.h for the conditional flags. Of greatest interest might be LUA_CONSOLE. This will cause the game to bring up a command console when run. However this console is severely lacking in many areas. If anybody knows of an open-source terminal/console that could be used instead, it would be appreciated. The existing console does bad things when you try to close it, and since it counts as a separate app, it pauses the game while it has focus. LUA scripting is very limited, basically just proof of concept. There is one global variable, the Soldiers array. An array index gives you the soldier in that slot in the currently loaded sector. The soldier has a few things that can be accessed: name (short name); fullname (long name); grid (current grid #, can be changed); walkto(grid) (function to walk to another grid); runto(grid) (function to run to another grid) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@924 3b4a5df2-a311-0410-b5c6-a8a6f20db521
13197 lines
347 KiB
C++
13197 lines
347 KiB
C++
// WANNE 2 <changed some lines> SCROLL BUTTONS CODE IS OUTCOMMENTED (search for // WANNE 2 <scroll>)
|
|
#ifdef PRECOMPILEDHEADERS
|
|
#include "Strategic All.h"
|
|
#include "HelpScreen.h"
|
|
#else
|
|
#include "mapscreen.h"
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
#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 <wchar.h>
|
|
#include <tchar.h>
|
|
#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
|
|
|
|
// WANNE 2 <change 2>
|
|
#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
|
|
|
|
// WANNE 2
|
|
#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
|
|
|
|
// WANNE 2
|
|
#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 2 (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},
|
|
//};
|
|
|
|
// WANNE 2 <change 2>
|
|
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 2 <scroll>
|
|
// buttons images
|
|
//UINT32 guiMapMercsScrollButtonsImage[ 2 ];
|
|
//UINT32 guiMapMercsScrollButtons[ 2 ];
|
|
//
|
|
//UINT32 guiMapVehicleScrollButtonsImage[ 2 ];
|
|
//UINT32 guiMapVehicleScrollButtons [ 2 ];
|
|
|
|
|
|
|
|
extern UINT16 usVehicleY;
|
|
|
|
// WANNE 2 <scroll>
|
|
// 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 2 <scroll>
|
|
//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 );
|
|
|
|
|
|
#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--;
|
|
|
|
|
|
// WANNE 2
|
|
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 );
|
|
|
|
// WANNE 2 <this is not correct!!>
|
|
//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 );
|
|
|
|
// WANNE 2 <change ETA position>
|
|
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));
|
|
|
|
// WANNE 2
|
|
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));
|
|
|
|
// WANNE 2
|
|
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));
|
|
|
|
// WANNE 2
|
|
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 2 <scroll>
|
|
/*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 ));*/
|
|
|
|
// WANNE 2
|
|
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 );
|
|
|
|
// WANNE 2
|
|
|
|
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 2 <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 );
|
|
}
|
|
|
|
|
|
// WANNE 2 <change 2>
|
|
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
|
|
{
|
|
// WANNE 2
|
|
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
|
|
{
|
|
// WANNE 2
|
|
//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
|
|
{
|
|
// WANNE 2
|
|
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
|
|
{
|
|
// WANNE 2
|
|
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);
|
|
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);
|
|
|
|
// 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:
|
|
// 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 ].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( 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 2 <scroll>
|
|
//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);
|
|
|
|
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 2 <scroll>
|
|
//DeleteButtonsForScrolling();
|
|
|
|
ForceButtonUnDirty( giMapContractButton );
|
|
ForceButtonUnDirty( giCharInfoButton[ 0 ] );
|
|
ForceButtonUnDirty( giCharInfoButton[ 1 ] );
|
|
RenderPreBattleInterface();
|
|
}
|
|
|
|
// now render lower panel
|
|
RenderMapScreenInterfaceBottom( );
|
|
}
|
|
|
|
// WANNE 2
|
|
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;
|
|
}
|
|
|
|
// WANNE 2
|
|
// 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);
|
|
|
|
// 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();
|
|
|
|
// WANNE 2
|
|
//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
|
|
|
|
// WANNE 2
|
|
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 ));*/
|
|
|
|
// WANNE 2
|
|
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 2 <scroll>
|
|
//void BtnMercsUpMapScreenCallback( GUI_BUTTON *btn,INT32 reason )
|
|
//{
|
|
// // WANNE 2 -> see Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback)
|
|
// int i = 10;
|
|
//}
|
|
//
|
|
//void BtnMercsDownMapScreenCallback( GUI_BUTTON *btn,INT32 reason )
|
|
//{
|
|
// // WANNE 2 -> see Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback)
|
|
// int i = 10;
|
|
//}
|
|
//
|
|
//void BtnVehicleUpMapScreenCallback( GUI_BUTTON *btn,INT32 reason )
|
|
//{
|
|
// // WANNE 2 -> see Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback)
|
|
// int i = 10;
|
|
//}
|
|
//
|
|
//void BtnVehicleDownMapScreenCallback( GUI_BUTTON *btn,INT32 reason )
|
|
//{
|
|
// // WANNE 2 -> see Map Screen Interface Bottom Line 766 (BtnMessageUpMapScreenCallback)
|
|
// int i = 10;
|
|
//}
|
|
|
|
// WANNE 2 <scroll>
|
|
//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 2 <scroll>
|
|
// 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 ) )
|
|
{
|
|
// WANNE 2
|
|
//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 )
|
|
{
|
|
// WANNE 2
|
|
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 ));
|
|
}
|
|
// WANNE 2
|
|
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 ] );
|
|
}
|
|
}
|
|
}
|