OSDN Git Service

[fix] #41503 超能力者でゲームを開始しようとするとクラッシュ
[hengband/hengband.git] / src / load / dungeon-loader.c
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/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 "world/world.h"
15
16 /*!
17  * @brief 保存されたフロアを読み込む / Read the dungeon
18  * @param player_ptr プレーヤーへの参照ポインタ
19  * @return エラーコード
20  * @details
21  * The monsters/objects must be loaded in the same order
22  * that they were stored, since the actual indexes matter.
23  */
24 static errr rd_dungeon(player_type *player_ptr)
25 {
26     init_saved_floors(player_ptr, FALSE);
27     errr err = 0;
28     if (h_older_than(1, 5, 0, 0)) {
29         err = rd_dungeon_old(player_ptr);
30         if (player_ptr->dungeon_idx) {
31             player_ptr->floor_id = get_new_floor_id(player_ptr);
32             get_sf_ptr(player_ptr->floor_id)->dun_level = player_ptr->current_floor_ptr->dun_level;
33         }
34
35         return err;
36     }
37
38     rd_s16b(&max_floor_id);
39     byte tmp8u;
40     rd_byte(&tmp8u);
41     player_ptr->dungeon_idx = (DUNGEON_IDX)tmp8u;
42     byte num;
43     rd_byte(&num);
44     if (num == 0) {
45         err = rd_saved_floor(player_ptr, NULL);
46     } else {
47         for (int i = 0; i < num; i++) {
48             saved_floor_type *sf_ptr = &saved_floors[i];
49
50             rd_s16b(&sf_ptr->floor_id);
51             rd_byte(&tmp8u);
52             sf_ptr->savefile_id = (s16b)tmp8u;
53
54             s16b tmp16s;
55             rd_s16b(&tmp16s);
56             sf_ptr->dun_level = (DEPTH)tmp16s;
57
58             rd_s32b(&sf_ptr->last_visit);
59             rd_u32b(&sf_ptr->visit_mark);
60             rd_s16b(&sf_ptr->upper_floor_id);
61             rd_s16b(&sf_ptr->lower_floor_id);
62         }
63
64         for (int i = 0; i < num; i++) {
65             saved_floor_type *sf_ptr = &saved_floors[i];
66             if (!sf_ptr->floor_id)
67                 continue;
68             rd_byte(&tmp8u);
69             if (tmp8u)
70                 continue;
71
72             err = rd_saved_floor(player_ptr, sf_ptr);
73             if (err)
74                 break;
75
76             if (!save_floor(player_ptr, sf_ptr, SLF_SECOND))
77                 err = 182;
78
79             if (err)
80                 break;
81         }
82
83         if (err == 0) {
84             if (!load_floor(player_ptr, get_sf_ptr(player_ptr->floor_id), SLF_SECOND))
85                 err = 183;
86         }
87     }
88
89     switch (err) {
90     case 151:
91         load_note(_("アイテムの配列が大きすぎる!", "Too many object entries!"));
92         break;
93
94     case 152:
95         load_note(_("アイテム配置エラー", "Object allocation error"));
96         break;
97
98     case 161:
99         load_note(_("モンスターの配列が大きすぎる!", "Too many monster entries!"));
100         break;
101
102     case 162:
103         load_note(_("モンスター配置エラー", "Monster allocation error"));
104         break;
105
106     case 171:
107         load_note(_("保存されたフロアのダンジョンデータが壊れています!", "Dungeon data of saved floors are broken!"));
108         break;
109
110     case 182:
111         load_note(_("テンポラリ・ファイルを作成できません!", "Failed to make temporary files!"));
112         break;
113
114     case 183:
115         load_note(_("Error 183", "Error 183"));
116         break;
117     }
118
119     current_world_ptr->character_dungeon = TRUE;
120     return err;
121 }
122
123 errr restore_dungeon(player_type *creature_ptr)
124 {
125     if (creature_ptr->is_dead) {
126         for (int i = MIN_RANDOM_QUEST; i < MAX_RANDOM_QUEST + 1; i++)
127             r_info[quest[i].r_idx].flags1 &= ~RF1_QUESTOR;
128
129         return 0;
130     }
131
132     load_note(_("ダンジョン復元中...", "Restoring Dungeon..."));
133     if (rd_dungeon(creature_ptr)) {
134         load_note(_("ダンジョンデータ読み込み失敗", "Error reading dungeon data"));
135         return 34;
136     }
137
138     rd_ghost();
139     s32b tmp32s;
140     rd_s32b(&tmp32s);
141     strip_bytes(tmp32s);
142     return 0;
143 }