OSDN Git Service

1eda0d816fbf154b735267b3b55027128017b813
[hengbandforosx/hengbandosx.git] / src / load / old / load-v1-5-0.cpp
1 /*!
2  * @brief 変愚蛮怒 v1.5.0以前の旧いセーブデータを読み込む処理
3  * @date 2020/07/04
4  * @author Hourier
5  * @details 互換性を最大限に確保するため、基本的に関数分割は行わないものとする.
6  */
7
8 #include "load/old/load-v1-5-0.h"
9 #include "artifact/fixed-art-types.h"
10 #include "floor/floor-object.h"
11 #include "game-option/birth-options.h"
12 #include "grid/feature.h"
13 #include "grid/grid.h"
14 #include "grid/trap.h"
15 #include "load/angband-version-comparer.h"
16 #include "load/item/item-loader-factory.h"
17 #include "load/item/item-loader-version-types.h"
18 #include "load/load-util.h"
19 #include "load/monster/monster-loader-factory.h"
20 #include "load/old-feature-types.h"
21 #include "load/old/item-loader-savefile50.h"
22 #include "load/old/monster-loader-savefile50.h"
23 #include "mind/mind-weaponsmith.h"
24 #include "monster-floor/monster-move.h"
25 #include "monster-race/monster-race.h"
26 #include "monster-race/race-flags-resistance.h"
27
28 #include "monster-race/race-indice-types.h"
29 #include "monster/monster-flag-types.h"
30 #include "monster/monster-info.h"
31 #include "monster/monster-list.h"
32 #include "object-enchant/object-ego.h"
33 #include "object-enchant/old-ego-extra-values.h"
34 #include "object-enchant/tr-types.h"
35 #include "object-enchant/trc-types.h"
36 #include "object-enchant/trg-types.h"
37 #include "object/object-kind-hook.h"
38 #include "sv-definition/sv-armor-types.h"
39 #include "sv-definition/sv-lite-types.h"
40 #include "system/angband-exceptions.h"
41 #include "system/artifact-type-definition.h"
42 #include "system/baseitem-info.h"
43 #include "system/dungeon-info.h"
44 #include "system/floor-type-definition.h"
45 #include "system/grid-type-definition.h"
46 #include "system/item-entity.h"
47 #include "system/monster-race-info.h"
48 #include "system/player-type-definition.h"
49 #include "util/bit-flags-calculator.h"
50 #include "util/enum-converter.h"
51 #include "world/world-object.h"
52 #include "world/world.h"
53
54 /* Old hidden trap flag */
55 static const BIT_FLAGS CAVE_TRAP = 0x8000;
56
57 const int OLD_QUEST_WATER_CAVE = 18; // 湖の洞窟.
58 const int QUEST_OLD_CASTLE = 27; // 古い城.
59 const int QUEST_ROYAL_CRYPT = 28; // 王家の墓.
60
61 /*!
62  * @brief アイテムオブジェクト1件を読み込む / Read an object
63  * @param o_ptr アイテムオブジェクト読み取り先ポインタ
64  */
65 void rd_item_old(ItemEntity *o_ptr)
66 {
67     o_ptr->bi_id = rd_s16b();
68
69     o_ptr->iy = rd_byte();
70     o_ptr->ix = rd_byte();
71
72     const auto tval = i2enum<ItemKindType>(rd_byte());
73     const auto sval = rd_byte();
74     o_ptr->bi_key = BaseitemKey(tval, sval);
75
76     if (h_older_than(0, 4, 4)) {
77         if (tval == i2enum<ItemKindType>(100)) {
78             o_ptr->bi_key = BaseitemKey(ItemKindType::GOLD, sval);
79         }
80         if (tval == i2enum<ItemKindType>(98)) {
81             o_ptr->bi_key = BaseitemKey(ItemKindType::MUSIC_BOOK, sval);
82         }
83         if (tval == i2enum<ItemKindType>(110)) {
84             o_ptr->bi_key = BaseitemKey(ItemKindType::HISSATSU_BOOK, sval);
85         }
86     }
87
88     o_ptr->pval = rd_s16b();
89     o_ptr->discount = rd_byte();
90     o_ptr->number = rd_byte();
91
92     o_ptr->weight = rd_s16b();
93
94     o_ptr->fixed_artifact_idx = i2enum<FixedArtifactId>(rd_byte());
95
96     o_ptr->ego_idx = i2enum<EgoType>(rd_byte());
97
98     o_ptr->timeout = rd_s16b();
99     o_ptr->to_h = rd_s16b();
100     o_ptr->to_d = rd_s16b();
101
102     o_ptr->to_a = rd_s16b();
103     o_ptr->ac = rd_s16b();
104     o_ptr->dd = rd_byte();
105
106     o_ptr->ds = rd_byte();
107
108     o_ptr->ident = rd_byte();
109     rd_FlagGroup_bytes(o_ptr->marked, rd_byte, 1);
110
111     for (int i = 0, count = (h_older_than(1, 3, 0, 0) ? 3 : 4); i < count; i++) {
112         auto tmp32u = rd_u32b();
113         migrate_bitflag_to_flaggroup(o_ptr->art_flags, tmp32u, i * 32);
114     }
115
116     if (h_older_than(1, 3, 0, 0)) {
117         if (o_ptr->ego_idx == EgoType::TELEPATHY) {
118             o_ptr->art_flags.set(TR_TELEPATHY);
119         }
120     }
121
122     if (h_older_than(1, 0, 11)) {
123         // バージョン 1.0.11 以前は tr_type の 93, 94, 95 は現在と違い呪い等の別の用途で使用されていたので番号をハードコーディングする
124         o_ptr->curse_flags.clear();
125         if (o_ptr->ident & 0x40) {
126             o_ptr->curse_flags.set(CurseTraitType::CURSED);
127             if (o_ptr->art_flags.has(i2enum<tr_type>(94))) {
128                 o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
129             }
130             if (o_ptr->art_flags.has(i2enum<tr_type>(95))) {
131                 o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
132             }
133             if (o_ptr->is_fixed_artifact()) {
134                 const auto &artifact = o_ptr->get_fixed_artifact();
135                 if (artifact.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
136                     o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
137                 }
138                 if (artifact.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
139                     o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
140                 }
141             } else if (o_ptr->is_ego()) {
142                 const auto &ego = o_ptr->get_ego();
143                 if (ego.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
144                     o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
145                 }
146                 if (ego.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
147                     o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
148                 }
149             }
150         }
151         o_ptr->art_flags.reset({ i2enum<tr_type>(93), i2enum<tr_type>(94), i2enum<tr_type>(95) });
152     } else {
153         auto tmp32u = rd_u32b();
154         migrate_bitflag_to_flaggroup(o_ptr->curse_flags, tmp32u);
155     }
156
157     o_ptr->held_m_idx = rd_s16b();
158     auto xtra1 = rd_byte(); // かつてエゴアイテムの情報を格納していた名残.
159     o_ptr->activation_id = i2enum<RandomArtActType>(rd_byte());
160
161     if (h_older_than(1, 0, 10)) {
162         if (xtra1 == enum2i<OldEgoType>(OldEgoType::XTRA_SUSTAIN)) {
163             switch (enum2i(o_ptr->activation_id) % 6) {
164             case 0:
165                 o_ptr->art_flags.set(TR_SUST_STR);
166                 break;
167             case 1:
168                 o_ptr->art_flags.set(TR_SUST_INT);
169                 break;
170             case 2:
171                 o_ptr->art_flags.set(TR_SUST_WIS);
172                 break;
173             case 3:
174                 o_ptr->art_flags.set(TR_SUST_DEX);
175                 break;
176             case 4:
177                 o_ptr->art_flags.set(TR_SUST_CON);
178                 break;
179             case 5:
180                 o_ptr->art_flags.set(TR_SUST_CHR);
181                 break;
182             }
183             o_ptr->activation_id = i2enum<RandomArtActType>(0);
184         } else if (xtra1 == enum2i<OldEgoType>(OldEgoType::XTRA_POWER)) {
185             switch (enum2i(o_ptr->activation_id) % 11) {
186             case 0:
187                 o_ptr->art_flags.set(TR_RES_BLIND);
188                 break;
189             case 1:
190                 o_ptr->art_flags.set(TR_RES_CONF);
191                 break;
192             case 2:
193                 o_ptr->art_flags.set(TR_RES_SOUND);
194                 break;
195             case 3:
196                 o_ptr->art_flags.set(TR_RES_SHARDS);
197                 break;
198             case 4:
199                 o_ptr->art_flags.set(TR_RES_NETHER);
200                 break;
201             case 5:
202                 o_ptr->art_flags.set(TR_RES_NEXUS);
203                 break;
204             case 6:
205                 o_ptr->art_flags.set(TR_RES_CHAOS);
206                 break;
207             case 7:
208                 o_ptr->art_flags.set(TR_RES_DISEN);
209                 break;
210             case 8:
211                 o_ptr->art_flags.set(TR_RES_POIS);
212                 break;
213             case 9:
214                 o_ptr->art_flags.set(TR_RES_DARK);
215                 break;
216             case 10:
217                 o_ptr->art_flags.set(TR_RES_LITE);
218                 break;
219             }
220             o_ptr->activation_id = i2enum<RandomArtActType>(0);
221         } else if (xtra1 == enum2i<OldEgoType>(OldEgoType::XTRA_ABILITY)) {
222             switch (enum2i(o_ptr->activation_id) % 8) {
223             case 0:
224                 o_ptr->art_flags.set(TR_LEVITATION);
225                 break;
226             case 1:
227                 o_ptr->art_flags.set(TR_LITE_1);
228                 break;
229             case 2:
230                 o_ptr->art_flags.set(TR_SEE_INVIS);
231                 break;
232             case 3:
233                 o_ptr->art_flags.set(TR_WARNING);
234                 break;
235             case 4:
236                 o_ptr->art_flags.set(TR_SLOW_DIGEST);
237                 break;
238             case 5:
239                 o_ptr->art_flags.set(TR_REGEN);
240                 break;
241             case 6:
242                 o_ptr->art_flags.set(TR_FREE_ACT);
243                 break;
244             case 7:
245                 o_ptr->art_flags.set(TR_HOLD_EXP);
246                 break;
247             }
248             o_ptr->activation_id = i2enum<RandomArtActType>(0);
249         }
250
251         xtra1 = 0;
252     }
253
254     if (h_older_than(0, 2, 3)) {
255         o_ptr->fuel = 0;
256         o_ptr->captured_monster_current_hp = 0;
257         o_ptr->smith_hit = 0;
258         o_ptr->smith_damage = 0;
259         o_ptr->captured_monster_max_hp = 0;
260         if (tval == ItemKindType::CHEST) {
261             o_ptr->chest_level = xtra1;
262         } else if (tval == ItemKindType::CAPTURE) {
263             o_ptr->captured_monster_speed = xtra1;
264         }
265
266         if (tval == ItemKindType::CAPTURE) {
267             const auto &r_ref = monraces_info[i2enum<MonsterRaceId>(o_ptr->pval)];
268             if (r_ref.misc_flags.has(MonsterMiscType::FORCE_MAXHP)) {
269                 o_ptr->captured_monster_max_hp = maxroll(r_ref.hdice, r_ref.hside);
270             } else {
271                 o_ptr->captured_monster_max_hp = damroll(r_ref.hdice, r_ref.hside);
272             }
273             if (ironman_nightmare) {
274                 o_ptr->captured_monster_max_hp = std::min<short>(MONSTER_MAXHP, o_ptr->captured_monster_max_hp * 2L);
275             }
276
277             o_ptr->captured_monster_current_hp = o_ptr->captured_monster_max_hp;
278         }
279     } else {
280         auto xtra3 = rd_byte();
281         if (h_older_than(1, 3, 0, 1)) {
282             if (o_ptr->is_smith() && (xtra3 >= 1 + 96)) {
283                 auto mes = _("古いバージョンで鍛冶師をプレイしたデータは読み込めません。", "The save data from playing a weaponsmith on versions older than v3.0.0 Aplha38 can't be read.");
284                 throw SaveDataNotSupportedException(mes);
285             }
286         }
287
288         auto xtra4 = rd_s16b();
289         if (tval == ItemKindType::LITE) {
290             o_ptr->fuel = xtra4;
291         } else if (tval == ItemKindType::CAPTURE) {
292             o_ptr->captured_monster_current_hp = xtra4;
293         } else {
294             o_ptr->smith_hit = static_cast<byte>(xtra4 >> 8);
295             o_ptr->smith_damage = static_cast<byte>(xtra4 & 0x000f);
296         }
297
298         o_ptr->captured_monster_max_hp = rd_s16b();
299     }
300
301     if (h_older_than(1, 0, 5) && o_ptr->is_fuel()) {
302         o_ptr->fuel = o_ptr->pval;
303         o_ptr->pval = 0;
304     }
305
306     o_ptr->feeling = rd_byte();
307
308     char buf[128];
309     rd_string(buf, sizeof(buf));
310     if (buf[0]) {
311         o_ptr->inscription.emplace(buf);
312     }
313
314     rd_string(buf, sizeof(buf));
315
316     /*!< @todo 元々このif文には末尾に";"が付いていた、バグかもしれない */
317     if (buf[0]) {
318         o_ptr->randart_name.emplace(buf);
319     }
320     {
321         auto tmp32s = rd_s32b();
322         strip_bytes(tmp32s);
323     }
324
325     if ((o_ptr->bi_id >= 445) && (o_ptr->bi_id <= 479)) {
326         return;
327     }
328
329     if (h_older_than(0, 4, 10) && (o_ptr->ego_idx == EgoType::TWILIGHT)) {
330         o_ptr->bi_id = lookup_baseitem_id({ ItemKindType::SOFT_ARMOR, SV_TWILIGHT_ROBE });
331     }
332
333     if (h_older_than(0, 4, 9)) {
334         if (o_ptr->art_flags.has(TR_MAGIC_MASTERY)) {
335             o_ptr->art_flags.reset(TR_MAGIC_MASTERY);
336             o_ptr->art_flags.set(TR_DEC_MANA);
337         }
338     }
339
340     if (o_ptr->is_fixed_artifact()) {
341         const auto &artifact = o_ptr->get_fixed_artifact();
342         if (artifact.name.empty()) {
343             o_ptr->fixed_artifact_idx = FixedArtifactId::NONE;
344         }
345     }
346
347     if (o_ptr->is_ego()) {
348         const auto &ego = o_ptr->get_ego();
349         if (ego.name.empty()) {
350             o_ptr->ego_idx = EgoType::NONE;
351         }
352     }
353 }
354
355 /*!
356  * @brief モンスターを読み込む / Read a monster
357  * @param player_ptr プレイヤーへの参照ポインタ
358  * @param m_ptr モンスター保存先ポインタ
359  */
360 void rd_monster_old(PlayerType *player_ptr, MonsterEntity *m_ptr)
361 {
362     m_ptr->r_idx = i2enum<MonsterRaceId>(rd_s16b());
363
364     if (h_older_than(1, 0, 12)) {
365         m_ptr->ap_r_idx = m_ptr->r_idx;
366     } else {
367         m_ptr->ap_r_idx = i2enum<MonsterRaceId>(rd_s16b());
368     }
369
370     if (h_older_than(1, 0, 14)) {
371         auto *r_ptr = &m_ptr->get_monrace();
372
373         m_ptr->sub_align = SUB_ALIGN_NEUTRAL;
374         if (r_ptr->kind_flags.has(MonsterKindType::EVIL)) {
375             m_ptr->sub_align |= SUB_ALIGN_EVIL;
376         }
377         if (r_ptr->kind_flags.has(MonsterKindType::GOOD)) {
378             m_ptr->sub_align |= SUB_ALIGN_GOOD;
379         }
380     } else {
381         m_ptr->sub_align = rd_byte();
382     }
383
384     m_ptr->fy = rd_byte();
385     m_ptr->fx = rd_byte();
386     m_ptr->current_floor_ptr = player_ptr->current_floor_ptr;
387
388     m_ptr->hp = rd_s16b();
389     m_ptr->maxhp = rd_s16b();
390
391     if (h_older_than(1, 0, 5)) {
392         m_ptr->max_maxhp = m_ptr->maxhp;
393     } else {
394         m_ptr->max_maxhp = rd_s16b();
395     }
396     if (h_older_than(2, 1, 2, 1)) {
397         m_ptr->dealt_damage = 0;
398     } else {
399         m_ptr->dealt_damage = rd_s32b();
400     }
401
402     m_ptr->mtimed[MTIMED_CSLEEP] = rd_s16b();
403     m_ptr->mspeed = rd_byte();
404
405     if (h_older_than(0, 4, 2)) {
406         m_ptr->energy_need = rd_byte();
407     } else {
408         m_ptr->energy_need = rd_s16b();
409     }
410
411     if (h_older_than(1, 0, 13)) {
412         m_ptr->energy_need = 100 - m_ptr->energy_need;
413     }
414
415     if (h_older_than(0, 0, 7)) {
416         m_ptr->mtimed[MTIMED_FAST] = 0;
417         m_ptr->mtimed[MTIMED_SLOW] = 0;
418     } else {
419         m_ptr->mtimed[MTIMED_FAST] = rd_byte();
420         m_ptr->mtimed[MTIMED_SLOW] = rd_byte();
421     }
422
423     m_ptr->mtimed[MTIMED_STUNNED] = rd_byte();
424     m_ptr->mtimed[MTIMED_CONFUSED] = rd_byte();
425     m_ptr->mtimed[MTIMED_MONFEAR] = rd_byte();
426
427     if (h_older_than(0, 0, 10)) {
428         reset_target(m_ptr);
429     } else if (h_older_than(0, 0, 11)) {
430         strip_bytes(2);
431         reset_target(m_ptr);
432     } else {
433         m_ptr->target_y = rd_s16b();
434         m_ptr->target_x = rd_s16b();
435     }
436
437     m_ptr->mtimed[MTIMED_INVULNER] = rd_byte();
438
439     auto tmp32u = rd_u32b();
440     migrate_bitflag_to_flaggroup(m_ptr->smart, tmp32u);
441
442     // 3.0.0Alpha10以前のSM_CLONED(ビット位置22)、SM_PET(23)、SM_FRIEDLY(28)をMFLAG2に移行する
443     // ビット位置の定義はなくなるので、ビット位置の値をハードコードする。
444     std::bitset<32> rd_bits_smart(tmp32u);
445     m_ptr->mflag2[MonsterConstantFlagType::CLONED] = rd_bits_smart[22];
446     m_ptr->mflag2[MonsterConstantFlagType::PET] = rd_bits_smart[23];
447     m_ptr->mflag2[MonsterConstantFlagType::FRIENDLY] = rd_bits_smart[28];
448     m_ptr->smart.reset(i2enum<MonsterSmartLearnType>(22)).reset(i2enum<MonsterSmartLearnType>(23)).reset(i2enum<MonsterSmartLearnType>(28));
449
450     if (h_older_than(0, 4, 5)) {
451         m_ptr->exp = 0;
452     } else {
453         m_ptr->exp = rd_u32b();
454     }
455
456     if (h_older_than(0, 2, 2)) {
457         if (enum2i(m_ptr->r_idx) < 0) {
458             m_ptr->r_idx = i2enum<MonsterRaceId>(0 - enum2i(m_ptr->r_idx));
459             m_ptr->mflag2.set(MonsterConstantFlagType::KAGE);
460         }
461     } else {
462         auto tmp8u = rd_byte();
463         constexpr auto base = enum2i(MonsterConstantFlagType::KAGE);
464         migrate_bitflag_to_flaggroup(m_ptr->mflag2, tmp8u, base, 7);
465     }
466
467     if (h_older_than(1, 0, 12)) {
468         if (m_ptr->mflag2.has(MonsterConstantFlagType::KAGE)) {
469             m_ptr->ap_r_idx = MonsterRaceId::KAGE;
470         }
471     }
472
473     if (h_older_than(0, 1, 3)) {
474         m_ptr->nickname.clear();
475     } else {
476         char buf[128];
477         rd_string(buf, sizeof(buf));
478         if (buf[0]) {
479             m_ptr->nickname = buf;
480         }
481     }
482
483     strip_bytes(1);
484 }
485
486 static void move_RF3_to_RFR(MonsterRaceInfo *r_ptr, BIT_FLAGS f3, const BIT_FLAGS rf3, const MonsterResistanceType rfr)
487 {
488     if (f3 & rf3) {
489         r_ptr->resistance_flags.set(rfr);
490     }
491 }
492
493 static void move_RF4_BR_to_RFR(MonsterRaceInfo *r_ptr, BIT_FLAGS f4, const BIT_FLAGS rf4_br, const MonsterResistanceType rfr)
494 {
495     if (f4 & rf4_br) {
496         r_ptr->resistance_flags.set(rfr);
497     }
498 }
499
500 /*!
501  * @brief モンスターの思い出を読み込む
502  * @param r_ptr モンスター種族情報への参照ポインタ
503  * @param r_idx モンスター種族ID
504  * @details 本来はr_idxからr_ptrを決定可能だが、互換性を優先するため元コードのままとする
505  */
506 void set_old_lore(MonsterRaceInfo *r_ptr, BIT_FLAGS f3, BIT_FLAGS f4, const MonsterRaceId r_idx)
507 {
508     r_ptr->r_resistance_flags.clear();
509     move_RF3_to_RFR(r_ptr, f3, RF3_IM_ACID, MonsterResistanceType::IMMUNE_ACID);
510     move_RF3_to_RFR(r_ptr, f3, RF3_IM_ELEC, MonsterResistanceType::IMMUNE_ELEC);
511     move_RF3_to_RFR(r_ptr, f3, RF3_IM_FIRE, MonsterResistanceType::IMMUNE_FIRE);
512     move_RF3_to_RFR(r_ptr, f3, RF3_IM_COLD, MonsterResistanceType::IMMUNE_COLD);
513     move_RF3_to_RFR(r_ptr, f3, RF3_IM_POIS, MonsterResistanceType::IMMUNE_POISON);
514     move_RF3_to_RFR(r_ptr, f3, RF3_RES_TELE, MonsterResistanceType::RESIST_TELEPORT);
515     move_RF3_to_RFR(r_ptr, f3, RF3_RES_NETH, MonsterResistanceType::RESIST_NETHER);
516     move_RF3_to_RFR(r_ptr, f3, RF3_RES_WATE, MonsterResistanceType::RESIST_WATER);
517     move_RF3_to_RFR(r_ptr, f3, RF3_RES_PLAS, MonsterResistanceType::RESIST_PLASMA);
518     move_RF3_to_RFR(r_ptr, f3, RF3_RES_NEXU, MonsterResistanceType::RESIST_NEXUS);
519     move_RF3_to_RFR(r_ptr, f3, RF3_RES_DISE, MonsterResistanceType::RESIST_DISENCHANT);
520     move_RF3_to_RFR(r_ptr, f3, RF3_RES_ALL, MonsterResistanceType::RESIST_ALL);
521
522     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_LITE, MonsterResistanceType::RESIST_LITE);
523     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_DARK, MonsterResistanceType::RESIST_DARK);
524     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_SOUN, MonsterResistanceType::RESIST_SOUND);
525     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_CHAO, MonsterResistanceType::RESIST_CHAOS);
526     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_TIME, MonsterResistanceType::RESIST_TIME);
527     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_INER, MonsterResistanceType::RESIST_INERTIA);
528     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_GRAV, MonsterResistanceType::RESIST_GRAVITY);
529     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_SHAR, MonsterResistanceType::RESIST_SHARDS);
530     move_RF4_BR_to_RFR(r_ptr, f4, RF4_BR_WALL, MonsterResistanceType::RESIST_FORCE);
531
532     if (f4 & RF4_BR_CONF) {
533         r_ptr->r_resistance_flags.set(MonsterResistanceType::NO_CONF);
534     }
535
536     if (r_idx == MonsterRaceId::STORMBRINGER) {
537         r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_CHAOS);
538     }
539
540     if (r_ptr->r_kind_flags.has(MonsterKindType::ORC)) {
541         r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_DARK);
542     }
543 }
544
545 /*!
546  * @brief ダンジョン情報を読み込む / Read the dungeon (old method)
547  * @param player_ptr プレイヤーへの参照ポインタ
548  * @details
549  * The monsters/objects must be loaded in the same order
550  * that they were stored, since the actual indexes matter.
551  */
552 errr rd_dungeon_old(PlayerType *player_ptr)
553 {
554     auto *floor_ptr = player_ptr->current_floor_ptr;
555     floor_ptr->dun_level = rd_s16b();
556     if (h_older_than(0, 3, 8)) {
557         floor_ptr->set_dungeon_index(DUNGEON_ANGBAND);
558     } else {
559         floor_ptr->set_dungeon_index(rd_byte());
560     }
561
562     floor_ptr->base_level = floor_ptr->dun_level;
563     floor_ptr->base_level = rd_s16b();
564
565     floor_ptr->num_repro = rd_s16b();
566     player_ptr->y = rd_s16b();
567     player_ptr->x = rd_s16b();
568     if (h_older_than(0, 3, 13) && !floor_ptr->dun_level && !floor_ptr->inside_arena) {
569         player_ptr->y = 33;
570         player_ptr->x = 131;
571     }
572     floor_ptr->height = rd_s16b();
573     floor_ptr->width = rd_s16b();
574     strip_bytes(2); /* max_panel_rows */
575     strip_bytes(2); /* max_panel_cols */
576
577     int ymax = floor_ptr->height;
578     int xmax = floor_ptr->width;
579
580     for (int x = 0, y = 0; y < ymax;) {
581         uint16_t info;
582         auto count = rd_byte();
583         if (h_older_than(0, 3, 6)) {
584             info = rd_byte();
585         } else {
586             info = rd_u16b();
587             info &= ~(CAVE_LITE | CAVE_VIEW | CAVE_MNLT | CAVE_MNDK);
588         }
589
590         for (int i = count; i > 0; i--) {
591             Grid *g_ptr;
592             g_ptr = &floor_ptr->grid_array[y][x];
593             g_ptr->info = info;
594             if (++x >= xmax) {
595                 x = 0;
596                 if (++y >= ymax) {
597                     break;
598                 }
599             }
600         }
601     }
602
603     for (int x = 0, y = 0; y < ymax;) {
604         auto count = rd_byte();
605         auto tmp8u = rd_byte();
606         for (int i = count; i > 0; i--) {
607             Grid *g_ptr;
608             g_ptr = &floor_ptr->grid_array[y][x];
609             g_ptr->feat = (int16_t)tmp8u;
610             if (++x >= xmax) {
611                 x = 0;
612                 if (++y >= ymax) {
613                     break;
614                 }
615             }
616         }
617     }
618
619     for (int x = 0, y = 0; y < ymax;) {
620         auto count = rd_byte();
621         auto tmp8u = rd_byte();
622         for (int i = count; i > 0; i--) {
623             Grid *g_ptr;
624             g_ptr = &floor_ptr->grid_array[y][x];
625             g_ptr->mimic = (int16_t)tmp8u;
626             if (++x >= xmax) {
627                 x = 0;
628                 if (++y >= ymax) {
629                     break;
630                 }
631             }
632         }
633     }
634
635     for (int x = 0, y = 0; y < ymax;) {
636         auto count = rd_byte();
637         auto tmp16s = rd_s16b();
638         for (int i = count; i > 0; i--) {
639             Grid *g_ptr;
640             g_ptr = &floor_ptr->grid_array[y][x];
641             g_ptr->special = tmp16s;
642             if (++x >= xmax) {
643                 x = 0;
644                 if (++y >= ymax) {
645                     break;
646                 }
647             }
648         }
649     }
650
651     if (h_older_than(1, 0, 99)) {
652         for (int y = 0; y < ymax; y++) {
653             for (int x = 0; x < xmax; x++) {
654                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
655             }
656         }
657     }
658
659     if (h_older_than(1, 1, 1, 0)) {
660         for (int y = 0; y < ymax; y++) {
661             for (int x = 0; x < xmax; x++) {
662                 Grid *g_ptr;
663                 g_ptr = &floor_ptr->grid_array[y][x];
664
665                 /* Very old */
666                 if (g_ptr->feat == OLD_FEAT_INVIS) {
667                     g_ptr->feat = feat_floor;
668                     g_ptr->info |= CAVE_TRAP;
669                 }
670
671                 /* Older than 1.1.1 */
672                 if (g_ptr->feat == OLD_FEAT_MIRROR) {
673                     g_ptr->feat = feat_floor;
674                     g_ptr->info |= CAVE_OBJECT;
675                 }
676             }
677         }
678     }
679
680     if (h_older_than(1, 3, 1, 0)) {
681         for (int y = 0; y < ymax; y++) {
682             for (int x = 0; x < xmax; x++) {
683                 Grid *g_ptr;
684                 g_ptr = &floor_ptr->grid_array[y][x];
685
686                 /* Old CAVE_IN_MIRROR flag */
687                 if (g_ptr->info & CAVE_OBJECT) {
688                     g_ptr->mimic = feat_mirror;
689                 } else if ((g_ptr->feat == OLD_FEAT_RUNE_EXPLOSION) || (g_ptr->feat == OLD_FEAT_RUNE_PROTECTION)) {
690                     g_ptr->info |= CAVE_OBJECT;
691                     g_ptr->mimic = g_ptr->feat;
692                     g_ptr->feat = feat_floor;
693                 } else if (g_ptr->info & CAVE_TRAP) {
694                     g_ptr->info &= ~CAVE_TRAP;
695                     g_ptr->mimic = g_ptr->feat;
696                     g_ptr->feat = choose_random_trap(floor_ptr);
697                 } else if (g_ptr->feat == OLD_FEAT_INVIS) {
698                     g_ptr->mimic = feat_floor;
699                     g_ptr->feat = feat_trap_open;
700                 }
701             }
702         }
703     }
704
705     /* Quest 18 was removed */
706     if (!vanilla_town) {
707         for (int y = 0; y < ymax; y++) {
708             for (int x = 0; x < xmax; x++) {
709                 Grid *g_ptr;
710                 g_ptr = &floor_ptr->grid_array[y][x];
711
712                 if ((g_ptr->special == OLD_QUEST_WATER_CAVE) && !floor_ptr->dun_level) {
713                     if (g_ptr->feat == OLD_FEAT_QUEST_ENTER) {
714                         g_ptr->feat = feat_tree;
715                         g_ptr->special = 0;
716                     } else if (g_ptr->feat == OLD_FEAT_BLDG_1) {
717                         g_ptr->special = lite_town ? QUEST_OLD_CASTLE : QUEST_ROYAL_CRYPT;
718                     }
719                 } else if ((g_ptr->feat == OLD_FEAT_QUEST_EXIT) && (floor_ptr->quest_number == i2enum<QuestId>(OLD_QUEST_WATER_CAVE))) {
720                     g_ptr->feat = feat_up_stair;
721                     g_ptr->special = 0;
722                 }
723             }
724         }
725     }
726
727     uint16_t limit;
728     limit = rd_u16b();
729     if (limit > w_ptr->max_o_idx) {
730         load_note(format(_("アイテムの配列が大きすぎる(%d)!", "Too many (%d) object entries!"), limit));
731         return 151;
732     }
733
734     auto item_loader = ItemLoaderFactory::create_loader();
735     for (int i = 1; i < limit; i++) {
736         OBJECT_IDX o_idx = o_pop(floor_ptr);
737         if (i != o_idx) {
738             load_note(format(_("アイテム配置エラー (%d <> %d)", "Object allocation error (%d <> %d)"), i, o_idx));
739             return 152;
740         }
741
742         auto &item = floor_ptr->o_list[o_idx];
743         item_loader->rd_item(&item);
744         auto &list = get_o_idx_list_contains(floor_ptr, o_idx);
745         list.add(floor_ptr, o_idx);
746     }
747
748     limit = rd_u16b();
749     if (limit > w_ptr->max_m_idx) {
750         load_note(format(_("モンスターの配列が大きすぎる(%d)!", "Too many (%d) monster entries!"), limit));
751         return 161;
752     }
753
754     auto monster_loader = MonsterLoaderFactory::create_loader(player_ptr);
755     for (int i = 1; i < limit; i++) {
756         auto m_idx = m_pop(floor_ptr);
757         if (i != m_idx) {
758             load_note(format(_("モンスター配置エラー (%d <> %d)", "Monster allocation error (%d <> %d)"), i, m_idx));
759             return 162;
760         }
761
762         auto m_ptr = &floor_ptr->m_list[m_idx];
763         monster_loader->rd_monster(m_ptr);
764         auto *g_ptr = &floor_ptr->grid_array[m_ptr->fy][m_ptr->fx];
765         g_ptr->m_idx = m_idx;
766         m_ptr->get_real_monrace().cur_num++;
767     }
768
769     if (h_older_than(0, 3, 13) && !floor_ptr->dun_level && !floor_ptr->inside_arena) {
770         w_ptr->character_dungeon = false;
771     } else {
772         w_ptr->character_dungeon = true;
773     }
774
775     return 0;
776 }