示例#1
0
nh_bool player_selection(int *out_role, int *out_race, int *out_gend,
			 int *out_align, int randomall, nh_bool tutorial)
{
    struct nh_menuitem *items;
    int icount, size;
    int i, k, n, listlen, id;
    char pick4u = 'n', thisch, lastch = 0;
    char pbuf[QBUFSZ], plbuf[QBUFSZ];
    struct nh_listitem list[LISTSZ]; /* need enough space for lists of roles or races */
    char listbuffers[LISTSZ][256];
    int pick_list[2];
    int initrole, initrace, initgend, initalign;
    const struct nh_roles_info *ri = nh_get_roles();
    
    if (tutorial)
	return tutorial_player_selection(out_role, out_race, out_gend, out_align);
    
    initrole = *out_role; initrace = *out_race;
    initalign = *out_align; initgend = *out_gend;
    if (initrole == ROLE_NONE) initrole = ri->def_role;
    if (initrace == ROLE_NONE) initrace = ri->def_race;
    if (initgend == ROLE_NONE) initgend = ri->def_gend;
    if (initalign == ROLE_NONE) initalign = ri->def_align;
    
    validate_character_presets(ri, &initrole, &initrace, &initgend, &initalign);
    
    for (i = 0; i < LISTSZ; i++) {
	listbuffers[i][0] = '\0';
	list[i].caption = listbuffers[i];
    }
    
    srandom(time(NULL));
    
    /* Should we randomly pick for the player? */
    if (!randomall &&
	(initrole == ROLE_NONE || initrace == ROLE_NONE ||
	    initgend == ROLE_NONE || initalign == ROLE_NONE)) {
	char *prompt = nh_build_plselection_prompt(pbuf, QBUFSZ, initrole,
			    initrace, initgend, initalign);

	pick4u = curses_yn_function(prompt, "ynq", 'y');	
	if (pick4u != 'y' && pick4u != 'n')
	    return FALSE;
    }

    nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    icount = 0; size = 10;
    items = malloc(sizeof(struct nh_menuitem) * size);

    /* Select a role, if necessary */
    /* if pre-selected race/gender/alignment are still set after
     * validate_character_presets we know they're OK */
    if (initrole < 0) {
	listlen = get_valid_roles(ri, initrace, initgend, initalign, list, LISTSZ);
	
	/* Process the choice */
	if (pick4u == 'y' || initrole == ROLE_RANDOM || randomall) {
	    /* Pick a random role */
	    initrole = list[random() % listlen].id;
	} else {
	    /* Prompt for a role */
	    for (i = 0; i < listlen; i++) {
		id = list[i].id + 1; /* list[i].id starts at 0 */
		thisch = tolower((unsigned char)*list[i].caption);
		if (thisch == lastch)
		    thisch = toupper((unsigned char)thisch);
		add_menu_item(items, size, icount, id, list[i].caption + 2, thisch, 0);
		lastch = thisch;
	    }
	    pick_list[0] = id = list[random() % listlen].id+1;
	    add_menu_item(items, size, icount, id, "随机", '*', 0);
	    add_menu_item(items, size, icount, -1, "退出", 'q', 0);
	    
	    sprintf(pbuf, "为你的%s选择一个角色", plbuf);
	    n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);

	    /* Process the choice */
	    if (n == -1 || pick_list[0] == -1)
		goto give_up;		/* Selected quit */

	    initrole = pick_list[0] - 1;
	    icount = 0;
	}
	nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    }
    
    /* Select a race, if necessary */
    if (initrace < 0) {
	listlen = get_valid_races(ri, initrole, initgend, initalign, list, LISTSZ);
	
	if (pick4u == 'y' || initrace == ROLE_RANDOM || randomall) {
	    initrace = list[random() % listlen].id;
	} else {	/* pick4u == 'n' */
	    /* Count the number of valid races */
	    k = list[0].id;	/* valid race */

	    /* Permit the user to pick, if there is more than one */
	    if (listlen > 1) {
		for (i = 0; i < listlen; i++) {
		    id = list[i].id + 1;
		    add_menu_item(items, size, icount, id, list[i].caption + 2,
				  list[i].caption[0], 0);
		}
		pick_list[0] = id = list[random() % listlen].id+1;
		add_menu_item(items, size, icount, id, "随机", '*', 0);
		add_menu_item(items, size, icount, -1, "退出", 'q', 0);

		sprintf(pbuf, "为你的%s选择一个种族", plbuf);
		n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);
		
		if (n == -1 || pick_list[0] == -1)
		    goto give_up;		/* Selected quit */

		k = pick_list[0] - 1;
		icount = 0;
	    }
	    initrace = k;
	}
	nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    }

    /* Select a gender, if necessary */
    if (initgend < 0) {
	listlen = get_valid_genders(ri, initrole, initrace, initalign, list, LISTSZ);

	if (pick4u == 'y' || initgend == ROLE_RANDOM || randomall) {
	    initgend = list[random() % listlen].id;
	} else {	/* pick4u == 'n' */
	    /* Count the number of valid genders */
	    k = list[0].id;	/* valid gender */

	    /* Permit the user to pick, if there is more than one */
	    if (listlen > 1) {
		for (i = 0; i < listlen; i++) {
		    id = list[i].id + 1;
		    add_menu_item(items, size, icount, id, list[i].caption + 2,
				  list[i].caption[0], 0);
		}
		pick_list[0] = id = list[random() % listlen].id+1;
		add_menu_item(items, size, icount, id, "随机", '*', 0);
		add_menu_item(items, size, icount, -1, "退出", 'q', 0);

		sprintf(pbuf, "为你的%s选择一个性别", plbuf);
		n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);
		
		if (n == -1 || pick_list[0] == -1)
		    goto give_up;		/* Selected quit */

		k = pick_list[0] - 1;
		icount = 0;
	    }
	    initgend = k;
	}
	nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    }

    /* Select an alignment, if necessary */
    if (initalign < 0) {
	listlen = get_valid_aligns(ri, initrole, initrace, initgend, list, LISTSZ);
	
	if (pick4u == 'y' || initalign == ROLE_RANDOM || randomall) {
	    initalign = list[random() % listlen].id;
	} else {	/* pick4u == 'n' */
	    /* Count the number of valid alignments */
	    k = list[0].id;	/* valid alignment */

	    /* Permit the user to pick, if there is more than one */
	    if (listlen > 1) {
		for (i = 0; i < listlen; i++) {
		    id = list[i].id + 1;
		    add_menu_item(items, size, icount, id, list[i].caption + 2,
				  list[i].caption[0], 0);
		}
		pick_list[0] = id = list[random() % listlen].id+1;
		add_menu_item(items, size, icount, id, "随机", '*', 0);
		add_menu_item(items, size, icount, -1, "退出", 'q', 0);
		
		sprintf(pbuf, "为你的%s选择一个阵营", plbuf);
		n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);
		
		if (n == -1 || pick_list[0] == -1)
		    goto give_up;		/* Selected quit */

		k = pick_list[0] - 1;
	    }
	    initalign = k;
	}
    }
    
    *out_role = initrole;
    *out_race = initrace;
    *out_gend = initgend;
    *out_align = initalign;
    
    free(items);
    return TRUE;
    
give_up:
    free(items);
    return FALSE;
}
示例#2
0
nh_bool loadgame(void)
{
    char buf[BUFSZ];
    fnchar savedir[BUFSZ], filename[1024], **files;
    struct nh_menuitem *items;
    int size, icount, fd, i, n, ret, pick[1];
    enum nh_log_status status;
    struct nh_game_info gi;

    if (!get_gamedir(SAVE_DIR, savedir)) {
        curses_raw_print("Could not find or create the save directory.");
        return FALSE;
    }

    files = list_gamefiles(savedir, &size);
    if (!size) {
        curses_msgwin("No saved games found.");
        return FALSE;
    }

    icount = 0;
    items = malloc(size * sizeof(struct nh_menuitem));

    for (i = 0; i < size; i++) {
        fd = sys_open(files[i], O_RDWR, FILE_OPEN_MASK);
        status = nh_get_savegame_status(fd, &gi);
        close(fd);

        describe_game(buf, status, &gi);
        add_menu_item(items, size, icount, (status == LS_IN_PROGRESS) ? 0 : icount + 1,
                      buf, 0, FALSE);
    }

    n = curses_display_menu(items, icount, "saved games", PICK_ONE, pick);
    free(items);
    filename[0] = '\0';
    if (n > 0)
        fnncat(filename, files[pick[0]-1], sizeof(filename)/sizeof(fnchar)-1);

    for (i = 0; i < icount; i++)
        free(files[i]);
    free(files);
    if (n <= 0)
        return FALSE;

    fd = sys_open(filename, O_RDWR, FILE_OPEN_MASK);
    create_game_windows();
    if (nh_restore_game(fd, NULL, FALSE) != GAME_RESTORED) {
        destroy_game_windows();
        close(fd);
        if (curses_yn_function("Failed to load the save. Do you wish to delete the file?", "yn", 'n') == 'y')
            unlink(filename);
        return FALSE;
    }

    load_keymap(); /* need to load the keymap after the game has been started */
    ret = commandloop();
    free_keymap();
    close(fd);

    destroy_game_windows();
    cleanup_messages();
    game_ended(ret, filename);

    return TRUE;
}