OSDN Git Service

[Refactor] #2807 Renamed monster-race-definition.h to monster-race-info.h
[hengbandforosx/hengbandosx.git] / src / load / quest-loader.cpp
1 #include "load/quest-loader.h"
2 #include "artifact/fixed-art-types.h"
3 #include "dungeon/quest.h"
4 #include "floor/floor-town.h"
5 #include "load/angband-version-comparer.h"
6 #include "load/load-util.h"
7 #include "load/load-zangband.h"
8 #include "load/savedata-old-flag-types.h"
9 #include "monster-race/monster-race.h"
10 #include "monster-race/race-flags1.h"
11 #include "monster-race/race-flags7.h"
12 #include "object-enchant/trg-types.h"
13 #include "system/angband-exceptions.h"
14 #include "system/artifact-type-definition.h"
15 #include "system/floor-type-definition.h"
16 #include "system/monster-race-info.h"
17 #include "system/player-type-definition.h"
18 #include "util/enum-converter.h"
19
20 errr load_town(void)
21 {
22     auto max_towns_load = rd_u16b();
23     if (max_towns_load <= max_towns) {
24         return 0;
25     }
26
27     load_note(format(_("町が多すぎる(%u)!", "Too many (%u) towns!"), max_towns_load));
28     return 23;
29 }
30
31 std::tuple<uint16_t, byte> load_quest_info()
32 {
33     auto max_quests_load = rd_u16b();
34     byte max_rquests_load;
35     if (h_older_than(1, 0, 7)) {
36         max_rquests_load = 10;
37     } else {
38         max_rquests_load = rd_byte();
39     }
40
41     return std::make_tuple(max_quests_load, max_rquests_load);
42 }
43
44 static void load_quest_completion(quest_type *q_ptr)
45 {
46     q_ptr->status = i2enum<QuestStatusType>(rd_s16b());
47     q_ptr->level = rd_s16b();
48
49     if (h_older_than(1, 0, 6)) {
50         q_ptr->complev = 0;
51     } else {
52         q_ptr->complev = rd_byte();
53     }
54
55     if (h_older_than(2, 1, 2, 2)) {
56         q_ptr->comptime = 0;
57     } else {
58         q_ptr->comptime = rd_u32b();
59     }
60 }
61
62 static void load_quest_details(PlayerType *player_ptr, quest_type *q_ptr, const QuestId loading_quest_index)
63 {
64     q_ptr->cur_num = rd_s16b();
65     q_ptr->max_num = rd_s16b();
66     q_ptr->type = i2enum<QuestKindType>(rd_s16b());
67
68     q_ptr->r_idx = i2enum<MonsterRaceId>(rd_s16b());
69     if ((q_ptr->type == QuestKindType::RANDOM) && !MonsterRace(q_ptr->r_idx).is_valid()) {
70         auto &quest_list = QuestList::get_instance();
71         determine_random_questor(player_ptr, &quest_list[loading_quest_index]);
72     }
73     q_ptr->reward_artifact_idx = i2enum<FixedArtifactId>(rd_s16b());
74     if (q_ptr->reward_artifact_idx != FixedArtifactId::NONE) {
75         artifacts_info.at(q_ptr->reward_artifact_idx).gen_flags.set(ItemGenerationTraitType::QUESTITEM);
76     }
77
78     q_ptr->flags = rd_byte();
79 }
80
81 static bool is_missing_id_ver_16(const QuestId q_idx)
82 {
83     auto is_missing_id = (enum2i(q_idx) == 0);
84     is_missing_id |= (enum2i(q_idx) == 13);
85     is_missing_id |= (enum2i(q_idx) == 17);
86     is_missing_id |= (enum2i(q_idx) >= 35 && enum2i(q_idx) <= 39);
87     is_missing_id |= (enum2i(q_idx) >= 88 && enum2i(q_idx) <= 100);
88
89     auto is_deleted_random_quest = (enum2i(q_idx) >= 50 || enum2i(q_idx) <= 88);
90
91     return is_missing_id || is_deleted_random_quest;
92 }
93
94 static bool is_loadable_quest(const QuestId q_idx, const byte max_rquests_load)
95 {
96     const auto &quest_list = QuestList::get_instance();
97     if (quest_list.find(q_idx) != quest_list.end()) {
98         return true;
99     }
100
101     bool is_missing_id;
102
103     if (loading_savefile_version_is_older_than(17)) {
104         is_missing_id = is_missing_id_ver_16(q_idx);
105     } else {
106         is_missing_id = false;
107     }
108
109     if (!is_missing_id) {
110         const std::string msg(_("削除されたクエストのあるセーブデータはサポート対象外です。",
111             "The save data with deleted quests is unsupported."));
112         throw SaveDataNotSupportedException(msg);
113     }
114
115     auto status = i2enum<QuestStatusType>(rd_s16b());
116
117     strip_bytes(2);
118     if (!h_older_than(1, 0, 6)) {
119         strip_bytes(1);
120     }
121     if (!h_older_than(2, 1, 2, 2)) {
122         strip_bytes(4);
123     }
124
125     auto is_quest_running = (status == QuestStatusType::TAKEN);
126     is_quest_running |= (!h_older_than(0, 3, 14) && (status == QuestStatusType::COMPLETED));
127     is_quest_running |= (!h_older_than(1, 0, 7) && (enum2i(q_idx) >= MIN_RANDOM_QUEST) && (enum2i(q_idx) <= (MIN_RANDOM_QUEST + max_rquests_load)));
128     if (!is_quest_running) {
129         return false;
130     }
131
132     strip_bytes(2);
133     strip_bytes(2);
134     strip_bytes(2);
135     strip_bytes(2);
136     strip_bytes(2);
137     strip_bytes(1);
138     return false;
139 }
140
141 void analyze_quests(PlayerType *player_ptr, const uint16_t max_quests_load, const byte max_rquests_load)
142 {
143     QuestId old_inside_quest = player_ptr->current_floor_ptr->quest_number;
144     for (auto i = 0; i < max_quests_load; i++) {
145         QuestId q_idx;
146         if (loading_savefile_version_is_older_than(17)) {
147             q_idx = i2enum<QuestId>(i);
148         } else {
149             q_idx = i2enum<QuestId>(rd_s16b());
150         }
151         if (!is_loadable_quest(q_idx, max_rquests_load)) {
152             continue;
153         }
154
155         auto &quest_list = QuestList::get_instance();
156         auto *q_ptr = &quest_list[q_idx];
157
158         if (loading_savefile_version_is_older_than(15)) {
159             if (i == enum2i(OldQuestId15::CITY_SEA) && q_ptr->status != QuestStatusType::UNTAKEN) {
160                 const std::string msg(_("海底都市クエストを受領または解決しているセーブデータはサポート外です。",
161                     "The save data with the taken quest of The City beneath the Sea is unsupported."));
162                 throw(SaveDataNotSupportedException(msg));
163             }
164         }
165
166         load_quest_completion(q_ptr);
167         auto is_quest_running = (q_ptr->status == QuestStatusType::TAKEN);
168         is_quest_running |= (!h_older_than(0, 3, 14) && (q_ptr->status == QuestStatusType::COMPLETED));
169         is_quest_running |= (!h_older_than(1, 0, 7) && (enum2i(q_idx) >= MIN_RANDOM_QUEST) && (enum2i(q_idx) <= (MIN_RANDOM_QUEST + max_rquests_load)));
170         if (!is_quest_running) {
171             continue;
172         }
173
174         load_quest_details(player_ptr, q_ptr, q_idx);
175         if (h_older_than(0, 3, 11)) {
176             set_zangband_quest(player_ptr, q_ptr, q_idx, old_inside_quest);
177         } else {
178             q_ptr->dungeon = rd_byte();
179         }
180
181         if (q_ptr->status == QuestStatusType::TAKEN || q_ptr->status == QuestStatusType::UNTAKEN) {
182             if (monraces_info[q_ptr->r_idx].kind_flags.has(MonsterKindType::UNIQUE)) {
183                 monraces_info[q_ptr->r_idx].flags1 |= RF1_QUESTOR;
184             }
185         }
186     }
187 }