2 * @brief ゲームデータ初期化2 / Initialization (part 2) -BEN-
6 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7 * This software may be copied and distributed for educational, research,
8 * and not for profit purposes provided that this copyright and statement
9 * are included in all such copies. Other copyrights may also apply.
10 * 2014 Deskull rearranged comment for Doxygen.\n
14 * This file is used to initialize various variables and arrays for the
15 * Angband game. Note the use of "fd_read()" and "fd_write()" to bypass
16 * the common limitation of "read()" and "write()" to only 32767 bytes
18 * Several of the arrays for Angband are built from "template" files in
19 * the "lib/file" directory, from which quick-load binary "image" files
20 * are constructed whenever they are not present in the "lib/data"
21 * directory, or if those files become obsolete, if we are allowed.
22 * Warning -- the "ascii" file parsers use a minor hack to collect the
23 * name and text information in a single pass. Thus, the game will not
24 * be able to load any template file with more than 20K of names or 60K
25 * of text, even though technically, up to 64K should be legal.
26 * The "init1.c" file is used only to parse the ascii template files,
27 * to create the binary image files. Note that the binary image files
28 * are extremely system dependant.
32 #include "main/init.h"
33 #include "cmd-building/cmd-building.h"
34 #include "cmd-io/macro-util.h"
35 #include "dungeon/dungeon.h"
36 #include "dungeon/quest.h"
37 #include "floor/floor-town.h"
38 #include "floor/floor-util.h"
39 #include "floor/wild.h"
40 #include "game-option/option-flags.h"
41 #include "game-option/option-types-table.h"
42 #include "grid/feature.h"
43 #include "grid/grid.h"
44 #include "grid/trap.h"
45 #include "info-reader/artifact-reader.h"
46 #include "info-reader/dungeon-reader.h"
47 #include "info-reader/ego-reader.h"
48 #include "info-reader/feature-reader.h"
49 #include "info-reader/general-parser.h"
50 #include "info-reader/kind-reader.h"
51 #include "info-reader/magic-reader.h"
52 #include "info-reader/parse-error-types.h"
53 #include "info-reader/race-reader.h"
54 #include "info-reader/skill-reader.h"
55 #include "info-reader/vault-reader.h"
56 #include "io/files-util.h"
57 #include "io/read-pref-file.h"
58 #include "io/uid-checker.h"
59 #include "main/angband-headers.h"
60 #include "main/info-initializer.h"
61 #include "main/init-error-messages-table.h"
62 #include "market/articles-on-sale.h"
63 #include "market/building-initializer.h"
64 #include "monster-race/monster-race.h"
65 #include "monster-race/race-flags7.h"
66 #include "object-enchant/object-ego.h"
67 #include "object/object-kind.h"
68 #include "player/player-class.h"
69 #include "player/player-skill.h"
70 #include "room/rooms-builder.h"
71 #include "room/rooms-vault.h"
72 #include "store/store-util.h"
73 #include "store/store.h"
74 #include "system/alloc-entries.h"
75 #include "system/angband-version.h"
76 #include "system/artifact-type-definition.h"
77 #include "system/building-type-definition.h"
78 #include "system/floor-type-definition.h"
79 #include "system/system-variables.h"
80 #include "term/gameterm.h"
81 #include "term/screen-processor.h"
82 #include "term/term-color-types.h"
83 #include "util/angband-files.h"
84 #include "util/quarks.h"
85 #include "util/tag-sorter.h"
86 #include "view/display-messages.h"
87 #include "world/world.h"
90 * @brief マクロ登録の最大数 / Maximum number of macros (see "io.c")
91 * @note Default: assume at most 256 macros are used
93 static const int MACRO_MAX = 256;
96 * @brief 各データファイルを読み取るためのパスを取得する
97 * Find the default paths to all of our important sub-directories.
98 * @param path パス保管先の文字列
102 * The purpose of each sub-directory is described in "variable.c".
103 * All of the sub-directories should, by default, be located inside
104 * the main "lib" directory, whose location is very system dependant.
105 * This function takes a writable buffer, initially containing the
106 * "path" to the "lib" directory, for example, "/pkg/lib/angband/",
107 * or a system dependant string, for example, ":lib:". The buffer
108 * must be large enough to contain at least 32 more characters.
109 * Various command line options may allow some of the important
110 * directories to be changed to user-specified directories, most
111 * importantly, the "info" and "user" and "save" directories,
112 * but this is done after this function, see "main.c".
113 * In general, the initial path should end in the appropriate "PATH_SEP"
114 * string. All of the "sub-directory" paths (created below or supplied
115 * by the user) will NOT end in the "PATH_SEP" string, see the special
116 * "path_build()" function in "util.c" for more information.
117 * Mega-Hack -- support fat raw files under NEXTSTEP, using special
118 * "suffixed" directories for the "ANGBAND_DIR_DATA" directory, but
119 * requiring the directories to be created by hand by the user.
120 * Hack -- first we free all the strings, since this is known
121 * to succeed even if the strings have not been allocated yet,
122 * as long as the variables start out as "NULL". This allows
123 * this function to be called multiple times, for example, to
124 * try several base "path" values until a good one is found.
127 void init_file_paths(char *path)
130 #ifdef PRIVATE_USER_PATH
133 string_free(ANGBAND_DIR);
134 string_free(ANGBAND_DIR_APEX);
135 string_free(ANGBAND_DIR_BONE);
136 string_free(ANGBAND_DIR_DATA);
137 string_free(ANGBAND_DIR_EDIT);
138 string_free(ANGBAND_DIR_SCRIPT);
139 string_free(ANGBAND_DIR_FILE);
140 string_free(ANGBAND_DIR_HELP);
141 string_free(ANGBAND_DIR_INFO);
142 string_free(ANGBAND_DIR_SAVE);
143 string_free(ANGBAND_DIR_USER);
144 string_free(ANGBAND_DIR_XTRA);
146 ANGBAND_DIR = string_make(path);
147 tail = path + strlen(path);
148 strcpy(tail, "apex");
149 ANGBAND_DIR_APEX = string_make(path);
150 strcpy(tail, "bone");
151 ANGBAND_DIR_BONE = string_make(path);
152 strcpy(tail, "data");
153 ANGBAND_DIR_DATA = string_make(path);
154 strcpy(tail, "edit");
155 ANGBAND_DIR_EDIT = string_make(path);
156 strcpy(tail, "script");
157 ANGBAND_DIR_SCRIPT = string_make(path);
158 strcpy(tail, "file");
159 ANGBAND_DIR_FILE = string_make(path);
160 strcpy(tail, "help");
161 ANGBAND_DIR_HELP = string_make(path);
162 strcpy(tail, "info");
163 ANGBAND_DIR_INFO = string_make(path);
164 strcpy(tail, "pref");
165 ANGBAND_DIR_PREF = string_make(path);
166 strcpy(tail, "save");
167 ANGBAND_DIR_SAVE = string_make(path);
168 #ifdef PRIVATE_USER_PATH
169 path_build(buf, sizeof(buf), PRIVATE_USER_PATH, VERSION_NAME);
170 ANGBAND_DIR_USER = string_make(buf);
172 strcpy(tail, "user");
173 ANGBAND_DIR_USER = string_make(path);
175 strcpy(tail, "xtra");
176 ANGBAND_DIR_XTRA = string_make(path);
180 * @brief クエスト情報初期化のメインルーチン /
181 * Initialize quest array
184 static errr init_quests(void)
186 C_MAKE(quest, max_q_idx, quest_type);
187 for (int i = 0; i < max_q_idx; i++)
188 quest[i].status = QUEST_STATUS_UNTAKEN;
194 * @brief その他の初期情報更新 /
195 * Initialize some other arrays
198 static errr init_other(player_type *player_ptr)
200 player_ptr->current_floor_ptr = &floor_info; // TODO:本当はこんなところで初期化したくない
201 floor_type *floor_ptr = player_ptr->current_floor_ptr;
202 C_MAKE(floor_ptr->o_list, current_world_ptr->max_o_idx, object_type);
203 C_MAKE(floor_ptr->m_list, current_world_ptr->max_m_idx, monster_type);
204 for (int i = 0; i < MAX_MTIMED; i++)
205 C_MAKE(floor_ptr->mproc_list[i], current_world_ptr->max_m_idx, s16b);
207 C_MAKE(max_dlv, current_world_ptr->max_d_idx, DEPTH);
208 for (int i = 0; i < MAX_HGT; i++)
209 C_MAKE(floor_ptr->grid_array[i], MAX_WID, grid_type);
211 C_MAKE(macro__pat, MACRO_MAX, concptr);
212 C_MAKE(macro__act, MACRO_MAX, concptr);
213 C_MAKE(macro__cmd, MACRO_MAX, bool);
214 C_MAKE(macro__buf, 1024, char);
217 C_MAKE(message__ptr, MESSAGE_MAX, u32b);
218 C_MAKE(message__buf, MESSAGE_BUF, char);
219 message__tail = MESSAGE_BUF;
221 for (int i = 0; option_info[i].o_desc; i++) {
222 int os = option_info[i].o_set;
223 int ob = option_info[i].o_bit;
224 if (!option_info[i].o_var)
227 option_mask[os] |= (1L << ob);
228 if (option_info[i].o_norm)
229 option_flag[os] |= (1L << ob);
231 option_flag[os] &= ~(1L << ob);
234 for (int n = 0; n < 8; n++)
235 for (int i = 0; i < 32; i++)
236 if (window_flag_desc[i])
237 window_mask[n] |= (1L << i);
240 * Set the "default" window flags
241 * Window 1 : Display messages
242 * Window 2 : Display inven/equip
244 window_flag[1] = 1L << A_MAX;
245 window_flag[2] = 1L << 0;
246 (void)format("%s (%s).", "Mr.Hoge", MAINTAINER);
251 * @brief オブジェクト配列を初期化する /
252 * Initialize some other arrays
255 static errr init_object_alloc(void)
258 (void)C_WIPE(&aux, MAX_DEPTH, s16b);
261 (void)C_WIPE(&num, MAX_DEPTH, s16b);
263 if (alloc_kind_table)
264 C_KILL(alloc_kind_table, alloc_kind_size, alloc_entry);
267 for (int i = 1; i < max_k_idx; i++) {
270 for (int j = 0; j < 4; j++) {
271 if (k_ptr->chance[j]) {
273 num[k_ptr->locale[j]]++;
278 for (int i = 1; i < MAX_DEPTH; i++)
279 num[i] += num[i - 1];
282 quit(_("町のアイテムがない!", "No town objects!"));
284 C_MAKE(alloc_kind_table, alloc_kind_size, alloc_entry);
286 table = alloc_kind_table;
287 for (int i = 1; i < max_k_idx; i++) {
290 for (int j = 0; j < 4; j++) {
291 if (k_ptr->chance[j] == 0)
294 int x = k_ptr->locale[j];
295 int p = (100 / k_ptr->chance[j]);
296 int y = (x > 0) ? num[x - 1] : 0;
298 table[z].index = (KIND_OBJECT_IDX)i;
299 table[z].level = (DEPTH)x;
300 table[z].prob1 = (PROB)p;
301 table[z].prob2 = (PROB)p;
302 table[z].prob3 = (PROB)p;
311 * @brief モンスター配列と生成テーブルを初期化する /
312 * Initialize some other arrays
315 static errr init_alloc(void)
319 C_MAKE(elements, max_r_idx, tag_type);
320 for (int i = 1; i < max_r_idx; i++) {
321 elements[i].tag = r_info[i].level;
322 elements[i].index = i;
325 tag_sort(elements, max_r_idx);
326 alloc_race_size = max_r_idx;
327 C_MAKE(alloc_race_table, alloc_race_size, alloc_entry);
328 for (int i = 1; i < max_r_idx; i++) {
329 r_ptr = &r_info[elements[i].index];
330 if (r_ptr->rarity == 0)
333 int x = r_ptr->level;
334 int p = (100 / r_ptr->rarity);
335 alloc_race_table[i].index = (KIND_OBJECT_IDX)elements[i].index;
336 alloc_race_table[i].level = (DEPTH)x;
337 alloc_race_table[i].prob1 = (PROB)p;
338 alloc_race_table[i].prob2 = (PROB)p;
339 alloc_race_table[i].prob3 = (PROB)p;
342 C_KILL(elements, max_r_idx, tag_type);
343 (void)init_object_alloc();
348 * @brief 画面左下にシステムメッセージを表示する /
349 * Hack -- take notes on line 23
352 static void init_note(concptr str)
354 term_erase(0, 23, 255);
355 term_putstr(20, 23, -1, TERM_WHITE, str);
360 * @brief 全ゲームデータ読み込みのサブルーチン /
361 * Hack -- Explain a broken "lib" folder and quit (see below).
365 * This function is "messy" because various things
366 * may or may not be initialized, but the "plog()" and "quit()"
367 * functions are "supposed" to work under any conditions.
370 static void init_angband_aux(concptr why)
373 plog(_("'lib'ディレクトリが存在しないか壊れているようです。", "The 'lib' directory is probably missing or broken."));
374 plog(_("ひょっとするとアーカイブが正しく解凍されていないのかもしれません。", "The 'lib' directory is probably missing or broken."));
375 plog(_("該当する'README'ファイルを読んで確認してみて下さい。", "See the 'README' file for more information."));
376 quit(_("致命的なエラー。", "Fatal Error."));
383 static void put_title(void)
387 sprintf(title, _("変愚蛮怒 %d.%d.%d.%d(%s)", "Hengband %d.%d.%d.%d(%s)"), H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH, H_VER_EXTRA,
389 sprintf(title, _("変愚蛮怒 %d.%d.%d(%s)", "Hengband %d.%d.%d(%s)"), H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH,
391 IS_STABLE_VERSION ? _("安定版", "Stable") : _("開発版", "Developing"));
392 int col = (80 - strlen(title)) / 2;
393 col = col < 0 ? 0 : col;
394 const int VER_INFO_ROW = 3; //!< タイトル表記(行)
395 prt(title, VER_INFO_ROW, col);
399 * @brief 全ゲームデータ読み込みのメインルーチン /
400 * @param player_ptr プレーヤーへの参照ポインタ
401 * @param process_autopick_file_command 自動拾いファイル読み込み関数への関数ポインタ
404 void init_angband(player_type *player_ptr, process_autopick_file_command_pf process_autopick_file_command)
407 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("news_j.txt", "news.txt"));
408 int fd = fd_open(buf, O_RDONLY);
411 sprintf(why, _("'%s'ファイルにアクセスできません!", "Cannot access the '%s' file!"), buf);
412 init_angband_aux(why);
417 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("news_j.txt", "news.txt"));
419 fp = angband_fopen(buf, "r");
422 while (0 == angband_fgets(fp, buf, sizeof(buf)))
423 term_putstr(0, i++, -1, TERM_WHITE, buf);
429 path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw");
430 fd = fd_open(buf, O_RDONLY);
431 BIT_FLAGS file_permission = 0664;
433 safe_setuid_grab(player_ptr);
434 fd = fd_make(buf, file_permission);
438 sprintf(why, _("'%s'ファイルを作成できません!", "Cannot create the '%s' file!"), buf);
439 init_angband_aux(why);
446 init_note(_("[変数を初期化しています...(その他)", "[Initializing values... (misc)]"));
447 if (init_misc(player_ptr))
448 quit(_("その他の変数を初期化できません", "Cannot initialize misc. values"));
450 init_note(_("[データの初期化中... (地形)]", "[Initializing arrays... (features)]"));
451 if (init_f_info(player_ptr))
452 quit(_("地形初期化不能", "Cannot initialize features"));
454 if (init_feat_variables())
455 quit(_("地形初期化不能", "Cannot initialize features"));
457 init_note(_("[データの初期化中... (アイテム)]", "[Initializing arrays... (objects)]"));
458 if (init_k_info(player_ptr))
459 quit(_("アイテム初期化不能", "Cannot initialize objects"));
461 init_note(_("[データの初期化中... (伝説のアイテム)]", "[Initializing arrays... (artifacts)]"));
462 if (init_a_info(player_ptr))
463 quit(_("伝説のアイテム初期化不能", "Cannot initialize artifacts"));
465 init_note(_("[データの初期化中... (名のあるアイテム)]", "[Initializing arrays... (ego-items)]"));
466 if (init_e_info(player_ptr))
467 quit(_("名のあるアイテム初期化不能", "Cannot initialize ego-items"));
469 init_note(_("[データの初期化中... (モンスター)]", "[Initializing arrays... (monsters)]"));
470 if (init_r_info(player_ptr))
471 quit(_("モンスター初期化不能", "Cannot initialize monsters"));
473 init_note(_("[データの初期化中... (ダンジョン)]", "[Initializing arrays... (dungeon)]"));
474 if (init_d_info(player_ptr))
475 quit(_("ダンジョン初期化不能", "Cannot initialize dungeon"));
477 for (int i = 1; i < current_world_ptr->max_d_idx; i++)
478 if (d_info[i].final_guardian)
479 r_info[d_info[i].final_guardian].flags7 |= RF7_GUARDIAN;
481 init_note(_("[データの初期化中... (魔法)]", "[Initializing arrays... (magic)]"));
482 if (init_m_info(player_ptr))
483 quit(_("魔法初期化不能", "Cannot initialize magic"));
485 init_note(_("[データの初期化中... (熟練度)]", "[Initializing arrays... (skill)]"));
486 if (init_s_info(player_ptr))
487 quit(_("熟練度初期化不能", "Cannot initialize skill"));
489 init_note(_("[配列を初期化しています... (荒野)]", "[Initializing arrays... (wilderness)]"));
490 if (init_wilderness())
491 quit(_("荒野を初期化できません", "Cannot initialize wilderness"));
493 init_note(_("[配列を初期化しています... (街)]", "[Initializing arrays... (towns)]"));
495 quit(_("街を初期化できません", "Cannot initialize towns"));
497 init_note(_("[配列を初期化しています... (建物)]", "[Initializing arrays... (buildings)]"));
498 if (init_buildings())
499 quit(_("建物を初期化できません", "Cannot initialize buildings"));
501 init_note(_("[配列を初期化しています... (クエスト)]", "[Initializing arrays... (quests)]"));
503 quit(_("クエストを初期化できません", "Cannot initialize quests"));
505 if (init_v_info(player_ptr))
506 quit(_("vault 初期化不能", "Cannot initialize vaults"));
508 init_note(_("[データの初期化中... (その他)]", "[Initializing arrays... (other)]"));
509 if (init_other(player_ptr))
510 quit(_("その他のデータ初期化不能", "Cannot initialize other stuff"));
512 init_note(_("[データの初期化中... (アロケーション)]", "[Initializing arrays... (alloc)]"));
514 quit(_("アロケーション・スタッフ初期化不能", "Cannot initialize alloc stuff"));
516 init_note(_("[ユーザー設定ファイルを初期化しています...]", "[Initializing user pref files...]"));
517 strcpy(buf, "pref.prf");
518 process_pref_file(player_ptr, buf, process_autopick_file_command);
519 sprintf(buf, "pref-%s.prf", ANGBAND_SYS);
520 process_pref_file(player_ptr, buf, process_autopick_file_command);
521 init_note(_("[初期化終了]", "[Initialization complete]"));