Exemple #1
0
/*
 * Present a sorted list to the player, and get a selection
 */
int get_player_sort_choice(cptr *choices, int num, int col, int wid,
                                  cptr helpfile, void (*hook) (cptr))
{
	int i;
	int choice;
	cptr *strings;

	C_MAKE(strings, num, cptr);

	/* Initialise the sorted string array */
	for (i = 0; i < num; i++)
	{
		strings[i] = choices[i];
	}

	/* Sort the strings */
	ang_sort_comp = ang_sort_comp_hook_string;
	ang_sort_swap = ang_sort_swap_hook_string;

	/* Sort the (unique) slopes */
	ang_sort((void *)strings, NULL, num);

	/* Get the choice */
	choice = get_player_choice(strings, num, col, wid, helpfile, hook);

	/* Invert the choice */
	for (i = 0; i < num; i++)
	{
		/* Does the string match the one we selected? */
		if (choices[i] == strings[choice])
		{
			/* Save the choice + exit */
			choice = i;
			break;
		}
	}

	/* Free the strings */
	FREE((void *)strings);

	/* Return the value from the list */
	return (choice);
}
Exemple #2
0
/*
 * Prepare the "temp" array for "target_interactive_set"
 *
 * Return the number of target_able monsters in the set.
 */
static void target_set_interactive_prepare(int mode)
{
	int y, x;

	/* Reset "temp" array */
	temp_n = 0;

	/* Scan the current panel */
	for (y = Term->offset_y; y < Term->offset_y + SCREEN_HGT; y++)
	{
		for (x = Term->offset_x; x < Term->offset_x + SCREEN_WID; x++)
		{
			/* Check bounds */
			if (!in_bounds_fully(y, x)) continue;

			/* Require "interesting" contents */
			if (!target_set_interactive_accept(y, x)) continue;

			/* Special mode */
			if (mode & (TARGET_KILL))
			{
				/* Must contain a monster */
				if (!(cave_m_idx[y][x] > 0)) continue;

				/* Must be a targettable monster */
			 	if (!target_able(cave_m_idx[y][x])) continue;
			}

			/* Save the location */
			temp_x[temp_n] = x;
			temp_y[temp_n] = y;
			temp_n++;
		}
	}

	/* Set the sort hooks */
	ang_sort_comp = ang_sort_comp_distance;
	ang_sort_swap = ang_sort_swap_distance;

	/* Sort the positions */
	ang_sort(temp_x, temp_y, temp_n);
}
Exemple #3
0
/*
 * Prepare the "temp" array for "target_interactive_set"
 *
 * Return the number of target_able monsters in the set.
 */
static void target_set_interactive_prepare(int mode)
{
	int y, x;

	bool expand_look = (mode & (TARGET_LOOK)) ? TRUE : FALSE;

	/* Reset "temp" array */
	clear_temp_array();

	/* Scan the current panel */
	for (y = Term->offset_y; y < Term->offset_y + SCREEN_HGT; y++)
	{
		for (x = Term->offset_x; x < Term->offset_x + SCREEN_WID; x++)
		{
			bool do_continue = FALSE;

			/* Check overflow */
			if (temp_n >= TEMP_MAX) continue;

			/* Check bounds */
			if (!in_bounds_fully(y, x)) continue;

			/* Require line of sight, unless "look" is "expanded" */
			if (!player_has_los_bold(y, x) && (!expand_look)) continue;

			/* Require "interesting" contents */
			if (!target_set_interactive_accept(y, x)) continue;

			/* Special mode */
			if (mode & (TARGET_KILL))
			{
				/* Must contain a monster */
				if (!(cave_m_idx[y][x] > 0)) do_continue = TRUE;

				/* Must be a targettable monster */
			 	if (!target_able(cave_m_idx[y][x])) do_continue = TRUE;
			}

			/* Don't continue on the trap exception, or if probing. */
			if ((mode & (TARGET_TRAP)) && target_able_trap(y, x)) do_continue = FALSE;
			else if (mode & (TARGET_PROBE)) do_continue = FALSE;

			if (do_continue) continue;

			/*
			 * Hack - don't go over redundant elemental terrain \
			 * (since we have large lakes and pools of the same terrain)
			 */
			if ((p_ptr->target_row > 0) || (p_ptr->target_col > 0))
			{
				if (cave_feat[p_ptr->target_row][p_ptr->target_col] == cave_feat[y][x])
				{
					if (cave_ff3_match(y, x, TERRAIN_MASK)) continue;
				}
			}

			/* Save the location */
			temp_x[temp_n] = x;
			temp_y[temp_n] = y;
			temp_n++;
		}
	}

	/* Set the sort hooks */
	ang_sort_comp = ang_sort_comp_distance;
	ang_sort_swap = ang_sort_swap_distance;

	/* Sort the positions */
	ang_sort(temp_x, temp_y, temp_n);
}
Exemple #4
0
/*
 * Identify a character, allow recall of monsters
 *
 * Several "special" responses recall "mulitple" monsters:
 *   ^A (all monsters)
 *   ^U (all unique monsters)
 *   ^N (all non-unique monsters)
 *
 * The responses may be sorted in several ways, see below.
 *
 * Note that the player ghosts are ignored, since they do not exist.
 */
void do_cmd_query_symbol(void)
{
	int i, n, r_idx;
	char sym, query;
	char buf[128];

	bool all = FALSE;
	bool uniq = FALSE;
	bool norm = FALSE;
	bool kill = TRUE;

	bool recall = FALSE;

	u16b why = 0;
	u16b *who;


	/* Get a character, or abort */
	if (!get_com("Enter character to be identified: ", &sym)) return;

	/* Find that character info, and describe it */
	for (i = 0; ident_info[i]; ++i)
	{
		if (sym == ident_info[i][0]) break;
	}

	/* Describe */
	if (sym == KTRL('A'))
	{
		all = TRUE;
		strcpy(buf, "Full monster list.");
	}
	else if (sym == KTRL('U'))
	{
		all = uniq = TRUE;
		strcpy(buf, "Unique monster list.");
	}
	else if (sym == KTRL('N'))
	{
		all = norm = TRUE;
		strcpy(buf, "Non-unique monster list.");
	}
	else if (sym == KTRL('K'))
	{
		all = kill = TRUE;
		strcpy(buf, "Killed monster list.");
	}
	else if (ident_info[i])
	{
		sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
	}
	else
	{
		sprintf(buf, "%c - %s.", sym, "Unknown Symbol");
	}

	/* Display the result */
	prt(buf, 0, 0);


	/* Allocate the "who" array */
	C_MAKE(who, z_info->r_max, u16b);

	/* Collect matching monsters */
	for (n = 0, i = 1; i < z_info->r_max - 1; i++)
	{
		monster_race *r_ptr = &r_info[i];
		monster_lore *l_ptr = &l_list[i];

		/* Nothing to recall */
		if (!cheat_know && !l_ptr->sights) continue;

		/* Skip unused monsters */
		if (!(r_ptr->hdice)) continue;

		/* Require non-unique monsters if needed */
		if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue;

		/* Require unique monsters if needed */
		if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue;

		/* Require killed if needed */
		if (kill && !(l_ptr->pkills)) continue;

		/* Collect "appropriate" monsters */
		if (all || (r_ptr->d_char == sym)) who[n++] = i;
	}

	/* Nothing to recall */
	if (!n)
	{
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}


	/* Prompt */
	put_str("Recall details? (k/K/p/P/a/A/y/n): ", 0, 40);

	/* Query */
	query = inkey();

	/* Restore */
	prt(buf, 0, 0);


	/* Sort by kills (and level) */
	if (query == 'k')
	{
		why = 4;
		query = 'y';
	}
	if (query == 'K')
	{
		why = 4+16;
		query = 'y';
	}

	/* Sort by total kills (and level) */
	if (query == 'a')
	{
		why = 3;
		query = 'y';
	}
	if (query == 'A')
	{
		why = 3+16;
		query = 'y';
	}

	/* Sort by level (and experience) */
	if (query == 'p')
	{
		why = 2;
		query = 'y';
	}
	if (query == 'P')
	{
		why = 2+16;
		query = 'y';
	}


	/* Catch "escape" */
	if (query != 'y')
	{
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}

	/* Sort if needed */
	if (why)
	{
		/* Select the sort method */
		ang_sort_comp = ang_sort_comp_hook;
		ang_sort_swap = ang_sort_swap_hook;

		/* Sort the array */
		ang_sort(who, &why, n);
	}


	/* Start at the end */
	i = n - 1;

	/* Scan the monster memory */
	while (1)
	{
		/* Extract a race */
		r_idx = who[i];

		/* Hack -- Auto-recall */
		monster_race_track(r_idx);

		/* Hack -- Handle stuff */
		handle_stuff();

		/* Hack -- Begin the prompt */
		roff_top(r_idx);

		/* Hack -- Complete the prompt */
		Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");

		/* Interact */
		while (1)
		{
			/* Recall */
			if (recall)
			{
				/* Save screen */
				screen_save();

				/* Recall on screen */
				screen_roff(who[i]);

				/* Hack -- Complete the prompt (again) */
				Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");
			}

			/* Command */
			query = inkey();

			/* Unrecall */
			if (recall)
			{
				/* Load screen */
				screen_load();
			}

			/* Normal commands */
			if (query != 'r') break;

			/* Toggle recall */
			recall = !recall;
		}

		/* Stop scanning */
		if (query == ESCAPE) break;

		/* Move to "prev" monster */
		if (query == '-')
		{
			if (++i == n)
			{
				i = 0;
				if (!expand_list) break;
			}
		}

		/* Move to "next" monster */
		else
		{
			if (i-- == 0)
			{
				i = n - 1;
				if (!expand_list) break;
			}
		}
	}


	/* Re-display the identity */
	prt(buf, 0, 0);

	/* Free the "who" array */
	FREE(who);
}
Exemple #5
0
void do_cmd_list_objects(void)
{
    int list[_MAX_OBJ_LIST];
    int i, ct = 0;
    int cx, cy, row = 1, col;

    for (i = 0; i < max_o_idx; i++)
    {
        object_type *o_ptr = &o_list[i];
        int          auto_pick_idx;

        if (!o_ptr->k_idx) continue;
        if (!(o_ptr->marked & OM_FOUND)) continue;
        if (o_ptr->tval == TV_GOLD) continue;
        if (ct >= _MAX_OBJ_LIST) break;

        auto_pick_idx = is_autopick(o_ptr);

        if (!p_ptr->wizard)
        {
            if (auto_pick_idx < 0) continue;
            if (!(autopick_list[auto_pick_idx].action & DO_DISPLAY)) continue;
            if (!(autopick_list[auto_pick_idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK | DONT_AUTOPICK))) continue;
        }
        list[ct++] = i;
    }

    if (!ct)
    {
        msg_print("No objects match your pickup preferences.");
        return;
    }

    ang_sort_comp = _compare_obj_list_info;
    ang_sort_swap = _swap_int;
    ang_sort(list, NULL, ct);

    Term_get_size(&cx, &cy);
    col = cx - 52;
    screen_save();
    c_prt(TERM_WHITE, format("%d object%s match your pickup preferences", ct, ct != 1 ? "s" : ""), 0, col);
    for (i = 0; i < ct; i++)
    {
        char         o_name[MAX_NLEN];
        object_type *o_ptr = &o_list[list[i]];
        byte         a = object_attr(o_ptr);
        char         c = object_char(o_ptr);
        byte         attr = TERM_WHITE;

        Term_erase(col - 1, row, 53);

        if (row >= cy - 2) 
        {
            c_prt(TERM_YELLOW, "...", row++, col+2);
            break;
        }

        object_desc(o_name, o_ptr, 0);
        attr = tval_to_attr[o_ptr->tval % 128];

        Term_queue_bigchar(col, row, a, c, 0, 0);
        c_put_str(attr, format(" %-50.50s", o_name), row++, col+1);
    }
    Term_erase(col - 1, row, 53);
    c_prt(TERM_YELLOW, "Hit any key.", row, col+2);
    inkey();
    prt("", 0, 0);

    screen_load();
}
Exemple #6
0
/* Idea borrowed from Vanilla 3.5, but recoded from scratch ... */
void do_cmd_list_monsters(void)
{
    int         i, ct_types, ct_total = 0;
    int_map_ptr info = int_map_alloc(free);
    
    /* Collect */
    for (i = 0; i < max_m_idx; i++)
    {
        const monster_type *m_ptr = &m_list[i];
        _mon_list_info_ptr  info_ptr;
        
        if (!m_ptr->ap_r_idx) continue;
        if (!m_ptr->ml) continue;

        info_ptr = int_map_find(info, m_ptr->ap_r_idx);
        if (!info_ptr)
        {
            info_ptr = malloc(sizeof(_mon_list_info_t));
            info_ptr->r_idx = m_ptr->ap_r_idx;
            info_ptr->ct_total = 0;
            info_ptr->ct_awake = 0;
            info_ptr->ct_los = 0;
            
            int_map_add(info, m_ptr->ap_r_idx, info_ptr);
        }

        assert(info_ptr);
        info_ptr->ct_total++;
        ct_total++;

        if (!MON_CSLEEP(m_ptr)) info_ptr->ct_awake++;
        if (projectable(py, px, m_ptr->fy, m_ptr->fx)) info_ptr->ct_los++;
    }
    
    ct_types = int_map_count(info);
    if (ct_types)
    {
        int_map_iter_ptr  iter;
        int              *order;
        int               cx, cy, row = 1, col;

        /* Sort */
        C_MAKE(order, ct_types, int);

        i = 0;
        for (iter = int_map_iter_alloc(info); 
                int_map_iter_is_valid(iter); 
                int_map_iter_next(iter))
        {
            _mon_list_info_ptr info_ptr = int_map_iter_current(iter);
            order[i++] = info_ptr->r_idx;
        }
        int_map_iter_free(iter);

        ang_sort_comp = _compare_r_level;
        ang_sort_swap = _swap_int;
        ang_sort(order, NULL, ct_types);

        /* Display */
        Term_get_size(&cx, &cy);
        col = cx - 52;
        screen_save();
        c_prt(TERM_WHITE, format("You see %d monster%s", ct_total, ct_total != 1 ? "s" : ""), 0, col);
        for (i = 0; i < ct_types; i++)
        {
            int                 r_idx = order[i];
            const monster_race *r_ptr = &r_info[r_idx];
            byte                attr = TERM_WHITE;
            _mon_list_info_ptr  info_ptr = int_map_find(info, r_idx);
            char                buf[100];

            assert(info_ptr);

            Term_erase(col - 1, row, 53);

            if (row >= cy - 2) 
            {
                c_prt(TERM_YELLOW, "...", row++, col+2);
                break;
            }

            if (r_ptr->flags1 & RF1_UNIQUE)
                attr = TERM_VIOLET;
            else if (r_ptr->level > base_level)
                attr = TERM_RED;                
            else if (!info_ptr->ct_awake)
                attr = TERM_L_UMBER;

            if (info_ptr->ct_total == 1)
                sprintf(buf, "%s", r_name + r_ptr->name);
            else if (!info_ptr->ct_awake)
                sprintf(buf, "%s (%d sleeping)", r_name + r_ptr->name, info_ptr->ct_total);
            else if (info_ptr->ct_awake == info_ptr->ct_total)
                sprintf(buf, "%s (%d awake)", r_name + r_ptr->name, info_ptr->ct_total);
            else
                sprintf(buf, "%s (%d awake, %d sleeping)", r_name + r_ptr->name, 
                    info_ptr->ct_awake, info_ptr->ct_total - info_ptr->ct_awake);

            Term_queue_bigchar(col, row, r_ptr->x_attr, r_ptr->x_char, 0, 0);
            c_put_str(attr, format(" %-50.50s", buf), row++, col+1);
        }
        Term_erase(col - 1, row, 53);
        c_prt(TERM_YELLOW, "Hit any key.", row, col+2);
        inkey();
        prt("", 0, 0);

        screen_load();

        C_KILL(order, ct_types, int);
    }
    else
        msg_print("You see no visible monsters.");

    int_map_free(info);
}
Exemple #7
0
/*
 * Identify a character, allow recall of monsters
 *
 * Several "special" responses recall "multiple" monsters:
 *   ^A (all monsters)
 *   ^U (all unique monsters)
 *   ^N (all non-unique monsters)
 *
 * The responses may be sorted in several ways, see below.
 *
 * Note that the player ghosts are ignored. XXX XXX XXX
 */
void do_cmd_query_symbol(void)
{
    int        i, n, r_idx;
    char    sym, query;
    char    buf[128];

    bool    all = FALSE;
    bool    uniq = FALSE;
    bool    norm = FALSE;
    bool    ride = FALSE;
    char    temp[80] = "";

    bool    recall = FALSE;

    u16b    why = 0;
    u16b    *who;

    /* Get a character, or abort */
    if (!get_com("Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): ", &sym, FALSE)) return;

    /* Find that character info, and describe it */
    for (i = 0; ident_info[i]; ++i)
    {
        if (sym == ident_info[i][0]) break;
    }

    /* Describe */
    if (sym == KTRL('A'))
    {
        all = TRUE;
        strcpy(buf, "Full monster list.");
    }
    else if (sym == KTRL('U'))
    {
        all = uniq = TRUE;
        strcpy(buf, "Unique monster list.");
    }
    else if (sym == KTRL('N'))
    {
        all = norm = TRUE;
        strcpy(buf, "Non-unique monster list.");
    }
    else if (sym == KTRL('R'))
    {
        all = ride = TRUE;
        strcpy(buf, "Ridable monster list.");
    }
    /* XTRA HACK WHATSEARCH */
    else if (sym == KTRL('M'))
    {
        all = TRUE;
        if (!get_string("Enter name:",temp, 70))
        {
            temp[0]=0;
            return;
        }
        sprintf(buf, "Monsters with a name \"%s\"",temp);
    }
    else if (ident_info[i])
    {
        sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
    }
    else
    {
        sprintf(buf, "%c - %s.", sym, "Unknown Symbol");
    }

    /* Display the result */
    prt(buf, 0, 0);

    /* Allocate the "who" array */
    C_MAKE(who, max_r_idx, u16b);

    /* Collect matching monsters */
    for (n = 0, i = 1; i < max_r_idx; i++)
    {
        monster_race *r_ptr = &r_info[i];

        /* Nothing to recall */
        if (!(cheat_know || p_ptr->wizard) && !r_ptr->r_sights) continue;

        /* Require non-unique monsters if needed */
        if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue;

        /* Require unique monsters if needed */
        if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue;

        /* Require ridable monsters if needed */
        if (ride && !(r_ptr->flags7 & (RF7_RIDING))) continue;

        /* XTRA HACK WHATSEARCH */
        if (temp[0])
        {
          int xx;
          char temp2[80];
  
          for (xx=0; temp[xx] && xx<80; xx++)
          {
            if (isupper(temp[xx])) temp[xx]=tolower(temp[xx]);
          }
  
          strcpy(temp2, r_name+r_ptr->name);
          for (xx=0; temp2[xx] && xx<80; xx++)
            if (isupper(temp2[xx])) temp2[xx]=tolower(temp2[xx]);
  
          if (my_strstr(temp2, temp))
              who[n++]=i;
        }

        /* Collect "appropriate" monsters */
        else if (all || (r_ptr->d_char == sym)) who[n++] = i;
    }

    /* Nothing to recall */
    if (!n)
    {
        /* Free the "who" array */
        C_KILL(who, max_r_idx, u16b);

        return;
    }


    /* Prompt XXX XXX XXX */
    put_str("Recall details? (k/y/n): ", 0, 40);


    /* Query */
    query = inkey();

    /* Restore */
    prt(buf, 0, 0);

    why = 2;

    /* Select the sort method */
    ang_sort_comp = ang_sort_comp_hook;
    ang_sort_swap = ang_sort_swap_hook;

    /* Sort the array */
    ang_sort(who, &why, n);

    /* Sort by kills (and level) */
    if (query == 'k')
    {
        why = 4;
        query = 'y';
    }

    /* Catch "escape" */
    if (query != 'y')
    {
        /* Free the "who" array */
        C_KILL(who, max_r_idx, u16b);

        return;
    }

    /* Sort if needed */
    if (why == 4)
    {
        /* Select the sort method */
        ang_sort_comp = ang_sort_comp_hook;
        ang_sort_swap = ang_sort_swap_hook;

        /* Sort the array */
        ang_sort(who, &why, n);
    }


    /* Start at the end */
    i = n - 1;

    /* Scan the monster memory */
    while (1)
    {
        /* Extract a race */
        r_idx = who[i];

        /* Hack -- Auto-recall */
        monster_race_track(r_idx);

        /* Hack -- Handle stuff */
        handle_stuff();

        /* Interact */
        while (1)
        {
            /* Recall */
            if (recall)
            {
                /* Save the screen */
                screen_save();

                /* Recall on screen */
                screen_roff(who[i], 0);
            }

            /* Hack -- Begin the prompt */
            roff_top(r_idx);

            /* Hack -- Complete the prompt */
            Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");

            /* Command */
            query = inkey();

            /* Unrecall */
            if (recall)
            {
                /* Restore */
                screen_load();
            }

            /* Normal commands */
            if (query != 'r') break;

            /* Toggle recall */
            recall = !recall;
        }

        /* Stop scanning */
        if (query == ESCAPE) break;

        /* Move to "prev" monster */
        if (query == '-')
        {
            if (++i == n)
            {
                i = 0;
                if (!expand_list) break;
            }
        }

        /* Move to "next" monster */
        else
        {
            if (i-- == 0)
            {
                i = n - 1;
                if (!expand_list) break;
            }
        }
    }

    /* Free the "who" array */
    C_KILL(who, max_r_idx, u16b);

    /* Re-display the identity */
    prt(buf, 0, 0);
}
Exemple #8
0
/*!
 * @brief 保存フロアの書き込み / Actually write a saved floor data using effectively compressed format.
 * @param sf_ptr 保存したいフロアの参照ポインタ
 * @return なし
 */
static void wr_saved_floor(saved_floor_type *sf_ptr)
{
	cave_template_type *templates;
	u16b max_num_temp;
	u16b num_temp = 0;
	int dummy_why;

	int i, y, x;

	u16b tmp16u;

	byte count;
	u16b prev_u16b;


	/*** Basic info ***/

	/* Dungeon floor specific info follows */

	if (!sf_ptr)
	{
		/*** Not a saved floor ***/

		wr_s16b(dun_level);
	}
	else
	{
		/*** The saved floor ***/

		wr_s16b(sf_ptr->floor_id);
		wr_byte(sf_ptr->savefile_id);
		wr_s16b(sf_ptr->dun_level);
		wr_s32b(sf_ptr->last_visit);
		wr_u32b(sf_ptr->visit_mark);
		wr_s16b(sf_ptr->upper_floor_id);
		wr_s16b(sf_ptr->lower_floor_id);
	}

	wr_u16b(base_level);
	wr_u16b(num_repro);
	wr_u16b((u16b)py);
	wr_u16b((u16b)px);
	wr_u16b(cur_hgt);
	wr_u16b(cur_wid);
	wr_byte(p_ptr->feeling);



	/*********** Make template for cave_type **********/

	/*
	 * Usually number of templates are fewer than 255.  Even if
	 * more than 254 are exist, the occurrence of each template
	 * with larger ID is very small when we sort templates by
	 * occurrence.  So we will use two (or more) bytes for
	 * templete ID larger than 254.
	 *
	 * Ex: 256 will be "0xff" "0x01".
	 *     515 will be "0xff" "0xff" "0x03"
	 */

	/* Fake max number */
	max_num_temp = 255;

	/* Allocate the "template" array */
	C_MAKE(templates, max_num_temp, cave_template_type);

	/* Extract template array */
	for (y = 0; y < cur_hgt; y++)
	{
		for (x = 0; x < cur_wid; x++)
		{
			cave_type *c_ptr = &cave[y][x];

			for (i = 0; i < num_temp; i++)
			{
				if (templates[i].info == c_ptr->info &&
				    templates[i].feat == c_ptr->feat &&
				    templates[i].mimic == c_ptr->mimic &&
				    templates[i].special == c_ptr->special)
				{
					/* Same terrain is exist */
					templates[i].occurrence++;
					break;
				}
			}

			/* Are there same one? */
			if (i < num_temp) continue;

			/* If the max_num_temp is too small, increase it. */
			if (num_temp >= max_num_temp)
			{
				cave_template_type *old_template = templates;

				/* Re-allocate the "template" array */
				C_MAKE(templates, max_num_temp + 255, cave_template_type);
				(void)C_COPY(templates, old_template, max_num_temp, cave_template_type);
				C_KILL(old_template, max_num_temp, cave_template_type);
				max_num_temp += 255;
			}

			/* Add new template */
			templates[num_temp].info = c_ptr->info;
			templates[num_temp].feat = c_ptr->feat;
			templates[num_temp].mimic = c_ptr->mimic;
			templates[num_temp].special = c_ptr->special;
			templates[num_temp].occurrence = 1;

			/* Increase number of template */
			num_temp++;
		}
	}

	/* Select the sort method */
	ang_sort_comp = ang_sort_comp_cave_temp;
	ang_sort_swap = ang_sort_swap_cave_temp;

	/* Sort by occurrence */
	ang_sort(templates, &dummy_why, num_temp);


	/*** Dump templates ***/

	/* Total templates */
	wr_u16b(num_temp);

	/* Dump the templates */
	for (i = 0; i < num_temp; i++)
	{
		cave_template_type *ct_ptr = &templates[i];

		/* Dump it */
		wr_u16b(ct_ptr->info);
		wr_s16b(ct_ptr->feat);
		wr_s16b(ct_ptr->mimic);
		wr_s16b(ct_ptr->special);
	}



	/*** "Run-Length-Encoding" of cave ***/

	/* Note that this will induce two wasted bytes */
	count = 0;
	prev_u16b = 0;

	/* Dump the cave */
	for (y = 0; y < cur_hgt; y++)
	{
		for (x = 0; x < cur_wid; x++)
		{
			cave_type *c_ptr = &cave[y][x];

			for (i = 0; i < num_temp; i++)
			{
				if (templates[i].info == c_ptr->info &&
				    templates[i].feat == c_ptr->feat &&
				    templates[i].mimic == c_ptr->mimic &&
				    templates[i].special == c_ptr->special)
					break;
			}

			/* Extract an ID */
			tmp16u = i;

			/* If the run is broken, or too full, flush it */
			if ((tmp16u != prev_u16b) || (count == MAX_UCHAR))
			{
				wr_byte((byte)count);

				while (prev_u16b >= MAX_UCHAR)
				{
					/* Mark as actual data is larger than 254 */
					wr_byte(MAX_UCHAR);
					prev_u16b -= MAX_UCHAR;
				}

				wr_byte((byte)prev_u16b);
				prev_u16b = tmp16u;
				count = 1;
			}

			/* Continue the run */
			else
			{
				count++;
			}
		}
	}

	/* Flush the data (if any) */
	if (count)
	{
		wr_byte((byte)count);

		while (prev_u16b >= MAX_UCHAR)
		{
			/* Mark as actual data is larger than 254 */
			wr_byte(MAX_UCHAR);
			prev_u16b -= MAX_UCHAR;
		}
		wr_byte((byte)prev_u16b);
	}


	/* Free the "template" array */
	C_KILL(templates, max_num_temp, cave_template_type);


	/*** Dump objects ***/

	/* Total objects */
	wr_u16b(o_max);

	/* Dump the objects */
	for (i = 1; i < o_max; i++)
	{
		object_type *o_ptr = &o_list[i];

		/* Dump it */
		wr_item(o_ptr);
	}


	/*** Dump the monsters ***/

	/* Total monsters */
	wr_u16b(m_max);

	/* Dump the monsters */
	for (i = 1; i < m_max; i++)
	{
		monster_type *m_ptr = &m_list[i];

		/* Dump it */
		wr_monster(m_ptr);
	}
}
Exemple #9
0
/*
 * Create a spoiler file for monsters
 */
static void spoil_mon_desc(cptr fname)
{
	int i, n = 0;

	char buf[1024];

	/* We use either ascii or system-specific encoding */
	int encoding = (xchars_to_file) ? SYSTEM_SPECIFIC : ASCII;

	char nam[DESC_LEN];
	char lev[32];
	char rar[32];
	char spd[32];
	char ac[32];
	char hp[32];
	char exp[32];

	u16b *who;
	u16b why = 2;

	/* Build the filename */
	(void)path_build(buf, sizeof(buf), ANGBAND_DIR_INFO, fname);

	/* File type is "TEXT" */
	FILE_TYPE(FILE_TYPE_TEXT);

	/* Open the file */
	fff = my_fopen(buf, "w");

	/* Oops */
	if (!fff)
	{
		msg_print("Cannot create spoiler file.");
		return;
	}

	/* Dump to the spoiler file */
	text_out_hook = text_out_to_file;
	text_out_file = fff;

	/* Print header */
	print_header("Brief Monster");

	/* Dump the header */
	fprintf(fff, "%-40.40s%4s%4s%6s%8s%4s  %11.11s\n",
		"Name", "Lev", "Rar", "Spd", "Hp", "Ac", "Visual Info");
	fprintf(fff, "%-40.40s%4s%4s%6s%8s%4s  %11.11s\n",
		"----", "---", "---", "---", "--", "--", "-----------");


	/* Allocate the "who" array */
	C_MAKE(who, z_info->r_max, u16b);

	/* Scan the monsters */
	for (i = 1; i < z_info->r_max; i++)
	{
		monster_race *r_ptr = &r_info[i];

		/* Use that monster */
		if (r_ptr->name) who[n++] = (u16b)i;
	}

	/* Select the sort method */
	ang_sort_comp = ang_sort_comp_hook;
	ang_sort_swap = ang_sort_swap_hook;

	/* Sort the array by dungeon depth of monsters */
	ang_sort(who, &why, n);

	/* Scan again */
	for (i = 0; i < n; i++)
	{
		monster_race *r_ptr = &r_info[who[i]];

		cptr name = (r_name + r_ptr->name);

		/* Get the "name" */
		if (r_ptr->flags1 & (RF1_QUESTOR))
		{
			(void)strnfmt(nam, sizeof(nam), "[Q] %s", name);
		}
		else if (r_ptr->flags1 & (RF1_UNIQUE))
		{
			(void)strnfmt(nam, sizeof(nam), "[U] %s", name);
		}
		else
		{
			(void)strnfmt(nam, sizeof(nam), "The %s", name);
		}


		/* Level */
		(void)strnfmt(lev, sizeof(lev), "%d", r_ptr->level);

		/* Rarity */
		(void)strnfmt(rar, sizeof(rar), "%d", r_ptr->rarity);

		/* Speed */
		(void)strnfmt(spd, sizeof(spd), "%+d", (r_ptr->speed - 110));


		/* Armor Class */
		(void)strnfmt(ac, sizeof(ac), "%d", r_ptr->ac);

		/* Hitpoints */
		if (r_ptr->flags1 & (RF1_FIXED_HPS))
		{
			(void)strnfmt(hp, sizeof(hp), "%d", (int)r_ptr->hitpoints);
		}
		else
		{
			(void)strnfmt(hp, sizeof(hp), "~%d", (int)r_ptr->hitpoints);
		}


		/* Experience */
		(void)strnfmt(exp, sizeof(exp), "%ld", (long)(r_ptr->mexp));

		/* Hack -- use visual instead */
		(void)strnfmt(exp, sizeof(exp), "%s '%c'", attr_to_text(r_ptr->d_attr),
		        r_ptr->d_char);

		/* Dump the info */
		x_fprintf(fff, encoding, "%-40.40s%4s%4s%6s%8s%4s  %11.11s\n",
			nam, lev, rar, spd, hp, ac, exp);
	}

	/* End it */
	fprintf(fff, "\n");

	/* Free the "who" array */
	FREE(who);

	/* Check for errors */
	if (ferror(fff) || my_fclose(fff))
	{
		msg_print("Cannot close spoiler file.");
		return;
	}

	/* Worked */
	msg_print("Successfully created a spoiler file.");
}
Exemple #10
0
/*
 * Create a spoiler file for monsters
 * [email protected] (Shawn McHorse)
 */
static void spoil_mon_info(cptr fname)
{
	char buf[1024];
	int i, n;
	u16b why = 2;
	u16b *who;
	int count = 0;


	/* Build the filename */
	(void)path_build(buf, sizeof(buf), ANGBAND_DIR_INFO, fname);

	/* File type is "TEXT" */
	FILE_TYPE(FILE_TYPE_TEXT);

	/* Open the file */
	fff = my_fopen(buf, "w");

	/* Oops */
	if (!fff)
	{
		msg_print("Cannot create spoiler file.");
		return;
	}

	/* Dump to the spoiler file */
	text_out_hook = text_out_to_file;
	text_out_file = fff;

	/* Print header */
	print_header("Full Monster");

	/* Allocate the "who" array */
	C_MAKE(who, z_info->r_max, u16b);

	/* Scan the monsters */
	for (i = 1; i < z_info->r_max; i++)
	{
		monster_race *r_ptr = &r_info[i];

		/* Use that monster */
		if (r_ptr->name) who[count++] = (u16b)i;
	}

	/* Select the sort method */
	ang_sort_comp = ang_sort_comp_hook;
	ang_sort_swap = ang_sort_swap_hook;

	/* Sort the array by dungeon depth of monsters */
	ang_sort(who, &why, count);

	/*
	 * List all monsters in order.
	 */
	for (n = 0; n < count; n++)
	{
		int r_idx = who[n];
		monster_race *r_ptr = &r_info[r_idx];

		/* Prefix */
		if (r_ptr->flags1 & RF1_QUESTOR)
		{
			text_out("[Q] ");
		}
		else if (r_ptr->flags1 & RF1_UNIQUE)
		{
			text_out("[U] ");
		}
		else
		{
			text_out("The ");
		}

		/* Name */
		(void)strnfmt(buf, sizeof(buf), "%s  (", (r_name + r_ptr->name));	/* ---)--- */
		text_out(buf);

		/* Color */
		text_out(attr_to_text(r_ptr->d_attr));

		/* Symbol --(-- */
		(void)strnfmt(buf, sizeof(buf), " '%c')\n", r_ptr->d_char);
		text_out(buf);


		/* Indent */
		(void)strnfmt(buf, sizeof(buf), "=== ");
		text_out(buf);

		/* Number */
		(void)strnfmt(buf, sizeof(buf), "Num:%d  ", r_idx);
		text_out(buf);

		/* Level */
		(void)strnfmt(buf, sizeof(buf), "Lev:%d  ", r_ptr->level);
		text_out(buf);

		/* Rarity */
		(void)strnfmt(buf, sizeof(buf), "Rar:%d  ", r_ptr->rarity);
		text_out(buf);

		/* Speed */
		if (r_ptr->speed >= 110)
		{
			(void)strnfmt(buf, sizeof(buf), "Spd:+%d  ", (r_ptr->speed - 110));
		}
		else
		{
			(void)strnfmt(buf, sizeof(buf), "Spd:-%d  ", (110 - r_ptr->speed));
		}
		text_out(buf);

		/* Hitpoints */
		if (r_ptr->flags1 & (RF1_FIXED_HPS))
		{
			(void)strnfmt(buf, sizeof(buf), "%d", r_ptr->hitpoints);
		}
		else
		{
			(void)strnfmt(buf, sizeof(buf), "~%d", r_ptr->hitpoints);
		}
		text_out(buf);

		/* Armor Class */
		(void)strnfmt(buf, sizeof(buf), "Ac:%d  ", r_ptr->ac);
		text_out(buf);

		/* Experience */
		(void)strnfmt(buf, sizeof(buf), "Exp:%ld\n", (long)(r_ptr->mexp));
		text_out(buf);

		/* Describe */
		describe_monster(r_idx, TRUE);

		/* Terminate the entry */
		text_out("\n");
	}

	/* Free the "who" array */
	FREE(who);

	/* Check for errors */
	if (ferror(fff) || my_fclose(fff))
	{
		msg_print("Cannot close spoiler file.");
		return;
	}

	msg_print("Successfully created a spoiler file.");
}
Exemple #11
0
/*
 * Create a spoiler file for monsters   -BEN-
 */
static void spoil_mon_desc(cptr fname)
{
    int i, n = 0;

    u16b why = 2;
    s16b *who;

    char buf[1024];

    char nam[80];
    char lev[80];
    char rar[80];
    char spd[80];
    char ac[80];
    char hp[80];
    char exp[80];

    /* Build the filename */
    path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);

    /* File type is "TEXT" */
    FILE_TYPE(FILE_TYPE_TEXT);

    /* Open the file */
    fff = my_fopen(buf, "w");

    /* Oops */
    if (!fff)
    {
        msg_print("Cannot create spoiler file.");
        return;
    }

    /* Allocate the "who" array */
    C_MAKE(who, max_r_idx, s16b);

    /* Dump the header */
    fprintf(fff, "Spoiler File -- Monsters (PosChengband %d.%d.%d)\n\n\n",
        VER_MAJOR, VER_MINOR, VER_PATCH);
    fprintf(fff, "------------------------------------------\n\n");

    /* Dump the header */
    fprintf(fff, "    %-38.38s%4s%4s%4s%7s%5s  %11.11s\n",
        "Name", "Lev", "Rar", "Spd", "Hp", "Ac", "Visual Info");
    fprintf(fff, "%-42.42s%4s%4s%4s%7s%5s  %11.11s\n",
        "--------", "---", "---", "---", "--", "--", "-----------");


    /* Scan the monsters */
    for (i = 1; i < max_r_idx; i++)
    {
        monster_race *r_ptr = &r_info[i];

        /* Use that monster */
        if (r_ptr->name) who[n++] = i;
    }

    /* Select the sort method */
    ang_sort_comp = ang_sort_comp_hook;
    ang_sort_swap = ang_sort_swap_hook;

    /* Sort the array by dungeon depth of monsters */
    ang_sort(who, &why, n);

    /* Scan again */
    for (i = 0; i < n; i++)
    {
        monster_race *r_ptr = &r_info[who[i]];

        cptr name = (r_name + r_ptr->name);
        if (r_ptr->flags7 & (RF7_KAGE)) continue;

        /* Get the "name" */
        /*
        else if (r_ptr->flags1 & (RF1_QUESTOR))
        {
            sprintf(nam, "[Q] %s", name);
        }
        */
        else if (r_ptr->flags1 & (RF1_UNIQUE))
        {
            sprintf(nam, "[U] %s", name);
        }
        else
        {
            sprintf(nam, "The %s", name);
        }


        /* Level */
        sprintf(lev, "%d", r_ptr->level);

        /* Rarity */
        sprintf(rar, "%d", r_ptr->rarity);

        /* Speed */
        if (r_ptr->speed >= 110)
        {
            sprintf(spd, "+%d", (r_ptr->speed - 110));
        }
        else
        {
            sprintf(spd, "-%d", (110 - r_ptr->speed));
        }

        /* Armor Class */
        sprintf(ac, "%d", r_ptr->ac);

        /* Hitpoints */
        if ((r_ptr->flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1))
        {
            sprintf(hp, "%d", r_ptr->hdice * r_ptr->hside);
        }
        else
        {
            sprintf(hp, "%dd%d", r_ptr->hdice, r_ptr->hside);
        }


        /* Experience */
        sprintf(exp, "%d", r_ptr->mexp);

        /* Hack -- use visual instead */
        sprintf(exp, "%s '%c'", attr_to_text(r_ptr), r_ptr->d_char);

        /* Dump the info */
        fprintf(fff, "%-42.42s%4s%4s%4s%7s%5s  %11.11s\n",
            nam, lev, rar, spd, hp, ac, exp);
    }

    /* End it */
    fprintf(fff, "\n");


    /* Free the "who" array */
    C_KILL(who, max_r_idx, s16b);

    /* Check for errors */
    if (ferror(fff) || my_fclose(fff))
    {
        msg_print("Cannot close spoiler file.");
        return;
    }

    /* Worked */
    msg_print("Successfully created a spoiler file.");
}
Exemple #12
0
/*
 * Print monsters' evolution information to file
 */
static void spoil_mon_evol(cptr fname)
{
    char buf[1024];
    monster_race *r_ptr;
    int **evol_tree, i, j, n, r_idx;
    int *evol_tree_zero; /* For C_KILL() */

    /* Build the filename */
    path_build(buf, sizeof buf, ANGBAND_DIR_USER, fname);

    /* File type is "TEXT" */
    FILE_TYPE(FILE_TYPE_TEXT);

    /* Open the file */
    fff = my_fopen(buf, "w");

    /* Oops */
    if (!fff)
    {
        msg_print("Cannot create spoiler file.");
        return;
    }

    /* Dump the header */
    sprintf(buf, "Monster Spoilers for PosChengband Version %d.%d.%d\n",
         VER_MAJOR, VER_MINOR, VER_PATCH);

    spoil_out(buf);
    spoil_out("------------------------------------------\n\n");

    /* Allocate the "evol_tree" array (2-dimension) */
    C_MAKE(evol_tree, max_r_idx, int *);
    C_MAKE(*evol_tree, max_r_idx * (MAX_EVOL_DEPTH + 1), int);
    for (i = 1; i < max_r_idx; i++) evol_tree[i] = *evol_tree + i * (MAX_EVOL_DEPTH + 1);
    evol_tree_zero = *evol_tree;

    /* Step 1: Build the evolution tree */
    for (i = 1; i < max_r_idx; i++)
    {
        r_ptr = &r_info[i];

        /* No evolution */
        if (!r_ptr->next_exp) continue;

        /* Trace evolution */
        n = 0;
        evol_tree[i][n++] = i;
        do
        {
            evol_tree[i][n++] = r_ptr->next_r_idx;
            r_ptr = &r_info[r_ptr->next_r_idx];
        }
        while (r_ptr->next_exp && (n < MAX_EVOL_DEPTH));
    }

    /* Step 2: Scan the evolution trees and remove "partial tree" */
    for (i = 1; i < max_r_idx; i++)
    {
        /* Not evolution tree */
        if (!evol_tree[i][0]) continue;

        for (j = 1; j < max_r_idx; j++)
        {
            /* Same tree */
            if (i == j) continue;

            /* Not evolution tree */
            if (!evol_tree[j][0]) continue;

            /* Is evolution tree[i] is part of [j]? */
            if (is_partial_tree(evol_tree[j], evol_tree[i]))
            {
                /* Remove this evolution tree */
                evol_tree[i][0] = 0;
                break;
            }
        }
    }

    /* Step 3: Sort the evolution trees */

    /* Select the sort method */
    ang_sort_comp = ang_sort_comp_evol_tree;
    ang_sort_swap = ang_sort_swap_evol_tree;

    /* Sort the array */
    ang_sort(evol_tree, NULL, max_r_idx);

    /* Step 4: Print the evolution trees */
    for (i = 0; i < max_r_idx; i++)
    {
        r_idx = evol_tree[i][0];

        /* No evolution or removed evolution tree */
        if (!r_idx) continue;

        /* Trace the evolution tree */
        r_ptr = &r_info[r_idx];
        fprintf(fff, "[%d]: %s (Level %d, '%c')\n", r_idx,
            r_name + r_ptr->name, r_ptr->level, r_ptr->d_char);
        for (n = 1; r_ptr->next_exp; n++)
        {
            fprintf(fff, "%*s-(%d)-> ", n * 2, "", r_ptr->next_exp);
            fprintf(fff, "[%d]: ", r_ptr->next_r_idx);
            r_ptr = &r_info[r_ptr->next_r_idx];
            fprintf(fff, "%s (Level %d, '%c')\n",
                r_name + r_ptr->name, r_ptr->level, r_ptr->d_char);
        }

        /* End of evolution tree */
        fputc('\n', fff);
    }

    /* Free the "evol_tree" array (2-dimension) */
    C_KILL(evol_tree_zero, max_r_idx * (MAX_EVOL_DEPTH + 1), int);
    C_KILL(evol_tree, max_r_idx, int *);

    /* Check for errors */
    if (ferror(fff) || my_fclose(fff))
    {
        msg_print("Cannot close spoiler file.");
        return;
    }

    /* Message */
    msg_print("Successfully created a spoiler file.");
}
Exemple #13
0
/*
 * Display list of svals to be squelched.
 */
static bool sval_menu(int tval, const char *desc)
{
	menu_type menu;
	menu_iter menu_f = { NULL, NULL, sval_display, sval_action };
	region area = { 1, 5, -1, -1 };

	int num = 0;
	size_t i;

	squelch_choice *choice;


	/* Create the array, with entries both for aware and unaware squelch */
	choice = C_ZNEW(2 * z_info->k_max, squelch_choice);

	/* Iterate over all possible object kinds, finding ones which can be squelched */
	for (i = 1; i < z_info->k_max; i++)
	{
		object_kind *k_ptr = &k_info[i];

		/* Skip empty objects, unseen objects, and incorrect tvals */
		if (!k_ptr->name) continue;
		if (k_ptr->tval != tval) continue;

		if (!k_ptr->aware)
		{
			/* can unaware squelch anything */
			/* XXX Eddie should it be required that unaware squelched flavors have been seen this game, if so, how to save that info? */

			choice[num].idx = i;
			choice[num].aware = FALSE;
			num++;
		}

		if (k_ptr->everseen || k_ptr->tval == TV_GOLD)
		{
			/* aware squelch requires everseen */
			/* do not require awareness for aware squelch, so people can set at game start */

			choice[num].idx = i;
			choice[num].aware = TRUE;
			num++;
		}
	}

	/* Return here if there are no objects */
	if (!num)
	{
		FREE(choice);
		return FALSE;
	}

	/* sort by name in squelch menus except for categories of items that are aware from the start */
	switch(tval)
	{
		case TV_LIGHT:
		case TV_MAGIC_BOOK:
		case TV_PRAYER_BOOK:
		case TV_DRAG_ARMOR:
		case TV_GOLD:
			/* leave sorted by sval */
			break;

		default:
			/* sort by name */
			ang_sort_comp = ang_sort_comp_hook_squelch_choices;
			ang_sort_swap = ang_sort_swap_hook_squelch_choices;
			ang_sort((void*)choice, NULL, num);
	}


	/* Save the screen and clear it */
	screen_save();
	clear_from(0);

	/* Help text */

	/* Output to the screen */
	text_out_hook = text_out_to_screen;

	/* Indent output */
	text_out_indent = 1;
	text_out_wrap = 79;
	Term_gotoxy(1, 0);

	/* Display some helpful information */
	text_out("Use the ");
	text_out_c(TERM_L_GREEN, "movement keys");
	text_out(" to scroll the list or ");
	text_out_c(TERM_L_GREEN, "ESC");
	text_out(" to return to the previous menu.  ");
	text_out_c(TERM_L_BLUE, "Enter");
	text_out(" toggles the current setting.");

	text_out_indent = 0;

	/* Run menu */
	menu_init(&menu, MN_SKIN_SCROLL, &menu_f);
	menu_setpriv(&menu, num, choice);
	menu_layout(&menu, &area);
	menu_select(&menu, 0);

	/* Free memory */
	FREE(choice);

	/* Load screen */
	screen_load();
	return TRUE;
}
Exemple #14
0
/*
 *  research_mon
 *  -KMW-
 */
bool research_mon(void)
{
	int i, n, r_idx;
	char sym, query;
	char buf[128];

	s16b oldkills;
	byte oldwake;
	bool oldcheat;

	bool notpicked;

	bool recall = FALSE;

	u16b why = 0;

	monster_race *r2_ptr;

	u16b	*who;

#ifdef JP
	/* XTRA HACK WHATSEARCH */
	bool    all = FALSE;
	bool    uniq = FALSE;
	bool    norm = FALSE;
	char temp[80] = "";

	/* XTRA HACK REMEMBER_IDX */
	static int old_sym = '\0';
	static int old_i = 0;
#endif
	oldcheat = cheat_know;


	/* Save the screen */
	screen_save();

	/* Get a character, or abort */
#ifdef JP
if (!get_com("モンスターの文字を入力して下さい(記号 or ^A全,^Uユ,^N非ユ,^M名前):", &sym)) 
#else
	if (!get_com("Enter character of monster: ", &sym))
#endif

	{
		/* Restore */
		screen_load();

		return (FALSE);
	}

	/* Allocate the "who" array */
	C_MAKE(who, max_r_idx, u16b);

	/* Find that character info, and describe it */
	for (i = 0; ident_info[i]; ++i)
	{
		if (sym == ident_info[i][0]) break;
	}

#ifdef JP
		/* XTRA HACK WHATSEARCH */
	if (sym == KTRL('A'))
	{
		all = TRUE;
		strcpy(buf, "全モンスターのリスト");
	}
	else if (sym == KTRL('U'))
	{
		all = uniq = TRUE;
		strcpy(buf, "ユニーク・モンスターのリスト");
	}
	else if (sym == KTRL('N'))
	{
		all = norm = TRUE;
		strcpy(buf, "ユニーク外モンスターのリスト");
	}
	else if (sym == KTRL('M'))
	{
		all = TRUE;
		if (!get_string("名前(英語の場合小文字で可)", temp, 70))
		{
		     all = FALSE;
		     temp[0] = 0;
		}
		sprintf(buf, "名前:%sにマッチ",temp);
	}

	else if (ident_info[i])
	{
		sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
	}
#else
	if (ident_info[i])
	{
		sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
	}
#endif
	else
	{
#ifdef JP
	  sprintf(buf, "%c - %s", sym, "無効な文字");
#else
		sprintf(buf, "%c - %s.", sym, "Unknown Symbol");
#endif

	}

	/* Display the result */
	prt(buf, 16, 10);


	/* Collect matching monsters */
	for (n = 0, i = 1; i < max_r_idx; i++)
	{
		monster_race *r_ptr = &r_info[i];

		cheat_know = TRUE;

#ifdef JP
		/* XTRA HACK WHATSEARCH */
		/* Require non-unique monsters if needed */
		if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue;

		/* Require unique monsters if needed */
		if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue;

		/* 名前検索 */
		if (temp[0]){
		    char temp2[80];
		    int xx;

		    for (xx=0; temp[xx] && xx<80; xx++){
		      if (iskanji(temp[xx])) { xx++; continue; }
		      if (isupper(temp[xx])) temp[xx]=tolower(temp[xx]);
		    }

		    strcpy(temp2, r_name+r_ptr->E_name);

		    for (xx=0; temp2[xx] && xx<80; xx++)
		      if (isupper(temp2[xx])) temp2[xx]=tolower(temp2[xx]);

		    if (my_strstr(temp2, temp) || my_strstr(r_name + r_ptr->name, temp) ) who[n++]=i;
		}

		else if (all || (r_ptr->d_char == sym)) who[n++] = i;
#else
		/* Collect "appropriate" monsters */
		if (r_ptr->d_char == sym) who[n++] = i;
#endif
	}

	/* Nothing to recall */
	if (!n)
	{
		cheat_know = oldcheat;

		/* Free the "who" array */
		C_KILL(who, max_r_idx, u16b);

		/* Restore */
		screen_load();

		return (FALSE);
	}

	/* Sort by level */
	why = 2;
	query = 'y';

	/* Sort if needed */
	if (why)
	{
		/* Select the sort method */
		ang_sort_comp = ang_sort_comp_hook;
		ang_sort_swap = ang_sort_swap_hook;

		/* Sort the array */
		ang_sort(who, &why, n);
	}


	/* Start at the end */
#ifdef JP
	/* XTRA HACK REMEMBER_IDX */
	if (old_sym == sym && old_i < n) i = old_i;
	else i = n - 1;
#else
	i = n - 1;
#endif

	notpicked = TRUE;

	/* Scan the monster memory */
	while (notpicked)
	{
		/* Extract a race */
		r_idx = who[i];

		/* Save this monster ID */
		p_ptr->monster_race_idx = r_idx;

		/* Hack -- Handle stuff */
		handle_stuff();

		/* Hack -- Begin the prompt */
		roff_top(r_idx);

		/* Hack -- Complete the prompt */
#ifdef JP
Term_addstr(-1, TERM_WHITE, " ['r'思い出, ' 'で続行, ESC]");
#else
		Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC, space to continue]");
#endif


		/* Interact */
		while (1)
		{
			/* Recall */
			if (recall)
			{
				/* Recall on screen */
				r2_ptr = &r_info[r_idx];

				oldkills = r2_ptr->r_tkills;
				oldwake = r2_ptr->r_wake;
				screen_roff(who[i], 1);
				r2_ptr->r_tkills = oldkills;
				r2_ptr->r_wake = oldwake;
				cheat_know = oldcheat;
				notpicked = FALSE;
#ifdef JP
				/* XTRA HACK REMEMBER_IDX */
				old_sym = sym;
				old_i = i;
#endif
			}

			/* Command */
			query = inkey();

			/* Normal commands */
			if (query != 'r') break;

			/* Toggle recall */
			recall = !recall;
		}

		/* Stop scanning */
		if (query == ESCAPE) break;

		/* Move to "prev" monster */
		if (query == '-')
		{
			if (++i == n)
			{
				i = 0;
				if (!expand_list) break;
			}
		}

		/* Move to "next" monster */
		else
		{
			if (i-- == 0)
			{
				i = n - 1;
				if (!expand_list) break;
			}
		}
	}


	/* Re-display the identity */
	/* prt(buf, 5, 5);*/

	cheat_know = oldcheat;

	/* Free the "who" array */
	C_KILL(who, max_r_idx, u16b);

	/* Restore */
	screen_load();

	return (!notpicked);
}