1 #include "load/floor-loader.h"
2 #include "floor/floor-generator.h"
3 #include "floor/floor-object.h"
4 #include "floor/floor-save-util.h"
5 #include "game-option/birth-options.h"
6 #include "grid/feature.h"
8 #include "io/files-util.h"
9 #include "io/uid-checker.h"
10 #include "load/angband-version-comparer.h"
11 #include "load/load-util.h"
12 #include "load/old-feature-types.h"
13 #include "load/old/item-loader-savefile10.h"
14 #include "load/old/load-v1-5-0.h"
15 #include "load/old/monster-loader-savefile10.h"
16 #include "monster-race/monster-race.h"
17 #include "monster/monster-info.h"
18 #include "monster/monster-list.h"
19 #include "save/floor-writer.h"
20 #include "system/angband-version.h"
21 #include "system/floor-type-definition.h"
22 #include "system/grid-type-definition.h"
23 #include "system/monster-race-definition.h"
24 #include "system/object-type-definition.h"
25 #include "system/player-type-definition.h"
26 #include "util/angband-files.h"
27 #include "world/world-object.h"
28 #include "world/world.h"
31 * @brief 保存されたフロアを読み込む / Read the saved floor
32 * @param player_ptr プレイヤーへの参照ポインタ
33 * @param sf_ptr 最後に保存されたフロアへの参照ポインタ
34 * @return info読み込みエラーコード
36 * この関数は、セーブデータの互換性を保つために多くのデータ改変処理を備えている。
39 * <li>1.7.0.2で8bitだったgrid_typeのfeat,mimicのID値を16bitに拡張する処理。</li>
40 * <li>1.7.0.8までに廃止、IDなどを差し替えたクエスト番号を置換する処理。</li>
42 * The monsters/objects must be loaded in the same order
43 * that they were stored, since the actual indexes matter.
45 errr rd_saved_floor(player_type *player_ptr, saved_floor_type *sf_ptr)
47 floor_type *floor_ptr = player_ptr->current_floor_ptr;
48 clear_cave(player_ptr);
49 player_ptr->x = player_ptr->y = 0;
52 floor_ptr->dun_level = rd_s16b();
53 floor_ptr->base_level = floor_ptr->dun_level;
55 if (rd_s16b() != sf_ptr->floor_id)
58 if (rd_byte() != sf_ptr->savefile_id)
61 if (rd_s16b() != sf_ptr->dun_level)
63 floor_ptr->dun_level = sf_ptr->dun_level;
65 if (rd_s32b() != sf_ptr->last_visit)
68 if (rd_u32b() != sf_ptr->visit_mark)
71 if (rd_s16b() != sf_ptr->upper_floor_id)
74 if (rd_s16b() != sf_ptr->lower_floor_id)
78 floor_ptr->base_level = rd_s16b();
79 floor_ptr->num_repro = rd_s16b();
81 player_ptr->y = rd_u16b();
83 player_ptr->x = rd_u16b();
85 floor_ptr->height = rd_s16b();
86 floor_ptr->width = rd_s16b();
88 player_ptr->feeling = rd_byte();
90 auto limit = rd_u16b();
91 std::vector<grid_template_type> templates(limit);
93 for (auto &ct_ref : templates) {
94 ct_ref.info = rd_u16b();
95 if (h_older_than(1, 7, 0, 2)) {
96 ct_ref.feat = rd_byte();
97 ct_ref.mimic = rd_byte();
99 ct_ref.feat = rd_s16b();
100 ct_ref.mimic = rd_s16b();
103 ct_ref.special = rd_s16b();
106 POSITION ymax = floor_ptr->height;
107 POSITION xmax = floor_ptr->width;
108 for (POSITION x = 0, y = 0; y < ymax;) {
109 auto count = rd_byte();
116 } while (tmp8u == MAX_UCHAR);
118 for (int i = count; i > 0; i--) {
119 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
120 g_ptr->info = templates[id].info;
121 g_ptr->feat = templates[id].feat;
122 g_ptr->mimic = templates[id].mimic;
123 g_ptr->special = templates[id].special;
133 /* Quest 18 was removed */
134 if (h_older_than(1, 7, 0, 6) && !vanilla_town) {
135 for (POSITION y = 0; y < ymax; y++) {
136 for (POSITION x = 0; x < xmax; x++) {
137 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
139 if ((g_ptr->special == OLD_QUEST_WATER_CAVE) && !floor_ptr->dun_level) {
140 if (g_ptr->feat == OLD_FEAT_QUEST_ENTER) {
141 g_ptr->feat = feat_tree;
143 } else if (g_ptr->feat == OLD_FEAT_BLDG_1) {
144 g_ptr->special = lite_town ? QUEST_OLD_CASTLE : QUEST_ROYAL_CRYPT;
146 } else if ((g_ptr->feat == OLD_FEAT_QUEST_EXIT) && (floor_ptr->inside_quest == OLD_QUEST_WATER_CAVE)) {
147 g_ptr->feat = feat_up_stair;
155 if (limit > w_ptr->max_o_idx)
157 for (int i = 1; i < limit; i++) {
160 o_idx = o_pop(floor_ptr);
164 o_ptr = &floor_ptr->o_list[o_idx];
167 auto &list = get_o_idx_list_contains(floor_ptr, o_idx);
168 list.add(floor_ptr, o_idx, o_ptr->stack_idx);
172 if (limit > w_ptr->max_m_idx)
175 for (int i = 1; i < limit; i++) {
179 m_idx = m_pop(floor_ptr);
183 m_ptr = &floor_ptr->m_list[m_idx];
184 rd_monster(player_ptr, m_ptr);
185 g_ptr = &floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
186 g_ptr->m_idx = m_idx;
187 real_r_ptr(m_ptr)->cur_num++;
194 * @brief 保存フロア読み込みのサブ関数 / Actually load and verify a floor save data
195 * @param player_ptr プレイヤーへの参照ポインタ
196 * @param sf_ptr 保存フロア読み込み先
199 static bool load_floor_aux(player_type *player_ptr, saved_floor_type *sf_ptr)
207 w_ptr->h_ver_extra = H_VER_EXTRA;
208 w_ptr->h_ver_patch = H_VER_PATCH;
209 w_ptr->h_ver_minor = H_VER_MINOR;
210 w_ptr->h_ver_major = H_VER_MAJOR;
211 loading_savefile_version = SAVEFILE_VERSION;
213 if (saved_floor_file_sign != rd_u32b())
216 if (rd_saved_floor(player_ptr, sf_ptr))
219 auto n_v_check = v_check;
220 if (rd_u32b() != n_v_check)
223 auto n_x_check = x_check;
224 if (rd_u32b() != n_x_check)
230 * @brief 一時保存フロア情報を読み込む / Attempt to load the temporarily saved-floor data
231 * @param player_ptr プレイヤーへの参照ポインタ
232 * @param sf_ptr 保存フロア読み込み先
236 bool load_floor(player_type *player_ptr, saved_floor_type *sf_ptr, BIT_FLAGS mode)
239 * Temporary files are always written in system depended kanji
253 FILE *old_fff = nullptr;
254 byte old_xor_byte = 0;
255 uint32_t old_v_check = 0;
256 uint32_t old_x_check = 0;
257 byte old_h_ver_major = 0;
258 byte old_h_ver_minor = 0;
259 byte old_h_ver_patch = 0;
260 byte old_h_ver_extra = 0;
261 uint32_t old_loading_savefile_version = 0;
262 if (mode & SLF_SECOND) {
263 old_fff = loading_savefile;
264 old_xor_byte = load_xor_byte;
265 old_v_check = v_check;
266 old_x_check = x_check;
267 old_h_ver_major = w_ptr->h_ver_major;
268 old_h_ver_minor = w_ptr->h_ver_minor;
269 old_h_ver_patch = w_ptr->h_ver_patch;
270 old_h_ver_extra = w_ptr->h_ver_extra;
271 old_loading_savefile_version = loading_savefile_version;
274 char floor_savefile[sizeof(savefile) + 32];
275 sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id);
277 safe_setuid_grab(player_ptr);
278 loading_savefile = angband_fopen(floor_savefile, "rb");
281 bool is_save_successful = true;
282 if (!loading_savefile)
283 is_save_successful = false;
285 if (is_save_successful) {
286 is_save_successful = load_floor_aux(player_ptr, sf_ptr);
287 if (ferror(loading_savefile))
288 is_save_successful = false;
290 angband_fclose(loading_savefile);
291 safe_setuid_grab(player_ptr);
292 if (!(mode & SLF_NO_KILL))
293 (void)fd_kill(floor_savefile);
298 if (mode & SLF_SECOND) {
299 loading_savefile = old_fff;
300 load_xor_byte = old_xor_byte;
301 v_check = old_v_check;
302 x_check = old_x_check;
303 w_ptr->h_ver_major = old_h_ver_major;
304 w_ptr->h_ver_minor = old_h_ver_minor;
305 w_ptr->h_ver_patch = old_h_ver_patch;
306 w_ptr->h_ver_extra = old_h_ver_extra;
307 loading_savefile_version = old_loading_savefile_version;
310 byte old_kanji_code = kanji_code;
311 kanji_code = old_kanji_code;
312 return is_save_successful;