1 #include "load/floor-loader.h"
2 #include "floor/floor-generator.h"
3 #include "floor/floor-save-util.h"
4 #include "game-option/birth-options.h"
5 #include "grid/feature.h"
7 #include "io/files-util.h"
8 #include "io/uid-checker.h"
9 #include "load/angband-version-comparer.h"
10 #include "load/item-loader.h"
11 #include "load/monster-loader.h"
12 #include "load/load-util.h"
13 #include "load/load-v1-5-0.h"
14 #include "load/old-feature-types.h"
15 #include "monster-race/monster-race.h"
16 #include "monster/monster-info.h"
17 #include "monster/monster-list.h"
18 #include "object-hook/hook-checker.h"
19 #include "save/floor-writer.h"
20 #include "system/angband-version.h"
21 #include "system/floor-type-definition.h"
22 #include "system/object-type-definition.h"
23 #include "util/angband-files.h"
24 #include "world/world-object.h"
25 #include "world/world.h"
28 * @brief 保存されたフロアを読み込む / Read the saved floor
29 * @param player_ptr プレーヤーへの参照ポインタ
30 * @param sf_ptr 最後に保存されたフロアへの参照ポインタ
31 * @return info読み込みエラーコード
33 * この関数は、セーブデータの互換性を保つために多くのデータ改変処理を備えている。
36 * <li>1.7.0.2で8bitだったgrid_typeのfeat,mimicのID値を16bitに拡張する処理。</li>
37 * <li>1.7.0.8までに廃止、IDなどを差し替えたクエスト番号を置換する処理。</li>
39 * The monsters/objects must be loaded in the same order
40 * that they were stored, since the actual indexes matter.
42 errr rd_saved_floor(player_type *player_ptr, saved_floor_type *sf_ptr)
44 grid_template_type *templates;
45 floor_type *floor_ptr = player_ptr->current_floor_ptr;
46 clear_cave(player_ptr);
47 player_ptr->x = player_ptr->y = 0;
52 floor_ptr->dun_level = (DEPTH)tmp16s;
53 floor_ptr->base_level = floor_ptr->dun_level;
57 if (tmp16s != sf_ptr->floor_id)
62 if (tmp8u != sf_ptr->savefile_id)
66 if (tmp16s != sf_ptr->dun_level)
68 floor_ptr->dun_level = sf_ptr->dun_level;
72 if (tmp32s != sf_ptr->last_visit)
77 if (tmp32u != sf_ptr->visit_mark)
81 if (tmp16s != sf_ptr->upper_floor_id)
85 if (tmp16s != sf_ptr->lower_floor_id)
91 floor_ptr->base_level = (DEPTH)tmp16s;
93 floor_ptr->num_repro = (MONSTER_NUMBER)tmp16s;
97 player_ptr->y = (POSITION)tmp16u;
100 player_ptr->x = (POSITION)tmp16u;
103 floor_ptr->height = (POSITION)tmp16s;
105 floor_ptr->width = (POSITION)tmp16s;
107 rd_byte(&player_ptr->feeling);
111 C_MAKE(templates, limit, grid_template_type);
113 for (int i = 0; i < limit; i++) {
114 grid_template_type *ct_ptr = &templates[i];
116 ct_ptr->info = (BIT_FLAGS)tmp16u;
117 if (h_older_than(1, 7, 0, 2)) {
120 ct_ptr->feat = (s16b)tmp8u;
122 ct_ptr->mimic = (s16b)tmp8u;
124 rd_s16b(&ct_ptr->feat);
125 rd_s16b(&ct_ptr->mimic);
128 rd_s16b(&ct_ptr->special);
131 POSITION ymax = floor_ptr->height;
132 POSITION xmax = floor_ptr->width;
133 for (POSITION x = 0, y = 0; y < ymax;) {
142 } while (tmp8u == MAX_UCHAR);
144 for (int i = count; i > 0; i--) {
145 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
146 g_ptr->info = templates[id].info;
147 g_ptr->feat = templates[id].feat;
148 g_ptr->mimic = templates[id].mimic;
149 g_ptr->special = templates[id].special;
159 /* Quest 18 was removed */
160 if (h_older_than(1, 7, 0, 6) && !vanilla_town) {
161 for (POSITION y = 0; y < ymax; y++) {
162 for (POSITION x = 0; x < xmax; x++) {
163 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
165 if ((g_ptr->special == OLD_QUEST_WATER_CAVE) && !floor_ptr->dun_level) {
166 if (g_ptr->feat == OLD_FEAT_QUEST_ENTER) {
167 g_ptr->feat = feat_tree;
169 } else if (g_ptr->feat == OLD_FEAT_BLDG_1) {
170 g_ptr->special = lite_town ? QUEST_OLD_CASTLE : QUEST_ROYAL_CRYPT;
172 } else if ((g_ptr->feat == OLD_FEAT_QUEST_EXIT) && (floor_ptr->inside_quest == OLD_QUEST_WATER_CAVE)) {
173 g_ptr->feat = feat_up_stair;
180 C_KILL(templates, limit, grid_template_type);
182 if (limit > current_world_ptr->max_o_idx)
184 for (int i = 1; i < limit; i++) {
187 o_idx = o_pop(floor_ptr);
191 o_ptr = &floor_ptr->o_list[o_idx];
192 rd_item(player_ptr, o_ptr);
194 if (object_is_held_monster(o_ptr)) {
196 m_ptr = &floor_ptr->m_list[o_ptr->held_m_idx];
197 o_ptr->next_o_idx = m_ptr->hold_o_idx;
198 m_ptr->hold_o_idx = o_idx;
200 grid_type *g_ptr = &floor_ptr->grid_array[o_ptr->iy][o_ptr->ix];
201 o_ptr->next_o_idx = g_ptr->o_idx;
202 g_ptr->o_idx = o_idx;
207 if (limit > current_world_ptr->max_m_idx)
210 for (int i = 1; i < limit; i++) {
214 m_idx = m_pop(floor_ptr);
218 m_ptr = &floor_ptr->m_list[m_idx];
219 rd_monster(player_ptr, m_ptr);
220 g_ptr = &floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
221 g_ptr->m_idx = m_idx;
222 real_r_ptr(m_ptr)->cur_num++;
229 * @brief 保存フロア読み込みのサブ関数 / Actually load and verify a floor save data
230 * @param player_ptr プレーヤーへの参照ポインタ
231 * @param sf_ptr 保存フロア読み込み先
234 static bool load_floor_aux(player_type *player_ptr, saved_floor_type *sf_ptr)
236 u32b n_x_check, n_v_check;
237 u32b o_x_check, o_v_check;
246 current_world_ptr->h_ver_extra = H_VER_EXTRA;
247 current_world_ptr->h_ver_patch = H_VER_PATCH;
248 current_world_ptr->h_ver_minor = H_VER_MINOR;
249 current_world_ptr->h_ver_major = H_VER_MAJOR;
253 if (saved_floor_file_sign != tmp32u)
256 if (rd_saved_floor(player_ptr, sf_ptr))
262 if (o_v_check != n_v_check)
268 if (o_x_check != n_x_check)
274 * @brief 一時保存フロア情報を読み込む / Attempt to load the temporarily saved-floor data
275 * @param player_ptr プレーヤーへの参照ポインタ
276 * @param sf_ptr 保存フロア読み込み先
280 bool load_floor(player_type *player_ptr, saved_floor_type *sf_ptr, BIT_FLAGS mode)
283 * Temporary files are always written in system depended kanji
297 FILE *old_fff = NULL;
298 byte old_xor_byte = 0;
299 u32b old_v_check = 0;
300 u32b old_x_check = 0;
301 byte old_h_ver_major = 0;
302 byte old_h_ver_minor = 0;
303 byte old_h_ver_patch = 0;
304 byte old_h_ver_extra = 0;
305 if (mode & SLF_SECOND) {
306 old_fff = loading_savefile;
307 old_xor_byte = load_xor_byte;
308 old_v_check = v_check;
309 old_x_check = x_check;
310 old_h_ver_major = current_world_ptr->h_ver_major;
311 old_h_ver_minor = current_world_ptr->h_ver_minor;
312 old_h_ver_patch = current_world_ptr->h_ver_patch;
313 old_h_ver_extra = current_world_ptr->h_ver_extra;
316 char floor_savefile[1024];
317 sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id);
319 safe_setuid_grab(player_ptr);
320 loading_savefile = angband_fopen(floor_savefile, "rb");
323 bool is_save_successful = TRUE;
324 if (!loading_savefile)
325 is_save_successful = FALSE;
327 if (is_save_successful) {
328 is_save_successful = load_floor_aux(player_ptr, sf_ptr);
329 if (ferror(loading_savefile))
330 is_save_successful = FALSE;
332 angband_fclose(loading_savefile);
333 safe_setuid_grab(player_ptr);
334 if (!(mode & SLF_NO_KILL))
335 (void)fd_kill(floor_savefile);
340 if (mode & SLF_SECOND) {
341 loading_savefile = old_fff;
342 load_xor_byte = old_xor_byte;
343 v_check = old_v_check;
344 x_check = old_x_check;
345 current_world_ptr->h_ver_major = old_h_ver_major;
346 current_world_ptr->h_ver_minor = old_h_ver_minor;
347 current_world_ptr->h_ver_patch = old_h_ver_patch;
348 current_world_ptr->h_ver_extra = old_h_ver_extra;
351 byte old_kanji_code = kanji_code;
352 kanji_code = old_kanji_code;
353 return is_save_successful;