void map_panel_size(void) { int wid, hgt; /* Only if the map exists */ if (!character_dungeon) return; /* Get size */ Term_get_size(&wid, &hgt); /* Offset */ wid -= COL_MAP + 1; /* reset panels */ if (p_ptr->depth) { /* Determine number of panels (dungeon) */ max_panel_rows = max_hgt - min_hgt; max_panel_cols = max_wid - min_wid; } else { /* Determine number of panels (wilderness) */ max_panel_rows = max_wild * 16; max_panel_cols = max_wild * 16; } /* Assume illegal panel */ panel_row_min = max_panel_rows; panel_col_min = max_panel_cols; /* Kill previous size of line */ #ifdef USE_TRANSPARENCY /* String of terrain characters along one row of the map */ if (mp_ta) C_KILL(mp_ta, map_wid_old, byte); if (mp_tc) C_KILL(mp_tc, map_wid_old, char); #endif /* USE_TRANSPARENCY */ /* String of characters along one row of the map */ if (mp_a) C_KILL(mp_a, map_wid_old, byte); if (mp_c) C_KILL(mp_c, map_wid_old, char); /* Save size */ map_wid_old = wid; /* Make the new lines */ #ifdef USE_TRANSPARENCY /* String of terrain characters along one row of the map */ C_MAKE(mp_ta, wid, byte); C_MAKE(mp_tc, wid, char); #endif /* USE_TRANSPARENCY */ /* String of characters along one row of the map */ C_MAKE(mp_a, wid, byte); C_MAKE(mp_c, wid, char); }
/* * Shuffle flavor indices of a group of objects with given tval */ static void shuffle_flavors(byte tval) { s16b *k_idx_list; int k_idx_list_num = 0; int i; /* Allocate an array for a list of k_idx */ C_MAKE(k_idx_list, max_k_idx, s16b); /* Search objects with given tval for shuffle */ for (i = 0; i < max_k_idx; i++) { object_kind *k_ptr = &k_info[i]; /* Skip non-Rings */ if (k_ptr->tval != tval) continue; /* Paranoia -- Skip objects without flavor */ if (!k_ptr->flavor) continue; /* Skip objects with a fixed flavor name */ if (k_ptr->gen_flags & TRG_FIXED_FLAVOR) continue; /* Remember k_idx */ k_idx_list[k_idx_list_num] = i; /* Increase number of remembered indices */ k_idx_list_num++; } /* Scrolls (random titles, always white) */ if (tval == TV_SCROLL) make_scroll_title(k_idx_list, k_idx_list_num); /* Shuffle flavors */ for (i = 0; i < k_idx_list_num; i++) { object_kind *k1_ptr = &k_info[k_idx_list[i]]; object_kind *k2_ptr = &k_info[k_idx_list[randint0(k_idx_list_num)]]; /* Swap flavors of this pair */ s16b tmp = k1_ptr->flavor; k1_ptr->flavor = k2_ptr->flavor; k2_ptr->flavor = tmp; } /* Free an array for a list of k_idx */ C_KILL(k_idx_list, max_k_idx, s16b); }
/*! * @brief 文字コードをSJISからEUCに変換する / Convert SJIS string to EUC string * @param str 変換する文字列のポインタ * @return なし * @details */ void sjis2euc(char *str) { int i; unsigned char c1, c2; unsigned char *tmp; int len = strlen(str); C_MAKE(tmp, len+1, byte); for (i = 0; i < len; i++) { c1 = str[i]; if (c1 & 0x80) { i++; c2 = str[i]; if (c2 >= 0x9f) { c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe0 : 0x60); c2 += 2; } else { c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe1 : 0x61); c2 += 0x60 + (c2 < 0x7f); } tmp[i - 1] = c1; tmp[i] = c2; } else tmp[i] = c1; } tmp[len] = 0; strcpy(str, (char *)tmp); C_KILL(tmp, len+1, byte); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i, j; int town_count; s32b wild_x_size; s32b wild_y_size; byte tmp8u; u16b tmp16u; u32b tmp32u; u16b tmp_k_idx; #ifdef VERIFY_CHECKSUMS u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; #endif /* Mention the savefile version */ #ifdef JP note(format("バージョン %d.%d.%d のセーブ・ファイルをロード中...", #else note(format("Loading a %d.%d.%d savefile...", #endif sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; #if SAVEFILE_VERSION /* Read the version number of the savefile */ rd_u32b(&sf_version); #endif /* SAVEFILE_VERSION */ /* Operating system info */ rd_u32b(&sf_xtra); /* Time of savefile creation */ rd_u32b(&sf_when); /* Number of resurrections */ rd_u16b(&sf_lives); /* Number of times played */ rd_u16b(&sf_saves); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Later use (always zero) */ rd_u16b(&tmp16u); /* Later use (always zero) */ rd_byte(&tmp8u); /* Kanji code */ rd_byte(&kanji_code); /* Read RNG state */ rd_randomizer(); #ifdef JP if (arg_fiddle) note("乱数情報をロードしました"); #else if (arg_fiddle) note("Loaded Randomizer Info"); #endif /* Then the options */ rd_options(); #ifdef JP if (arg_fiddle) note("オプションをロードしました"); #else if (arg_fiddle) note("Loaded Option Flags"); #endif /* * Munchkin players are marked * * XXX - should be replaced with a better method, * after the new scorefile-handling is implemented. */ if (munchkin_death) { /* Mark savefile */ noscore |= 0x0001; } /* Then the "messages" */ rd_messages(); #ifdef JP if (arg_fiddle) note("メッセージをロードしました"); #else if (arg_fiddle) note("Loaded Messages"); #endif /* Monster Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > max_r_idx) { #ifdef JP note(format("モンスターの種族が多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) monster races!", tmp16u)); #endif return (21); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_lore(i); } #ifdef JP if (arg_fiddle) note("モンスターの思い出をロードしました"); #else if (arg_fiddle) note("Loaded Monster Memory"); #endif /* Object Memory */ rd_u16b(&tmp_k_idx); /* Incompatible save files */ if (tmp_k_idx > max_k_idx) { #ifdef JP note(format("アイテムの種類が多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) object kinds!", tmp16u)); #endif return (22); } /* Make array for object memory */ C_MAKE(obj_mem, tmp_k_idx, byte); /* Read the object memory */ for (i = 0; i < tmp_k_idx; i++) { #if 0 byte tmp8u; object_kind *k_ptr = &k_info[i]; rd_byte(&tmp8u); k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; #else rd_byte(&obj_mem[i]); #endif } #ifdef JP if (arg_fiddle) note("アイテムの記録をロードしました"); #else if (arg_fiddle) note("Loaded Object Memory"); #endif #if 0 /* * Initialize arena and rewards information */ p_ptr->arena_number = 0; p_ptr->inside_arena = 0; p_ptr->inside_quest = 0; p_ptr->exit_bldg = TRUE; /* Start in town 1 */ p_ptr->town_num = 1; p_ptr->wilderness_x = 4; p_ptr->wilderness_y = 4; #endif /* Init the wilderness seeds */ for (i = 0; i < max_wild_x; i++) { for (j = 0; j < max_wild_y; j++) { wilderness[j][i].seed = randint0(0x10000000); } } /* 2.1.3 or newer version */ { u16b max_towns_load; u16b max_quests_load; byte max_rquests_load; /* Number of towns */ rd_u16b(&max_towns_load); /* Incompatible save files */ if (max_towns_load > max_towns) { #ifdef JP note(format("町が多すぎる(%u)!", max_towns_load)); #else note(format("Too many (%u) towns!", max_towns_load)); #endif return (23); } /* Number of quests */ rd_u16b(&max_quests_load); rd_byte(&max_rquests_load); /* Incompatible save files */ if (max_quests_load > max_quests) { #ifdef JP note(format("クエストが多すぎる(%u)!", max_quests_load)); #else note(format("Too many (%u) quests!", max_quests_load)); #endif return (23); } for (i = 0; i < max_quests_load; i++) { if (i < max_quests) { rd_s16b(&quest[i].status); rd_s16b(&quest[i].level); rd_byte(&quest[i].complev); /* Load quest status if quest is running */ if ((quest[i].status == QUEST_STATUS_TAKEN) || (quest[i].status == QUEST_STATUS_COMPLETED) || ((i >= MIN_RANDOM_QUEST) && (i <= (MIN_RANDOM_QUEST + max_rquests_load)))) { rd_s16b(&quest[i].cur_num); rd_s16b(&quest[i].max_num); rd_s16b(&quest[i].type); /* Load quest monster index */ rd_s16b(&quest[i].r_idx); if ((quest[i].type == QUEST_TYPE_RANDOM) && (!quest[i].r_idx)) { int r_idx; while (1) { monster_race *r_ptr; /* * Random monster 5 - 10 levels out of depth * (depending on level) */ r_idx = get_mon_num(quest[i].level + 10); r_ptr = &r_info[r_idx]; if(!(r_ptr->flags1 & RF1_UNIQUE)) continue; if (r_ptr->flags1 & RF1_QUESTOR) continue; if (r_ptr->level >= quest[i].level + 5) continue; if (r_ptr->level >= quest[i].level) break; } quest[i].r_idx = r_idx; } /* Load quest item index */ rd_s16b(&quest[i].k_idx); if (quest[i].k_idx) a_info[quest[i].k_idx].gen_flags |= TRG_QUESTITEM; /* Load quest flags */ rd_byte(&quest[i].flags); } } /* Ignore the empty quests from old versions */ else { /* Ignore quest status */ strip_bytes(2); /* Ignore quest level */ strip_bytes(2); /* * We don't have to care about the other info, * since status should be 0 for these quests anyway */ } } /* Position in the wilderness */ rd_s32b(&p_ptr->wilderness_x); rd_s32b(&p_ptr->wilderness_y); /* Size of the wilderness */ rd_s32b(&wild_x_size); rd_s32b(&wild_y_size); /* Incompatible save files */ if ((wild_x_size > max_wild_x) || (wild_y_size > max_wild_y)) { #ifdef JP note(format("荒野が大きすぎる(%u/%u)!", wild_x_size, wild_y_size)); #else note(format("Wilderness is too big (%u/%u)!", wild_x_size, wild_y_size)); #endif return (23); } /* Load the wilderness seeds */ for (i = 0; i < wild_x_size; i++) { for (j = 0; j < wild_y_size; j++) { rd_u32b(&wilderness[j][i].seed); } } } #ifdef JP if (arg_fiddle) note("クエスト情報をロードしました"); #else if (arg_fiddle) note("Loaded Quests"); #endif /* Load the Artifacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > max_a_idx) { #ifdef JP note(format("伝説のアイテムが多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) artifacts!", tmp16u)); #endif return (24); } /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); a_info[i].cur_num = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } #ifdef JP if (arg_fiddle) note("伝説のアイテムをロードしました"); #else if (arg_fiddle) note("Loaded Artifacts"); #endif /* Read the extra stuff */ rd_extra(); #ifdef JP if (arg_fiddle) note("特別情報をロードしました"); #else if (arg_fiddle) note("Loaded extra information"); #endif /* Read the player_hp array */ rd_u16b(&tmp16u); /* Remark questor flag on random quester */ if (!death) { for (i = MIN_RANDOM_QUEST; i <= MAX_RANDOM_QUEST; i++) { r_info[quest[i].r_idx].flags1 |= RF1_QUESTOR; } } /* Incompatible save files */ if (tmp16u > PY_MAX_LEVEL) { #ifdef JP note(format("ヒットポイント配列が大きすぎる(%u)!", tmp16u)); #else note(format("Too many (%u) hitpoint entries!", tmp16u)); #endif return (25); } /* Read the player_hp array */ for (i = 0; i < tmp16u; i++) { rd_s16b(&player_hp[i]); } /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/class */ rp_ptr = &race_info[p_ptr->prace]; cp_ptr = &class_info[p_ptr->pclass]; /* Important -- Initialize the magic */ mp_ptr = &m_info[p_ptr->pclass]; /* Read spell info */ rd_u32b(&spell_learned1); rd_u32b(&spell_learned2); rd_u32b(&spell_worked1); rd_u32b(&spell_worked2); rd_u32b(&spell_forgotten1); rd_u32b(&spell_forgotten2); for (i = 0; i < 64; i++) { rd_byte(&spell_order[i]); } /* Read the inventory */ if (rd_inventory()) { #ifdef JP note("持ち物情報を読み込むことができません"); #else note("Unable to read inventory"); #endif return (21); } /* Read number of towns */ rd_u16b(&tmp16u); town_count = tmp16u; /* Read the stores */ rd_u16b(&tmp16u); for (i = 1; i < town_count; i++) { for (j = 0; j < tmp16u; j++) { if (rd_store(i, j)) return (22); } } for (i = 0; i < tmp_k_idx; i++) { byte tmp8u = obj_mem[i]; object_kind *k_ptr = &k_info[i]; k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; } /* Free array for object memories */ C_KILL(obj_mem, tmp_k_idx, byte); /* Read the pet command settings */ if (sf_version > 2) { rd_s16b(&p_ptr->pet_follow_distance); rd_byte(&p_ptr->pet_open_doors); rd_byte(&p_ptr->pet_pickup_items); } else { rd_byte(&tmp8u); p_ptr->pet_follow_distance = tmp8u; rd_byte(&p_ptr->pet_open_doors); rd_byte(&p_ptr->pet_pickup_items); } /* I'm not dead yet... */ if (!death) { /* Dead players have no dungeon */ #ifdef JP note("ダンジョン復元中..."); #else note("Restoring Dungeon..."); #endif if (rd_dungeon()) { #ifdef JP note("ダンジョンデータ読み込み失敗"); #else note("Error reading dungeon data"); #endif return (34); } /* Read the ghost info */ rd_ghost(); { s32b tmp32s; rd_s32b(&tmp32s); strip_bytes(tmp32s); } } #ifdef VERIFY_CHECKSUMS /* Save the checksum */ n_v_check = v_check; /* Read the old checksum */ rd_u32b(&o_v_check); /* Verify */ if (o_v_check != n_v_check) { #ifdef JP note("チェックサムがおかしい"); #else note("Invalid checksum"); #endif return (11); } /* Save the encoded checksum */ n_x_check = x_check; /* Read the checksum */ rd_u32b(&o_x_check); /* Verify */ if (o_x_check != n_x_check) { #ifdef JP note("エンコードされたチェックサムがおかしい"); #else note("Invalid encoded checksum"); #endif return (11); } #endif /* Success */ return (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); }
/*! * @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); } }
/* * 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."); }
/* * 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); }