OSDN Git Service

[Refactor] QUESTOR を新定義に合わせた
[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-info.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     auto &floor = *player_ptr->current_floor_ptr;
33     if (h_older_than(1, 5, 0, 0)) {
34         err = rd_dungeon_old(player_ptr);
35         if (floor.dungeon_idx) {
36             player_ptr->floor_id = get_unused_floor_id(player_ptr);
37             get_sf_ptr(player_ptr->floor_id)->dun_level = floor.dun_level;
38         }
39
40         return err;
41     }
42
43     max_floor_id = rd_s16b();
44     floor.set_dungeon_index(rd_byte()); // @todo セーブデータの方を16ビットにするかdungeon_idxの定義を8ビットにした方が良い.
45     auto num = rd_byte();
46     if (num == 0) {
47         err = rd_saved_floor(player_ptr, nullptr);
48     } else {
49         for (int i = 0; i < num; i++) {
50             saved_floor_type *sf_ptr = &saved_floors[i];
51
52             sf_ptr->floor_id = rd_s16b();
53             sf_ptr->savefile_id = rd_byte();
54
55             sf_ptr->dun_level = rd_s16b();
56
57             sf_ptr->last_visit = rd_s32b();
58             sf_ptr->visit_mark = rd_u32b();
59             sf_ptr->upper_floor_id = rd_s16b();
60             sf_ptr->lower_floor_id = rd_s16b();
61         }
62
63         for (int i = 0; i < num; i++) {
64             saved_floor_type *sf_ptr = &saved_floors[i];
65             if (!is_saved_floor(sf_ptr)) {
66                 continue;
67             }
68             if (rd_byte() != 0) {
69                 continue;
70             }
71
72             err = rd_saved_floor(player_ptr, sf_ptr);
73             if (err) {
74                 break;
75             }
76
77             if (!save_floor(player_ptr, sf_ptr, SLF_SECOND)) {
78                 err = 182;
79             }
80
81             if (err) {
82                 break;
83             }
84         }
85
86         if (err == 0) {
87             if (!load_floor(player_ptr, get_sf_ptr(player_ptr->floor_id), SLF_SECOND)) {
88                 err = 183;
89             }
90         }
91
92         // latest_visit_mark の復元。
93         // 全ての保存フロアについての visit_mark の最大値 + 1 とする。
94         for (int i = 0; i < num; ++i) {
95             const uint32_t next_visit_mark = saved_floors[i].visit_mark + 1;
96             if (next_visit_mark > latest_visit_mark) {
97                 latest_visit_mark = next_visit_mark;
98             }
99         }
100     }
101
102     switch (err) {
103     case 151:
104         load_note(_("アイテムの配列が大きすぎる!", "Too many object entries!"));
105         break;
106
107     case 152:
108         load_note(_("アイテム配置エラー", "Object allocation error"));
109         break;
110
111     case 161:
112         load_note(_("モンスターの配列が大きすぎる!", "Too many monster entries!"));
113         break;
114
115     case 162:
116         load_note(_("モンスター配置エラー", "Monster allocation error"));
117         break;
118
119     case 171:
120         load_note(_("保存されたフロアのダンジョンデータが壊れています!", "Dungeon data of saved floors are broken!"));
121         break;
122
123     case 182:
124         load_note(_("テンポラリ・ファイルを作成できません!", "Failed to make temporary files!"));
125         break;
126
127     case 183:
128         load_note(_("Error 183", "Error 183"));
129         break;
130     }
131
132     w_ptr->character_dungeon = true;
133     return err;
134 }
135
136 errr restore_dungeon(PlayerType *player_ptr)
137 {
138     if (player_ptr->is_dead) {
139         const auto &quest_list = QuestList::get_instance();
140         for (auto q_idx : EnumRange(QuestId::RANDOM_QUEST1, QuestId::RANDOM_QUEST10)) {
141             monraces_info[quest_list[q_idx].r_idx].misc_flags.reset(MonsterMiscType::QUESTOR);
142         }
143
144         return 0;
145     }
146
147     load_note(_("ダンジョン復元中...", "Restoring Dungeon..."));
148     if (rd_dungeon(player_ptr)) {
149         load_note(_("ダンジョンデータ読み込み失敗", "Error reading dungeon data"));
150         return 34;
151     }
152
153     rd_ghost();
154     auto tmp32s = rd_s32b();
155     strip_bytes(tmp32s);
156     return 0;
157 }