OSDN Git Service

「ダイス目nn以上の」の修正。nnが異なる複数の行を同じものと勘違いして最初の
[hengbandforosx/hengbandosx.git] / src / load.c
index 66bb5c1..4cfc7b9 100644 (file)
@@ -67,29 +67,32 @@ static u32b x_check = 0L;
 
 
 
-#if 0
 /*
  * This function determines if the version of the savefile
- * currently being read is older than version "x.y.z".
+ * currently being read is older than version "major.minor.patch.extra".
  */
-static bool older_than(byte x, byte y, byte z)
+static bool h_older_than(byte major, byte minor, byte patch, byte extra)
 {
        /* Much older, or much more recent */
-       if (sf_major < x) return (TRUE);
-       if (sf_major > x) return (FALSE);
+       if (h_ver_major < major) return (TRUE);
+       if (h_ver_major > major) return (FALSE);
 
        /* Distinctly older, or distinctly more recent */
-       if (sf_minor < y) return (TRUE);
-       if (sf_minor > y) return (FALSE);
+       if (h_ver_minor < minor) return (TRUE);
+       if (h_ver_minor > minor) return (FALSE);
+
+       /* Barely older, or barely more recent */
+       if (h_ver_patch < patch) return (TRUE);
+       if (h_ver_patch > patch) return (FALSE);
 
        /* Barely older, or barely more recent */
-       if (sf_patch < z) return (TRUE);
-       if (sf_patch > z) return (FALSE);
+       if (h_ver_extra < extra) return (TRUE);
+       if (h_ver_extra > extra) return (FALSE);
 
        /* Identical versions */
        return (FALSE);
 }
-#endif
+
 
 /*
  * The above function, adapted for Zangband
@@ -134,46 +137,6 @@ static void note(cptr msg)
 
 
 /*
- * Hack -- determine if an item is "wearable" (or a missile)
- */
-static bool wearable_p(object_type *o_ptr)
-{
-       /* Valid "tval" codes */
-       switch (o_ptr->tval)
-       {
-               case TV_SHOT:
-               case TV_ARROW:
-               case TV_BOLT:
-               case TV_BOW:
-               case TV_DIGGING:
-               case TV_HAFTED:
-               case TV_POLEARM:
-               case TV_SWORD:
-               case TV_BOOTS:
-               case TV_GLOVES:
-               case TV_HELM:
-               case TV_CROWN:
-               case TV_SHIELD:
-               case TV_CLOAK:
-               case TV_SOFT_ARMOR:
-               case TV_HARD_ARMOR:
-               case TV_DRAG_ARMOR:
-               case TV_LITE:
-               case TV_AMULET:
-               case TV_RING:
-               case TV_CAPTURE:
-               case TV_CARD:
-               {
-                       return (TRUE);
-               }
-       }
-
-       /* Nope */
-       return (FALSE);
-}
-
-
-/*
  * The following functions are used to load the basic building blocks
  * of savefiles.  They also maintain the "checksum" info for 2.7.0+
  */
@@ -232,10 +195,6 @@ static void rd_string(char *str, int max)
 {
        int i;
 
-#ifdef JP
-        int    kanji, iseuc,l;
-       unsigned char c1,c2;
-#endif
        /* Read the string */
        for (i = 0; TRUE; i++)
        {
@@ -254,64 +213,7 @@ static void rd_string(char *str, int max)
        /* Terminate */
        str[max-1] = '\0';
 #ifdef JP
-        kanji = 0;
-        iseuc = 1;
-       l=strlen(str);
-        for (i = 0; i < l; i++) {
-                c1 = str[i];
-                if (c1 & 0x80)  kanji = 1;
-                if ( c1>=0x80 && (c1 < 0xa1 || c1 > 0xfe)) iseuc = 0;
-                }
-#ifdef EUC
-               if (kanji && !iseuc) {
-                       unsigned char   tmp[256];
-                       for (i = 0; i < l; i++) {
-                               c1 = str[i];
-                               if (c1 & 0x80) {
-                                       i++;
-                                       c2 = str[i];
-                                       if (c2 >= 0x9f) {
-                                               c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe0 : 0x60);
-                                               c2 += 2;
-                                       } else {
-                                               c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe1 : 0x61);
-                                               c2 += 0x60 + (c2 < 0x7f);
-                                       }
-                                       tmp[i - 1] = c1;
-                                       tmp[i] = c2;
-                               } else
-                                       tmp[i] = c1;
-                       }
-                       tmp[l] = 0;
-                       strcpy(str, (char *)tmp);
-               }
-#endif
-
-#ifdef SJIS
-               if (kanji && iseuc) {
-                       unsigned char   tmp[256];
-                       for (i = 0; i < l; i++) {
-                               c1 = str[i];
-                               if (c1 & 0x80) {
-                                       i++;
-                                       c2 = str[i];
-                                       if (c1 % 2) {
-                                               c1 = (c1 >> 1) + (c1 < 0xdf ? 0x31 : 0x71);
-                                               c2 -= 0x60 + (c2 < 0xe0);
-                                       } else {
-                                               c1 = (c1 >> 1) + (c1 < 0xdf ? 0x30 : 0x70);
-                                               c2 -= 2;
-                                       }
-                                       tmp[i - 1] = c1;
-                                       tmp[i] = c2;
-                               } else
-                                       tmp[i] = c1;
-                       }
-                       tmp[l] = 0;
-                       strcpy(str, tmp);
-               }
-#endif
-
+       codeconv(str);
 #endif
 }
 
@@ -348,13 +250,6 @@ static void strip_bytes(int n)
  */
 static void rd_item(object_type *o_ptr)
 {
-       byte old_dd;
-       byte old_ds;
-
-       u32b f1, f2, f3;
-
-       object_kind *k_ptr;
-
        char buf[128];
 
 
@@ -393,17 +288,47 @@ static void rd_item(object_type *o_ptr)
 
        rd_s16b(&o_ptr->ac);
 
-       rd_byte(&old_dd);
-       rd_byte(&old_ds);
+       rd_byte(&o_ptr->dd);
+       rd_byte(&o_ptr->ds);
 
        rd_byte(&o_ptr->ident);
 
        rd_byte(&o_ptr->marked);
 
-       /* Old flags */
-       rd_u32b(&o_ptr->art_flags1);
-       rd_u32b(&o_ptr->art_flags2);
-       rd_u32b(&o_ptr->art_flags3);
+       /* Object flags */
+       rd_u32b(&o_ptr->art_flags[0]);
+       rd_u32b(&o_ptr->art_flags[1]);
+       rd_u32b(&o_ptr->art_flags[2]);
+       if (h_older_than(1, 3, 0, 0)) o_ptr->art_flags[3] = 0L;
+        else rd_u32b(&o_ptr->art_flags[3]);
+
+       if (z_older_than(11, 0, 11))
+       {
+               o_ptr->curse_flags = 0L;
+               if (o_ptr->ident & 0x40)
+               {
+                       o_ptr->curse_flags |= TRC_CURSED;
+                       if (o_ptr->art_flags[2] & 0x40000000L) o_ptr->curse_flags |= TRC_HEAVY_CURSE;
+                       if (o_ptr->art_flags[2] & 0x80000000L) o_ptr->curse_flags |= TRC_PERMA_CURSE;
+                       if (o_ptr->name1)
+                       {
+                               artifact_type *a_ptr = &a_info[o_ptr->name1];
+                               if (a_ptr->gen_flags & (TRG_HEAVY_CURSE)) o_ptr->curse_flags |= TRC_HEAVY_CURSE;
+                               if (a_ptr->gen_flags & (TRG_PERMA_CURSE)) o_ptr->curse_flags |= TRC_PERMA_CURSE;
+                       }
+                       else if (o_ptr->name2)
+                       {
+                               ego_item_type *e_ptr = &e_info[o_ptr->name2];
+                               if (e_ptr->gen_flags & (TRG_HEAVY_CURSE)) o_ptr->curse_flags |= TRC_HEAVY_CURSE;
+                               if (e_ptr->gen_flags & (TRG_PERMA_CURSE)) o_ptr->curse_flags |= TRC_PERMA_CURSE;
+                       }
+               }
+               o_ptr->art_flags[2] &= (0x1FFFFFFFL);
+       }
+       else
+       {
+               rd_u32b(&o_ptr->curse_flags);
+       }
 
        /* Monster holding object */
        rd_s16b(&o_ptr->held_m_idx);
@@ -411,6 +336,58 @@ static void rd_item(object_type *o_ptr)
        /* Special powers */
        rd_byte(&o_ptr->xtra1);
        rd_byte(&o_ptr->xtra2);
+
+       if (z_older_than(11, 0, 10))
+       {
+               if (o_ptr->xtra1 == EGO_XTRA_SUSTAIN)
+               {
+                       switch (o_ptr->xtra2 % 6)
+                       {
+                       case 0: add_flag(o_ptr->art_flags, TR_SUST_STR); break;
+                       case 1: add_flag(o_ptr->art_flags, TR_SUST_INT); break;
+                       case 2: add_flag(o_ptr->art_flags, TR_SUST_WIS); break;
+                       case 3: add_flag(o_ptr->art_flags, TR_SUST_DEX); break;
+                       case 4: add_flag(o_ptr->art_flags, TR_SUST_CON); break;
+                       case 5: add_flag(o_ptr->art_flags, TR_SUST_CHR); break;
+                       }
+                       o_ptr->xtra2 = 0;
+               }
+               else if (o_ptr->xtra1 == EGO_XTRA_POWER)
+               {
+                       switch (o_ptr->xtra2 % 11)
+                       {
+                       case  0: add_flag(o_ptr->art_flags, TR_RES_BLIND);  break;
+                       case  1: add_flag(o_ptr->art_flags, TR_RES_CONF);   break;
+                       case  2: add_flag(o_ptr->art_flags, TR_RES_SOUND);  break;
+                       case  3: add_flag(o_ptr->art_flags, TR_RES_SHARDS); break;
+                       case  4: add_flag(o_ptr->art_flags, TR_RES_NETHER); break;
+                       case  5: add_flag(o_ptr->art_flags, TR_RES_NEXUS);  break;
+                       case  6: add_flag(o_ptr->art_flags, TR_RES_CHAOS);  break;
+                       case  7: add_flag(o_ptr->art_flags, TR_RES_DISEN);  break;
+                       case  8: add_flag(o_ptr->art_flags, TR_RES_POIS);   break;
+                       case  9: add_flag(o_ptr->art_flags, TR_RES_DARK);   break;
+                       case 10: add_flag(o_ptr->art_flags, TR_RES_LITE);   break;
+                       }
+                       o_ptr->xtra2 = 0;
+               }               
+               else if (o_ptr->xtra1 == EGO_XTRA_ABILITY)
+               {
+                       switch (o_ptr->xtra2 % 8)
+                       {
+                       case 0: add_flag(o_ptr->art_flags, TR_FEATHER);     break;
+                       case 1: add_flag(o_ptr->art_flags, TR_LITE);        break;
+                       case 2: add_flag(o_ptr->art_flags, TR_SEE_INVIS);   break;
+                       case 3: add_flag(o_ptr->art_flags, TR_WARNING);     break;
+                       case 4: add_flag(o_ptr->art_flags, TR_SLOW_DIGEST); break;
+                       case 5: add_flag(o_ptr->art_flags, TR_REGEN);       break;
+                       case 6: add_flag(o_ptr->art_flags, TR_FREE_ACT);    break;
+                       case 7: add_flag(o_ptr->art_flags, TR_HOLD_LIFE);   break;
+                       }
+                       o_ptr->xtra2 = 0;
+               }
+               o_ptr->xtra1 = 0;
+       }
+
        if (z_older_than(10, 2, 3))
        {
                o_ptr->xtra3 = 0;
@@ -437,6 +414,12 @@ static void rd_item(object_type *o_ptr)
        else
        {
                rd_byte(&o_ptr->xtra3);
+                if (h_older_than(1, 3, 0, 1))
+                {
+                        if (o_ptr->tval > TV_CAPTURE && o_ptr->xtra3 >= 1+96)
+                                o_ptr->xtra3 += -96 + MIN_SPECIAL_ESSENCE;
+                }
+
                rd_s16b(&o_ptr->xtra4);
                rd_s16b(&o_ptr->xtra5);
        }
@@ -447,40 +430,15 @@ static void rd_item(object_type *o_ptr)
                o_ptr->pval = 0;
        }
 
-       /* Feeling - from 2.3.1, "savefile version 1" */
-       if (sf_version >= 1)
-       {
-               rd_byte(&o_ptr->feeling);
-       }
+        rd_byte(&o_ptr->feeling);
 
        /* Inscription */
-       rd_string(buf, 128);
-
-       /* If this savefile is old, maybe we need to translate the feeling */
-       if (sf_version < 1)
-       {
-               byte i;
-
-               for (i = 0; i <= FEEL_MAX; i++)
-               {
-                       if (game_inscriptions[i] == NULL)
-                       {
-                               continue;
-                       }
-
-                       if (streq(buf, game_inscriptions[i]))
-                       {
-                               o_ptr->feeling = i;
-                               buf[0] = 0;
-                               break;
-                       }
-               }
-       }
+       rd_string(buf, sizeof(buf));
 
        /* Save the inscription */
        if (buf[0]) o_ptr->inscription = quark_add(buf);
 
-       rd_string(buf, 128);
+       rd_string(buf, sizeof(buf));
        if (buf[0]) o_ptr->art_name = quark_add(buf);
 
        /* The Python object */
@@ -496,50 +454,12 @@ static void rd_item(object_type *o_ptr)
 
        if (z_older_than(10, 4, 10) && (o_ptr->name2 == EGO_YOIYAMI)) o_ptr->k_idx = lookup_kind(TV_SOFT_ARMOR, SV_YOIYAMI_ROBE);
 
-       /* Obtain the "kind" template */
-       k_ptr = &k_info[o_ptr->k_idx];
-
-       /* Obtain tval/sval from k_info */
-       o_ptr->tval = k_ptr->tval;
-       o_ptr->sval = k_ptr->sval;
-
-       /* Hack -- notice "broken" items */
-       if (k_ptr->cost <= 0) o_ptr->ident |= (IDENT_BROKEN);
-
-
-       /* Repair non "wearable" items */
-       if (!wearable_p(o_ptr))
-       {
-               /* Acquire correct fields */
-               o_ptr->to_h = k_ptr->to_h;
-               o_ptr->to_d = k_ptr->to_d;
-               o_ptr->to_a = k_ptr->to_a;
-
-               /* Acquire correct fields */
-               o_ptr->ac = k_ptr->ac;
-               o_ptr->dd = k_ptr->dd;
-               o_ptr->ds = k_ptr->ds;
-
-               /* Acquire correct weight */
-               o_ptr->weight = k_ptr->weight;
-
-               /* Paranoia */
-               o_ptr->name1 = o_ptr->name2 = 0;
-
-               /* All done */
-               return;
-       }
-
-
-       /* Extract the flags */
-       object_flags(o_ptr, &f1, &f2, &f3);
-
        if (z_older_than(10, 4, 9))
        {
-               if (o_ptr->art_flags1 & TR1_MAGIC_MASTERY)
+               if (have_flag(o_ptr->art_flags, TR_MAGIC_MASTERY))
                {
-                       o_ptr->art_flags1 &= ~(TR1_MAGIC_MASTERY);
-                       o_ptr->art_flags3 |= (TR3_DEC_MANA);
+                       remove_flag(o_ptr->art_flags, TR_MAGIC_MASTERY);
+                       add_flag(o_ptr->art_flags, TR_DEC_MANA);
                }
        }
 
@@ -567,67 +487,6 @@ static void rd_item(object_type *o_ptr)
                if (!e_ptr->name) o_ptr->name2 = 0;
 
        }
-
-       /* Acquire standard fields */
-       o_ptr->ac = k_ptr->ac;
-       o_ptr->dd = k_ptr->dd;
-       o_ptr->ds = k_ptr->ds;
-
-       /* Acquire standard weight */
-       o_ptr->weight = k_ptr->weight;
-
-       /* Hack -- extract the "broken" flag */
-       if (!o_ptr->pval < 0) o_ptr->ident |= (IDENT_BROKEN);
-
-       /* Artifacts */
-       if (o_ptr->name1)
-       {
-               artifact_type *a_ptr;
-
-               /* Obtain the artifact info */
-               a_ptr = &a_info[o_ptr->name1];
-
-               /* Acquire new artifact "pval" */
-               o_ptr->pval = a_ptr->pval;
-
-               /* Acquire new artifact fields */
-               o_ptr->ac = a_ptr->ac;
-               o_ptr->dd = a_ptr->dd;
-               o_ptr->ds = a_ptr->ds;
-
-               /* Acquire new artifact weight */
-               o_ptr->weight = a_ptr->weight;
-
-               /* Hack -- extract the "broken" flag */
-               if (!a_ptr->cost) o_ptr->ident |= (IDENT_BROKEN);
-       }
-
-       /* Ego items */
-       if (o_ptr->name2)
-       {
-               ego_item_type *e_ptr;
-
-               /* Obtain the ego-item info */
-               e_ptr = &e_info[o_ptr->name2];
-
-               o_ptr->dd = old_dd;
-               o_ptr->ds = old_ds;
-
-               if (o_ptr->name2 == EGO_DWARVEN)
-               {
-                       o_ptr->ac += 5;
-                       o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
-               }
-
-               /* Hack -- extract the "broken" flag */
-               if (!e_ptr->cost) o_ptr->ident |= (IDENT_BROKEN);
-       }
-
-       if (o_ptr->art_name) /* A random artifact */
-       {
-               o_ptr->dd = old_dd;
-               o_ptr->ds = old_ds;
-       }
 }
 
 
@@ -644,6 +503,22 @@ static void rd_monster(monster_type *m_ptr)
        /* Read the monster race */
        rd_s16b(&m_ptr->r_idx);
 
+       if (z_older_than(11, 0, 12))
+               m_ptr->ap_r_idx = m_ptr->r_idx;
+       else
+               rd_s16b(&m_ptr->ap_r_idx);
+
+       if (z_older_than(11, 0, 14))
+       {
+               monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+               m_ptr->sub_align = SUB_ALIGN_NEUTRAL;
+               if (r_ptr->flags3 & RF3_EVIL) m_ptr->sub_align |= SUB_ALIGN_EVIL;
+               if (r_ptr->flags3 & RF3_GOOD) m_ptr->sub_align |= SUB_ALIGN_GOOD;
+       }
+       else
+               rd_byte(&m_ptr->sub_align);
+
        /* Read the other information */
        rd_byte(&m_ptr->fy);
        rd_byte(&m_ptr->fx);
@@ -662,9 +537,13 @@ static void rd_monster(monster_type *m_ptr)
        if (z_older_than(10, 4, 2))
        {
                rd_byte(&tmp8u);
-               m_ptr->energy = (s16b)tmp8u;
+               m_ptr->energy_need = (s16b)tmp8u;
        }
-       else rd_s16b(&m_ptr->energy);
+       else rd_s16b(&m_ptr->energy_need);
+
+       if (z_older_than(11, 0, 13))
+               m_ptr->energy_need = 100 - m_ptr->energy_need;
+
        if (z_older_than(10,0,7))
        {
                m_ptr->fast = 0;
@@ -681,15 +560,13 @@ static void rd_monster(monster_type *m_ptr)
 
        if (z_older_than(10,0,10))
        {
-               m_ptr->target_y = 0;
-               m_ptr->target_x = 0;
+               reset_target(m_ptr);
        }
        else if (z_older_than(10,0,11))
        {
                s16b tmp16s;
                rd_s16b(&tmp16s);
-               m_ptr->target_y = 0;
-               m_ptr->target_x = 0;
+               reset_target(m_ptr);
        }
        else
        {
@@ -697,11 +574,7 @@ static void rd_monster(monster_type *m_ptr)
                rd_s16b(&m_ptr->target_x);
        }
 
-       /* Monster invulnerability introduced from 2.3.2+ */
-       if (sf_version < 2)
-               m_ptr->invulner = 0;
-       else
-               rd_byte(&m_ptr->invulner);
+        rd_byte(&m_ptr->invulner);
 
        if (!(z_major == 2 && z_minor == 0 && z_patch == 6))
                rd_u32b(&m_ptr->smart);
@@ -726,13 +599,19 @@ static void rd_monster(monster_type *m_ptr)
                rd_byte(&m_ptr->mflag2);
        }
 
+       if (z_older_than(11, 0, 12))
+       {
+               if (m_ptr->mflag2 & MFLAG_KAGE)
+                       m_ptr->ap_r_idx = MON_KAGE;
+       }
+
        if (z_older_than(10, 1, 3))
        {
                m_ptr->nickname = 0;
        }
        else
        {
-               rd_string(buf, 128);
+               rd_string(buf, sizeof(buf));
                if (buf[0]) m_ptr->nickname = quark_add(buf);
        }
 
@@ -1072,7 +951,7 @@ static void rd_options(void)
 
        rd_u16b(&c);
 
-       if (c & 0x0002) wizard = TRUE;
+       if (c & 0x0002) p_ptr->wizard = TRUE;
 
        cheat_peek = (c & 0x0100) ? TRUE : FALSE;
        cheat_hear = (c & 0x0200) ? TRUE : FALSE;
@@ -1200,14 +1079,56 @@ static void rd_ghost(void)
        char buf[64];
 
        /* Strip name */
-       rd_string(buf, 64);
+       rd_string(buf, sizeof(buf));
 
        /* Strip old data */
        strip_bytes(60);
 }
 
 
+/*
+ * Save quick start data
+ */
+static void load_quick_start(void)
+{
+       byte tmp8u;
+       int i;
+
+       if (z_older_than(11, 0, 13))
+       {
+               previous_char.quick_ok = FALSE;
+               return;
+       }
+
+       rd_byte(&previous_char.psex);
+       rd_byte(&previous_char.prace);
+       rd_byte(&previous_char.pclass);
+       rd_byte(&previous_char.pseikaku);
+       rd_byte(&previous_char.realm1);
+       rd_byte(&previous_char.realm2);
+
+       rd_s16b(&previous_char.age);
+       rd_s16b(&previous_char.ht);
+       rd_s16b(&previous_char.wt);
+       rd_s16b(&previous_char.sc);
+       rd_s32b(&previous_char.au);
+
+       for (i = 0; i < 6; i++) rd_s16b(&previous_char.stat_max[i]);
+       for (i = 0; i < 6; i++) rd_s16b(&previous_char.stat_max_max[i]);
+
+       for (i = 0; i < PY_MAX_LEVEL; i++) rd_s16b(&previous_char.player_hp[i]);
 
+       rd_s16b(&previous_char.chaos_patron);
+
+       for (i = 0; i < 8; i++) rd_s16b(&previous_char.vir_types[i]);
+
+       for (i = 0; i < 4; i++) rd_string(previous_char.history[i], sizeof(previous_char.history[i]));
+
+       rd_byte(&previous_char.quests);
+
+       rd_byte(&tmp8u);
+       previous_char.quick_ok = (bool)tmp8u;
+}
 
 /*
  * Read the "extra" information
@@ -1219,13 +1140,15 @@ static void rd_extra(void)
        byte tmp8u;
        s16b tmp16s;
 
-       rd_string(player_name, 32);
+       rd_string(player_name, sizeof(player_name));
 
-       rd_string(died_from, 80);
+       rd_string(p_ptr->died_from, sizeof(p_ptr->died_from));
+
+       load_quick_start();
 
        for (i = 0; i < 4; i++)
        {
-               rd_string(history[i], 60);
+               rd_string(p_ptr->history[i], sizeof(p_ptr->history[i]));
        }
 
        /* Class/Race/Seikaku/Gender/Spells */
@@ -1269,20 +1192,20 @@ static void rd_extra(void)
 
        rd_s16b(&p_ptr->lev);
 
-       for (i = 0; i < 64; i++) rd_s16b(&spell_exp[i]);
+       for (i = 0; i < 64; i++) rd_s16b(&p_ptr->spell_exp[i]);
        if ((p_ptr->pclass == CLASS_SORCERER) && z_older_than(10, 4, 2))
        {
-               for (i = 0; i < 64; i++) spell_exp[i] = 1600;
+               for (i = 0; i < 64; i++) p_ptr->spell_exp[i] = 1600;
        }
        if (z_older_than(10, 3, 6))
-               for (i = 0; i < 5; i++) for (j = 0; j < 60; j++) rd_s16b(&weapon_exp[i][j]);
+               for (i = 0; i < 5; i++) for (j = 0; j < 60; j++) rd_s16b(&p_ptr->weapon_exp[i][j]);
        else
-               for (i = 0; i < 5; i++) for (j = 0; j < 64; j++) rd_s16b(&weapon_exp[i][j]);
-       for (i = 0; i < 10; i++) rd_s16b(&skill_exp[i]);
+               for (i = 0; i < 5; i++) for (j = 0; j < 64; j++) rd_s16b(&p_ptr->weapon_exp[i][j]);
+       for (i = 0; i < 10; i++) rd_s16b(&p_ptr->skill_exp[i]);
        if (z_older_than(10, 4, 1))
        {
-               if (p_ptr->pclass != CLASS_BEASTMASTER) skill_exp[GINOU_RIDING] /= 2;
-               skill_exp[GINOU_RIDING] = MIN(skill_exp[GINOU_RIDING], s_info[p_ptr->pclass].s_max[GINOU_RIDING]);
+               if (p_ptr->pclass != CLASS_BEASTMASTER) p_ptr->skill_exp[GINOU_RIDING] /= 2;
+               p_ptr->skill_exp[GINOU_RIDING] = MIN(p_ptr->skill_exp[GINOU_RIDING], s_info[p_ptr->pclass].s_max[GINOU_RIDING]);
        }
        if (z_older_than(10, 3, 14))
        {
@@ -1293,6 +1216,16 @@ static void rd_extra(void)
        {
                for (i = 0; i < 108; i++) rd_s32b(&p_ptr->magic_num1[i]);
                for (i = 0; i < 108; i++) rd_byte(&p_ptr->magic_num2[i]);
+                if (h_older_than(1, 3, 0, 1))
+                {
+                        if (p_ptr->pclass == CLASS_SMITH)
+                        {
+                                p_ptr->magic_num1[TR_ES_ATTACK] = p_ptr->magic_num1[96];
+                                p_ptr->magic_num1[96] = 0;
+                                p_ptr->magic_num1[TR_ES_AC] = p_ptr->magic_num1[97];
+                                p_ptr->magic_num1[97] = 0;
+                        }
+                }
        }
        if ((p_ptr->pclass == CLASS_BARD) && p_ptr->magic_num1[0]) p_ptr->action = ACTION_SING;
 
@@ -1315,10 +1248,10 @@ static void rd_extra(void)
        {
                for (i = 0; i < OLD_MAX_MANE; i++)
                {
-                       mane_spell[i] = -1;
-                       mane_dam[i] = 0;
+                       p_ptr->mane_spell[i] = -1;
+                       p_ptr->mane_dam[i] = 0;
                }
-               mane_num = 0;
+               p_ptr->mane_num = 0;
        }
        else if (z_older_than(10, 2, 3))
        {
@@ -1329,20 +1262,20 @@ static void rd_extra(void)
                }
                for (i = 0; i < MAX_MANE; i++)
                {
-                       mane_spell[i] = -1;
-                       mane_dam[i] = 0;
+                       p_ptr->mane_spell[i] = -1;
+                       p_ptr->mane_dam[i] = 0;
                }
                rd_s16b(&tmp16s);
-               mane_num = 0;
+               p_ptr->mane_num = 0;
        }
        else
        {
                for (i = 0; i < MAX_MANE; i++)
                {
-                       rd_s16b(&mane_spell[i]);
-                       rd_s16b(&mane_dam[i]);
+                       rd_s16b(&p_ptr->mane_spell[i]);
+                       rd_s16b(&p_ptr->mane_dam[i]);
                }
-               rd_s16b(&mane_num);
+               rd_s16b(&p_ptr->mane_num);
        }
 
        if (z_older_than(10, 0, 3))
@@ -1490,7 +1423,11 @@ note(format("
        rd_s16b(&p_ptr->confused);
        rd_s16b(&p_ptr->food);
        strip_bytes(4); /* Old "food_digested" / "protection" */
-       rd_s16b(&p_ptr->energy);
+
+       rd_s16b(&p_ptr->energy_need);
+       if (z_older_than(11, 0, 13))
+               p_ptr->energy_need = 100 - p_ptr->energy_need;
+
        rd_s16b(&p_ptr->fast);
        rd_s16b(&p_ptr->slow);
        rd_s16b(&p_ptr->afraid);
@@ -1589,6 +1526,17 @@ note(format("
                        rd_s16b(&p_ptr->tim_sh_fire);
                }
 
+               if (z_older_than(11, 0, 99))
+               {
+                       p_ptr->tim_sh_holy = 0;
+                       p_ptr->tim_eyeeye = 0;
+               }
+               else
+               {
+                       rd_s16b(&p_ptr->tim_sh_holy);
+                       rd_s16b(&p_ptr->tim_eyeeye);
+               }
+
                /* by henkma */
                if ( z_older_than(11,0,3) ){
                  p_ptr->tim_reflect=0;
@@ -1648,7 +1596,7 @@ note(format("
                if (tmp8u) p_ptr->action = ACTION_LEARN;
        }
        rd_byte((byte *)&preserve_mode);
-       rd_byte((byte *)&wait_report_score);
+       rd_byte((byte *)&p_ptr->wait_report_score);
 
        /* Future use */
        for (i = 0; i < 48; i++) rd_byte(&tmp8u);
@@ -1663,14 +1611,14 @@ note(format("
 
 
        /* Special stuff */
-       rd_u16b(&panic_save);
-       rd_u16b(&total_winner);
-       rd_u16b(&noscore);
+       rd_u16b(&p_ptr->panic_save);
+       rd_u16b(&p_ptr->total_winner);
+       rd_u16b(&p_ptr->noscore);
 
 
        /* Read "death" */
        rd_byte(&tmp8u);
-       death = tmp8u;
+       p_ptr->is_dead = tmp8u;
 
        /* Read "feeling" */
        rd_byte(&tmp8u);
@@ -1688,6 +1636,13 @@ note(format("
        }
        else rd_s32b(&dungeon_turn);
 
+       if (z_older_than(11, 0, 13))
+       {
+               old_turn /= 2;
+               turn /= 2;
+               dungeon_turn /= 2;
+       }
+
        if (z_older_than(10, 3, 13))
        {
                old_battle = turn;
@@ -1877,7 +1832,7 @@ static void rd_messages(void)
        for (i = 0; i < num; i++)
        {
                /* Read the message */
-               rd_string(buf, 128);
+               rd_string(buf, sizeof(buf));
 
                /* Save the message */
                message_add(buf);
@@ -1923,8 +1878,8 @@ static errr rd_dungeon(void)
        if (z_older_than(10, 3, 13) && !dun_level && !p_ptr->inside_arena) {py = 33;px = 131;}
        rd_s16b(&cur_hgt);
        rd_s16b(&cur_wid);
-       rd_s16b(&max_panel_rows);
-       rd_s16b(&max_panel_cols);
+       rd_s16b(&tmp16s); /* max_panel_rows */
+       rd_s16b(&tmp16s); /* max_panel_cols */
 
 #if 0
        if (!py || !px) {py = 10;px = 10;}/* ¥À¥ó¥¸¥ç¥óÀ¸À®¤Ë¼ºÇÔ¤·¤Æ¥»¥°¥á¥ó¥Æ¤Ã¤¿¤È¤­¤ÎÉüµìÍÑ */
@@ -1986,12 +1941,6 @@ static errr rd_dungeon(void)
                        /* Access the cave */
                        c_ptr = &cave[y][x];
 
-                       if (c_ptr->feat == FEAT_INVIS)
-                       {
-                               c_ptr->feat = FEAT_FLOOR;
-                               c_ptr->info |= CAVE_TRAP;
-                       }
-
                        /* Extract "feat" */
                        c_ptr->feat = tmp8u;
 
@@ -2007,6 +1956,39 @@ static errr rd_dungeon(void)
                }
        }
 
+        /* Convert cave data */
+        if (z_older_than(11, 0, 99))
+        {
+                for (y = 0; y < ymax; y++) for (x = 0; x < xmax; x++)
+                {
+                       /* Wipe old unused flags */
+                       cave[y][x].info &= ~(CAVE_MASK);
+                }
+        }
+
+        if (h_older_than(1, 1, 1, 0))
+        {
+                for (y = 0; y < ymax; y++) for (x = 0; x < xmax; x++)
+                {
+                       /* Access the cave */
+                       c_ptr = &cave[y][x];
+
+                        /* Very old */
+                        if (c_ptr->feat == FEAT_INVIS)
+                        {
+                                c_ptr->feat = FEAT_FLOOR;
+                                c_ptr->info |= CAVE_TRAP;
+                        }
+                
+                        /* Older than 1.1.1 */
+                        if (c_ptr->feat == FEAT_MIRROR)
+                        {
+                                c_ptr->feat = FEAT_FLOOR;
+                                c_ptr->info |= CAVE_IN_MIRROR;
+                        }
+                }
+        }
+
        /*** Run length decoding ***/
 
        /* Load the dungeon data */
@@ -2247,13 +2229,13 @@ static errr rd_savefile_new_aux(void)
 
 
        /* Mention the savefile version */
+        note(format(
 #ifdef JP
-note(format("¥Ð¡¼¥¸¥ç¥ó %d.%d.%d ¤Î¥»¡¼¥Ö¡¦¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥ÉÃæ...",
+                     "¥Ð¡¼¥¸¥ç¥ó %d.%d.%d ¤Î¥»¡¼¥Ö¡¦¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥ÉÃæ...",
 #else
-       note(format("Loading a %d.%d.%d savefile...",
+                     "Loading a %d.%d.%d savefile...",
 #endif
-
-               (z_major > 9) ? z_major - 10 : z_major, z_minor, z_patch));
+                     (z_major > 9) ? z_major - 10 : z_major, z_minor, z_patch));
 
 
        /* Strip the version bytes */
@@ -2267,13 +2249,15 @@ note(format("
        v_check = 0L;
        x_check = 0L;
 
-#if SAVEFILE_VERSION
        /* Read the version number of the savefile */
-       rd_u32b(&sf_version);
-#endif /* SAVEFILE_VERSION */
+        /* Old savefile will be version 0.0.0.3 */
+        rd_byte(&h_ver_extra);
+        rd_byte(&h_ver_patch);
+        rd_byte(&h_ver_minor);
+        rd_byte(&h_ver_major);
 
        /* Operating system info */
-       rd_u32b(&sf_xtra);
+       rd_u32b(&sf_system);
 
        /* Time of savefile creation */
        rd_u32b(&sf_when);
@@ -2319,7 +2303,7 @@ if (arg_fiddle) note("
        if (munchkin_death)
        {
                /* Mark savefile */
-               noscore |= 0x0001;
+               p_ptr->noscore |= 0x0001;
        }
 
        /* Then the "messages" */
@@ -2435,7 +2419,7 @@ if (arg_fiddle) note("
        {
                for (j = 0; j < max_wild_y; j++)
                {
-                       wilderness[j][i].seed = rand_int(0x10000000);
+                       wilderness[j][i].seed = randint0(0x10000000);
                }
        }
 
@@ -2522,7 +2506,7 @@ note(format("
                                                         * Random monster 5 - 10 levels out of depth
                                                         * (depending on level)
                                                         */
-                                                       r_idx = get_mon_num(quest[i].level + 5 + randint(quest[i].level / 10));
+                                                       r_idx = get_mon_num(quest[i].level + 5 + randint1(quest[i].level / 10));
                                                        r_ptr = &r_info[r_idx];
 
                                                        if(!(r_ptr->flags1 & RF1_UNIQUE)) continue;
@@ -2549,7 +2533,7 @@ note(format("
                                        rd_s16b(&quest[i].k_idx);
 
                                        if (quest[i].k_idx)
-                                               a_info[quest[i].k_idx].flags3 |= TR3_QUESTITEM;
+                                               a_info[quest[i].k_idx].gen_flags |= TRG_QUESTITEM;
 
                                        rd_byte(&quest[i].flags);
 
@@ -2674,7 +2658,8 @@ if (arg_fiddle) note("
 
        /* Read the extra stuff */
        rd_extra();
-       if (p_ptr->energy > 999) world_player = TRUE;
+       if (p_ptr->energy_need < -999) world_player = TRUE;
+
 #ifdef JP
 if (arg_fiddle) note("ÆÃÊ̾ðÊó¤ò¥í¡¼¥É¤·¤Þ¤·¤¿");
 #else
@@ -2700,7 +2685,7 @@ note(format("
        /* Read the player_hp array */
        for (i = 0; i < tmp16u; i++)
        {
-               rd_s16b(&player_hp[i]);
+               rd_s16b(&p_ptr->player_hp[i]);
        }
 
        /* Important -- Initialize the sex */
@@ -2711,22 +2696,22 @@ note(format("
        cp_ptr = &class_info[p_ptr->pclass];
        ap_ptr = &seikaku_info[p_ptr->pseikaku];
 
-       if(z_older_than(10, 2, 2) && (p_ptr->pclass == CLASS_BEASTMASTER) && !death)
+       if(z_older_than(10, 2, 2) && (p_ptr->pclass == CLASS_BEASTMASTER) && !p_ptr->is_dead)
        {
                p_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
                do_cmd_rerate(FALSE);
        }
-       if(z_older_than(10, 3, 2) && (p_ptr->pclass == CLASS_ARCHER) && !death)
+       if(z_older_than(10, 3, 2) && (p_ptr->pclass == CLASS_ARCHER) && !p_ptr->is_dead)
        {
                p_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
                do_cmd_rerate(FALSE);
        }
-       if(z_older_than(10, 2, 6) && (p_ptr->pclass == CLASS_SORCERER) && !death)
+       if(z_older_than(10, 2, 6) && (p_ptr->pclass == CLASS_SORCERER) && !p_ptr->is_dead)
        {
                p_ptr->hitdie = rp_ptr->r_mhp/2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
                do_cmd_rerate(FALSE);
        }
-       if(z_older_than(10, 4, 7) && (p_ptr->pclass == CLASS_BLUE_MAGE) && !death)
+       if(z_older_than(10, 4, 7) && (p_ptr->pclass == CLASS_BLUE_MAGE) && !p_ptr->is_dead)
        {
                p_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
                do_cmd_rerate(FALSE);
@@ -2737,12 +2722,12 @@ note(format("
 
 
        /* Read spell info */
-       rd_u32b(&spell_learned1);
-       rd_u32b(&spell_learned2);
-       rd_u32b(&spell_worked1);
-       rd_u32b(&spell_worked2);
-       rd_u32b(&spell_forgotten1);
-       rd_u32b(&spell_forgotten2);
+       rd_u32b(&p_ptr->spell_learned1);
+       rd_u32b(&p_ptr->spell_learned2);
+       rd_u32b(&p_ptr->spell_worked1);
+       rd_u32b(&p_ptr->spell_worked2);
+       rd_u32b(&p_ptr->spell_forgotten1);
+       rd_u32b(&p_ptr->spell_forgotten2);
 
        if (z_older_than(10,0,5))
        {
@@ -2751,8 +2736,8 @@ note(format("
                {
                        /* Count known spells */
                        if ((i < 32) ?
-                           (spell_learned1 & (1L << i)) :
-                           (spell_learned2 & (1L << (i - 32))))
+                           (p_ptr->spell_learned1 & (1L << i)) :
+                           (p_ptr->spell_learned2 & (1L << (i - 32))))
                        {
                                p_ptr->learned_spells++;
                        }
@@ -2769,7 +2754,7 @@ note(format("
 
        for (i = 0; i < 64; i++)
        {
-               rd_byte(&spell_order[i]);
+               rd_byte(&p_ptr->spell_order[i]);
        }
 
 
@@ -2843,11 +2828,11 @@ note("
        if (!z_older_than(11, 0, 9))
        {
                char buf[SCREEN_BUF_SIZE];
-               rd_string(buf, SCREEN_BUF_SIZE);
+               rd_string(buf, sizeof(buf));
                if (buf[0]) screen_dump = string_make(buf);
        }
 
-       if (death)
+       if (p_ptr->is_dead)
        {
                for (i = MIN_RANDOM_QUEST; i < MAX_RANDOM_QUEST + 1; i++)
                {
@@ -2857,7 +2842,7 @@ note("
 
 
        /* I'm not dead yet... */
-       if (!death)
+       if (!p_ptr->is_dead)
        {
                /* Dead players have no dungeon */
 #ifdef JP