The g? structs had a mix of variables that were written to
the savefile, and those that were not.
For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.
This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.
Details:
gb.bases -> svb.bases
gb.bbubbles -> svb.bbubbles
gb.branches -> svb.branches
gc.context -> svc.context
gd.disco -> svd.disco
gd.dndest -> svd.dndest
gd.doors -> svd.doors
gd.doors_alloc -> svd.doors_alloc
gd.dungeon_topology -> svd.dungeon_topology
gd.dungeons -> svd.dungeons
ge.exclusion_zones -> sve.exclusion_zones
gh.hackpid -> svh.hackpid
gi.inv_pos -> svi.inv_pos
gk.killer -> svk.killer
gl.lastseentyp -> svl.lastseentyp
gl.level -> svl.level
gl.level_info -> svl.level_info
gm.mapseenchn -> svm.mapseenchn
gm.moves -> svm.moves
gm.mvitals -> svm.mvitals
gn.n_dgns -> svn.n_dgns
gn.n_regions -> svn.n_regions
gn.nroom -> svn.nroom
go.oracle_cnt -> svo.oracle_cnt
gp.pl_character -> svp.pl_character
gp.pl_fruit -> svp.pl_fruit
gp.plname -> svp.plname
gp.program_state -> svp.program_state
gq.quest_status -> svq.quest_status
gr.rooms -> svr.rooms
gs.sp_levchn -> svs.sp_levchn
gs.spl_book -> svs.spl_book
gt.timer_id -> svt.timer_id
gt.tune -> svt.tune
gu.updest -> svu.updest
gx.xmax -> svx.xmax
gx.xmin -> svx.xmin
gy.ymax -> svy.ymax
gy.ymin -> svy.ymin
Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
gf.ftrap, gl.light_base, gt.timer_base
826 lines
28 KiB
C
826 lines
28 KiB
C
/* NetHack 3.6 mhdlg.c $NHDT-Date: 1432512802 2015/05/25 00:13:22 $ $NHDT-Branch: master $:$NHDT-Revision: 1.18 $ */
|
|
/* Copyright (C) 2001 by Alex Kompel */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
/* various dialog boxes are defined here */
|
|
|
|
#include "winMS.h"
|
|
#include "hack.h"
|
|
#include "func_tab.h"
|
|
#include "mhdlg.h"
|
|
#include "mhmain.h"
|
|
|
|
#define CheckDlgButton(dlg, btn_id, st) \
|
|
SendDlgItemMessage((dlg), (btn_id), BM_SETCHECK, (WPARAM)(st), 0)
|
|
|
|
/*---------------------------------------------------------------*/
|
|
/* data for getlin dialog */
|
|
struct getlin_data {
|
|
const char *question;
|
|
char *result;
|
|
size_t result_size;
|
|
};
|
|
|
|
LRESULT CALLBACK GetlinDlgProc(HWND, UINT, WPARAM, LPARAM);
|
|
|
|
int
|
|
mswin_getlin_window(const char *question, char *result, size_t result_size)
|
|
{
|
|
int ret;
|
|
struct getlin_data data;
|
|
|
|
/* initilize dialog data */
|
|
ZeroMemory(&data, sizeof(data));
|
|
data.question = question;
|
|
data.result = result;
|
|
data.result_size = result_size;
|
|
|
|
/* create modal dialog window */
|
|
ret = DialogBoxParam(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_GETLIN),
|
|
GetNHApp()->hMainWnd, GetlinDlgProc, (LPARAM) &data);
|
|
if (ret == -1)
|
|
panic("Cannot create getlin window");
|
|
|
|
return ret;
|
|
}
|
|
|
|
LRESULT CALLBACK
|
|
GetlinDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
struct getlin_data *data;
|
|
RECT main_rt, text_rt, dlg_rt, edit_rt;
|
|
SIZE dlg_sz;
|
|
TCHAR wbuf[BUFSZ];
|
|
HDC hdc;
|
|
HWND control;
|
|
HWND hwndMap;
|
|
|
|
#if defined(WIN_CE_POCKETPC)
|
|
SHInputDialog(hWnd, message, wParam);
|
|
#endif
|
|
|
|
switch (message) {
|
|
case WM_INITDIALOG:
|
|
data = (struct getlin_data *) lParam;
|
|
SetWindowText(hWnd, NH_A2W(data->question, wbuf, sizeof(wbuf)));
|
|
SetWindowLong(hWnd, GWL_USERDATA, lParam);
|
|
|
|
/* get title text width */
|
|
SetRect(&text_rt, 0, 0, 100, 50);
|
|
hdc = GetWindowDC(hWnd);
|
|
DrawText(hdc, wbuf, _tcslen(wbuf), &text_rt,
|
|
DT_CALCRECT | DT_SINGLELINE | DT_NOPREFIX | DT_LEFT
|
|
| DT_VCENTER);
|
|
ReleaseDC(hWnd, hdc);
|
|
|
|
/* center dialog in the main window */
|
|
GetWindowRect(hWnd, &dlg_rt);
|
|
hwndMap = mswin_hwnd_from_winid(WIN_MAP);
|
|
GetWindowRect(IsWindow(hwndMap) ? hwndMap : GetNHApp()->hMainWnd,
|
|
&main_rt);
|
|
dlg_sz.cx = max(
|
|
dlg_rt.right - dlg_rt.left,
|
|
min(text_rt.right - text_rt.left + GetSystemMetrics(SM_CXICON),
|
|
main_rt.right - main_rt.left));
|
|
dlg_sz.cy =
|
|
min(dlg_rt.bottom - dlg_rt.top, main_rt.bottom - main_rt.top);
|
|
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
|
|
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
|
|
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
|
|
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
|
|
MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
|
|
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
|
|
dlg_sz.cy, TRUE);
|
|
|
|
/* change layout of controls */
|
|
GetClientRect(hWnd, &dlg_rt);
|
|
|
|
control = GetDlgItem(hWnd, IDC_GETLIN_EDIT);
|
|
GetWindowRect(control, &edit_rt);
|
|
MoveWindow(control, 0, 0, dlg_rt.right - dlg_rt.left,
|
|
edit_rt.bottom - edit_rt.top, TRUE);
|
|
|
|
control = GetDlgItem(hWnd, IDOK);
|
|
GetWindowRect(control, &text_rt);
|
|
MoveWindow(control, 0, edit_rt.bottom - edit_rt.top,
|
|
(dlg_rt.right - dlg_rt.left) / 2,
|
|
text_rt.bottom - text_rt.top, TRUE);
|
|
|
|
control = GetDlgItem(hWnd, IDCANCEL);
|
|
GetWindowRect(control, &text_rt);
|
|
MoveWindow(control, (dlg_rt.right - dlg_rt.left) / 2,
|
|
edit_rt.bottom - edit_rt.top,
|
|
(dlg_rt.right - dlg_rt.left) / 2,
|
|
text_rt.bottom - text_rt.top, TRUE);
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
NHSPhoneDialogSetup(hWnd, IDC_SPHONE_DIALOGBAR, TRUE, FALSE);
|
|
#endif
|
|
|
|
/* set focus to the edit control */
|
|
SetFocus(GetDlgItem(hWnd, IDC_GETLIN_EDIT));
|
|
|
|
/* tell windows that we've set the focus */
|
|
return FALSE;
|
|
break;
|
|
|
|
case WM_COMMAND: {
|
|
TCHAR wbuf[BUFSZ];
|
|
|
|
switch (LOWORD(wParam)) {
|
|
/* OK button was pressed */
|
|
case IDOK:
|
|
data = (struct getlin_data *) GetWindowLong(hWnd, GWL_USERDATA);
|
|
SendDlgItemMessage(hWnd, IDC_GETLIN_EDIT, WM_GETTEXT,
|
|
(WPARAM) sizeof(wbuf), (LPARAM) wbuf);
|
|
NH_W2A(wbuf, data->result, data->result_size);
|
|
|
|
/* Fall through. */
|
|
|
|
/* cancel button was pressed */
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, wParam);
|
|
return TRUE;
|
|
}
|
|
} break;
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
case WM_HOTKEY:
|
|
if (VK_TBACK == HIWORD(lParam)) {
|
|
SHSendBackToFocusWindow(message, wParam, lParam);
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
} /* end switch (message) */
|
|
return FALSE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------*/
|
|
/* dialog data for the list of extended commands */
|
|
struct extcmd_data {
|
|
int *selection;
|
|
};
|
|
|
|
LRESULT CALLBACK ExtCmdDlgProc(HWND, UINT, WPARAM, LPARAM);
|
|
|
|
int
|
|
mswin_ext_cmd_window(int *selection)
|
|
{
|
|
int ret;
|
|
struct extcmd_data data;
|
|
|
|
/* init dialog data */
|
|
ZeroMemory(&data, sizeof(data));
|
|
*selection = -1;
|
|
data.selection = selection;
|
|
|
|
/* create modal dialog window */
|
|
ret = DialogBoxParam(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_EXTCMD),
|
|
GetNHApp()->hMainWnd, ExtCmdDlgProc, (LPARAM) &data);
|
|
if (ret == -1)
|
|
panic("Cannot create extcmd window");
|
|
return ret;
|
|
}
|
|
|
|
LRESULT CALLBACK
|
|
ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
struct extcmd_data *data;
|
|
RECT main_rt, dlg_rt;
|
|
SIZE dlg_sz;
|
|
int i;
|
|
const char *ptr;
|
|
TCHAR wbuf[255];
|
|
|
|
switch (message) {
|
|
case WM_INITDIALOG:
|
|
data = (struct extcmd_data *) lParam;
|
|
SetWindowLong(hWnd, GWL_USERDATA, lParam);
|
|
|
|
/* center dialog in the main window */
|
|
GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
|
|
GetWindowRect(hWnd, &dlg_rt);
|
|
dlg_sz.cx = dlg_rt.right - dlg_rt.left;
|
|
dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
|
|
|
|
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
|
|
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
|
|
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
|
|
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
|
|
MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
|
|
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
|
|
dlg_sz.cy, TRUE);
|
|
|
|
/* fill combobox with extended commands */
|
|
for (i = 0; (ptr = extcmdlist[i].ef_txt); i++) {
|
|
SendDlgItemMessage(hWnd, IDC_EXTCMD_LIST, LB_ADDSTRING,
|
|
(WPARAM) 0,
|
|
(LPARAM) NH_A2W(ptr, wbuf, sizeof(wbuf)));
|
|
}
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
NHSPhoneDialogSetup(hWnd, IDC_SPHONE_DIALOGBAR, FALSE, FALSE);
|
|
|
|
GetClientRect(hWnd, &dlg_rt);
|
|
MoveWindow(GetDlgItem(hWnd, IDC_EXTCMD_LIST), dlg_rt.left, dlg_rt.top,
|
|
dlg_rt.right - dlg_rt.left, dlg_rt.bottom - dlg_rt.top,
|
|
TRUE);
|
|
#endif
|
|
|
|
/* set focus to the list control */
|
|
SetFocus(GetDlgItem(hWnd, IDC_EXTCMD_LIST));
|
|
|
|
/* tell windows we set the focus */
|
|
return FALSE;
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
data = (struct extcmd_data *) GetWindowLong(hWnd, GWL_USERDATA);
|
|
switch (LOWORD(wParam)) {
|
|
/* OK button ws clicked */
|
|
case IDOK:
|
|
*data->selection = SendDlgItemMessage(
|
|
hWnd, IDC_EXTCMD_LIST, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
|
|
if (*data->selection == LB_ERR)
|
|
*data->selection = -1;
|
|
/* Fall through. */
|
|
|
|
/* CANCEL button ws clicked */
|
|
case IDCANCEL:
|
|
EndDialog(hWnd, wParam);
|
|
return TRUE;
|
|
|
|
/* list control events */
|
|
case IDC_EXTCMD_LIST:
|
|
switch (HIWORD(wParam)) {
|
|
case LBN_DBLCLK:
|
|
/* double click within the list
|
|
wParam
|
|
The low-order word is the list box identifier.
|
|
The high-order word is the notification message.
|
|
lParam
|
|
Handle to the list box
|
|
*/
|
|
*data->selection = SendMessage((HWND) lParam, LB_GETCURSEL,
|
|
(WPARAM) 0, (LPARAM) 0);
|
|
if (*data->selection == LB_ERR)
|
|
*data->selection = -1;
|
|
EndDialog(hWnd, IDOK);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*---------------------------------------------------------------*/
|
|
/* player selector dialog data */
|
|
struct plsel_data {
|
|
int *selection;
|
|
};
|
|
|
|
BOOL CALLBACK PlayerSelectorDlgProc(HWND, UINT, WPARAM, LPARAM);
|
|
static void plselInitDialog(HWND hWnd);
|
|
static void plselAdjustLists(HWND hWnd, int changed_opt);
|
|
static int plselFinalSelection(HWND hWnd, int *selection);
|
|
|
|
int
|
|
mswin_player_selection_window(int *selection)
|
|
{
|
|
int ret;
|
|
struct plsel_data data;
|
|
|
|
/* init dialog data */
|
|
ZeroMemory(&data, sizeof(data));
|
|
data.selection = selection;
|
|
|
|
/* create modal dialog */
|
|
ret = DialogBoxParam(
|
|
GetNHApp()->hApp, MAKEINTRESOURCE(IDD_PLAYER_SELECTOR),
|
|
GetNHApp()->hMainWnd, PlayerSelectorDlgProc, (LPARAM) &data);
|
|
if (ret == -1)
|
|
panic("Cannot create getlin window");
|
|
|
|
return ret;
|
|
}
|
|
|
|
BOOL CALLBACK
|
|
PlayerSelectorDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
struct plsel_data *data;
|
|
RECT main_rt, dlg_rt;
|
|
SIZE dlg_sz;
|
|
|
|
switch (message) {
|
|
case WM_INITDIALOG:
|
|
data = (struct plsel_data *) lParam;
|
|
SetWindowLong(hWnd, GWL_USERDATA, lParam);
|
|
|
|
/* center dialog in the main window */
|
|
GetWindowRect(GetNHApp()->hMainWnd, &main_rt);
|
|
GetWindowRect(hWnd, &dlg_rt);
|
|
dlg_sz.cx = dlg_rt.right - dlg_rt.left;
|
|
dlg_sz.cy = dlg_rt.bottom - dlg_rt.top;
|
|
|
|
dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
|
|
dlg_rt.right = dlg_rt.left + dlg_sz.cx;
|
|
dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
|
|
dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
|
|
MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
|
|
(main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
|
|
dlg_sz.cy, TRUE);
|
|
|
|
/* init dialog */
|
|
plselInitDialog(hWnd);
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
NHSPhoneDialogSetup(hWnd, IDC_SPHONE_DIALOGBAR, FALSE, FALSE);
|
|
#endif
|
|
/* set focus on the role checkbox (random) field */
|
|
SetFocus(GetDlgItem(hWnd, IDC_PLSEL_ROLE_RANDOM));
|
|
|
|
/* tell windows we set the focus */
|
|
return FALSE;
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
data = (struct plsel_data *) GetWindowLong(hWnd, GWL_USERDATA);
|
|
switch (LOWORD(wParam)) {
|
|
/* OK button was clicked */
|
|
case IDOK:
|
|
if (plselFinalSelection(hWnd, data->selection)) {
|
|
EndDialog(hWnd, wParam);
|
|
} else {
|
|
MessageBox(
|
|
hWnd, TEXT("Cannot match this role. Try something else."),
|
|
TEXT("STOP"), MB_OK);
|
|
}
|
|
return TRUE;
|
|
|
|
/* CANCEL button was clicked */
|
|
case IDCANCEL:
|
|
*data->selection = -1;
|
|
EndDialog(hWnd, wParam);
|
|
return TRUE;
|
|
|
|
/* following are events from dialog controls:
|
|
"random" checkboxes send BN_CLICKED messages;
|
|
role/race/... combo-boxes send CBN_SELENDOK
|
|
if something was selected;
|
|
*/
|
|
case IDC_PLSEL_ROLE_RANDOM:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
/* enable corresponding list window if "random"
|
|
checkbox was "unchecked" */
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST),
|
|
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
|
|
== BST_UNCHECKED);
|
|
}
|
|
break;
|
|
|
|
case IDC_PLSEL_RACE_RANDOM:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST),
|
|
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
|
|
== BST_UNCHECKED);
|
|
}
|
|
break;
|
|
|
|
case IDC_PLSEL_GENDER_RANDOM:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST),
|
|
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
|
|
== BST_UNCHECKED);
|
|
}
|
|
break;
|
|
|
|
case IDC_PLSEL_ALIGN_RANDOM:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST),
|
|
SendMessage((HWND) lParam, BM_GETCHECK, 0, 0)
|
|
== BST_UNCHECKED);
|
|
}
|
|
break;
|
|
|
|
case IDC_PLSEL_ROLE_LIST:
|
|
if (HIWORD(wParam) == CBN_SELENDOK) {
|
|
/* filter out invalid options if
|
|
the selection was made */
|
|
plselAdjustLists(hWnd, LOWORD(wParam));
|
|
}
|
|
break;
|
|
|
|
case IDC_PLSEL_RACE_LIST:
|
|
if (HIWORD(wParam) == CBN_SELENDOK) {
|
|
plselAdjustLists(hWnd, LOWORD(wParam));
|
|
}
|
|
break;
|
|
|
|
case IDC_PLSEL_GENDER_LIST:
|
|
if (HIWORD(wParam) == CBN_SELENDOK) {
|
|
plselAdjustLists(hWnd, LOWORD(wParam));
|
|
}
|
|
break;
|
|
|
|
case IDC_PLSEL_ALIGN_LIST:
|
|
if (HIWORD(wParam) == CBN_SELENDOK) {
|
|
plselAdjustLists(hWnd, LOWORD(wParam));
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
setComboBoxValue(HWND hWnd, int combo_box, int value)
|
|
{
|
|
int index_max = SendDlgItemMessage(hWnd, combo_box, CB_GETCOUNT, 0, 0);
|
|
int index;
|
|
int value_to_set = LB_ERR;
|
|
for (index = 0; index < index_max; index++) {
|
|
if (SendDlgItemMessage(hWnd, combo_box, CB_GETITEMDATA,
|
|
(WPARAM) index, 0) == value) {
|
|
value_to_set = index;
|
|
break;
|
|
}
|
|
}
|
|
SendDlgItemMessage(hWnd, combo_box, CB_SETCURSEL, (WPARAM) value_to_set,
|
|
0);
|
|
}
|
|
|
|
/* initialize player selector dialog */
|
|
void
|
|
plselInitDialog(HWND hWnd)
|
|
{
|
|
TCHAR wbuf[BUFSZ];
|
|
|
|
/* set player name */
|
|
SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(svp.plname, wbuf, sizeof(wbuf)));
|
|
|
|
/* check flags for consistency */
|
|
if (flags.initrole >= 0) {
|
|
if (flags.initrace >= 0
|
|
&& !validrace(flags.initrole, flags.initrace)) {
|
|
flags.initrace = ROLE_NONE;
|
|
}
|
|
|
|
if (flags.initgend >= 0
|
|
&& !validgend(flags.initrole, flags.initrace, flags.initgend)) {
|
|
flags.initgend = ROLE_NONE;
|
|
}
|
|
|
|
if (flags.initalign >= 0
|
|
&& !validalign(flags.initrole, flags.initrace, flags.initalign)) {
|
|
flags.initalign = ROLE_NONE;
|
|
}
|
|
}
|
|
|
|
/* populate select boxes */
|
|
plselAdjustLists(hWnd, -1);
|
|
|
|
/* intialize roles list */
|
|
if (flags.initrole < 0
|
|
|| !ok_role(flags.initrole, ROLE_NONE, ROLE_NONE, ROLE_NONE)) {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_CHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), FALSE);
|
|
} else {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_ROLE_RANDOM, BST_UNCHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST), TRUE);
|
|
setComboBoxValue(hWnd, IDC_PLSEL_ROLE_LIST, flags.initrole);
|
|
}
|
|
|
|
/* intialize races list */
|
|
if (flags.initrace < 0
|
|
|| !ok_race(flags.initrole, flags.initrace, ROLE_NONE, ROLE_NONE)) {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_CHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), FALSE);
|
|
} else {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_RACE_RANDOM, BST_UNCHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST), TRUE);
|
|
setComboBoxValue(hWnd, IDC_PLSEL_RACE_LIST, flags.initrace);
|
|
}
|
|
|
|
/* intialize genders list */
|
|
if (flags.initgend < 0
|
|
|| !ok_gend(flags.initrole, flags.initrace, flags.initgend,
|
|
ROLE_NONE)) {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_CHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), FALSE);
|
|
} else {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_GENDER_RANDOM, BST_UNCHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST), TRUE);
|
|
setComboBoxValue(hWnd, IDC_PLSEL_GENDER_LIST, flags.initgend);
|
|
}
|
|
|
|
/* intialize alignments list */
|
|
if (flags.initalign < 0
|
|
|| !ok_align(flags.initrole, flags.initrace, flags.initgend,
|
|
flags.initalign)) {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_CHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), FALSE);
|
|
} else {
|
|
CheckDlgButton(hWnd, IDC_PLSEL_ALIGN_RANDOM, BST_UNCHECKED);
|
|
EnableWindow(GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST), TRUE);
|
|
setComboBoxValue(hWnd, IDC_PLSEL_ALIGN_LIST, flags.initalign);
|
|
}
|
|
}
|
|
|
|
/* adjust role/race/alignment/gender list - filter out
|
|
invalid combinations
|
|
changed_sel points to the list where selection occurred
|
|
(-1 if unknown)
|
|
*/
|
|
void
|
|
plselAdjustLists(HWND hWnd, int changed_sel)
|
|
{
|
|
HWND control_role, control_race, control_gender, control_align;
|
|
int initrole, initrace, initgend, initalign;
|
|
int i;
|
|
int ind;
|
|
int valid_opt;
|
|
TCHAR wbuf[255];
|
|
|
|
/* get control handles */
|
|
control_role = GetDlgItem(hWnd, IDC_PLSEL_ROLE_LIST);
|
|
control_race = GetDlgItem(hWnd, IDC_PLSEL_RACE_LIST);
|
|
control_gender = GetDlgItem(hWnd, IDC_PLSEL_GENDER_LIST);
|
|
control_align = GetDlgItem(hWnd, IDC_PLSEL_ALIGN_LIST);
|
|
|
|
/* get current selections */
|
|
ind = SendMessage(control_role, CB_GETCURSEL, 0, 0);
|
|
initrole = (ind == LB_ERR)
|
|
? flags.initrole
|
|
: SendMessage(control_role, CB_GETITEMDATA, ind, 0);
|
|
|
|
ind = SendMessage(control_race, CB_GETCURSEL, 0, 0);
|
|
initrace = (ind == LB_ERR)
|
|
? flags.initrace
|
|
: SendMessage(control_race, CB_GETITEMDATA, ind, 0);
|
|
|
|
ind = SendMessage(control_gender, CB_GETCURSEL, 0, 0);
|
|
initgend = (ind == LB_ERR)
|
|
? flags.initgend
|
|
: SendMessage(control_gender, CB_GETITEMDATA, ind, 0);
|
|
|
|
ind = SendMessage(control_align, CB_GETCURSEL, 0, 0);
|
|
initalign = (ind == LB_ERR)
|
|
? flags.initalign
|
|
: SendMessage(control_align, CB_GETITEMDATA, ind, 0);
|
|
|
|
/* intialize roles list */
|
|
if (changed_sel == -1) {
|
|
valid_opt = 0;
|
|
|
|
/* reset content and populate the list */
|
|
SendMessage(control_role, CB_RESETCONTENT, 0, 0);
|
|
for (i = 0; roles[i].name.m; i++) {
|
|
if (ok_role(i, initrace, initgend, initalign)) {
|
|
if (initgend >= 0 && flags.female && roles[i].name.f)
|
|
ind = SendMessage(
|
|
control_role, CB_ADDSTRING, (WPARAM) 0,
|
|
(LPARAM) NH_A2W(roles[i].name.f, wbuf, sizeof(wbuf)));
|
|
else
|
|
ind = SendMessage(
|
|
control_role, CB_ADDSTRING, (WPARAM) 0,
|
|
(LPARAM) NH_A2W(roles[i].name.m, wbuf, sizeof(wbuf)));
|
|
|
|
SendMessage(control_role, CB_SETITEMDATA, (WPARAM) ind,
|
|
(LPARAM) i);
|
|
if (i == initrole) {
|
|
SendMessage(control_role, CB_SETCURSEL, (WPARAM) ind,
|
|
(LPARAM) 0);
|
|
valid_opt = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* set selection to the previously selected role
|
|
if it is still valid */
|
|
if (!valid_opt) {
|
|
initrole = ROLE_NONE;
|
|
initrace = ROLE_NONE;
|
|
initgend = ROLE_NONE;
|
|
initalign = ROLE_NONE;
|
|
SendMessage(control_role, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
|
|
}
|
|
|
|
/* trigger change of the races list */
|
|
changed_sel = IDC_PLSEL_ROLE_LIST;
|
|
}
|
|
|
|
/* intialize races list */
|
|
if (changed_sel == IDC_PLSEL_ROLE_LIST) {
|
|
valid_opt = 0;
|
|
|
|
/* reset content and populate the list */
|
|
SendMessage(control_race, CB_RESETCONTENT, 0, 0);
|
|
for (i = 0; races[i].noun; i++)
|
|
if (ok_race(initrole, i, ROLE_NONE, ROLE_NONE)) {
|
|
ind = SendMessage(
|
|
control_race, CB_ADDSTRING, (WPARAM) 0,
|
|
(LPARAM) NH_A2W(races[i].noun, wbuf, sizeof(wbuf)));
|
|
SendMessage(control_race, CB_SETITEMDATA, (WPARAM) ind,
|
|
(LPARAM) i);
|
|
if (i == initrace) {
|
|
SendMessage(control_race, CB_SETCURSEL, (WPARAM) ind,
|
|
(LPARAM) 0);
|
|
valid_opt = 1;
|
|
}
|
|
}
|
|
|
|
/* set selection to the previously selected race
|
|
if it is still valid */
|
|
if (!valid_opt) {
|
|
initrace = ROLE_NONE;
|
|
initgend = ROLE_NONE;
|
|
initalign = ROLE_NONE;
|
|
SendMessage(control_race, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
|
|
}
|
|
|
|
/* trigger change of the genders list */
|
|
changed_sel = IDC_PLSEL_RACE_LIST;
|
|
}
|
|
|
|
/* intialize genders list */
|
|
if (changed_sel == IDC_PLSEL_RACE_LIST) {
|
|
valid_opt = 0;
|
|
|
|
/* reset content and populate the list */
|
|
SendMessage(control_gender, CB_RESETCONTENT, 0, 0);
|
|
for (i = 0; i < ROLE_GENDERS; i++)
|
|
if (ok_gend(initrole, initrace, i, ROLE_NONE)) {
|
|
ind = SendMessage(
|
|
control_gender, CB_ADDSTRING, (WPARAM) 0,
|
|
(LPARAM) NH_A2W(genders[i].adj, wbuf, sizeof(wbuf)));
|
|
SendMessage(control_gender, CB_SETITEMDATA, (WPARAM) ind,
|
|
(LPARAM) i);
|
|
if (i == initgend) {
|
|
SendMessage(control_gender, CB_SETCURSEL, (WPARAM) ind,
|
|
(LPARAM) 0);
|
|
valid_opt = 1;
|
|
}
|
|
}
|
|
|
|
/* set selection to the previously selected gender
|
|
if it is still valid */
|
|
if (!valid_opt) {
|
|
initgend = ROLE_NONE;
|
|
initalign = ROLE_NONE;
|
|
SendMessage(control_gender, CB_SETCURSEL, (WPARAM) -1,
|
|
(LPARAM) 0);
|
|
}
|
|
|
|
/* trigger change of the alignments list */
|
|
changed_sel = IDC_PLSEL_GENDER_LIST;
|
|
}
|
|
|
|
/* intialize alignments list */
|
|
if (changed_sel == IDC_PLSEL_GENDER_LIST) {
|
|
valid_opt = 0;
|
|
|
|
/* reset content and populate the list */
|
|
SendMessage(control_align, CB_RESETCONTENT, 0, 0);
|
|
for (i = 0; i < ROLE_ALIGNS; i++)
|
|
if (ok_align(initrole, initrace, initgend, i)) {
|
|
ind = SendMessage(
|
|
control_align, CB_ADDSTRING, (WPARAM) 0,
|
|
(LPARAM) NH_A2W(aligns[i].adj, wbuf, sizeof(wbuf)));
|
|
SendMessage(control_align, CB_SETITEMDATA, (WPARAM) ind,
|
|
(LPARAM) i);
|
|
if (i == initalign) {
|
|
SendMessage(control_align, CB_SETCURSEL, (WPARAM) ind,
|
|
(LPARAM) 0);
|
|
valid_opt = 1;
|
|
}
|
|
}
|
|
|
|
/* set selection to the previously selected alignment
|
|
if it is still valid */
|
|
if (!valid_opt) {
|
|
initalign = ROLE_NONE;
|
|
SendMessage(control_align, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* player made up his mind - get final selection here */
|
|
int
|
|
plselFinalSelection(HWND hWnd, int *selection)
|
|
{
|
|
int ind;
|
|
|
|
/* get current selections */
|
|
if (SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_RANDOM, BM_GETCHECK, 0, 0)
|
|
== BST_CHECKED) {
|
|
flags.initrole = ROLE_RANDOM;
|
|
} else {
|
|
ind =
|
|
SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST, CB_GETCURSEL, 0, 0);
|
|
flags.initrole = (ind == LB_ERR)
|
|
? ROLE_RANDOM
|
|
: SendDlgItemMessage(hWnd, IDC_PLSEL_ROLE_LIST,
|
|
CB_GETITEMDATA, ind, 0);
|
|
}
|
|
|
|
if (SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_RANDOM, BM_GETCHECK, 0, 0)
|
|
== BST_CHECKED) {
|
|
flags.initrace = ROLE_RANDOM;
|
|
} else {
|
|
ind =
|
|
SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST, CB_GETCURSEL, 0, 0);
|
|
flags.initrace = (ind == LB_ERR)
|
|
? ROLE_RANDOM
|
|
: SendDlgItemMessage(hWnd, IDC_PLSEL_RACE_LIST,
|
|
CB_GETITEMDATA, ind, 0);
|
|
}
|
|
|
|
if (SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_RANDOM, BM_GETCHECK, 0, 0)
|
|
== BST_CHECKED) {
|
|
flags.initgend = ROLE_RANDOM;
|
|
} else {
|
|
ind = SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST, CB_GETCURSEL, 0,
|
|
0);
|
|
flags.initgend = (ind == LB_ERR)
|
|
? ROLE_RANDOM
|
|
: SendDlgItemMessage(hWnd, IDC_PLSEL_GENDER_LIST,
|
|
CB_GETITEMDATA, ind, 0);
|
|
}
|
|
|
|
if (SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_RANDOM, BM_GETCHECK, 0, 0)
|
|
== BST_CHECKED) {
|
|
flags.initalign = ROLE_RANDOM;
|
|
} else {
|
|
ind = SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST, CB_GETCURSEL, 0,
|
|
0);
|
|
flags.initalign = (ind == LB_ERR)
|
|
? ROLE_RANDOM
|
|
: SendDlgItemMessage(hWnd, IDC_PLSEL_ALIGN_LIST,
|
|
CB_GETITEMDATA, ind, 0);
|
|
}
|
|
|
|
/* check the role */
|
|
if (flags.initrole == ROLE_RANDOM) {
|
|
flags.initrole = pick_role(flags.initrace, flags.initgend,
|
|
flags.initalign, PICK_RANDOM);
|
|
if (flags.initrole < 0) {
|
|
MessageBox(hWnd, TEXT("Incompatible role!"), TEXT("STOP"), MB_OK);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* Select a race, if necessary */
|
|
/* force compatibility with role */
|
|
if (flags.initrace == ROLE_RANDOM
|
|
|| !validrace(flags.initrole, flags.initrace)) {
|
|
/* pre-selected race not valid */
|
|
if (flags.initrace == ROLE_RANDOM) {
|
|
flags.initrace = pick_race(flags.initrole, flags.initgend,
|
|
flags.initalign, PICK_RANDOM);
|
|
}
|
|
|
|
if (flags.initrace < 0) {
|
|
MessageBox(hWnd, TEXT("Incompatible race!"), TEXT("STOP"), MB_OK);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* Select a gender, if necessary */
|
|
/* force compatibility with role/race, try for compatibility with
|
|
* pre-selected alignment */
|
|
if (flags.initgend < 0
|
|
|| !validgend(flags.initrole, flags.initrace, flags.initgend)) {
|
|
/* pre-selected gender not valid */
|
|
if (flags.initgend == ROLE_RANDOM) {
|
|
flags.initgend = pick_gend(flags.initrole, flags.initrace,
|
|
flags.initalign, PICK_RANDOM);
|
|
}
|
|
|
|
if (flags.initgend < 0) {
|
|
MessageBox(hWnd, TEXT("Incompatible gender!"), TEXT("STOP"),
|
|
MB_OK);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* Select an alignment, if necessary */
|
|
/* force compatibility with role/race/gender */
|
|
if (flags.initalign < 0
|
|
|| !validalign(flags.initrole, flags.initrace, flags.initalign)) {
|
|
/* pre-selected alignment not valid */
|
|
if (flags.initalign == ROLE_RANDOM) {
|
|
flags.initalign = pick_align(flags.initrole, flags.initrace,
|
|
flags.initgend, PICK_RANDOM);
|
|
} else {
|
|
MessageBox(hWnd, TEXT("Incompatible alignment!"), TEXT("STOP"),
|
|
MB_OK);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|