Пример #1
0
static void
deliver_by_window (struct qtmsg *qt_msg, int how)
{
        long    size;
        winid datawin = create_nhwindow(how);

        for (size = 0; size < qt_msg->size; size += (long)strlen(in_line)) {
            (void) dlb_fgets(in_line, 80, msg_file);
            convert_line();
            putstr(datawin, 0, out_line);
        }
        display_nhwindow(datawin, true);
        destroy_nhwindow(datawin);
}
Пример #2
0
void nds_show_keys()
{
  winid win;
  int i;
  char buffer[BUFSZ];

  win = create_nhwindow(NHW_TEXT);

  for (i = 0; i < numkeys; i++) {
    sprintf(buffer, "%s = %s", nds_key_to_string(keymap[i].key), nds_command_to_string(keymap[i].command));
    putstr(win, ATR_NONE, buffer);
  }

  display_nhwindow(win, FALSE);
  destroy_nhwindow(win);
}
Пример #3
0
const char *nds_get_bool_option()
{
  int i, j;
  int optcnt;

  winid win;
  menu_item *sel;
  ANY_P *ids;
  const char *res;

  for (i = 0, optcnt = 0; boolopt[i].name; i++) {
    if (boolopt[i].addr != NULL) {
      optcnt++;
    }
  }

  ids = (ANY_P *)malloc(sizeof(ANY_P) * optcnt);

  win = create_nhwindow(NHW_MENU);

  start_menu(win);

  for (i = 0, j = 0; boolopt[i].name; i++) {
    if ((boolopt[i].addr == NULL) || (boolopt[i].optflags != SET_IN_GAME)) {
      continue;
    }

    ids[j].a_int = i + 1;
    add_menu(win, NO_GLYPH, &(ids[j]), 0, 0, 0, boolopt[i].name, 0);

    j++;
  }

  end_menu(win, "Which Option Should Be Toggled?");

  if (select_menu(win, PICK_ONE, &sel) >= 0) {
    res = boolopt[sel->item.a_int - 1].name;
  } else {
    res = NULL;
  }

  destroy_nhwindow(win);
  NULLFREE(sel);
  NULLFREE(ids);

  return res;
}
Пример #4
0
nds_cmd_t nds_get_pan_direction()
{
  winid win;
  menu_item *sel;
  ANY_P ids[4];
  nds_cmd_t cmd;
  int res;

  win = create_nhwindow(NHW_MENU);
  start_menu(win);

  ids[0].a_int = CMD_PAN_UP;
  ids[1].a_int = CMD_PAN_DOWN;
  ids[2].a_int = CMD_PAN_LEFT;
  ids[3].a_int = CMD_PAN_RIGHT;

  add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Pan Up", 0);
  add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "Pan Down", 0);
  add_menu(win, NO_GLYPH, &(ids[2]), 0, 0, 0, "Pan Left", 0);
  add_menu(win, NO_GLYPH, &(ids[3]), 0, 0, 0, "Pan Right", 0);

  end_menu(win, "What Direction?");
  res = select_menu(win, PICK_ONE, &sel);
  destroy_nhwindow(win);

  if (res <= 0) {
    cmd.f_char = -1;
    cmd.name = NULL;
  } else {
    cmd.f_char = sel->item.a_int;

    if (cmd.f_char == CMD_PAN_UP) {
      cmd.name = "Pan Up";
    } else if (cmd.f_char == CMD_PAN_DOWN) {
      cmd.name = "Pan Down";
    } else if (cmd.f_char == CMD_PAN_LEFT) {
      cmd.name = "Pan Left";
    } else if (cmd.f_char == CMD_PAN_RIGHT) {
      cmd.name = "Pan Right";
    }
  }

  NULLFREE(sel);

  return cmd;
}
Пример #5
0
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;
	}
    }
}
Пример #6
0
int
tty_doprev_message()
{
    register struct WinDesc *cw = wins[WIN_MESSAGE];

    winid prevmsg_win;
    int i;
    if ((iflags.prevmsg_window != 's') && !ttyDisplay->inread) { /* not single */
        if(iflags.prevmsg_window == 'f') { /* full */
            prevmsg_win = create_nhwindow(NHW_MENU);
            putstr(prevmsg_win, 0, "Message History");
            putstr(prevmsg_win, 0, "");
            cw->maxcol = cw->maxrow;
            i = cw->maxcol;
            do {
                if(cw->data[i] && strcmp(cw->data[i], "") )
                    putstr(prevmsg_win, 0, cw->data[i]);
                i = (i + 1) % cw->rows;
            } while (i != cw->maxcol);
            putstr(prevmsg_win, 0, toplines);
            display_nhwindow(prevmsg_win, TRUE);
            destroy_nhwindow(prevmsg_win);
        } else if (iflags.prevmsg_window == 'c') {		/* combination */
            do {
                morc = 0;
                if (cw->maxcol == cw->maxrow) {
                    ttyDisplay->dismiss_more = C('p');	/* <ctrl/P> allowed at --More-- */
                    redotoplin(toplines);
                    cw->maxcol--;
                    if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
                    if (!cw->data[cw->maxcol])
                        cw->maxcol = cw->maxrow;
                } else if (cw->maxcol == (cw->maxrow - 1)){
                    ttyDisplay->dismiss_more = C('p');	/* <ctrl/P> allowed at --More-- */
                    redotoplin(cw->data[cw->maxcol]);
                    cw->maxcol--;
                    if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
                    if (!cw->data[cw->maxcol])
                        cw->maxcol = cw->maxrow;
                } else {
                    prevmsg_win = create_nhwindow(NHW_MENU);
                    putstr(prevmsg_win, 0, "Message History");
                    putstr(prevmsg_win, 0, "");
                    cw->maxcol = cw->maxrow;
                    i = cw->maxcol;
                    do {
                        if(cw->data[i] && strcmp(cw->data[i], "") )
                            putstr(prevmsg_win, 0, cw->data[i]);
                        i = (i + 1) % cw->rows;
                    } while (i != cw->maxcol);
                    putstr(prevmsg_win, 0, toplines);
                    display_nhwindow(prevmsg_win, TRUE);
                    destroy_nhwindow(prevmsg_win);
                }

            } while (morc == C('p'));
            ttyDisplay->dismiss_more = 0;
        } else { /* reversed */
            morc = 0;
            prevmsg_win = create_nhwindow(NHW_MENU);
            putstr(prevmsg_win, 0, "Message History");
            putstr(prevmsg_win, 0, "");
            putstr(prevmsg_win, 0, toplines);
            cw->maxcol=cw->maxrow-1;
            if(cw->maxcol < 0) cw->maxcol = cw->rows-1;
            do {
                putstr(prevmsg_win, 0, cw->data[cw->maxcol]);
                cw->maxcol--;
                if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
                if (!cw->data[cw->maxcol])
                    cw->maxcol = cw->maxrow;
            } while (cw->maxcol != cw->maxrow);

            display_nhwindow(prevmsg_win, TRUE);
            destroy_nhwindow(prevmsg_win);
            cw->maxcol = cw->maxrow;
            ttyDisplay->dismiss_more = 0;
        }
    } else if(iflags.prevmsg_window == 's') { /* single */
        ttyDisplay->dismiss_more = C('p');  /* <ctrl/P> allowed at --More-- */
        do {
            morc = 0;
            if (cw->maxcol == cw->maxrow)
                redotoplin(toplines);
            else if (cw->data[cw->maxcol])
                redotoplin(cw->data[cw->maxcol]);
            cw->maxcol--;
            if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
            if (!cw->data[cw->maxcol])
                cw->maxcol = cw->maxrow;
        } while (morc == C('p'));
        ttyDisplay->dismiss_more = 0;
    }
    return 0;
}
Пример #7
0
/*
 *   Generic yes/no function. 'def' is the default (returned by space or
 *   return; 'esc' returns 'q', or 'n', or the default, depending on
 *   what's in the string. The 'query' string is printed before the user
 *   is asked about the string.
 *   If resp is NULL, any single character is accepted and returned.
 *   If not-NULL, only characters in it are allowed (exceptions:  the
 *   quitchars are always allowed, and if it contains '#' then digits
 *   are allowed); if it includes an <esc>, anything beyond that won't
 *   be shown in the prompt to the user but will be acceptable as input.
 */
char nds_yn_function(const char *ques, const char *cstr, CHAR_P def)
{
  char buffer[INPUT_BUFFER_SIZE];

  char *choices;
  ANY_P header_id;
  ANY_P *ids;
  winid win;
  menu_item *sel = NULL;
  int ret;
  int yn = 0;
  int ynaq = 0;
  char *direction_keys = nds_get_direction_keys();

  if ((strstr(ques, "In what direction") != NULL) ||
      (strstr(ques, "in what direction") != NULL)) {
    /*
     * We're going to use nh_poskey to get a command from the user.  However,
     * we must handle clicks specially.  Unlike normal movement, you can't
     * just click anywhere to pick a direction.  Instead, the user will be
     * expected to click in one of the adjacent squares around the player,
     * and the click will then be translated into a movement character.
     */
    while (1) {
      int x, y, mod;
      int sym;

      nds_draw_prompt("Tap an adjacent square or press a direction key.");
      nds_flush(0);
      sym = nds_get_input(&x, &y, &mod);
      nds_clear_prompt();

      if (mod == CLICK_1) {
        if ((x == u.ux - 1) && (y == u.uy - 1)) {
          return direction_keys[DIR_UP_LEFT];
        } else if ((x == u.ux) && (y == u.uy - 1)) {
          return direction_keys[DIR_UP];
        } else if ((x == u.ux + 1) && (y == u.uy - 1)) {
          return direction_keys[DIR_UP_RIGHT];
        } else if ((x == u.ux - 1) && (y == u.uy)) {
          return direction_keys[DIR_LEFT];
        } else if ((x == u.ux) && (y == u.uy)) {
          return direction_keys[DIR_WAIT];
        } else if ((x == u.ux + 1) && (y == u.uy)) {
          return direction_keys[DIR_RIGHT];
        } else if ((x == u.ux - 1) && (y == u.uy + 1)) {
          return direction_keys[DIR_DOWN_LEFT];
        } else if ((x == u.ux) && (y == u.uy + 1)) {
          return direction_keys[DIR_DOWN];
        } else if ((x == u.ux + 1) && (y == u.uy + 1)) {
          return direction_keys[DIR_DOWN_RIGHT];
        }
      } else if (mod == CLICK_2) {
        if ((x == u.ux) && (y == u.uy)) {
          return '>';
        }
      } else {
        return sym;
      }
    }
  } else if (! iflags.cmdwindow) {
    return nds_prompt_char(ques, cstr, 0);
  } else if (strstr(ques, "Adjust letter to what") != NULL) {
    return nds_prompt_char(ques, cstr, 0);
  } else if (strstr(ques, "What command?") != NULL) {
    nds_cmd_t cmd;
    
    nds_draw_prompt("Select a command.");
    nds_flush(0);
    cmd = nds_cmd_loop(CMDLOOP_WHATDOES);
    nds_clear_prompt();

    return cmd.f_char;
  } else if (strstr(ques, "What do you look for?") != NULL) {
    return nds_prompt_char(ques, cstr, 0);
  } else if (strstr(ques, "adjust?") != NULL) {
    cstr = ynchars;
  }

  if ((index(ques, '[') == NULL) && (cstr == NULL)) {
    nds_draw_prompt(ques);
    return '*';
  }

  win = create_nhwindow(NHW_MENU);

  start_menu(win);
  
  if ((cstr != NULL) && 
      ((strcasecmp(cstr, ynchars) == 0) ||
       (strcasecmp(cstr, ynqchars) == 0) ||
       ((ynaq = strcasecmp(cstr, ynaqchars)) == 0))) {

    ids = (ANY_P *)malloc(sizeof(ANY_P) * 2);

    yn = 1;

    ids[0].a_int = 'y';
    ids[1].a_int = 'n';

    add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Yes", 0);
    add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "No", 0);

    if (ynaq) {
      ids[2].a_int = 'a';

      add_menu(win, NO_GLYPH, &(ids[2]), 0, 0, 0, "All", 0);
    }
  } else if ((cstr != NULL) && (strcasecmp(cstr, "rl") == 0)) {

    ids = (ANY_P *)malloc(sizeof(ANY_P) * 2);

    ids[0].a_int = 'r';
    ids[1].a_int = 'l';

    add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Right Hand", 0);
    add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "Left Hand", 0);
  } else {
    int i;
    char curclass = -1;

    choices = _nds_parse_choices(ques);

    ids = (ANY_P *)malloc(sizeof(ANY_P) * strlen(choices));
    header_id.a_int = 0;

    for (i = 0; i < strlen(choices); i++) {

      ids[i].a_int = choices[i];

      if (choices[i] == ' ') {
        add_menu(win, NO_GLYPH, &(header_id), 0, 0, 0, "Other", 0);
      } else if (choices[i] == '*') {
        add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, "Something from your inventory", 0);
      } else if ((choices[i] == '-') || (choices[i] == '.')) {
        add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, "Nothing/your finger", 0);
      } else if (choices[i] == '?') {
        continue;
      } else {
        int oclass;
        char oname[BUFSZ];

        if (choices[i] == '$') {
          oclass = COIN_CLASS;
          sprintf(oname, "%ld gold piece%s", u.ugold, plur(u.ugold));
        } else {
          struct obj *otmp = obj_for_let(choices[i]);

          oclass = otmp->oclass;
          strcpy(oname, doname(otmp));
        }

        if (oclass != curclass) {
          add_menu(win, NO_GLYPH, &(header_id), 0, 0, 0, let_to_name(oclass, FALSE), 0);

          curclass = oclass;
        } 

        add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, oname, 0);
      }
    }
  }

  end_menu(win, ques);

  int mode = ((cstr == NULL) || (index(cstr, '#') != NULL)) ? PICK_ONE_TYPE : PICK_ONE;
  int cnt = select_menu(win, mode, &sel);

  if (cnt <= 0) {
    ret = yn ? 'n' : '\033';
  } else if ((mode == PICK_ONE) || (sel->count < 0)) {
    ret = sel->item.a_int;
  } else if (mode == PICK_ONE_TYPE) {
    sprintf(buffer, "%d%c", sel->count, sel->item.a_int);

    nds_input_buffer_append(buffer + 1);
    ret = *buffer;
  }

  if (sel != NULL) {
    free(sel);
  }

  free(ids);

  destroy_nhwindow(win);

  return ret;
}
Пример #8
0
/**
   Runs before player selection, and is used to determine which game
   mode to play in. If the choice is to continue or start a new game, it
   sets the character name to determine which (currently unused name for
   the player = new game, currently used name = continue that game);
   otherwise, it implements the choice itself then either loops or
   exits.

   This is based on the tty code, except that it uses a menu rather
   than rendering the game mode selection by hand.
*/
void
Sdlgl_game_mode_selection()
{
  int c;
  char** saved;
  char** sp;
  int plname_in_saved = 0;
  int plname_was_explicit = !!*plname;
  (void) plname_was_explicit; /* TODO: use this */

  winid menuwin;
  int n;
  menu_item *selected;
  anything any;

  saved = get_saved_games();

  if (*plname && saved && *saved) {
    for (sp = saved; *sp; sp++) {
      /* Note that this means that public servers need to prevent two
         users with the same name but different capitalisation. (If
         they aren't, it's likely to cause problems anyway...) */
      if (!strcmpi(plname, *sp)) {
        plname_in_saved = 1;
        /* Fix capitalisation of the name to match the saved game. */
        strncpy(plname, *sp, sizeof(plname)-1);
      }
    }
  } else if (*plname) {
    set_savefile_name();
    /* Let's just try to open the savefile directly to see if it exists */
    plname_in_saved = verify_savefile();
  }

retry_mode_selection:;
reread_char:
  menuwin = create_nhwindow(NHW_MENU);
  any.a_void = 0;
  start_menu(menuwin);

  any.a_int = 'c';
  add_menu(menuwin, NO_GLYPH, &any, 'c', 0, ATR_NONE,
           "Continue game", MENU_UNSELECTED);
  any.a_int = 'n';
  add_menu(menuwin, NO_GLYPH, &any, 'n', 0, ATR_NONE,
           "New game", MENU_UNSELECTED);
  any.a_int = 't';
  add_menu(menuwin, NO_GLYPH, &any, 't', 0, ATR_NONE,
           "Tutorial", MENU_UNSELECTED);
  any.a_int = 'm';
  add_menu(menuwin, NO_GLYPH, &any, 'm', 0, ATR_NONE,
           "Other modes", MENU_UNSELECTED);

  any.a_void = 0;
  add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);

  any.a_int = 's';
  add_menu(menuwin, NO_GLYPH, &any, 's', 0, ATR_NONE,
           "Continue game", MENU_UNSELECTED);
  any.a_int = 'o';
  add_menu(menuwin, NO_GLYPH, &any, 'o', 0, ATR_NONE,
           "New game", MENU_UNSELECTED);
  any.a_int = '?';
  add_menu(menuwin, NO_GLYPH, &any, '?', 0, ATR_NONE,
           "Tutorial", MENU_UNSELECTED);
  any.a_int = 'q';
  add_menu(menuwin, NO_GLYPH, &any, 'q', 0, ATR_NONE,
           "Other modes", MENU_UNSELECTED);

  end_menu(menuwin, "Welcome to AceHack!");
  n = select_menu(menuwin, PICK_ONE, &selected);
  destroy_nhwindow(menuwin);

  if (n > 0) {
    c = selected[0].item.a_int;
    free((genericptr_t)selected);
  } else goto retry_mode_selection;

#if 0
  /* TODO: This is tty code for graying out unavailable options;
     we should do that in SDL/GL code too */
  {
    if (c == 1) { /* gray out if there's no game to continue */
      if (!*plname && (!saved || !*saved)) xputs("\033[31m");
      else if (*plname && !plname_in_saved) xputs("\033[31m");
      /* and bold if there is */
      else xputs("\033[1m");
    }
    else if (c == 2) { /* gray out if a game must be continued */
      if (*plname && plname_in_saved) xputs("\033[31m");
    }
    else xputc(c); /* low-level as codes are in the file itself */
  }
#endif

  switch (c) {
  case 'c': /* continue game */
    if (*plname && plname_in_saved) break; /* just load by name */
    if (!saved || !*saved) goto reread_char;
    if (*plname && !plname_in_saved) goto reread_char;
    if (!saved[1]) {
      /* only one game to continue */
      (void) strncpy(plname, *saved, sizeof(plname)-1);
    } else {
      /* we'll have to ask which game to continue */
      winid win;
      win = create_nhwindow(NHW_MENU);
      start_menu(win);
      any.a_void = 0;
      for (sp = saved; *sp; sp++) {
        any.a_void = (void*) *sp;
        add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, *sp, MENU_UNSELECTED);
      }
      end_menu(win, "Continue which saved game?");
      c = select_menu(win, PICK_ONE, &selected);
      destroy_nhwindow(win);
      if (c != 1) {
        free((genericptr_t) selected);
        goto retry_mode_selection;
      }
      (void) strncpy(plname, (char*)selected[0].item.a_void, sizeof(plname)-1);
      free((genericptr_t) selected);
    }
    break;
  case 'n': case 't': case 'm': /* the new game options */
    /* if the name is forced by the -u option, don't give an option to
       start a new game, as we're forced onto the existing game */
    if (*plname && plname_in_saved) goto reread_char;
    if (!*plname) {
      Sdlgl_askname();
      if (saved)
        for (sp = saved; *sp; sp++) {
          if (!strcmpi(plname, *sp)) {
            pline("A game is running with that name already.");
            Sdlgl_dismiss_nhwindow(NHW_MESSAGE); /* force a --More-- */
            *plname = 0;
            goto retry_mode_selection;
          }
        }
    }
    if (c == 'm') {
      pline("TODO: implement game mode selection here");
      goto retry_mode_selection;
      do {
        c = 0; /* read from keyboard */
        switch(c) {
          /* -D, -X on command line are overriden by selecting a normal game
             explicitly */
        case 'n': wizard = FALSE; discover = FALSE; break;
        case 't': break;
        case 'd':
#ifdef WIZARD
          /* The rules here are a little complex:
             - with no -u (local play, private server play), anyone
               can enter debug mode;
             - with -u set (generally public server play), only an
               authorized user can enter debug mode.
             Thus people can enter it freely in their own compiles,
             but on public servers likely only the admin can enter it,
             as only they can tweak the command line. (-D works too
             to enter wizmode, whatever the -u option, as if it's
             given the player has control over the command line anyway.) */
          if (plname_was_explicit && strcmpi(plname,WIZARD)) {
            extern int wiz_error_flag; /* from unixmain.c */
            wiz_error_flag = TRUE;
          } else {
            wizard = TRUE;
            c = 'n';
            break;
          }
          /*FALLTHRU*/
#endif /* otherwise fall through, as debug mode isn't compiled in */
        case 'x': discover = TRUE; c = 'n'; break;
        case 's': solo = TRUE; c = 'n'; break;
        case '\033': goto retry_mode_selection;
        default: continue;
        }
      } while (c != 'n' && c != 't');
    }
    if (c == 't') flags.tutorial = 1;
    break;
  case 's': /* show high score list */
    prscore_interactive();
    goto retry_mode_selection;
  case 'o': /* options */
    doset();
    goto retry_mode_selection;
  case '?': /* help */
    dohelp();
    Sdlgl_dismiss_nhwindow(NHW_MESSAGE); /* force a --More-- */
    goto retry_mode_selection;
  case 'q': case '\033': /* exit */
    /* This is the standard Sdlgl method of exiting. */
    Sdlgl_exit_nhwindows(0);
    terminate(EXIT_SUCCESS);
    /*NOTREACHED*/
  default:
    goto reread_char;
  }

  if (saved) free_saved_games(saved);
}
Пример #9
0
nds_cmd_t nds_get_config_cmd(u16 key)
{
  winid win;
  menu_item *sel;
  ANY_P ids[15];
  nds_cmd_t cmd;
  char tmp[BUFSZ];
  int res;

  win = create_nhwindow(NHW_MENU);
  start_menu(win);

  ids[0].a_int = 1;
  ids[1].a_int = 2;
  ids[2].a_int = 3;
  ids[3].a_int = 4;
  ids[4].a_int = 5;

  add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Movement", 0);
  add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "Game Command", 0);
  add_menu(win, NO_GLYPH, &(ids[2]), 0, 0, 0, "Toggle Option", 0);
  add_menu(win, NO_GLYPH, &(ids[3]), 0, 0, 0, "Map Panning", 0);
  add_menu(win, NO_GLYPH, &(ids[4]), 0, 0, 0, "No Command", 0);

  sprintf(tmp, "What do you want to assign to %s?", nds_key_to_string(key));
  end_menu(win, tmp);
  res = select_menu(win, PICK_ONE, &sel);
  destroy_nhwindow(win);

  if (res <= 0) {
    cmd.f_char = -1;
    cmd.name = NULL;
  } else {
    switch (sel->item.a_int) {
      case 1:
        cmd = nds_get_direction();
        break;

      case 2:
        nds_flush(0);
        cmd = nds_cmd_loop(CMDLOOP_CONFIG);
        break;

      case 3:
        {
          const char *tmp = nds_get_bool_option();

          if (tmp != NULL) {
            cmd.f_char = CMD_OPT_TOGGLE;
            cmd.name = "Toggle Option";

            nds_input_buffer_append((char *)tmp);
          } else {
            cmd.f_char = -1;
            cmd.name = NULL;
          }
        }

        break;

      case 4:
        cmd = nds_get_pan_direction();
        break;

      case 5:
        nds_flush(0);

        cmd.f_char = 0;
        cmd.name = NULL;
        break;
    }
  }

  NULLFREE(sel);

  return cmd;
}
Пример #10
0
nds_cmd_t nds_get_direction()
{
  winid win;
  menu_item *sel;
  ANY_P ids[25];
  nds_cmd_t cmd;
  int i, j, k;
  int res;

  char tmp[2];
  char *direction_keys = nds_get_direction_keys();

  win = create_nhwindow(NHW_MENU);
  start_menu(win);

  ids[0].a_int = 0;

  for (i = 0, j = 1; i < 3; i++) {
    switch (i) {
      case 0:
        add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Walk", 0);
        break;

      case 1:
        add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Run", 0);
        break;

      case 2:
        add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Fight", 0);
        break;
    }

    for (k = 0; k < 8; j++, k++) {
      tmp[0] = direction_keys[k];
      tmp[1] = '\0';

      ids[j].a_int = j;

      add_menu(win, NO_GLYPH, &(ids[j]), 0, 0, 0, nds_command_to_string(tmp), 0);
    }
  }

  end_menu(win, "What Type of Movement?");
  res = select_menu(win, PICK_ONE, &sel);
  destroy_nhwindow(win);

  if (res <= 0) {
    cmd.f_char = -1;
    cmd.name = NULL;
  } else if (sel->item.a_int < 9) {
    tmp[0] = direction_keys[sel->item.a_int - 1];
    tmp[1] = '\0';

    cmd.f_char = direction_keys[sel->item.a_int - 1];
    cmd.name = nds_command_to_string(tmp);
  } else if (sel->item.a_int < 17) {
    nds_input_buffer_push(direction_keys[sel->item.a_int - 9]);

    cmd.f_char = 'g';
    cmd.name = nds_command_to_string(nds_input_buffer_shiftall());
  } else {
    nds_input_buffer_push(direction_keys[sel->item.a_int - 17]);

    cmd.f_char = 'F';
    cmd.name = nds_command_to_string(nds_input_buffer_shiftall());
  }

  NULLFREE(sel);

  return cmd;
}
Пример #11
0
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;
    }
  }
}
Пример #12
0
/*
 * Look in the "data" file for more info.  Called if the user typed in the
 * whole name (user_typed_name == true), or we've found a possible match
 * with a character/glyph and flags.help is true.
 *
 * NOTE: when (user_typed_name == false), inp is considered read-only and
 *       must not be changed directly, e.g. via lcase(). We want to force
 *       lcase() for data.base lookup so that we can have a clean key.
 *       Therefore, we create a copy of inp _just_ for data.base lookup.
 */
static void checkfile (char *inp, struct permonst *pm, bool user_typed_name, bool without_asking) {
    dlb *fp;
    char buf[BUFSZ], newstr[BUFSZ];
    char *ep, *dbase_str;
    long txt_offset;
    int chk_skip;
    bool found_in_file = false, skipping_entry = false;

    fp = dlb_fopen(DATAFILE, "r");
    if (!fp) {
        pline("Cannot open data file!");
        return;
    }

    /* To prevent the need for entries in data.base like *ngel to account
     * for Angel and angel, make the lookup string the same for both
     * user_typed_name and picked name.
     */
    if (pm != (struct permonst *) 0 && !user_typed_name)
        dbase_str = strcpy(newstr, pm->mname);
    else dbase_str = strcpy(newstr, inp);
    (void) lcase(dbase_str);

    if (!strncmp(dbase_str, "interior of ", 12))
        dbase_str += 12;
    if (!strncmp(dbase_str, "a ", 2))
        dbase_str += 2;
    else if (!strncmp(dbase_str, "an ", 3))
        dbase_str += 3;
    else if (!strncmp(dbase_str, "the ", 4))
        dbase_str += 4;
    if (!strncmp(dbase_str, "tame ", 5))
        dbase_str += 5;
    else if (!strncmp(dbase_str, "peaceful ", 9))
        dbase_str += 9;
    if (!strncmp(dbase_str, "invisible ", 10))
        dbase_str += 10;
    if (!strncmp(dbase_str, "statue of ", 10))
        dbase_str[6] = '\0';
    else if (!strncmp(dbase_str, "figurine of ", 12))
        dbase_str[8] = '\0';

    /* Make sure the name is non-empty. */
    if (*dbase_str) {
        /* adjust the input to remove "named " and convert to lower case */
        char *alt = 0;  /* alternate description */

        if ((ep = strstri(dbase_str, " named ")) != 0)
            alt = ep + 7;
        else
            ep = strstri(dbase_str, " called ");
        if (!ep) ep = strstri(dbase_str, ", ");
        if (ep && ep > dbase_str) *ep = '\0';

        /*
         * If the object is named, then the name is the alternate description;
         * otherwise, the result of makesingular() applied to the name is. This
         * isn't strictly optimal, but named objects of interest to the user
         * will usually be found under their name, rather than under their
         * object type, so looking for a singular form is pointless.
         */

        if (!alt)
            alt = makesingular(dbase_str);
        else
            if (user_typed_name)
                (void) lcase(alt);

        /* skip first record; read second */
        txt_offset = 0L;
        if (!dlb_fgets(buf, BUFSZ, fp) || !dlb_fgets(buf, BUFSZ, fp)) {
            impossible("can't read 'data' file");
            (void) dlb_fclose(fp);
            return;
        } else if (sscanf(buf, "%8lx\n", &txt_offset) < 1 || txt_offset <= 0)
            goto bad_data_file;

        /* look for the appropriate entry */
        while (dlb_fgets(buf,BUFSZ,fp)) {
            if (*buf == '.') break;  /* we passed last entry without success */

            if (digit(*buf)) {
                /* a number indicates the end of current entry */
                skipping_entry = false;
            } else if (!skipping_entry) {
                if (!(ep = index(buf, '\n'))) goto bad_data_file;
                *ep = 0;
                /* if we match a key that begins with "~", skip this entry */
                chk_skip = (*buf == '~') ? 1 : 0;
                if (pmatch(&buf[chk_skip], dbase_str) ||
                        (alt && pmatch(&buf[chk_skip], alt))) {
                    if (chk_skip) {
                        skipping_entry = true;
                        continue;
                    } else {
                        found_in_file = true;
                        break;
                    }
                }
            }
        }
    }

    if(found_in_file) {
        long entry_offset;
        int  entry_count;
        int  i;

        /* skip over other possible matches for the info */
        do {
            if (!dlb_fgets(buf, BUFSZ, fp)) goto bad_data_file;
        } while (!digit(*buf));
        if (sscanf(buf, "%ld,%d\n", &entry_offset, &entry_count) < 2) {
bad_data_file:  impossible("'data' file in wrong format");
                (void) dlb_fclose(fp);
                return;
        }

        if (user_typed_name || without_asking || yn("More info?") == 'y') {
            winid datawin;

            if (dlb_fseek(fp, txt_offset + entry_offset, SEEK_SET) < 0) {
                pline("? Seek error on 'data' file!");
                (void) dlb_fclose(fp);
                return;
            }
            datawin = create_nhwindow(NHW_MENU);
            for (i = 0; i < entry_count; i++) {
                if (!dlb_fgets(buf, BUFSZ, fp)) goto bad_data_file;
                if ((ep = index(buf, '\n')) != 0) *ep = 0;
                if (index(buf+1, '\t') != 0) (void) tabexpand(buf+1);
                putstr(datawin, 0, buf+1);
            }
            display_nhwindow(datawin, false);
            destroy_nhwindow(datawin);
        }
    } else if (user_typed_name)
        pline("I don't have any information on those things.");

    (void) dlb_fclose(fp);
}