OSDN Git Service

Merge pull request #765 from sikabane-works/release/3.0.0Alpha17
[hengbandforosx/hengbandosx.git] / src / load / load.cpp
1 /*!
2  * @brief セーブファイル読み込み処理 / Purpose: support for loading savefiles -BEN-
3  * @date 2014/07/07
4  * @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  *
7  * This software may be copied and distributed for educational, research,
8  * and not for profit purposes provided that this copyright and statement
9  * are included in all such copies.  Other copyrights may also apply.
10  */
11
12 #include "load/load.h"
13 #include "dungeon/quest.h"
14 #include "game-option/birth-options.h"
15 #include "game-option/runtime-arguments.h"
16 #include "io/files-util.h"
17 #include "io/report.h"
18 #include "io/uid-checker.h"
19 #include "load/angband-version-comparer.h"
20 #include "load/dummy-loader.h"
21 #include "load/dungeon-loader.h"
22 #include "load/extra-loader.h"
23 #include "load/info-loader.h"
24 #include "load/inventory-loader.h"
25 #include "load/item-loader.h"
26 #include "load/load-util.h"
27 #include "load/load-v1-5-0.h"
28 #include "load/load-v1-7-0.h"
29 #include "load/load-zangband.h"
30 #include "load/lore-loader.h"
31 #include "load/option-loader.h"
32 #include "load/player-info-loader.h"
33 #include "load/quest-loader.h"
34 #include "load/store-loader.h"
35 #include "load/world-loader.h"
36 #include "player/player-class.h"
37 #include "player/player-personality.h"
38 #include "player/player-race.h"
39 #include "player/player-sex.h"
40 #include "player/race-info-table.h"
41 #include "system/angband-version.h"
42 #include "system/system-variables.h"
43 #include "util/angband-files.h"
44 #include "view/display-messages.h"
45 #include "world/world.h"
46
47 /*!
48  * @brief 変愚蛮怒 v2.1.3で追加された街とクエストについて読み込む
49  * @param creature_ptr プレーヤーへの参照ポインタ
50  * @return エラーコード
51  */
52 static errr load_town_quest(player_type *creature_ptr)
53 {
54     if (h_older_than(2, 1, 3))
55         return 0;
56
57     errr load_town_result = load_town();
58     if (load_town_result != 0)
59         return load_town_result;
60
61     u16b max_quests_load;
62     byte max_rquests_load;
63     errr load_quest_result = load_quest_info(&max_quests_load, &max_rquests_load);
64     if (load_quest_result != 0)
65         return load_quest_result;
66
67     analyze_quests(creature_ptr, max_quests_load, max_rquests_load);
68
69     /* Quest 18 was removed */
70     if (h_older_than(1, 7, 0, 6)) {
71         (void)WIPE(&quest[OLD_QUEST_WATER_CAVE], quest_type);
72         quest[OLD_QUEST_WATER_CAVE].status = QUEST_STATUS_UNTAKEN;
73     }
74
75     load_wilderness_info(creature_ptr);
76     return analyze_wilderness();
77 }
78
79 static void load_player_world(player_type *creature_ptr)
80 {
81     rd_base_info(creature_ptr);
82     rd_player_info(creature_ptr);
83     rd_byte((byte *)&preserve_mode);
84     rd_byte((byte *)&creature_ptr->wait_report_score);
85     rd_dummy2();
86     rd_global_configurations(creature_ptr);
87     rd_extra(creature_ptr);
88
89     if (creature_ptr->energy_need < -999)
90         creature_ptr->timewalk = TRUE;
91
92     if (arg_fiddle)
93         load_note(_("特別情報をロードしました", "Loaded extra information"));
94 }
95
96 static errr load_hp(player_type *creature_ptr)
97 {
98     u16b tmp16u;
99     rd_u16b(&tmp16u);
100     if (tmp16u > PY_MAX_LEVEL) {
101         load_note(format(_("ヒットポイント配列が大きすぎる(%u)!", "Too many (%u) hitpoint entries!"), tmp16u));
102         return 25;
103     }
104
105     for (int i = 0; i < tmp16u; i++) {
106         s16b tmp16s;
107         rd_s16b(&tmp16s);
108         creature_ptr->player_hp[i] = (HIT_POINT)tmp16s;
109     }
110
111     return 0;
112 }
113
114 static void load_spells(player_type *creature_ptr)
115 {
116     rd_u32b(&creature_ptr->spell_learned1);
117     rd_u32b(&creature_ptr->spell_learned2);
118     rd_u32b(&creature_ptr->spell_worked1);
119     rd_u32b(&creature_ptr->spell_worked2);
120     rd_u32b(&creature_ptr->spell_forgotten1);
121     rd_u32b(&creature_ptr->spell_forgotten2);
122
123     if (h_older_than(0, 0, 5))
124         set_zangband_learnt_spells(creature_ptr);
125     else
126         rd_s16b(&creature_ptr->learned_spells);
127
128     if (h_older_than(0, 0, 6))
129         creature_ptr->add_spells = 0;
130     else
131         rd_s16b(&creature_ptr->add_spells);
132 }
133
134 static errr verify_checksum()
135 {
136     u32b n_v_check = v_check;
137     u32b o_v_check;
138     rd_u32b(&o_v_check);
139     if (o_v_check == n_v_check)
140         return 0;
141
142     load_note(_("チェックサムがおかしい", "Invalid checksum"));
143     return 11;
144 }
145
146 static errr verify_encoded_checksum()
147 {
148     u32b n_x_check = x_check;
149     u32b o_x_check;
150     rd_u32b(&o_x_check);
151     if (o_x_check == n_x_check)
152         return 0;
153
154     load_note(_("エンコードされたチェックサムがおかしい", "Invalid encoded checksum"));
155     return 11;
156 }
157
158 /*!
159  * @brief セーブファイル読み込み処理の実体 / Actually read the savefile
160  * @return エラーコード
161  */
162 static errr exe_reading_savefile(player_type *creature_ptr)
163 {
164     rd_version_info();
165     rd_dummy3();
166     rd_system_info();
167     rd_unique_info();
168     errr load_lore_result = load_lore();
169     if (load_lore_result != 0)
170         return load_lore_result;
171
172     errr load_item_result = load_item();
173     if (load_item_result != 0)
174         return load_item_result;
175
176     errr load_town_quest_result = load_town_quest(creature_ptr);
177     if (load_town_quest_result != 0)
178         return load_town_quest_result;
179
180     if (arg_fiddle)
181         load_note(_("クエスト情報をロードしました", "Loaded Quests"));
182
183     errr load_artifact_result = load_artifact();
184     if (load_artifact_result != 0)
185         return load_artifact_result;
186
187     load_player_world(creature_ptr);
188     errr load_hp_result = load_hp(creature_ptr);
189     if (load_hp_result != 0)
190         return load_hp_result;
191
192     sp_ptr = &sex_info[creature_ptr->psex];
193     rp_ptr = &race_info[creature_ptr->prace];
194     cp_ptr = &class_info[creature_ptr->pclass];
195     ap_ptr = &personality_info[creature_ptr->pseikaku];
196
197     set_zangband_class(creature_ptr);
198     mp_ptr = &m_info[creature_ptr->pclass];
199
200     load_spells(creature_ptr);
201     if (creature_ptr->pclass == CLASS_MINDCRAFTER)
202         creature_ptr->add_spells = 0;
203
204     errr load_inventory_result = load_inventory(creature_ptr);
205     if (load_inventory_result != 0)
206         return load_inventory_result;
207
208     errr load_store_result = load_store(creature_ptr);
209     if (load_store_result != 0)
210         return load_store_result;
211
212     rd_s16b(&creature_ptr->pet_follow_distance);
213     if (h_older_than(0, 4, 10))
214         set_zangband_pet(creature_ptr);
215     else
216         rd_s16b(&creature_ptr->pet_extra_flags);
217
218     if (!h_older_than(1, 0, 9)) {
219         char *buf;
220         C_MAKE(buf, SCREEN_BUF_MAX_SIZE, char);
221         rd_string(buf, SCREEN_BUF_MAX_SIZE);
222         if (buf[0])
223             screen_dump = string_make(buf);
224         C_KILL(buf, SCREEN_BUF_MAX_SIZE, char);
225     }
226
227     errr restore_dungeon_result = restore_dungeon(creature_ptr);
228     if (restore_dungeon_result != 0)
229         return restore_dungeon_result;
230
231     if (h_older_than(1, 7, 0, 6))
232         remove_water_cave(creature_ptr);
233
234     errr checksum_result = verify_checksum();
235     if (checksum_result != 0)
236         return checksum_result;
237
238     return verify_encoded_checksum();
239 }
240
241 /*!
242  * @brief セーブファイル読み込み処理 (UIDチェック等含む) / Reading the savefile (including UID check)
243  * @param player_ptr プレーヤーへの参照ポインタ
244  * @return エラーコード
245  */
246 static errr rd_savefile(player_type *player_ptr)
247 {
248     safe_setuid_grab(player_ptr);
249     loading_savefile = angband_fopen(savefile, "rb");
250     safe_setuid_drop();
251     if (!loading_savefile)
252         return -1;
253
254     errr err = exe_reading_savefile(player_ptr);
255     if (ferror(loading_savefile))
256         err = -1;
257
258     angband_fclose(loading_savefile);
259     return err;
260 }
261
262 /*!
263  * @brief セーブデータ読み込みのメインルーチン /
264  * Attempt to Load a "savefile"
265  * @param creature_ptr プレーヤーへの参照ポインタ
266  * @param new_game セーブデータの新規作成が必要か否か
267  * @return セーブデータが読み込めればtrue
268  */
269 bool load_savedata(player_type *player_ptr, bool *new_game)
270 {
271     concptr what = "generic";
272     current_world_ptr->game_turn = 0;
273     player_ptr->is_dead = FALSE;
274     if (!savefile[0])
275         return TRUE;
276
277 #ifndef WINDOWS
278     if (access(savefile, 0) < 0) {
279         msg_print(_("セーブファイルがありません。", "Savefile does not exist."));
280         msg_print(NULL);
281         *new_game = TRUE;
282         return TRUE;
283     }
284 #endif
285
286     bool err = false;
287     int fd = -1;
288     byte fake_ver[4];
289     if (!err) {
290         fd = fd_open(savefile, O_RDONLY);
291         if (fd < 0)
292             err = true;
293
294         if (err)
295             what = _("セーブファイルを開けません", "Cannot open savefile");
296     }
297
298     if (!err) {
299         if (fd_read(fd, (char *)(fake_ver), 4))
300             err = true;
301
302         if (err)
303             what = _("セーブファイルを読めません", "Cannot read savefile");
304
305         (void)fd_close(fd);
306     }
307
308     if (!err) {
309         if (fake_ver[0] < FAKE_VER_PLUS) {
310             what = _("セーブデータが古すぎます", "Savefile version is too old");
311             err = true;
312         }
313     }
314
315     if (err) {
316         msg_format("%s: %s", what, savefile);
317         msg_print(NULL);
318         return FALSE;
319     }
320
321     current_world_ptr->sf_extra = fake_ver[3];
322
323     if (!err) {
324         term_clear();
325         if (rd_savefile(player_ptr))
326             err = true;
327         if (err)
328             what = _("セーブファイルを解析出来ません。", "Cannot parse savefile");
329     }
330
331     if (!err) {
332         if (!current_world_ptr->game_turn)
333             err = true;
334
335         if (err)
336             what = _("セーブファイルが壊れています", "Broken savefile");
337     }
338
339     if (err) {
340         msg_format(_("エラー(%s)がバージョン%d.%d.%d.%d 用セーブファイル読み込み中に発生。", "Error (%s) reading %d.%d.%d.% savefile."), what,
341             current_world_ptr->h_ver_major, current_world_ptr->h_ver_minor, current_world_ptr->h_ver_patch, current_world_ptr->h_ver_extra);
342
343         msg_print(NULL);
344         return FALSE;
345     }
346
347     if (player_ptr->is_dead) {
348         *new_game = TRUE;
349         if (arg_wizard) {
350             current_world_ptr->character_loaded = TRUE;
351             return TRUE;
352         }
353
354         player_ptr->is_dead = FALSE;
355         current_world_ptr->sf_lives++;
356         return TRUE;
357     }
358
359     current_world_ptr->character_loaded = TRUE;
360     u32b tmp = counts_read(player_ptr, 2);
361     if (tmp > player_ptr->count)
362         player_ptr->count = tmp;
363
364     if (counts_read(player_ptr, 0) > current_world_ptr->play_time || counts_read(player_ptr, 1) == current_world_ptr->play_time)
365         counts_write(player_ptr, 2, ++player_ptr->count);
366
367     counts_write(player_ptr, 1, current_world_ptr->play_time);
368     return TRUE;
369 }