2 * @file angband-initializer.cpp
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
11 * 2014 Deskull rearranged comment for Doxygen.\n
15 #include "main/angband-initializer.h"
16 #include "dungeon/dungeon.h"
17 #include "floor/wild.h"
18 #include "info-reader/feature-reader.h"
19 #include "io/files-util.h"
20 #include "io/read-pref-file.h"
21 #include "io/uid-checker.h"
22 #include "main/game-data-initializer.h"
23 #include "main/info-initializer.h"
24 #include "market/building-initializer.h"
25 #include "monster-race/monster-race.h"
26 #include "monster-race/race-flags7.h"
27 #include "system/angband-version.h"
28 #include "system/monster-race-definition.h"
29 #include "system/system-variables.h"
30 #include "term/screen-processor.h"
31 #include "term/term-color-types.h"
33 #include "util/angband-files.h"
34 #include "world/world.h"
37 #include "util/string-processor.h"
41 * @brief 各データファイルを読み取るためのパスを取得する
42 * Find the default paths to all of our important sub-directories.
43 * @param path パス保管先の文字列
45 void init_file_paths(char *libpath, char *varpath)
47 char *libtail, *vartail;
50 string_free(ANGBAND_DIR);
51 string_free(ANGBAND_DIR_APEX);
52 string_free(ANGBAND_DIR_BONE);
53 string_free(ANGBAND_DIR_DATA);
54 string_free(ANGBAND_DIR_EDIT);
55 string_free(ANGBAND_DIR_SCRIPT);
56 string_free(ANGBAND_DIR_FILE);
57 string_free(ANGBAND_DIR_HELP);
58 string_free(ANGBAND_DIR_INFO);
59 string_free(ANGBAND_DIR_SAVE);
60 string_free(ANGBAND_DIR_DEBUG_SAVE);
61 string_free(ANGBAND_DIR_USER);
62 string_free(ANGBAND_DIR_XTRA);
64 ANGBAND_DIR = string_make(libpath);
65 libtail = libpath + strlen(libpath);
66 vartail = varpath + strlen(varpath);
67 strcpy(vartail, "apex");
68 ANGBAND_DIR_APEX = string_make(varpath);
69 strcpy(vartail, "bone");
70 ANGBAND_DIR_BONE = string_make(varpath);
71 strcpy(vartail, "data");
72 ANGBAND_DIR_DATA = string_make(varpath);
73 strcpy(libtail, "edit");
74 ANGBAND_DIR_EDIT = string_make(libpath);
75 strcpy(libtail, "script");
76 ANGBAND_DIR_SCRIPT = string_make(libpath);
77 strcpy(libtail, "file");
78 ANGBAND_DIR_FILE = string_make(libpath);
79 strcpy(libtail, "help");
80 ANGBAND_DIR_HELP = string_make(libpath);
81 strcpy(libtail, "info");
82 ANGBAND_DIR_INFO = string_make(libpath);
83 strcpy(libtail, "pref");
84 ANGBAND_DIR_PREF = string_make(libpath);
85 strcpy(vartail, "save");
86 ANGBAND_DIR_SAVE = string_make(varpath);
87 path_build(buf, sizeof(buf), ANGBAND_DIR_SAVE, "log");
88 ANGBAND_DIR_DEBUG_SAVE = string_make(buf);
89 #ifdef PRIVATE_USER_PATH
90 path_build(buf, sizeof(buf), PRIVATE_USER_PATH, VERSION_NAME);
91 ANGBAND_DIR_USER = string_make(buf);
93 strcpy(vartail, "user");
94 ANGBAND_DIR_USER = string_make(varpath);
96 strcpy(libtail, "xtra");
97 ANGBAND_DIR_XTRA = string_make(libpath);
99 time_t now = time(nullptr);
100 struct tm *t = localtime(&now);
102 strftime(tmp, sizeof(tmp), "%Y-%m-%d-%H-%M-%S", t);
103 path_build(debug_savefile, sizeof(debug_savefile), ANGBAND_DIR_DEBUG_SAVE, tmp);
106 struct _finddata_t c_file;
108 char log_file_expr[1024];
109 path_build(log_file_expr, sizeof(log_file_expr), ANGBAND_DIR_DEBUG_SAVE, "*-*");
111 if ((hFile = _findfirst(log_file_expr, &c_file)) != -1L) {
113 if (((t->tm_yday + 365 - localtime(&c_file.time_write)->tm_yday) % 365) > 7) {
114 char c_file_fullpath[1024];
115 path_build(c_file_fullpath, sizeof(c_file_fullpath), ANGBAND_DIR_DEBUG_SAVE, c_file.name);
116 remove(c_file_fullpath);
118 } while (_findnext(hFile, &c_file) == 0);
123 DIR *saves_dir = opendir(ANGBAND_DIR_DEBUG_SAVE);
126 struct dirent *next_entry;
128 while ((next_entry = readdir(saves_dir))) {
129 if (angband_strchr(next_entry->d_name, '-')) {
131 struct stat next_stat;
133 path_build(path, sizeof(path), ANGBAND_DIR_DEBUG_SAVE, next_entry->d_name);
135 * Remove if modified more than a week ago,
136 * 7*24*60*60 seconds.
138 if (stat(path, &next_stat) == 0 &&
139 difftime(now, next_stat.st_mtime) > 604800) {
151 * @brief 画面左下にシステムメッセージを表示する / Take notes on line 23
152 * @param str 初期化中のコンテンツ文字列
154 static void init_note_term(concptr str)
156 term_erase(0, 23, 255);
157 term_putstr(20, 23, -1, TERM_WHITE, str);
162 * @brief ゲーム画面無しの時の初期化メッセージ出力
163 * @param str 初期化中のコンテンツ文字列
165 static void init_note_no_term(concptr str)
167 /* Don't show initialization message when there is no game terminal. */
172 * @brief 全ゲームデータ読み込みのサブルーチン / Explain a broken "lib" folder and quit (see below).
176 * This function is "messy" because various things
177 * may or may not be initialized, but the "plog()" and "quit()"
178 * functions are "supposed" to work under any conditions.
181 static void init_angband_aux(concptr why)
184 plog(_("'lib'ディレクトリが存在しないか壊れているようです。", "The 'lib' directory is probably missing or broken."));
185 plog(_("ひょっとするとアーカイブが正しく解凍されていないのかもしれません。", "The 'lib' directory is probably missing or broken."));
186 plog(_("該当する'README'ファイルを読んで確認してみて下さい。", "See the 'README' file for more information."));
187 quit(_("致命的なエラー。", "Fatal Error."));
194 static void put_title(void)
199 int col = (80 - strlen(title)) / 2;
200 col = col < 0 ? 0 : col;
201 const int VER_INFO_ROW = 3; //!< タイトル表記(行)
202 prt(title, VER_INFO_ROW, col);
206 * @brief 全ゲームデータ読み込みのメインルーチン /
207 * @param player_ptr プレイヤーへの参照ポインタ
208 * @param no_term TRUEならゲーム画面無しの状態で初期化を行う。
209 * コマンドラインからスポイラーの出力のみを行う時の使用を想定する。
211 void init_angband(player_type *player_ptr, bool no_term)
214 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("news_j.txt", "news.txt"));
215 int fd = fd_open(buf, O_RDONLY);
217 char why[sizeof(buf) + 128];
218 sprintf(why, _("'%s'ファイルにアクセスできません!", "Cannot access the '%s' file!"), buf);
219 init_angband_aux(why);
227 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("news_j.txt", "news.txt"));
229 fp = angband_fopen(buf, "r");
232 while (0 == angband_fgets(fp, buf, sizeof(buf)))
233 term_putstr(0, i++, -1, TERM_WHITE, buf);
241 path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw");
242 fd = fd_open(buf, O_RDONLY);
243 BIT_FLAGS file_permission = 0664;
245 safe_setuid_grab(player_ptr);
246 fd = fd_make(buf, file_permission);
249 char why[sizeof(buf) + 128];
250 sprintf(why, _("'%s'ファイルを作成できません!", "Cannot create the '%s' file!"), buf);
251 init_angband_aux(why);
260 void (*init_note)(concptr) = (no_term ? init_note_no_term : init_note_term);
262 init_note(_("[変数を初期化しています...(その他)", "[Initializing values... (misc)]"));
263 if (init_misc(player_ptr))
264 quit(_("その他の変数を初期化できません", "Cannot initialize misc. values"));
266 init_note(_("[データの初期化中... (地形)]", "[Initializing arrays... (features)]"));
268 quit(_("地形初期化不能", "Cannot initialize features"));
270 if (init_feat_variables())
271 quit(_("地形初期化不能", "Cannot initialize features"));
273 init_note(_("[データの初期化中... (アイテム)]", "[Initializing arrays... (objects)]"));
275 quit(_("アイテム初期化不能", "Cannot initialize objects"));
277 init_note(_("[データの初期化中... (伝説のアイテム)]", "[Initializing arrays... (artifacts)]"));
279 quit(_("伝説のアイテム初期化不能", "Cannot initialize artifacts"));
281 init_note(_("[データの初期化中... (名のあるアイテム)]", "[Initializing arrays... (ego-items)]"));
283 quit(_("名のあるアイテム初期化不能", "Cannot initialize ego-items"));
285 init_note(_("[データの初期化中... (モンスター)]", "[Initializing arrays... (monsters)]"));
287 quit(_("モンスター初期化不能", "Cannot initialize monsters"));
289 init_note(_("[データの初期化中... (ダンジョン)]", "[Initializing arrays... (dungeon)]"));
291 quit(_("ダンジョン初期化不能", "Cannot initialize dungeon"));
293 for (const auto &d_ref : d_info)
294 if (d_ref.idx > 0 && d_ref.final_guardian)
295 r_info[d_ref.final_guardian].flags7 |= RF7_GUARDIAN;
297 init_note(_("[データの初期化中... (魔法)]", "[Initializing arrays... (magic)]"));
299 quit(_("魔法初期化不能", "Cannot initialize magic"));
301 init_note(_("[データの初期化中... (熟練度)]", "[Initializing arrays... (skill)]"));
303 quit(_("熟練度初期化不能", "Cannot initialize skill"));
305 init_note(_("[配列を初期化しています... (荒野)]", "[Initializing arrays... (wilderness)]"));
306 if (init_wilderness())
307 quit(_("荒野を初期化できません", "Cannot initialize wilderness"));
309 init_note(_("[配列を初期化しています... (街)]", "[Initializing arrays... (towns)]"));
312 init_note(_("[配列を初期化しています... (建物)]", "[Initializing arrays... (buildings)]"));
315 init_note(_("[配列を初期化しています... (クエスト)]", "[Initializing arrays... (quests)]"));
318 quit(_("vault 初期化不能", "Cannot initialize vaults"));
320 init_note(_("[データの初期化中... (その他)]", "[Initializing arrays... (other)]"));
321 init_other(player_ptr);
322 init_note(_("[データの初期化中... (アロケーション)]", "[Initializing arrays... (alloc)]"));
324 init_note(_("[ユーザー設定ファイルを初期化しています...]", "[Initializing user pref files...]"));
325 strcpy(buf, "pref.prf");
326 process_pref_file(player_ptr, buf);
327 sprintf(buf, "pref-%s.prf", ANGBAND_SYS);
328 process_pref_file(player_ptr, buf);
329 init_note(_("[初期化終了]", "[Initialization complete]"));