static void fill_nh_score_entry(struct toptenentry *in, struct nh_topten_entry *out, int rank, boolean highlight) { int rolenum = str2role(in->plrole); int racenum = str2race(in->plrace); int gendnum = str2gend(in->plgend); int alignnum = str2align(in->plalign); if (rolenum == ROLE_NONE || racenum == ROLE_NONE || gendnum == ROLE_NONE || alignnum == ROLE_NONE) return; out->rank = rank; out->points = in->points; out->maxlvl = in->maxlvl; out->hp = in->hp; out->maxhp = in->maxhp; out->deaths = in->deaths; out->ver_major = in->ver_major; out->ver_minor = in->ver_minor; out->patchlevel = in->patchlevel; out->highlight = highlight; out->moves = in->moves; out->end_how = in->how; strncpy(out->name, in->name, NAMSZ); strncpy(out->death, in->death, DTHSZ); if (gendnum == 1 && roles[rolenum].name.f) strncpy(out->plrole, roles[rolenum].name.f, PLRBUFSZ); else strncpy(out->plrole, roles[rolenum].name.m, PLRBUFSZ); strncpy(out->plrace, races[racenum].noun, PLRBUFSZ); strncpy(out->plgend, genders[gendnum].adj, PLRBUFSZ); strncpy(out->plalign, aligns[alignnum].adj, PLRBUFSZ); topten_death_description(in, out->entrytxt); }
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; } } }
static void process_args(int argc, char *argv[]) { int i; const struct nh_roles_info *ri = nh_get_roles(); /* * Process options. */ while (argc > 1 && argv[1][0] == '-') { argv++; argc--; switch (argv[0][1]) { case '-': if (!strcmp(argv[0], "--help")) { puts("Usage: nethack4 [--interface PLUGIN] [OPTIONS]"); puts(""); puts("-k connection-only mode"); puts("-D start games in wizard mode"); puts("-X start games in explore mode"); puts("-u name specify player name"); puts("-p role specify role"); puts("-r race specify race"); puts("-@ specify a random character"); puts("-H dir override the playfield location"); puts("-U dir override the user directory"); puts("-Z disable suspending the process"); puts(""); puts("PLUGIN can be any libuncursed plugin that is installed"); puts("on your system; examples may include 'tty' and 'sdl'."); exit(0); } else if (!strcmp(argv[0], "--version")) { printf("NetHack 4 version %d.%d.%d\n", VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL); exit(0); } break; case 'k': ui_flags.connection_only = 1; break; case 'D': ui_flags.playmode = MODE_WIZARD; break; case 'X': ui_flags.playmode = MODE_EXPLORE; break; case 'u': if (argv[0][2]) strncpy(cmdline_name, argv[0] + 2, sizeof (cmdline_name) - 1); else if (argc > 1) { argc--; argv++; strncpy(cmdline_name, argv[0], sizeof (cmdline_name) - 1); } else printf("Player name expected after -u"); break; case 'p': /* profession (role) */ if (argv[0][2]) { i = str2role(ri, &argv[0][2]); if (i >= 0) cmdline_role = i; } else if (argc > 1) { argc--; argv++; i = str2role(ri, argv[0]); if (i >= 0) cmdline_role = i; } break; case 'r': /* race */ if (argv[0][2]) { i = str2race(ri, &argv[0][2]); if (i >= 0) cmdline_race = i; } else if (argc > 1) { argc--; argv++; i = str2race(ri, argv[0]); if (i >= 0) cmdline_race = i; } break; case '@': random_player = TRUE; break; case 'H': #ifdef UNIX if (setregid(getgid(), getgid()) < 0) exit(14); #endif if (argv[0][2]) { override_hackdir = argv[0] + 2; } else if (argc > 1) { argc--; argv++; override_hackdir = argv[0]; } break; case 'U': #ifdef UNIX if (setregid(getgid(), getgid()) < 0) exit(14); #endif if (argv[0][2]) { override_userdir = argv[0] + 2; } else if (argc > 1) { argc--; argv++; override_userdir = argv[0]; } break; case 'Z': ui_flags.no_stop = 1; break; default: i = str2role(ri, argv[0]); if (i >= 0) cmdline_role = i; } } }