OSDN Git Service

91d05fae93e91a841cb3c821fb873737f66b7be1
[hengbandforosx/hengbandosx.git] / src / load / dungeon-loader.cpp
1 #include "load/dungeon-loader.h"
2 #include "dungeon/quest.h"
3 #include "floor/floor-save-util.h"
4 #include "floor/floor-save.h"
5 #include "load/angband-version-comparer.h"
6 #include "load/dummy-loader.h"
7 #include "load/floor-loader.h"
8 #include "load/load-util.h"
9 #include "load/old/load-v1-5-0.h"
10 #include "monster-race/monster-race.h"
11 #include "monster-race/race-flags1.h"
12 #include "save/floor-writer.h"
13 #include "system/floor-type-definition.h"
14 #include "system/monster-race-definition.h"
15 #include "system/player-type-definition.h"
16 #include "util/bit-flags-calculator.h"
17 #include "util/enum-range.h"
18 #include "world/world.h"
19
20 /*!
21  * @brief 保存されたフロアを読み込む / Read the dungeon
22  * @param player_ptr プレイヤーへの参照ポインタ
23  * @return エラーコード
24  * @details
25  * The monsters/objects must be loaded in the same order
26  * that they were stored, since the actual indexes matter.
27  */
28 static errr rd_dungeon(PlayerType *player_ptr)
29 {
30     init_saved_floors(player_ptr, false);
31     errr err = 0;
32     if (h_older_than(1, 5, 0, 0)) {
33         err = rd_dungeon_old(player_ptr);
34         if (player_ptr->dungeon_idx) {
35             player_ptr->floor_id = get_new_floor_id(player_ptr);
36             get_sf_ptr(player_ptr->floor_id)->dun_level = player_ptr->current_floor_ptr->dun_level;
37         }
38
39         return err;
40     }
41
42     max_floor_id = rd_s16b();
43     player_ptr->dungeon_idx = rd_byte(); // @todo セーブデータの方を16ビットにするかdungeon_idxの定義を8ビットにした方が良い.
44     auto num = rd_byte();
45     if (num == 0) {
46         err = rd_saved_floor(player_ptr, nullptr);
47     } else {
48         for (int i = 0; i < num; i++) {
49             saved_floor_type *sf_ptr = &saved_floors[i];
50
51             sf_ptr->floor_id = rd_s16b();
52             sf_ptr->savefile_id = rd_byte();
53
54             sf_ptr->dun_level = rd_s16b();
55
56             sf_ptr->last_visit = rd_s32b();
57             sf_ptr->visit_mark = rd_u32b();
58             sf_ptr->upper_floor_id = rd_s16b();
59             sf_ptr->lower_floor_id = rd_s16b();
60         }
61
62         for (int i = 0; i < num; i++) {
63             saved_floor_type *sf_ptr = &saved_floors[i];
64             if (!sf_ptr->floor_id) {
65                 continue;
66             }
67             if (rd_byte() != 0) {
68                 continue;
69             }
70
71             err = rd_saved_floor(player_ptr, sf_ptr);
72             if (err) {
73                 break;
74             }
75
76             if (!save_floor(player_ptr, sf_ptr, SLF_SECOND)) {
77                 err = 182;
78             }
79
80             if (err) {
81                 break;
82             }
83         }
84
85         if (err == 0) {
86             if (!load_floor(player_ptr, get_sf_ptr(player_ptr->floor_id), SLF_SECOND)) {
87                 err = 183;
88             }
89         }
90
91         // latest_visit_mark の復元。
92         // 全ての保存フロアについての visit_mark の最大値 + 1 とする。
93         for (int i = 0; i < num; ++i) {
94             const uint32_t next_visit_mark = saved_floors[i].visit_mark + 1;
95             if (next_visit_mark > latest_visit_mark) {
96                 latest_visit_mark = next_visit_mark;
97             }
98         }
99     }
100
101     switch (err) {
102     case 151:
103         load_note(_("アイテムの配列が大きすぎる!", "Too many object entries!"));
104         break;
105
106     case 152:
107         load_note(_("アイテム配置エラー", "Object allocation error"));
108         break;
109
110     case 161:
111         load_note(_("モンスターの配列が大きすぎる!", "Too many monster entries!"));
112         break;
113
114     case 162:
115         load_note(_("モンスター配置エラー", "Monster allocation error"));
116         break;
117
118     case 171:
119         load_note(_("保存されたフロアのダンジョンデータが壊れています!", "Dungeon data of saved floors are broken!"));
120         break;
121
122     case 182:
123         load_note(_("テンポラリ・ファイルを作成できません!", "Failed to make temporary files!"));
124         break;
125
126     case 183:
127         load_note(_("Error 183", "Error 183"));
128         break;
129     }
130
131     w_ptr->character_dungeon = true;
132     return err;
133 }
134
135 errr restore_dungeon(PlayerType *player_ptr)
136 {
137     if (player_ptr->is_dead) {
138         const auto &quest_list = QuestList::get_instance();
139         for (auto q_idx : EnumRange(QuestId::RANDOM_QUEST1, QuestId::RANDOM_QUEST10)) {
140             reset_bits(monraces_info[quest_list[q_idx].r_idx].flags1, RF1_QUESTOR);
141         }
142
143         return 0;
144     }
145
146     load_note(_("ダンジョン復元中...", "Restoring Dungeon..."));
147     if (rd_dungeon(player_ptr)) {
148         load_note(_("ダンジョンデータ読み込み失敗", "Error reading dungeon data"));
149         return 34;
150     }
151
152     rd_ghost();
153     auto tmp32s = rd_s32b();
154     strip_bytes(tmp32s);
155     return 0;
156 }