int randrace(int rolenum) { int i, n = 0; /* Count the number of valid races */ for (i = 0; races[i].noun; i++) { if (validrace(rolenum, i)) n++; } /* Pick a random race */ /* Use a factor of 100 in case of bad random number generators */ if (n) n = rn2(n*100)/100; for (i = 0; races[i].noun; i++) { if (validrace(rolenum, i)) { if (n) n--; else return i; } } /* This role has no permitted races? */ return rn2(SIZE(races)-1); }
boolean nh_start_game(int fd, const char *name, int irole, int irace, int igend, int ialign, enum nh_game_modes playmode) { unsigned int seed = 0; if (!api_entry_checkpoint()) return FALSE; /* init failed; programmer error! */ if (fd == -1 || !name || !*name) goto err_out; if (!program_state.restoring) { turntime = (unsigned long long)time(NULL); seed = turntime ^ get_seedval(); /* initialize the random number generator */ mt_srand(seed); } /* else: turntime and rng seeding are done in logreplay.c */ startup_common(name, playmode); if (!validrole(irole) || !validrace(irole, irace) || !validgend(irole, irace, igend) || !validalign(irole, irace, ialign)) goto err_out; u.initrole = irole; u.initrace = irace; u.initgend = igend; u.initalign = ialign; /* write out a new logfile header "NHGAME ..." with all the initial details */ log_init(); log_newgame(fd, turntime, seed, playmode); newgame(); was_on_elbereth = !sengr_at("Elbereth", u.ux, u.uy); /* force botl update later */ wd_message(); api_exit(); return TRUE; err_out: api_exit(); return FALSE; }
static int select_a_race(int pick4u) { int choice; while (!validrace(flags.initrole, flags.initrace)) { if (pick4u || flags.initrace == ROLE_RANDOM || flags.randomall) { flags.initrace = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM); break; } /* select a race */ for (;;) { choice = do_player_selection_menu("race", query_race_name); if (choice != ROLE_NONE) break; /* reset */ if (flags.initalign >= 0) flags.initalign = ROLE_NONE; else if (flags.initgend >= 0) flags.initgend = ROLE_NONE; else return 0; } if (choice == ROLE_QUIT) { flags.initrole = ROLE_NONE; flags.initrace = ROLE_NONE; return -1; } flags.initrace = choice; } return 0; }
/* Do a window-port specific player type selection. If player_selection() offers a Quit option, it is its responsibility to clean up and terminate the process. You need to fill in pl_character[0]. */ void dummy_player_selection() { #if 0 int n, i, sel; const char** choices; int* pickmap; /* prevent an unnecessary prompt */ rigid_role_checks(); if (!flags.randomall && flags.initrole < 0) { /* select a role */ for (n = 0; roles[n].name.m; n++) continue; choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n+1)); for (;;) { for (n = 0, i = 0; roles[i].name.m; i++) { if (ok_role(i, flags.initrace, flags.initgend, flags.initalign)) { if (flags.initgend >= 0 && flags.female && roles[i].name.f) choices[n] = roles[i].name.f; else choices[n] = roles[i].name.m; pickmap[n++] = i; } } if (n > 0) break; else if (flags.initalign >= 0) flags.initalign = -1; /* reset */ else if (flags.initgend >= 0) flags.initgend = -1; else if (flags.initrace >= 0) flags.initrace = -1; else panic("no available ROLE+race+gender+alignment combinations"); } choices[n] = (const char *) 0; if (n > 1) sel = ghack_player_sel_dialog(choices, _("Player selection"), _("Choose one of the following roles:")); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); dummy_exit_nhwindows(0); } free(choices); free(pickmap); } else if (flags.initrole < 0) sel = ROLE_RANDOM; else sel = flags.initrole; if (sel == ROLE_RANDOM) { /* Random role */ sel = pick_role(flags.initrace, flags.initgend, flags.initalign, PICK_RANDOM); if (sel < 0) sel = randrole(); } flags.initrole = sel; /* Select a race, if necessary */ /* force compatibility with role, try for compatibility with * pre-selected gender/alignment */ if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) { if (flags.initrace == ROLE_RANDOM || flags.randomall) { flags.initrace = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM); if (flags.initrace < 0) flags.initrace = randrace(flags.initrole); } else { /* Count the number of valid races */ n = 0; /* number valid */ for (i = 0; races[i].noun; i++) { if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) n++; } if (n == 0) { for (i = 0; races[i].noun; i++) { if (validrace(flags.initrole, i)) n++; } } choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n + 1)); for (n = 0, i = 0; races[i].noun; i++) { if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { choices[n] = races[i].noun; pickmap[n++] = i; } } choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) sel = ghack_player_sel_dialog(choices, _("Race selection"), _("Choose one of the following races:")); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); dummy_exit_nhwindows(0); } flags.initrace = sel; free(choices); free(pickmap); } if (flags.initrace == ROLE_RANDOM) { /* Random role */ sel = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM); if (sel < 0) sel = randrace(flags.initrole); flags.initrace = sel; } } /* 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)) { if (flags.initgend == ROLE_RANDOM || flags.randomall) { flags.initgend = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM); if (flags.initgend < 0) flags.initgend = randgend(flags.initrole, flags.initrace); } else { /* Count the number of valid genders */ n = 0; /* number valid */ for (i = 0; i < ROLE_GENDERS; i++) { if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) n++; } if (n == 0) { for (i = 0; i < ROLE_GENDERS; i++) { if (validgend(flags.initrole, flags.initrace, i)) n++; } } choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n + 1)); for (n = 0, i = 0; i < ROLE_GENDERS; i++) { if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { choices[n] = genders[i].adj; pickmap[n++] = i; } } choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) sel = ghack_player_sel_dialog(choices, _("Gender selection"), _("Choose one of the following genders:")); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); dummy_exit_nhwindows(0); } flags.initgend = sel; free(choices); free(pickmap); } if (flags.initgend == ROLE_RANDOM) { /* Random gender */ sel = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM); if (sel < 0) sel = randgend(flags.initrole, flags.initrace); flags.initgend = sel; } } /* Select an alignment, if necessary */ /* force compatibility with role/race/gender */ if (flags.initalign < 0 || !validalign(flags.initrole, flags.initrace, flags.initalign)) { if (flags.initalign == ROLE_RANDOM || flags.randomall) { flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM); if (flags.initalign < 0) flags.initalign = randalign(flags.initrole, flags.initrace); } else { /* Count the number of valid alignments */ n = 0; /* number valid */ for (i = 0; i < ROLE_ALIGNS; i++) { if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) n++; } if (n == 0) { for (i = 0; i < ROLE_ALIGNS; i++) if (validalign(flags.initrole, flags.initrace, i)) n++; } choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n + 1)); for (n = 0, i = 0; i < ROLE_ALIGNS; i++) { if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { choices[n] = aligns[i].adj; pickmap[n++] = i; } } choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) sel = ghack_player_sel_dialog(choices, _("Alignment selection"), _("Choose one of the following alignments:")); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); dummy_exit_nhwindows(0); } flags.initalign = sel; free(choices); free(pickmap); } if (flags.initalign == ROLE_RANDOM) { sel = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM); if (sel < 0) sel = randalign(flags.initrole, flags.initrace); flags.initalign = sel; } } #endif }
void curses_choose_character() { int n, i, sel, count_off, pick4u; int count = 0; int cur_character = 0; const char** choices; int* pickmap; char *prompt; char pbuf[QBUFSZ]; char choice[QBUFSZ]; char tmpchoice[QBUFSZ]; #ifdef TUTORIAL_MODE winid win; anything any; menu_item *selected = 0; #endif prompt = build_plselection_prompt(pbuf, QBUFSZ, flags.initrole, flags.initrace, flags.initgend, flags.initalign); /* This part is irritating: we have to strip the choices off of the string and put them in a separate string in order to use curses_character_input_dialog for this prompt. */ while (cur_character != '[') { cur_character = prompt[count]; count++; } count_off = count; while (cur_character != ']') { tmpchoice[count - count_off] = prompt[count]; count++; cur_character = prompt[count]; } tmpchoice[count - count_off] = '\0'; lcase(tmpchoice); while (!isspace(prompt[count_off])) { count_off--; } prompt[count_off] = '\0'; sprintf(choice, "%s%c", tmpchoice, '\033'); if(strchr(tmpchoice, 't')) /* Tutorial mode */ { mvaddstr(0, 1, "New? Press t to enter a tutorial."); } /* Add capital letters as choices that aren't displayed */ for (count = 0; tmpchoice[count]; count++) { tmpchoice[count] = toupper(tmpchoice[count]); } sprintf(choice, "%s%s", choice, tmpchoice); /* prevent an unnecessary prompt */ rigid_role_checks(); if (!flags.randomall && (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE || flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)) { pick4u = tolower(curses_character_input_dialog(prompt, choice, 'y')); } else { pick4u = 'y'; } if (pick4u == 'q') /* Quit or cancelled */ { clearlocks(); curses_bail(0); } if (pick4u == 'y') { flags.randomall = TRUE; } #ifdef TUTORIAL_MODE else if (pick4u == 't') /* Tutorial mode in UnNetHack */ { clear(); mvaddstr(0, 1, "Choose a character"); refresh(); win = curses_get_wid(NHW_MENU); curses_create_nhmenu(win); any.a_int = 1; curses_add_menu(win, NO_GLYPH, &any, 'v', 0, ATR_NONE, "lawful female dwarf Valkyrie (uses melee and thrown weapons)", MENU_UNSELECTED); any.a_int = 2; curses_add_menu(win, NO_GLYPH, &any, 'w', 0, ATR_NONE, "chaotic male elf Wizard (relies mostly on spells)", MENU_UNSELECTED); any.a_int = 3; curses_add_menu(win, NO_GLYPH, &any, 'R', 0, ATR_NONE, "neutral female human Ranger (good with ranged combat)", MENU_UNSELECTED); any.a_int = 4; curses_add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE, "quit", MENU_UNSELECTED); curses_end_menu(win, "What character do you want to try?"); n = curses_select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); if (n != 1 || selected[0].item.a_int == 4) { clearlocks(); curses_bail(0); } switch (selected[0].item.a_int) { case 1: flags.initrole = str2role("Valkyrie"); flags.initrace = str2race("dwarf"); flags.initgend = str2gend("female"); flags.initalign = str2align("lawful"); break; case 2: flags.initrole = str2role("Wizard"); flags.initrace = str2race("elf"); flags.initgend = str2gend("male"); flags.initalign = str2align("chaotic"); break; case 3: flags.initrole = str2role("Ranger"); flags.initrace = str2race("human"); flags.initgend = str2gend("female"); flags.initalign = str2align("neutral"); break; default: panic("Impossible menu selection"); break; } free((genericptr_t) selected); selected = 0; flags.tutorial = 1; } #endif clear(); refresh(); if (!flags.randomall && flags.initrole < 0) { /* select a role */ for (n = 0; roles[n].name.m; n++) continue; choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n+1)); for (;;) { for (n = 0, i = 0; roles[i].name.m; i++) { if (ok_role(i, flags.initrace, flags.initgend, flags.initalign)) { if (flags.initgend >= 0 && flags.female && roles[i].name.f) choices[n] = roles[i].name.f; else choices[n] = roles[i].name.m; pickmap[n++] = i; } } if (n > 0) break; else if (flags.initalign >= 0) flags.initalign = -1; /* reset */ else if (flags.initgend >= 0) flags.initgend = -1; else if (flags.initrace >= 0) flags.initrace = -1; else panic("no available ROLE+race+gender+alignment combinations"); } choices[n] = (const char *) 0; if (n > 1) sel = curses_character_dialog(choices, "Choose one of the following roles:"); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); curses_bail(0); } free(choices); free(pickmap); } else if (flags.initrole < 0) sel = ROLE_RANDOM; else sel = flags.initrole; if (sel == ROLE_RANDOM) { /* Random role */ sel = pick_role(flags.initrace, flags.initgend, flags.initalign, PICK_RANDOM); if (sel < 0) sel = randrole(); } flags.initrole = sel; /* Select a race, if necessary */ /* force compatibility with role, try for compatibility with * pre-selected gender/alignment */ if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) { if (flags.initrace == ROLE_RANDOM || flags.randomall) { flags.initrace = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM); if (flags.initrace < 0) flags.initrace = randrace(flags.initrole); } else { /* Count the number of valid races */ n = 0; /* number valid */ for (i = 0; races[i].noun; i++) { if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) n++; } if (n == 0) { for (i = 0; races[i].noun; i++) { if (validrace(flags.initrole, i)) n++; } } choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n + 1)); for (n = 0, i = 0; races[i].noun; i++) { if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { choices[n] = races[i].noun; pickmap[n++] = i; } } choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) sel = curses_character_dialog(choices, "Choose one of the following races:"); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); curses_bail(0); } flags.initrace = sel; free(choices); free(pickmap); } if (flags.initrace == ROLE_RANDOM) { /* Random role */ sel = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM); if (sel < 0) sel = randrace(flags.initrole); flags.initrace = sel; } } /* 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)) { if (flags.initgend == ROLE_RANDOM || flags.randomall) { flags.initgend = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM); if (flags.initgend < 0) flags.initgend = randgend(flags.initrole, flags.initrace); } else { /* Count the number of valid genders */ n = 0; /* number valid */ for (i = 0; i < ROLE_GENDERS; i++) { if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) n++; } if (n == 0) { for (i = 0; i < ROLE_GENDERS; i++) { if (validgend(flags.initrole, flags.initrace, i)) n++; } } choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n + 1)); for (n = 0, i = 0; i < ROLE_GENDERS; i++) { if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { choices[n] = genders[i].adj; pickmap[n++] = i; } } choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) sel = curses_character_dialog(choices, "Choose one of the following genders:"); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); curses_bail(0); } flags.initgend = sel; free(choices); free(pickmap); } if (flags.initgend == ROLE_RANDOM) { /* Random gender */ sel = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM); if (sel < 0) sel = randgend(flags.initrole, flags.initrace); flags.initgend = sel; } } /* Select an alignment, if necessary */ /* force compatibility with role/race/gender */ if (flags.initalign < 0 || !validalign(flags.initrole, flags.initrace, flags.initalign)) { if (flags.initalign == ROLE_RANDOM || flags.randomall) { flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM); if (flags.initalign < 0) flags.initalign = randalign(flags.initrole, flags.initrace); } else { /* Count the number of valid alignments */ n = 0; /* number valid */ for (i = 0; i < ROLE_ALIGNS; i++) { if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) n++; } if (n == 0) { for (i = 0; i < ROLE_ALIGNS; i++) if (validalign(flags.initrole, flags.initrace, i)) n++; } choices = (const char **)alloc(sizeof(char *) * (n+1)); pickmap = (int*)alloc(sizeof(int) * (n + 1)); for (n = 0, i = 0; i < ROLE_ALIGNS; i++) { if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { choices[n] = aligns[i].adj; pickmap[n++] = i; } } choices[n] = (const char *) 0; /* Permit the user to pick, if there is more than one */ if (n > 1) sel = curses_character_dialog(choices, "Choose one of the following alignments:"); else sel = 0; if (sel >= 0) sel = pickmap[sel]; else if (sel == ROLE_NONE) { /* Quit */ clearlocks(); curses_bail(0); } flags.initalign = sel; free(choices); free(pickmap); } if (flags.initalign == ROLE_RANDOM) { sel = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM); if (sel < 0) sel = randalign(flags.initrole, flags.initrace); flags.initalign = sel; } } }
void nds_player_selection() { int i, k, n; char pick4u = 'n', thisch, lastch = 0; char pbuf[PROMPT_LAYER_WIDTH], plbuf[PROMPT_LAYER_WIDTH]; winid win; anything any; menu_item *selected = 0; /* prevent an unnecessary prompt */ rigid_role_checks(); /* Should we randomly pick for the player? */ if (!flags.randomall && (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE || flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)) { char *prompt = build_plselection_prompt(pbuf, PROMPT_LAYER_WIDTH, flags.initrole, flags.initrace, flags.initgend, flags.initalign); int res = _nds_display_yes_no_prompt(prompt); if (res < 0) { give_up: return; } if (res) { pick4u = 'y'; } } root_plselection_prompt(plbuf, PROMPT_LAYER_WIDTH - 1, flags.initrole, flags.initrace, flags.initgend, flags.initalign); /* Select a role, if necessary */ /* we'll try to be compatible with pre-selected race/gender/alignment, * but may not succeed */ if (flags.initrole < 0) { char rolenamebuf[PROMPT_LAYER_WIDTH]; /* Process the choice */ if (pick4u == 'y' || flags.initrole == ROLE_RANDOM || flags.randomall) { /* Pick a random role */ flags.initrole = pick_role(flags.initrace, flags.initgend, flags.initalign, PICK_RANDOM); if (flags.initrole < 0) { iprintf("Incompatible role!"); flags.initrole = randrole(); } } else { /* Prompt for a role */ win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; roles[i].name.m; i++) { if (ok_role(i, flags.initrace, flags.initgend, flags.initalign)) { any.a_int = i+1; /* must be non-zero */ thisch = lowc(roles[i].name.m[0]); if (thisch == lastch) thisch = highc(thisch); if (flags.initgend != ROLE_NONE && flags.initgend != ROLE_RANDOM) { if (flags.initgend == 1 && roles[i].name.f) Strcpy(rolenamebuf, roles[i].name.f); else Strcpy(rolenamebuf, roles[i].name.m); } else { if (roles[i].name.f) { Strcpy(rolenamebuf, roles[i].name.m); Strcat(rolenamebuf, "/"); Strcat(rolenamebuf, roles[i].name.f); } else Strcpy(rolenamebuf, roles[i].name.m); } add_menu(win, NO_GLYPH, &any, thisch, 0, ATR_NONE, an(rolenamebuf), MENU_UNSELECTED); lastch = thisch; } } any.a_int = pick_role(flags.initrace, flags.initgend, flags.initalign, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randrole()+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); Sprintf(pbuf, "Pick a role for your %s", plbuf); end_menu(win, pbuf); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); /* Process the choice */ if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ flags.initrole = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } (void) root_plselection_prompt(plbuf, PROMPT_LAYER_WIDTH - 1, flags.initrole, flags.initrace, flags.initgend, flags.initalign); } /* Select a race, if necessary */ /* force compatibility with role, try for compatibility with * pre-selected gender/alignment */ if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) { /* pre-selected race not valid */ if (pick4u == 'y' || flags.initrace == ROLE_RANDOM || flags.randomall) { flags.initrace = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM); if (flags.initrace < 0) { iprintf("Incompatible race!"); flags.initrace = randrace(flags.initrole); } } else { /* pick4u == 'n' */ /* Count the number of valid races */ n = 0; /* number valid */ k = 0; /* valid race */ for (i = 0; races[i].noun; i++) { if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { n++; k = i; } } if (n == 0) { for (i = 0; races[i].noun; i++) { if (validrace(flags.initrole, i)) { n++; k = i; } } } /* Permit the user to pick, if there is more than one */ if (n > 1) { win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; races[i].noun; i++) if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any, races[i].noun[0], 0, ATR_NONE, races[i].noun, MENU_UNSELECTED); } any.a_int = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randrace(flags.initrole)+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); Sprintf(pbuf, "Pick the race of your %s", plbuf); end_menu(win, pbuf); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ k = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } flags.initrace = k; } (void) root_plselection_prompt(plbuf, PROMPT_LAYER_WIDTH - 1, flags.initrole, flags.initrace, flags.initgend, flags.initalign); } /* 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 (pick4u == 'y' || flags.initgend == ROLE_RANDOM || flags.randomall) { flags.initgend = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM); if (flags.initgend < 0) { iprintf("Incompatible gender!"); flags.initgend = randgend(flags.initrole, flags.initrace); } } else { /* pick4u == 'n' */ /* Count the number of valid genders */ n = 0; /* number valid */ k = 0; /* valid gender */ for (i = 0; i < ROLE_GENDERS; i++) { if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { n++; k = i; } } if (n == 0) { for (i = 0; i < ROLE_GENDERS; i++) { if (validgend(flags.initrole, flags.initrace, i)) { n++; k = i; } } } /* Permit the user to pick, if there is more than one */ if (n > 1) { win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; i < ROLE_GENDERS; i++) if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { any.a_int = i+1; add_menu(win, NO_GLYPH, &any, genders[i].adj[0], 0, ATR_NONE, genders[i].adj, MENU_UNSELECTED); } any.a_int = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randgend(flags.initrole, flags.initrace)+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); Sprintf(pbuf, "Pick the gender of your %s", plbuf); end_menu(win, pbuf); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ k = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } flags.initgend = k; } (void) root_plselection_prompt(plbuf, PROMPT_LAYER_WIDTH - 1, flags.initrole, flags.initrace, flags.initgend, flags.initalign); } /* 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 (pick4u == 'y' || flags.initalign == ROLE_RANDOM || flags.randomall) { flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM); if (flags.initalign < 0) { iprintf("Incompatible alignment!"); flags.initalign = randalign(flags.initrole, flags.initrace); } } else { /* pick4u == 'n' */ /* Count the number of valid alignments */ n = 0; /* number valid */ k = 0; /* valid alignment */ for (i = 0; i < ROLE_ALIGNS; i++) { if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { n++; k = i; } } if (n == 0) { for (i = 0; i < ROLE_ALIGNS; i++) { if (validalign(flags.initrole, flags.initrace, i)) { n++; k = i; } } } /* Permit the user to pick, if there is more than one */ if (n > 1) { win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; i < ROLE_ALIGNS; i++) if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { any.a_int = i+1; add_menu(win, NO_GLYPH, &any, aligns[i].adj[0], 0, ATR_NONE, aligns[i].adj, MENU_UNSELECTED); } any.a_int = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randalign(flags.initrole, flags.initrace)+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); Sprintf(pbuf, "Pick the alignment of your %s", plbuf); end_menu(win, pbuf); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ k = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } flags.initalign = k; } } }
/* * Special setup modifications here: * * Unfortunately, this is going to have to be done * on each newgame or restore, because you lose the permonst mods * across a save/restore. :-) * * 1 - The Rogue Leader is the Tourist Nemesis. * 2 - Priests start with a random alignment - convert the leader and * guardians here. * 3 - Elves can have one of two different leaders, but can't work it * out here because it requires hacking the level file data (see * sp_lev.c). * * This code also replaces quest_init(). */ void role_init(void) { int alignmnt; /* Check for a valid role. Try u.initrole first. */ if (!validrole(u.initrole)) { /* Try the player letter second */ if ((u.initrole = str2role(pl_character)) < 0) /* None specified; pick a random role */ u.initrole = randrole(); } /* We now have a valid role index. Copy the role name back. */ /* This should become OBSOLETE */ strcpy(pl_character, roles[u.initrole].name.m); pl_character[PL_CSIZ-1] = '\0'; /* Check for a valid race */ if (!validrace(u.initrole, u.initrace)) u.initrace = randrace(u.initrole); /* Check for a valid gender. If new game, check both initgend * and female. On restore, assume flags.female is correct. */ if (flags.pantheon == -1) { /* new game */ if (!validgend(u.initrole, u.initrace, flags.female)) flags.female = !flags.female; } if (!validgend(u.initrole, u.initrace, u.initgend)) /* Note that there is no way to check for an unspecified gender. */ u.initgend = flags.female; /* Check for a valid alignment */ if (!validalign(u.initrole, u.initrace, u.initalign)) /* Pick a random alignment */ u.initalign = randalign(u.initrole, u.initrace); alignmnt = aligns[u.initalign].value; /* Initialize urole and urace */ urole = roles[u.initrole]; urace = races[u.initrace]; /* Fix up the quest leader */ pm_leader = mons[urole.ldrnum]; if (urole.ldrnum != NON_PM) { pm_leader.msound = MS_LEADER; pm_leader.mflags2 |= (M2_PEACEFUL); pm_leader.mflags3 |= M3_CLOSE; pm_leader.maligntyp = alignmnt * 3; } /* Fix up the quest guardians */ pm_guardian = mons[urole.guardnum]; if (urole.guardnum != NON_PM) { pm_guardian.mflags2 |= (M2_PEACEFUL); pm_guardian.maligntyp = alignmnt * 3; } /* Fix up the quest nemesis */ pm_nemesis = mons[urole.neminum]; if (urole.neminum != NON_PM) { pm_nemesis.msound = MS_NEMESIS; pm_nemesis.mflags2 &= ~(M2_PEACEFUL); pm_nemesis.mflags2 |= (M2_NASTY|M2_STALK|M2_HOSTILE); pm_nemesis.mflags3 |= M3_WANTSARTI | M3_WAITFORU; } /* Fix up the god names */ if (flags.pantheon == -1) { /* new game */ flags.pantheon = u.initrole; /* use own gods */ while (!roles[flags.pantheon].lgod) /* unless they're missing */ flags.pantheon = randrole(); } if (!urole.lgod) { urole.lgod = roles[flags.pantheon].lgod; urole.ngod = roles[flags.pantheon].ngod; urole.cgod = roles[flags.pantheon].cgod; } /* Fix up initial roleplay flags */ if (Role_if(PM_MONK)) flags.vegetarian = TRUE; flags.vegan |= flags.ascet; flags.vegetarian |= flags.vegan; /* Artifacts are fixed in hack_artifacts() */ /* Success! */ return; }
/* 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; }
/* initialize player selector dialog */ void plselInitDialog(HWND hWnd) { TCHAR wbuf[BUFSZ]; /* set player name */ SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(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); } }