1 #include "main/info-initializer.h"
2 #include "dungeon/dungeon.h"
3 #include "grid/feature.h"
4 #include "info-reader/artifact-reader.h"
5 #include "info-reader/dungeon-reader.h"
6 #include "info-reader/ego-reader.h"
7 #include "info-reader/feature-reader.h"
8 #include "info-reader/fixed-map-parser.h"
9 #include "info-reader/general-parser.h"
10 #include "info-reader/kind-reader.h"
11 #include "info-reader/magic-reader.h"
12 #include "info-reader/race-reader.h"
13 #include "info-reader/skill-reader.h"
14 #include "info-reader/vault-reader.h"
15 #include "io/files-util.h"
16 #include "io/uid-checker.h"
17 #include "main/angband-headers.h"
18 #include "monster-race/monster-race.h"
19 #include "object-enchant/object-ego.h"
20 #include "object/object-kind.h"
21 #include "player/player-class.h"
22 #include "player/player-skill.h"
23 #include "room/rooms-vault.h"
24 #include "system/angband-version.h"
25 #include "system/artifact-type-definition.h"
26 #include "util/angband-files.h"
27 #include "view/display-messages.h"
28 #include "world/world.h"
31 #include <sys/types.h> // Windows
\82Å
\82Í
\8eg
\82í
\82ê
\82Ä
\82¢
\82È
\82¢.
35 * @brief
\8aî
\96{
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
36 * Initialize misc. values
37 * @param player_ptr
\83v
\83\8c\81[
\83\84\81[
\82Ö
\82Ì
\8eQ
\8fÆ
\83|
\83C
\83\93\83^
38 * @return
\83G
\83\89\81[
\83R
\81[
\83h
40 errr init_misc(player_type *player_ptr) { return parse_fixed_map(player_ptr, "misc.txt", 0, 0, 0, 0); }
43 * @brief raw
\83t
\83@
\83C
\83\8b\82©
\82ç
\82Ì
\83f
\81[
\83^
\82Ì
\93Ç
\82Ý
\8eæ
\82è
\8f\88\97\9d
44 * Initialize the "*_info" array, by parsing a binary "image" file
45 * @param fd
\83t
\83@
\83C
\83\8b\83f
\83B
\83X
\83N
\83\8a\83v
\83^
46 * @param head raw
\83t
\83@
\83C
\83\8b\82Ì
\83w
\83b
\83_
47 * @return
\83G
\83\89\81[
\83R
\81[
\83h
49 static errr init_info_raw(int fd, angband_header *head)
52 if (fd_read(fd, (char *)(&test), sizeof(angband_header)) || (test.v_major != head->v_major) || (test.v_minor != head->v_minor)
53 || (test.v_patch != head->v_patch) || (test.info_num != head->info_num) || (test.info_len != head->info_len) || (test.head_size != head->head_size)
54 || (test.info_size != head->info_size)) {
59 C_MAKE(head->info_ptr, head->info_size, char);
60 fd_read(fd, head->info_ptr, head->info_size);
61 if (head->name_size) {
62 C_MAKE(head->name_ptr, head->name_size, char);
63 fd_read(fd, head->name_ptr, head->name_size);
66 if (head->text_size) {
67 C_MAKE(head->text_ptr, head->text_size, char);
68 fd_read(fd, head->text_ptr, head->text_size);
72 C_MAKE(head->tag_ptr, head->tag_size, char);
73 fd_read(fd, head->tag_ptr, head->tag_size);
79 static void update_header(angband_header *head, void **info, char **name, char **text, char **tag)
82 *info = head->info_ptr;
85 *name = head->name_ptr;
88 *text = head->text_ptr;
95 * @brief
\83w
\83b
\83_
\8d\
\91¢
\91Ì
\82Ì
\8dX
\90V
96 * Initialize the header of an *_info.raw file.
97 * @param head raw
\83t
\83@
\83C
\83\8b\82Ì
\83w
\83b
\83_
98 * @param num
\83f
\81[
\83^
\90\94
99 * @param len
\83f
\81[
\83^
\82Ì
\92·
\82³
100 * @return
\83G
\83\89\81[
\83R
\81[
\83h
102 static void init_header(angband_header *head, IDX num, int len)
104 head->v_major = FAKE_VER_MAJOR;
105 head->v_minor = FAKE_VER_MINOR;
106 head->v_patch = FAKE_VER_PATCH;
109 head->info_num = (IDX)num;
110 head->info_len = len;
112 head->head_size = sizeof(angband_header);
113 head->info_size = head->info_num * head->info_len;
117 * @brief
\83e
\83L
\83X
\83g
\83t
\83@
\83C
\83\8b\82Æraw
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\82ð
\94ä
\8ar
\82·
\82é
118 * Find the default paths to all of our important sub-directories.
119 * @param fd
\83t
\83@
\83C
\83\8b\83f
\83B
\83X
\83N
\83\8a\83v
\83^
120 * @param template_file
\83t
\83@
\83C
\83\8b\96¼
121 * @return
\83e
\83L
\83X
\83g
\82Ì
\95û
\82ª
\90V
\82µ
\82¢
\82©
\81Araw
\83t
\83@
\83C
\83\8b\82ª
\82È
\82
\8dX
\90V
\82Ì
\95K
\97v
\82ª
\82 \82é
\8fê
\8d\87-1
\81A
\8dX
\90V
\82Ì
\95K
\97v
\82ª
\82È
\82¢
\8fê
\8d\870
\81B
123 static errr check_modification_date(int fd, concptr template_file)
125 struct stat txt_stat, raw_stat;
127 path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file);
128 if (stat(buf, &txt_stat))
131 if (fstat(fd, &raw_stat))
134 if (txt_stat.st_mtime > raw_stat.st_mtime)
141 * @brief
\83w
\83b
\83_
\8d\
\91¢
\91Ì
\82Ì
\8dX
\90V
142 * Initialize the "*_info" array
143 * @param filename
\83t
\83@
\83C
\83\8b\96¼(
\8ag
\92£
\8eqtxt/raw)
144 * @param head
\8f\88\97\9d\82É
\97p
\82¢
\82é
\83w
\83b
\83_
\8d\
\91¢
\91Ì
145 * @param info
\83f
\81[
\83^
\95Û
\8aÇ
\90æ
\82Ì
\8d\
\91¢
\91Ì
\83|
\83C
\83\93\83^
146 * @param name
\96¼
\8fÌ
\97p
\89Â
\95Ï
\95¶
\8e\9a\97ñ
\82Ì
\95Û
\8aÇ
\90æ
147 * @param text
\83e
\83L
\83X
\83g
\97p
\89Â
\95Ï
\95¶
\8e\9a\97ñ
\82Ì
\95Û
\8aÇ
\90æ
148 * @param tag
\83^
\83O
\97p
\89Â
\95Ï
\95¶
\8e\9a\97ñ
\82Ì
\95Û
\8aÇ
\90æ
149 * @return
\83G
\83\89\81[
\83R
\81[
\83h
151 * Note that we let each entry have a unique "name" and "text" string,
152 * even if the string happens to be empty (everyone has a unique '\0').
154 static errr init_info(player_type *player_ptr, concptr filename, angband_header *head, void **info, char **name, char **text, char **tag)
157 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename));
158 int fd = fd_open(buf, O_RDONLY);
161 err = check_modification_date(fd, format("%s.txt", filename));
163 err = init_info_raw(fd, head);
168 BIT_FLAGS file_permission = 0644;
170 update_header(head, info, name, text, tag);
174 C_MAKE(head->info_ptr, head->info_size, char);
176 C_MAKE(head->name_ptr, FAKE_NAME_SIZE, char);
179 C_MAKE(head->text_ptr, FAKE_TEXT_SIZE, char);
182 C_MAKE(head->tag_ptr, FAKE_TAG_SIZE, char);
185 *info = head->info_ptr;
188 *name = head->name_ptr;
191 *text = head->text_ptr;
194 *tag = head->tag_ptr;
196 path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, format("%s.txt", filename));
198 fp = angband_fopen(buf, "r");
200 quit(format(_("'%s.txt'
\83t
\83@
\83C
\83\8b\82ð
\83I
\81[
\83v
\83\93\82Å
\82«
\82Ü
\82¹
\82ñ
\81B", "Cannot open '%s.txt' file."), filename));
202 err = init_info_txt(fp, buf, head, head->parse_info_txt);
206 oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : _("
\96¢
\92m
\82Ì", "unknown"));
208 msg_format("'%s.txt'
\83t
\83@
\83C
\83\8b\82Ì %d
\8ds
\96Ú
\82É
\83G
\83\89\81[
\81B", filename, error_line);
210 msg_format("Error %d at line %d of '%s.txt'.", err, error_line, filename);
212 msg_format(_("
\83\8c\83R
\81[
\83h %d
\82Í '%s'
\83G
\83\89\81[
\82ª
\82 \82è
\82Ü
\82·
\81B", "Record %d contains a '%s' error."), error_idx, oops);
213 msg_format(_("
\8d\
\95¶ '%s'
\81B", "Parsing '%s'."), buf);
215 quit(format(_("'%s.txt'
\83t
\83@
\83C
\83\8b\82É
\83G
\83\89\81[", "Error in '%s.txt' file."), filename));
219 (*head->retouch)(head);
221 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename));
222 safe_setuid_grab(player_ptr);
224 fd = fd_make(buf, file_permission);
227 fd_write(fd, (concptr)(head), head->head_size);
228 fd_write(fd, head->info_ptr, head->info_size);
229 fd_write(fd, head->name_ptr, head->name_size);
230 fd_write(fd, head->text_ptr, head->text_size);
231 fd_write(fd, head->tag_ptr, head->tag_size);
235 C_KILL(head->info_ptr, head->info_size, char);
237 C_KILL(head->name_ptr, FAKE_NAME_SIZE, char);
240 C_KILL(head->text_ptr, FAKE_TEXT_SIZE, char);
243 C_KILL(head->tag_ptr, FAKE_TAG_SIZE, char);
245 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename));
246 fd = fd_open(buf, O_RDONLY);
248 quit(format(_("'%s_j.raw'
\83t
\83@
\83C
\83\8b\82ð
\83\8d\81[
\83h
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B", "Cannot load '%s.raw' file."), filename));
250 err = init_info_raw(fd, head);
253 quit(format(_("'%s_j.raw'
\83t
\83@
\83C
\83\8b\82ð
\89ð
\90Í
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B", "Cannot parse '%s.raw' file."), filename));
255 update_header(head, info, name, text, tag);
260 * @brief
\92n
\8c`
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
261 * Initialize the "f_info" array
262 * @return
\83G
\83\89\81[
\83R
\81[
\83h
264 errr init_f_info(player_type *player_ptr)
266 init_header(&f_head, max_f_idx, sizeof(feature_type));
267 f_head.parse_info_txt = parse_f_info;
268 f_head.retouch = retouch_f_info;
269 return init_info(player_ptr, "f_info", &f_head, (void *)&f_info, &f_name, NULL, &f_tag);
273 * @brief
\83x
\81[
\83X
\83A
\83C
\83e
\83\80\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
274 * Initialize the "k_info" array
275 * @return
\83G
\83\89\81[
\83R
\81[
\83h
277 errr init_k_info(player_type *player_ptr)
279 init_header(&k_head, max_k_idx, sizeof(object_kind));
280 k_head.parse_info_txt = parse_k_info;
281 return init_info(player_ptr, "k_info", &k_head, (void *)&k_info, &k_name, &k_text, NULL);
285 * @brief
\8cÅ
\92è
\83A
\81[
\83e
\83B
\83t
\83@
\83N
\83g
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
286 * Initialize the "a_info" array
287 * @return
\83G
\83\89\81[
\83R
\81[
\83h
289 errr init_a_info(player_type *player_ptr)
291 init_header(&a_head, max_a_idx, sizeof(artifact_type));
292 a_head.parse_info_txt = parse_a_info;
293 return init_info(player_ptr, "a_info", &a_head, (void *)&a_info, &a_name, &a_text, NULL);
297 * @brief
\8cÅ
\92è
\83A
\81[
\83e
\83B
\83t
\83@
\83N
\83g
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
298 * Initialize the "e_info" array
299 * @return
\83G
\83\89\81[
\83R
\81[
\83h
301 errr init_e_info(player_type *player_ptr)
303 init_header(&e_head, max_e_idx, sizeof(ego_item_type));
304 e_head.parse_info_txt = parse_e_info;
305 return init_info(player_ptr, "e_info", &e_head, (void *)&e_info, &e_name, &e_text, NULL);
309 * @brief
\83\82\83\93\83X
\83^
\81[
\8eí
\91°
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
310 * Initialize the "r_info" array
311 * @return
\83G
\83\89\81[
\83R
\81[
\83h
313 errr init_r_info(player_type *player_ptr)
315 init_header(&r_head, max_r_idx, sizeof(monster_race));
316 r_head.parse_info_txt = parse_r_info;
317 return init_info(player_ptr, "r_info", &r_head, (void *)&r_info, &r_name, &r_text, NULL);
321 * @brief
\83_
\83\93\83W
\83\87\83\93\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
322 * Initialize the "d_info" array
323 * @return
\83G
\83\89\81[
\83R
\81[
\83h
325 errr init_d_info(player_type *player_ptr)
327 init_header(&d_head, current_world_ptr->max_d_idx, sizeof(dungeon_type));
328 d_head.parse_info_txt = parse_d_info;
329 return init_info(player_ptr, "d_info", &d_head, (void *)&d_info, &d_name, &d_text, NULL);
333 * @brief Vault
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
334 * Initialize the "v_info" array
335 * @return
\83G
\83\89\81[
\83R
\81[
\83h
337 * Note that we let each entry have a unique "name" and "text" string,
338 * even if the string happens to be empty (everyone has a unique '\0').
340 errr init_v_info(player_type *player_ptr)
342 init_header(&v_head, max_v_idx, sizeof(vault_type));
343 v_head.parse_info_txt = parse_v_info;
344 return init_info(player_ptr, "v_info", &v_head, (void *)&v_info, &v_name, &v_text, NULL);
348 * @brief
\90E
\8bÆ
\8bZ
\94\
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
349 * Initialize the "s_info" array
350 * @return
\83G
\83\89\81[
\83R
\81[
\83h
352 errr init_s_info(player_type *player_ptr)
354 init_header(&s_head, MAX_CLASS, sizeof(skill_table));
355 s_head.parse_info_txt = parse_s_info;
356 return init_info(player_ptr, "s_info", &s_head, (void *)&s_info, NULL, NULL, NULL);
360 * @brief
\90E
\8bÆ
\96\82\96@
\8fî
\95ñ
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\83\81\83C
\83\93\83\8b\81[
\83`
\83\93 /
361 * Initialize the "m_info" array
362 * @return
\83G
\83\89\81[
\83R
\81[
\83h
364 errr init_m_info(player_type *player_ptr)
366 init_header(&m_head, MAX_CLASS, sizeof(player_magic));
367 m_head.parse_info_txt = parse_m_info;
368 return init_info(player_ptr, "m_info", &m_head, (void *)&m_info, NULL, NULL, NULL);