示例#1
0
/* display a selection menu for enum options */
static void
select_enum_value(union nh_optvalue *value, struct nh_option_desc *option)
{
    struct nh_menulist menu;
    int i, selectidx;

    init_menulist(&menu);

    add_menu_txt(&menu, option->helptxt, MI_TEXT);
    add_menu_txt(&menu, "", MI_TEXT);

    for (i = 0; i < option->e.numchoices; i++) {
        char capbuf[QBUFSZ];
        const char *cap;

        if (option->value.e == option->e.choices[i].id) {
            snprintf(capbuf, QBUFSZ, "%s (set)", option->e.choices[i].caption);
            cap = capbuf;
        } else {
            cap = option->e.choices[i].caption;
        }
        /* don't use the choice ids directly, 0 is a valid value for those */
        add_menu_item(&menu, i + 1, cap, 0, 0);
    }

    int pick_list[1];
    curses_display_menu(&menu, option->name, PICK_ONE, PLHINT_RIGHT, pick_list,
                        curses_menu_callback);

    value->e = option->value.e; /* in case of ESC */
    if (pick_list[0] != CURSES_MENU_CANCELLED) {
        selectidx = pick_list[0] - 1;
        value->e = option->e.choices[selectidx].id;
    }
}
示例#2
0
/* display a selection menu for tilesets */
static void
select_tileset_value(union nh_optvalue *value, struct nh_option_desc *option)
{
    struct nh_menulist menu;
    int i;

    int tc;
    struct tileset_description *tilesets = get_tileset_descriptions(&tc);
    struct tileset_description tilesets_copy[tc];
    memcpy(tilesets_copy, tilesets, sizeof tilesets_copy);
    free(tilesets);

    init_menulist(&menu);

    add_menu_txt(&menu, option->helptxt, MI_TEXT);
    add_menu_txt(&menu, "", MI_TEXT);

    for (i = 0; i < tc; i++)
        add_menu_item(&menu, i + 1, tilesets_copy[i].desc, 0, 0);

    int pick_list[1];
    curses_display_menu(&menu, option->name, PICK_ONE, PLHINT_RIGHT, pick_list,
                        curses_menu_callback);

    const char *newname = option->value.s;
    if (pick_list[0] != CURSES_MENU_CANCELLED)
        newname = tilesets_copy[pick_list[0] - 1].basename;

    value->s = malloc(strlen(newname) + 1);
    strcpy(value->s, newname);
}
示例#3
0
文件: history.c 项目: FredrIQ/fiqhack
int
dohistory(const struct nh_cmd_arg *arg)
{
    struct nh_menulist menu;
    boolean over = program_state.gameover;
    boolean showall = over || wizard;
    int i;

    (void) arg;

    if (histcount < 2) {
        /* you get an automatic entry on turn 1 for being born. If it's the
           only one, there is nothing worth reporting */
        if (!over)
            pline(msgc_info, "History has not recorded anything about you.");
        return 0;
    }

    init_menulist(&menu);

    for (i = 0; i < histcount; i++) {
        if (histevents[i].hidden && !showall)
            continue;
        add_menutext(&menu, msgprintf("On T:%u you %s", histevents[i].when,
                                      histevents[i].what));
    }

    display_menu(&menu, "History has recorded:", PICK_NONE,
                 PLHINT_ANYWHERE, NULL);

    return 0;
}
示例#4
0
int
dosave(void)
{
    int n, selected[1];
    struct menulist menu;

    init_menulist(&menu);
    add_menuitem(&menu, 1, "Quicksave and exit the game", 'y', FALSE);
    add_menuitem(&menu, 2, "Abandon this game and delete its save file", '!',
                 FALSE);
    add_menuitem(&menu, 3, "Continue playing", 'n', FALSE);
    n = display_menu(menu.items, menu.icount, "Do you want to stop playing?",
                     PICK_ONE, PLHINT_URGENT, selected);
    free(menu.items);
    if (n)
        n = selected[0];
    else
        n = 3;

    if (n == 3) {
        if (multi > 0)
            nomul(0, NULL);
    } else if (n == 1) {
        pline("Saving...");
        if (dosave0(FALSE)) {
            program_state.something_worth_saving = 0;
            u.uhp = -1; /* universal game's over indicator */
            terminate();
        } else
            doredraw();
    } else if (n == 2) {
        return done2();
    }
    return 0;
}
示例#5
0
void
outoracle(boolean special, boolean delphi)
{
    char line[COLNO];
    char *endp;
    dlb *oracles;
    int oracle_idx;

    if (oracle_flg < 0 ||       /* couldn't open ORACLEFILE */
        (oracle_flg > 0 && oracle_cnt == 0))    /* oracles already exhausted */
        return;

    oracles = dlb_fopen(ORACLEFILE, "r");

    if (oracles) {
        struct nh_menulist menu;

        if (oracle_flg == 0) {  /* if this is the first outoracle() */
            init_oracles(oracles);
            oracle_flg = 1;
            if (oracle_cnt == 0)
                return;
        }
        /* oracle_loc[0] is the special oracle; */
        /* oracle_loc[1..oracle_cnt-1] are normal ones */
        if (oracle_cnt <= 1 && !special)
            return;     /* (shouldn't happen) */
        oracle_idx = special ? 0 : rnd((int)oracle_cnt - 1);
        dlb_fseek(oracles, oracle_loc[oracle_idx], SEEK_SET);
        if (!special)
            oracle_loc[oracle_idx] = oracle_loc[--oracle_cnt];

        init_menulist(&menu);

        if (delphi)
            add_menutext(
                &menu, special ?
                "Potter protests, but then takes your money and says:" :
                "Potter thinks for a second, and then announces in a gravelly voice:");
        else
            add_menutext(&menu, "The message reads:");
        add_menutext(&menu, "");

        while (dlb_fgets(line, COLNO, oracles) && strcmp(line, "---\n")) {
            if ((endp = strchr(line, '\n')) != 0)
                *endp = 0;
            char decrypted_line[strlen(line) + 1];
            add_menutext(&menu, xcrypt(line, decrypted_line));
        }

        display_menu(&menu, NULL, PICK_NONE, PLHINT_ANYWHERE,
                     NULL);
        dlb_fclose(oracles);
    } else {
        pline("Can't open oracles file!");
        oracle_flg = -1;        /* don't try to open it again */
    }
}
示例#6
0
void
outoracle(boolean special, boolean delphi)
{
    char line[COLNO];
    char *endp;
    dlb *oracles;
    int oracle_idx;
    char xbuf[BUFSZ];

    if (oracle_flg < 0 ||       /* couldn't open ORACLEFILE */
        (oracle_flg > 0 && oracle_cnt == 0))    /* oracles already exhausted */
        return;

    oracles = dlb_fopen(ORACLEFILE, "r");

    if (oracles) {
        struct menulist menu;

        if (oracle_flg == 0) {  /* if this is the first outoracle() */
            init_oracles(oracles);
            oracle_flg = 1;
            if (oracle_cnt == 0)
                return;
        }
        /* oracle_loc[0] is the special oracle; */
        /* oracle_loc[1..oracle_cnt-1] are normal ones */
        if (oracle_cnt <= 1 && !special)
            return;     /* (shouldn't happen) */
        oracle_idx = special ? 0 : rnd((int)oracle_cnt - 1);
        dlb_fseek(oracles, oracle_loc[oracle_idx], SEEK_SET);
        if (!special)
            oracle_loc[oracle_idx] = oracle_loc[--oracle_cnt];

        init_menulist(&menu);
        if (delphi)
            add_menutext(&menu,
                         special ?
                         "The Oracle scornfully takes all your money and says:"
                         :
                         "The Oracle meditates for a moment and then intones:");
        else
            add_menutext(&menu, "The message reads:");
        add_menutext(&menu, "");

        while (dlb_fgets(line, COLNO, oracles) && strcmp(line, "---\n")) {
            if ((endp = strchr(line, '\n')) != 0)
                *endp = 0;
            add_menutext(&menu, xcrypt(line, xbuf));
        }
        display_menu(menu.items, menu.icount, NULL, PICK_NONE, PLHINT_ANYWHERE,
                     NULL);
        free(menu.items);
        dlb_fclose(oracles);
    } else {
        pline("Can't open oracles file!");
        oracle_flg = -1;        /* don't try to open it again */
    }
}
示例#7
0
int do_naming(void)
{
	int n, selected[1];
	struct obj *obj;
	static const char allowall[] = {ALL_CLASSES, 0};
	struct menulist menu;

	init_menulist(&menu);

	add_menuitem(&menu, 1, "Name a monster", 'C', FALSE);
	add_menuitem(&menu, 2, "Name the current level", 'f', FALSE);
	add_menuitem(&menu, 3, "Name an individual item", 'y', FALSE);
	add_menuitem(&menu, 4, "Name all items of a certain type", 'n', FALSE);

	n = display_menu(menu.items, menu.icount, "What do you wish to name?",
			PICK_ONE, selected);
	free(menu.items);
	if (n)
	    n = selected[0] - 1;
	else
	    return 0;

	switch (n) {
	    default: break;
	    case 0:
		do_mname();
		break;
		
	    case 1:
		donamelevel();
		break;

		/* cases 2 & 3 duplicated from ddocall() */
	    case 2:
		obj = getobj(allowall, "name");
		if(obj)
		    do_oname(obj);
		break;
	    case 3:
		obj = getobj(callable, "call");
		if (obj) {
		    /* behave as if examining it in inventory;
		     * this might set dknown if it was picked up
		     * while blind and the hero can now see */
		    xname(obj);

		    if (!obj->dknown) {
			pline("You would never recognize another one.");
			return 0;
		    }
		    docall(obj);
		}
		break;
	}
	return 0;
}
示例#8
0
HRESULT CRetroArchSettings::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
{
   GetChildById(L"XuiMenuList", &m_menulist);
   GetChildById(L"XuiBackButton", &m_back);
   GetChildById(L"XuiTxtTitle", &m_menutitle);

   XuiTextElementSetText(m_menutitle, L"Settings");

   init_menulist(INGAME_MENU_SETTINGS_MODE);

   return 0;
}
示例#9
0
HRESULT CRetroArchLoadGameHistory::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
{
   GetChildById(L"XuiMenuList", &m_menulist);
   GetChildById(L"XuiBackButton", &m_back);
   GetChildById(L"XuiTxtTitle", &m_menutitle);

   XuiTextElementSetText(m_menutitle, L"Load History");

   init_menulist(INGAME_MENU_LOAD_GAME_HISTORY_MODE);

   return 0;
}
示例#10
0
HRESULT CRetroArchControls::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
{
   GetChildById(L"XuiMenuList", &m_menulist);
   GetChildById(L"XuiBackButton", &m_back);
   GetChildById(L"XuiTxtTitle", &m_menutitle);

   XuiTextElementSetText(m_menutitle, L"Input options");

   init_menulist(INGAME_MENU_INPUT_OPTIONS_MODE);

   return 0;
}
示例#11
0
void
print_options(void)
{
    struct nh_menulist menu;
    int i;
    char buf[BUFSZ];
    struct nh_option_desc *options = curses_get_nh_opts();

    init_menulist(&menu);

    add_menu_txt(&menu, "Birth options:", MI_HEADING);
    for (i = 0; options[i].name; i++) {
        if (options[i].birth_option != nh_birth_lasting)
            continue;
        snprintf(buf, BUFSZ, "%s\t%s", options[i].name, options[i].helptxt);
        add_menu_txt(&menu, buf, MI_TEXT);
    }
    add_menu_txt(&menu, "", MI_TEXT);

    add_menu_txt(&menu, "Game creation options:", MI_HEADING);
    for (i = 0; options[i].name; i++) {
        if (options[i].birth_option != nh_birth_creation)
            continue;
        snprintf(buf, BUFSZ, "%s\t%s", options[i].name, options[i].helptxt);
        add_menu_txt(&menu, buf, MI_TEXT);
    }
    add_menu_txt(&menu, "", MI_TEXT);

    add_menu_txt(&menu, "Game options:", MI_HEADING);
    for (i = 0; options[i].name; i++) {
        if (options[i].birth_option != nh_birth_ingame)
            continue;
        snprintf(buf, BUFSZ, "%s\t%s", options[i].name, options[i].helptxt);
        add_menu_txt(&menu, buf, MI_TEXT);
    }
    add_menu_txt(&menu, "", MI_TEXT);

    /* add UI specific options */
    add_menu_txt(&menu, "Interface options:", MI_HEADING);
    for (i = 0; curses_options[i].name; i++) {
        snprintf(buf, BUFSZ, "%s\t%s", curses_options[i].name,
                 curses_options[i].helptxt);
        add_menu_txt(&menu, buf, MI_TEXT);
    }

    curses_display_menu(&menu, "Available options:", PICK_NONE,
                        PLHINT_ANYWHERE, NULL, null_menu_callback);

    curses_free_nh_opts(options);
}
示例#12
0
static int rgui_iterate(void *data, unsigned action)
{
   rgui_handle_t *rgui = (rgui_handle_t*)data;

   if (action == RGUI_ACTION_OK)
   {
      XuiSceneNavigateBack(current_menu, root_menu, XUSER_INDEX_ANY);
      current_menu = root_menu;
      XuiElementGetChildById(current_menu, L"XuiMenuList", &m_menulist);
      init_menulist(INGAME_MENU_MAIN_MODE);
   }

   return 0;
}
示例#13
0
HRESULT CRetroArchCoreOptions::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
{
   GetChildById(L"XuiMenuList", &m_menulist);
   GetChildById(L"XuiBackButton", &m_back);
   GetChildById(L"XuiTxtTitle", &m_menutitle);

   XuiListDeleteItems(m_menulist, 0, XuiListGetItemCount(m_menulist));

   XuiTextElementSetText(m_menutitle, L"Core Options");

   init_menulist(INGAME_MENU_CORE_OPTIONS_MODE);

   return 0;
}
示例#14
0
/* display the option dialog */
void
display_options(nh_bool change_birth_opt)
{
    struct nh_menulist menu;
    struct nh_option_desc *options;
    int selected[1];

    do {
        init_menulist(&menu);
        options = curses_get_nh_opts();

        if (!change_birth_opt) {
            /* add general game options */
            add_menu_txt(&menu, "Game options:", MI_HEADING);
            menu_add_options(&menu, GAME_OPTS, options, nh_birth_ingame, FALSE);

            /* add or display birth options */
            add_menu_txt(&menu, "Birth options for this game:", MI_HEADING);
            menu_add_options(&menu, BIRTH_OPTS, options,
                             nh_birth_lasting, TRUE);
        } else {
            /* add or display birth options */
            add_menu_txt(&menu, "Birth options:", MI_HEADING);
            menu_add_options(&menu, BIRTH_OPTS, options,
                             nh_birth_lasting, FALSE);

            add_menu_txt(&menu, "Game creation options:", MI_HEADING);
            menu_add_options(&menu, CREATION_OPTS, options,
                             nh_birth_creation, FALSE);

            add_menu_txt(&menu, "Game options:", MI_HEADING);
            menu_add_options(&menu, GAME_OPTS, options, nh_birth_ingame, FALSE);
        }

        /* add UI specific options */
        add_menu_txt(&menu, "Interface options:", MI_HEADING);
        menu_add_options(&menu, UI_OPTS, curses_options, FALSE, FALSE);

        curses_display_menu_core(
            &menu, "Set what options?", PICK_ONE, selected,
            curses_menu_callback, 0, 0, -1, -1, FALSE, query_new_value, TRUE);

        curses_free_nh_opts(options);
    } while (*selected != CURSES_MENU_CANCELLED);

    write_ui_config();
    if (!game_is_running)
        write_nh_config();
}
示例#15
0
HRESULT CRetroArchMain::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
{
   GetChildById(L"XuiMenuList", &m_menulist);
   GetChildById(L"XuiTxtTitle", &m_menutitle);
   GetChildById(L"XuiTxtBottom", &m_menutitlebottom);

   init_menulist(INGAME_MENU_MAIN_MODE);

   mbstowcs(strw_buffer, g_extern.title_buf, sizeof(strw_buffer) / sizeof(wchar_t));
   XuiTextElementSetText(m_menutitlebottom, strw_buffer);
   menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_RARCH_VERSION, sizeof(strw_buffer));
   XuiTextElementSetText(m_menutitle, strw_buffer);

   return 0;
}
示例#16
0
文件: do_name.c 项目: FredrIQ/nhfourk
int
do_naming(const struct nh_cmd_arg *arg)
{
    int n;
    const int *selected;
    char classes[20], *s;
    struct nh_menulist menu;

    (void) arg;

    init_menulist(&menu);

    /* group_accel settings are for keystroke-compatibility with nethack.alt.org
       (which uses a/b/c/d); they shouldn't show in the interface because
       there's no good reason to use them other than muscle memory */
    add_menuitem(&menu, 1, "Name a monster", 'C', FALSE);
    menu.items[menu.icount-1].group_accel = 'a';
    add_menuitem(&menu, 2, "Name an individual item", 'y', FALSE);
    menu.items[menu.icount-1].group_accel = 'b';
    add_menuitem(&menu, 3, "Name all items of a certain type", 'n', FALSE);
    menu.items[menu.icount-1].group_accel = 'c';
    add_menuitem(&menu, 4, "Name an item type by appearance", 'A', FALSE);
    add_menuitem(&menu, 5, "Name the current level", 'f', FALSE);
    if (flags.recently_broken_otyp != STRANGE_OBJECT) {
        const char *buf;

        buf = msgprintf("Name %s (recently broken)",
                        an(obj_typename(flags.recently_broken_otyp)));
        add_menuitem(&menu, 6, buf, 'V', FALSE);
    }

    n = display_menu(&menu, "What do you wish to name?",
                     PICK_ONE, PLHINT_ANYWHERE, &selected);
    if (n > 0)
        n = selected[0] - 1;
    else
        return 0;

    switch (n) {
    default:
        break;
    case 0:
        do_mname(&(struct nh_cmd_arg){.argtype = 0});
        break;

    case 1:
        do_oname(&(struct nh_cmd_arg){.argtype = 0});
示例#17
0
void
net_loadgame(void)
{
    char buf[BUFSZ];
    struct nhnet_game *gamelist;
    struct nh_menulist menu;
    int id, size, i, ret, pick[1];

    gamelist = nhnet_list_games(FALSE, FALSE, &size);
    if (!gamelist) {
        curses_msgwin("Failed to retrieve the list of saved games.",
                      krc_notification);
        return;
    }
    if (!size) {
        curses_msgwin("No saved games found.", krc_notification);
        return;
    }

    init_menulist(&menu);

    for (i = 0; i < size; i++) {
        if (gamelist[i].status == LS_DONE || gamelist[i].status == LS_INVALID)
            continue;
        describe_game(buf, gamelist[i].status, &gamelist[i].i);
        id = (gamelist[i].status == LS_IN_PROGRESS) ? 0 : gamelist[i].gameid;
        add_menu_item(&menu, id, buf, 0, FALSE);
    }

    curses_display_menu(&menu, "saved games", PICK_ONE, PLHINT_ANYWHERE, pick,
                        curses_menu_callback);

    if (*pick == CURSES_MENU_CANCELLED)
        return;

    id = pick[0];

    create_game_windows();

    ret = playgame(id, FM_PLAY);

    destroy_game_windows();
    cleanup_messages();

    game_ended(ret, NULL, TRUE);
}
示例#18
0
static int
get_autopickup_oclass(struct nh_autopick_option *desc, int cur)
{
    int i, selected[1];
    struct nh_menulist menu;

    init_menulist(&menu);

    for (i = 0; i < desc->numclasses; i++)
        add_menu_item(&menu, desc->classes[i].id, desc->classes[i].caption,
                      (char)desc->classes[i].id, 0);

    curses_display_menu(&menu, "Object class match:", PICK_ONE,
                        PLHINT_RIGHT, selected, curses_menu_callback);

    if (*selected == CURSES_MENU_CANCELLED)
        return cur;
    return selected[0];
}
示例#19
0
/* display a selecton menu for boolean options */
static void
select_boolean_value(union nh_optvalue *value, struct nh_option_desc *option)
{
    struct nh_menulist menu;
    int pick_list[1];

    init_menulist(&menu);

    add_menu_txt(&menu, option->helptxt, MI_TEXT);
    add_menu_txt(&menu, "", MI_TEXT);
    add_menu_item(&menu, 1, option->value.b ? "true (set)" : "true", 't', 0);
    add_menu_item(&menu, 2, option->value.b ? "false" : "false (set)", 'f', 0);

    curses_display_menu(&menu, option->name, PICK_ONE, PLHINT_RIGHT,
                        pick_list, curses_menu_callback);

    value->b = option->value.b; /* in case of ESC */
    if (pick_list[0] != CURSES_MENU_CANCELLED)
        value->b = pick_list[0] == 1;
}
示例#20
0
int
wiz_light_sources(const struct nh_cmd_arg *arg)
{
    struct nh_menulist menu;
    const char *buf;
    light_source *ls;

    (void) arg;

    init_menulist(&menu);

    buf = msgprintf("Mobile light sources: hero @ (%2d,%2d)", u.ux, u.uy);
    add_menutext(&menu, buf);
    add_menutext(&menu, "");

    if (level->lev_lights) {
        add_menutext(&menu, "location range flags  type    id");
        add_menutext(&menu, "-------- ----- ------ ----  -------");
        for (ls = level->lev_lights; ls; ls = ls->next) {
            buf = msgprintf("  %2d,%2d   %2d   0x%04x  %s  %p",
                    ls->x, ls->y, ls->range, ls->flags,
                    (ls->type == LS_OBJECT ? "obj" :
                     ls->type == LS_MONSTER ? (
                       mon_is_local((struct monst *)ls->id) ? "mon" :
                       ((struct monst *)ls->id == &youmonst) ? "you" :
                       "<m>") : /* migrating monster */ "???"),
                    ls->id);
            add_menutext(&menu, buf);
        }
    } else
        add_menutext(&menu, "<none>");


    display_menu(&menu, NULL, PICK_NONE, PLHINT_ANYWHERE,
                 NULL);

    return 0;
}
示例#21
0
文件: light.c 项目: DanielT/NitroHack
int wiz_light_sources(void)
{
    struct menulist menu;
    char buf[BUFSZ];
    light_source *ls;

    init_menulist(&menu);

    sprintf(buf, "Mobile light sources: hero @ (%2d,%2d)", u.ux, u.uy);
    add_menutext(&menu, buf);
    add_menutext(&menu, "");

    if (level->lev_lights) {
	add_menutext(&menu, "location range flags  type    id");
	add_menutext(&menu, "-------- ----- ------ ----  -------");
	for (ls = level->lev_lights; ls; ls = ls->next) {
	    sprintf(buf, "  %2d,%2d   %2d   0x%04x  %s  %p",
		ls->x, ls->y, ls->range, ls->flags,
		(ls->type == LS_OBJECT ? "obj" :
		 ls->type == LS_MONSTER ?
		    (mon_is_local((struct monst *)ls->id) ? "mon" :
		     ((struct monst *)ls->id == &youmonst) ? "you" :
		     "<m>") :		/* migrating monster */
		 "???"),
		ls->id);
	    add_menutext(&menu, buf);
	}
    } else
	add_menutext(&menu, "<none>");


    display_menu(menu.items, menu.icount, NULL, PICK_NONE, NULL);
    free(menu.items);

    return 0;
}
示例#22
0
int
network_motd(void)
{
    char errmsg[256];
    char motdmsg[4096];
    int fd = -1;

    if (settings.show_motd == MOTD_TRUE) {

        fd = connect_server(MOTD_SERVER, MOTD_PORT, FALSE,
                            errmsg, sizeof errmsg);
        if (fd == -1)
            fd = connect_server(MOTD_SERVER, MOTD_PORT, TRUE,
                                errmsg, sizeof errmsg);
        
        errmsg[sizeof errmsg - 1] = '\0';

        if (fd == -1) {
            strcpy(motdmsg, "Could not connect to <" MOTD_SERVER "> to "
                   "receive a Message of the Day: ");
            strcat(motdmsg, errmsg);
        } else {
            /* We want to receive until the connection closes (which causes
               either EPIPE on abnormal shutdown, or 0 on normal shutdown). So
               continue until we get an error message other than EINTR or the
               buffer fills (indicating a malicious connection; I'm not planning
               on sending malicious packets from motd.nethack4.org, especially
               as I wrote this code and so know it wouldn't work, but it's worth
               allowing for the possibility that someone else intercepts the
               connection). */
            int recvlen = 0;
            int rv;
            while (recvlen < sizeof motdmsg &&
                   (((rv = recv(fd, motdmsg + recvlen,
                                (sizeof motdmsg) - recvlen, 0))) > 0 ||
                    errno == EINTR))
                recvlen += rv < 0 ? 0 : rv;
            if (recvlen >= sizeof motdmsg)
                recvlen = -1 + sizeof motdmsg;

            motdmsg[recvlen] = '\0';
        }

        close(fd);
    } else if (settings.show_motd == MOTD_FALSE) {
        return 1;
    } else {
        /* It's a bad idea to do network connections without asking the user for
           permission first. (Arguably we could make an exception for
           connection-only mode, but that connects to localhost, which is not
           quite the same thing as connecting to the Internet, so I'd rather
           make absolutely sure we aren't doing connections unsolicited.)

           Note that nothing is sent (other than the fact that the connection
           exists); the nethack4 binary just creates the connection, then reads
           from it. */
        strcpy(motdmsg, "The Message of the Day system connects to the "
               "Internet to receive gameplay tips and announcements (such "
               "as tournament information or release announcements). Do you "
               "want to turn it on? (You can change this later with the "
               "\x0enetwork_motd\x0f option.)");
    }

    /* SI/SO in the output indicate bold text. This isn't implemented yet.  Also
       strip out all other unprintable characters for security reasons. We just
       use the ASCII space-to-tilde range for printables; we're not expecting
       any control characters but SI/SO, not even newlines. */
    char *f, *t;
    f = t = motdmsg;
    while (*f) {
        if (*f >= ' ' && *f <= '~')
            *(t++) = *f;
        f++;
    }
    *t = '\0';

    int outcount;
    char **outlines;
    wrap_text(COLNO-6, motdmsg, &outcount, &outlines);

    struct nh_menulist menu;
    int i;

    init_menulist(&menu);

    for (i = 0; i < outcount; i++)
        add_menu_txt(&menu, outlines[i], MI_TEXT);

    free_wrap(outlines);

    if (settings.show_motd == MOTD_ASK) {
        add_menu_txt(&menu, "", MI_TEXT);
        add_menu_item(&menu, 1,
                      "Yes, I'd like announcements and gameplay tips",
                      'y', FALSE);
        add_menu_item(&menu, 2,
                      "No, please don't connect to the MotD server",
                      'n', FALSE);

        curses_display_menu(&menu, "Message of the Day", PICK_ONE,
                            PLHINT_ANYWHERE, &i, curses_menu_callback);

        if (i == 1) {
            curses_set_option("networkmotd",
                              (union nh_optvalue){.e = MOTD_TRUE});
示例#23
0
文件: pager.c 项目: FredrIQ/nethack4
/*
 * 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.
 */
static void
checkfile(const char *inp, struct permonst *pm, boolean user_typed_name,
          boolean without_asking)
{
    dlb *fp;
    char buf[BUFSZ], newstr[BUFSZ];
    char *ep, *dbase_str;
    long txt_offset = 0;
    int chk_skip;
    boolean 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 != NULL && !user_typed_name)
        dbase_str = strcpy(newstr, pm->mname);
    else
        dbase_str = strcpy(newstr, inp);

    for (ep = dbase_str; *ep; ep++)
        *ep = lowc(*ep);

    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 " [seen" and "named " and convert to
           lower case */
        const char *alt = 0;  /* alternate description */

        if ((ep = strstri_mutable(dbase_str, " [seen")) != 0)
            *ep = '\0';

        if ((ep = strstri_mutable(dbase_str, " named ")) != 0)
            alt = ep + 7;
        else
            ep = strstri_mutable(dbase_str, " called ");
        if (!ep)
            ep = strstri_mutable(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)
            alt = msglowercase(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");
            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 = strchr(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");
            dlb_fclose(fp);
            return;
        }

        if (user_typed_name || without_asking || yn("More info?") == 'y') {
            struct nh_menulist menu;

            if (dlb_fseek(fp, txt_offset + entry_offset, SEEK_SET) < 0) {
                pline("? Seek error on 'data' file!");
                dlb_fclose(fp);
                return;
            }

            init_menulist(&menu);

            for (i = 0; i < entry_count; i++) {
                if (!dlb_fgets(buf, BUFSZ, fp))
                    goto bad_data_file;
                if ((ep = strchr(buf, '\n')) != 0)
                    *ep = 0;
                if (strchr(buf + 1, '\t') != 0)
                    tabexpand(buf + 1);
                add_menutext(&menu, buf + 1);
            }

            display_menu(&menu, NULL, FALSE, PLHINT_ANYWHERE,
                         NULL);
        }
    } else if (user_typed_name)
        pline("I don't have any information on those things.");

    dlb_fclose(fp);
}
示例#24
0
void
net_replay(void)
{
    char buf[BUFSZ];
    struct nhnet_game *gamelist;
    struct nh_menulist menu;
    int pick[1];
    int i, gamecount, gameid, want_done, show_all;

    want_done = FALSE;
    show_all = TRUE;
    while (1) {
        gamelist = nhnet_list_games(want_done, show_all, &gamecount);

        init_menulist(&menu);

        if (!gamecount)
            add_menu_txt(&menu, "(No games in this list)",
                         MI_NORMAL);

        /* add all the files to the menu */
        for (i = 0; i < gamecount; i++) {
            describe_game(buf, gamelist[i].status, &gamelist[i].i);
            add_menu_item(&menu, gamelist[i].gameid, buf, 0,
                          FALSE);
        }

        add_menu_txt(&menu, "", MI_NORMAL);
        if (want_done)
            add_menu_item(&menu, -1, show_all ? "Watch current games" :
                          "Replay your unfinished games", '!', FALSE);
        else
            add_menu_item(&menu, -1,
                          "Replay a completed game", '!', FALSE);

        if (show_all)
            add_menu_item(&menu, -2, want_done ? "View your completed games" :
                          "View your saved games", '#', FALSE);
        else
            add_menu_item(&menu, -2, "View games from other players",
                          '#', FALSE);

        curses_display_menu(&menu, want_done ? show_all ?
                            "Completed games by other players" :
                            "Your completed games" : show_all ?
                            "Pick a current game to watch" :
                            "Replay your saved games", PICK_ONE,
                            PLHINT_ANYWHERE, pick, curses_menu_callback);
        if (pick[0] == CURSES_MENU_CANCELLED)
            return;

        if (pick[0] == -1) {
            want_done = !want_done;
            if (want_done)
                show_all = FALSE; /* will normally be intended */
            continue;
        } else if (pick[0] == -2) {
            show_all = !show_all;
            continue;
        } else
            gameid = pick[0];

        break;
    }

    create_game_windows();

    /* If the game is over, we want to replay (nothing to watch). If it's our
       game, we want to replay (not much point in watching yourself). Otherwise,
       we start in watch mode; the player can change to replay mode from the
       watch menu. */
    int ret = playgame(gameid, show_all && !want_done ? FM_WATCH : FM_REPLAY);

    destroy_game_windows();
    cleanup_messages();

    game_ended(ret, NULL, TRUE);
}
示例#25
0
static void
show_autopickup_menu(struct nh_option_desc *opt)
{
    struct nh_menulist menu;
    int i, j, parts, selected[1], id;
    struct nh_autopickup_rule *r;
    char buf[BUFSZ];
    struct nh_autopickup_rule *rule;
    union nh_optvalue value;

    /* clone autopickup rules */
    value.ar = malloc(sizeof (struct nh_autopickup_rules));
    value.ar->num_rules = 0;
    value.ar->rules = NULL;
    if (opt->value.ar) {
        int size;
        value.ar->num_rules = opt->value.ar->num_rules;
        size = value.ar->num_rules * sizeof (struct nh_autopickup_rule);
        value.ar->rules = malloc(size);
        memcpy(value.ar->rules, opt->value.ar->rules, size);
    }

    do {
        init_menulist(&menu);

        add_menu_txt(&menu, "Pos\tRule\tAction", MI_HEADING);

        /* list the rules in human-readable form */
        for (i = 0; i < value.ar->num_rules; i++) {
            r = &value.ar->rules[i];
            parts = 0;
            snprintf(buf, ARRAY_SIZE(buf), "%2d.\tIF ", i + 1);

            if (strlen(r->pattern)) {
                parts++;
                sprintf(buf + strlen(buf), "name matches \"%s\"", r->pattern);
            }

            if (r->oclass != OCLASS_ANY) {
                const char *classname = NULL;

                for (j = 0; j < opt->a.numclasses && !classname; j++)
                    if (opt->a.classes[j].id == r->oclass)
                        classname = opt->a.classes[j].caption;

                if (parts++)
                    strcat(buf, " AND ");
                sprintf(buf + strlen(buf), "type is \"%s\"", classname);
            }

            if (r->buc != B_DONT_CARE) {
                if (parts++)
                    strcat(buf, " AND ");
                sprintf(buf + strlen(buf), "beatitude is %s", bucnames[r->buc]);
            }

            if (!parts)
                snprintf(buf, ARRAY_SIZE(buf), "%2d.\teverything", i + 1);

            if (r->action == AP_GRAB)
                sprintf(buf + strlen(buf), ":\t< GRAB");
            else
                sprintf(buf + strlen(buf), ":\t  LEAVE >");

            add_menu_item(&menu, i + 1, buf, 0, 0);
        }

        add_menu_txt(&menu, "", MI_TEXT);
        add_menu_item(&menu, -1, "add a new rule", '!', 0);
        add_menu_item(&menu, -2, "help", '?', 0);

        /* TODO */
        curses_display_menu(&menu, "Autopickup rules:", PICK_ONE,
                            PLHINT_RIGHT, selected, curses_menu_callback);
        if (*selected == CURSES_MENU_CANCELLED)
            break;

        /* add or edit a rule */
        id = selected[0];
        if (id == -1) {
            int size;

            /* create a new rule */
            id = value.ar->num_rules;
            value.ar->num_rules++;
            size = value.ar->num_rules * sizeof (struct nh_autopickup_rule);
            value.ar->rules = realloc(value.ar->rules, size);

            rule = &value.ar->rules[id];
            memset(rule->pattern, 0, sizeof(rule->pattern));
            rule->oclass = OCLASS_ANY;
            rule->buc = B_DONT_CARE;
            rule->action = AP_GRAB;
        } else if (id == -2) {
            autopickup_rules_help();
            continue;
        } else
            id--;

        edit_ap_rule(&opt->a, value.ar, id);
    } while (1);

    curses_set_option(opt->name, value);

    free(value.ar->rules);
    free(value.ar);
}
示例#26
0
static void
edit_ap_rule(struct nh_autopick_option *desc, struct nh_autopickup_rules *ar,
             int ruleno)
{
    struct nh_autopickup_rule *r = &ar->rules[ruleno];
    struct nh_autopickup_rule tmprule;
    struct nh_menulist menu;
    int i, selected[1], newpos, allocsize;
    char query[BUFSZ], buf[BUFSZ];
    const char *classname;

    do {
        init_menulist(&menu);

        snprintf(buf, ARRAY_SIZE(buf), "rule position:\t[%d]", ruleno + 1);
        add_menu_item(&menu, 1, buf, 0, 0);

        snprintf(buf, ARRAY_SIZE(buf), "name pattern:\t[%s]", r->pattern);
        add_menu_item(&menu, 2, buf, 0, 0);

        classname = NULL;
        for (i = 0; i < desc->numclasses && !classname; i++)
            if (desc->classes[i].id == r->oclass)
                classname = desc->classes[i].caption;
        snprintf(buf, ARRAY_SIZE(buf), "object type:\t[%s]", classname);
        add_menu_item(&menu, 3, buf, 0, 0);

        snprintf(buf, ARRAY_SIZE(buf), "beatitude:\t[%s]", bucnames[r->buc]);
        add_menu_item(&menu, 4, buf, 0, 0);

        snprintf(buf, ARRAY_SIZE(buf), "action:\t[%s]", r->action == AP_GRAB ? "GRAB" : "LEAVE");
        add_menu_item(&menu, 5, buf, 0, 0);
        add_menu_txt(&menu, "", MI_TEXT);
        add_menu_item(&menu, 6, "delete this rule", 'x', 0);

        curses_display_menu(&menu, "Edit rule:", PICK_ONE, PLHINT_RIGHT,
                            selected, curses_menu_callback);
        if (*selected == CURSES_MENU_CANCELLED)
            return;

        switch (selected[0]) {
            /* move this rule */
        case 1:
            snprintf(query, ARRAY_SIZE(query), "New rule position: (1 - %d), currently: %d",
                    ar->num_rules, ruleno + 1);
            newpos = ar->num_rules;
            curses_getline(query, &newpos, rule_position_callback);
            newpos--;
            if (newpos == ruleno || newpos < 0)
                break;

            tmprule = ar->rules[ruleno];
            /* shift the rules around */
            if (newpos > ruleno) {
                for (i = ruleno; i < newpos; i++)
                    ar->rules[i] = ar->rules[i + 1];
            } else {
                for (i = ruleno; i > newpos; i--)
                    ar->rules[i] = ar->rules[i - 1];
            }
            ar->rules[newpos] = tmprule;
            return;

            /* edit the pattern */
        case 2:
            snprintf(query, ARRAY_SIZE(query), "New name pattern (empty matches everything):");
            curses_getline(query, r->pattern, rule_pattern_callback);
            break;

            /* edit object class match */
        case 3:
            r->oclass = get_autopickup_oclass(desc, r->oclass);
            break;

            /* edit beatitude match */
        case 4:
            r->buc = get_autopickup_buc(r->buc);
            break;

            /* toggle action */
        case 5:
            if (r->action == AP_GRAB)
                r->action = AP_LEAVE;
            else
                r->action = AP_GRAB;
            break;

            /* delete */
        case 6:
            for (i = ruleno; i < ar->num_rules - 1; i++)
                ar->rules[i] = ar->rules[i + 1];
            ar->num_rules--;
            allocsize = ar->num_rules;
            if (allocsize < 1)
                allocsize = 1;
            ar->rules =
                realloc(ar->rules,
                        allocsize * sizeof (struct nh_autopickup_rule));
            return;
        }

    } while (1);
}