X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fload.c;h=55c6e21c9d4fb3569011a548e90f4af356abcb93;hb=7c2a13a32a702408f62e58b83056ac9f988302de;hp=7404015f6778398836845e7ed462411940dc9a70;hpb=d3143d0481c18cd87e58c93a843f93dcf42b929e;p=hengband%2Fhengband.git diff --git a/src/load.c b/src/load.c index 7404015f6..55c6e21c9 100644 --- a/src/load.c +++ b/src/load.c @@ -1,5 +1,13 @@ /* File: load.c */ +/* + * Copyright (c) 1997 Ben Harrison, and others + * + * This software may be copied and distributed for educational, research, + * and not for profit purposes provided that this copyright and statement + * are included in all such copies. Other copyrights may also apply. + */ + /* Purpose: support for loading savefiles -BEN- */ #include "angband.h" @@ -65,31 +73,41 @@ static u32b v_check = 0L; */ static u32b x_check = 0L; +/* + * Hack -- Japanese Kanji code + * 0: Unknown + * 1: ASCII + * 2: EUC + * 3: SJIS + */ +static byte kanji_code = 0; - -#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 (sf_patch < z) return (TRUE); - if (sf_patch > z) return (FALSE); + if (h_ver_patch < patch) return (TRUE); + if (h_ver_patch > patch) return (FALSE); + + /* Barely older, or barely more recent */ + 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 @@ -209,8 +227,40 @@ static void rd_string(char *str, int max) /* Terminate */ str[max-1] = '\0'; + + #ifdef JP - codeconv(str); + /* Convert Kanji code */ + switch (kanji_code) + { +#ifdef SJIS + case 2: + /* EUC to SJIS */ + euc2sjis(str); + break; +#endif + +#ifdef EUC + case 3: + /* SJIS to EUC */ + sjis2euc(str); + break; +#endif + + case 0: + { + /* ÉÔÌÀ¤Î´Á»ú¥³¡¼¥É¤«¤é¥·¥¹¥Æ¥à¤Î´Á»ú¥³¡¼¥É¤ËÊÑ´¹ */ + byte code = codeconv(str); + + /* ´Á»ú¥³¡¼¥É¤¬È½ÌÀ¤·¤¿¤é¡¢¤½¤ì¤òµ­Ï¿ */ + if (code) kanji_code = code; + + break; + } + default: + /* No conversion needed */ + break; + } #endif } @@ -229,7 +279,7 @@ static void strip_bytes(int n) #define OLD_MAX_MANE 22 /* - * Read an object + * Read an object (Old method) * * This function attempts to "repair" old savefiles, and to extract * the most up to date values for various object fields. @@ -245,7 +295,7 @@ static void strip_bytes(int n) * a complete hack, items which are inscribed with "uncursed" will be * "uncursed" when imported from pre-2.7.9 savefiles. */ -static void rd_item(object_type *o_ptr) +static void rd_item_old(object_type *o_ptr) { char buf[128]; @@ -292,10 +342,18 @@ static void rd_item(object_type *o_ptr) 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 (h_older_than(1, 3, 0, 0)) + { + if (o_ptr->name2 == EGO_TELEPATHY) + add_flag(o_ptr->art_flags, TR_TELEPATHY); + } if (z_older_than(11, 0, 11)) { @@ -303,22 +361,22 @@ static void rd_item(object_type *o_ptr) if (o_ptr->ident & 0x40) { o_ptr->curse_flags |= TRC_CURSED; - if (o_ptr->art_flags3 & 0x40000000L) o_ptr->curse_flags |= TRC_HEAVY_CURSE; - if (o_ptr->art_flags3 & 0x80000000L) o_ptr->curse_flags |= TRC_PERMA_CURSE; - if (o_ptr->name1) + 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 (object_is_fixed_artifact(o_ptr)) { 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) + else if (object_is_ego(o_ptr)) { 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_flags3 &= (0x1FFFFFFFL); + o_ptr->art_flags[2] &= (0x1FFFFFFFL); } else { @@ -338,12 +396,12 @@ static void rd_item(object_type *o_ptr) { switch (o_ptr->xtra2 % 6) { - case 0: o_ptr->art_flags2 |= (TR2_SUST_STR); break; - case 1: o_ptr->art_flags2 |= (TR2_SUST_INT); break; - case 2: o_ptr->art_flags2 |= (TR2_SUST_WIS); break; - case 3: o_ptr->art_flags2 |= (TR2_SUST_DEX); break; - case 4: o_ptr->art_flags2 |= (TR2_SUST_CON); break; - case 5: o_ptr->art_flags2 |= (TR2_SUST_CHR); break; + 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; } @@ -351,17 +409,17 @@ static void rd_item(object_type *o_ptr) { switch (o_ptr->xtra2 % 11) { - case 0: o_ptr->art_flags2 |= (TR2_RES_BLIND); break; - case 1: o_ptr->art_flags2 |= (TR2_RES_CONF); break; - case 2: o_ptr->art_flags2 |= (TR2_RES_SOUND); break; - case 3: o_ptr->art_flags2 |= (TR2_RES_SHARDS); break; - case 4: o_ptr->art_flags2 |= (TR2_RES_NETHER); break; - case 5: o_ptr->art_flags2 |= (TR2_RES_NEXUS); break; - case 6: o_ptr->art_flags2 |= (TR2_RES_CHAOS); break; - case 7: o_ptr->art_flags2 |= (TR2_RES_DISEN); break; - case 8: o_ptr->art_flags2 |= (TR2_RES_POIS); break; - case 9: o_ptr->art_flags2 |= (TR2_RES_DARK); break; - case 10: o_ptr->art_flags2 |= (TR2_RES_LITE); break; + 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; } @@ -369,14 +427,14 @@ static void rd_item(object_type *o_ptr) { switch (o_ptr->xtra2 % 8) { - case 0: o_ptr->art_flags3 |= (TR3_FEATHER); break; - case 1: o_ptr->art_flags3 |= (TR3_LITE); break; - case 2: o_ptr->art_flags3 |= (TR3_SEE_INVIS); break; - case 3: o_ptr->art_flags3 |= (TR3_WARNING); break; - case 4: o_ptr->art_flags3 |= (TR3_SLOW_DIGEST); break; - case 5: o_ptr->art_flags3 |= (TR3_REGEN); break; - case 6: o_ptr->art_flags2 |= (TR2_FREE_ACT); break; - case 7: o_ptr->art_flags2 |= (TR2_HOLD_LIFE); break; + case 0: add_flag(o_ptr->art_flags, TR_LEVITATION); 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; } @@ -409,6 +467,12 @@ static void rd_item(object_type *o_ptr) else { rd_byte(&o_ptr->xtra3); + if (h_older_than(1, 3, 0, 1)) + { + if (object_is_smith(o_ptr) && o_ptr->xtra3 >= 1+96) + o_ptr->xtra3 += -96 + MIN_SPECIAL_ESSENCE; + } + rd_s16b(&o_ptr->xtra4); rd_s16b(&o_ptr->xtra5); } @@ -419,40 +483,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 */ @@ -470,15 +509,15 @@ static void rd_item(object_type *o_ptr) 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); } } /* Paranoia */ - if (o_ptr->name1) + if (object_is_fixed_artifact(o_ptr)) { artifact_type *a_ptr; @@ -490,7 +529,7 @@ static void rd_item(object_type *o_ptr) } /* Paranoia */ - if (o_ptr->name2) + if (object_is_ego(o_ptr)) { ego_item_type *e_ptr; @@ -504,12 +543,130 @@ static void rd_item(object_type *o_ptr) } +/* + * Read an object (New method) + */ +static void rd_item(object_type *o_ptr) +{ + object_kind *k_ptr; + u32b flags; + char buf[128]; + + if (h_older_than(1, 5, 0, 0)) + { + rd_item_old(o_ptr); + return; + } + + /*** Item save flags ***/ + rd_u32b(&flags); + + /*** Read un-obvious elements ***/ + /* Kind */ + rd_s16b(&o_ptr->k_idx); + + /* Location */ + rd_byte(&o_ptr->iy); + rd_byte(&o_ptr->ix); + + /* Type/Subtype */ + k_ptr = &k_info[o_ptr->k_idx]; + o_ptr->tval = k_ptr->tval; + o_ptr->sval = k_ptr->sval; + + /* Special pval */ + if (flags & SAVE_ITEM_PVAL) rd_s16b(&o_ptr->pval); + else o_ptr->pval = 0; + + if (flags & SAVE_ITEM_DISCOUNT) rd_byte(&o_ptr->discount); + else o_ptr->discount = 0; + if (flags & SAVE_ITEM_NUMBER) rd_byte(&o_ptr->number); + else o_ptr->number = 1; + + rd_s16b(&o_ptr->weight); + + if (flags & SAVE_ITEM_NAME1) rd_byte(&o_ptr->name1); + else o_ptr->name1 = 0; + if (flags & SAVE_ITEM_NAME2) rd_byte(&o_ptr->name2); + else o_ptr->name2 = 0; + if (flags & SAVE_ITEM_TIMEOUT) rd_s16b(&o_ptr->timeout); + else o_ptr->timeout = 0; + + if (flags & SAVE_ITEM_TO_H) rd_s16b(&o_ptr->to_h); + else o_ptr->to_h = 0; + if (flags & SAVE_ITEM_TO_D) rd_s16b(&o_ptr->to_d); + else o_ptr->to_d = 0; + if (flags & SAVE_ITEM_TO_A) rd_s16b(&o_ptr->to_a); + else o_ptr->to_a = 0; + + if (flags & SAVE_ITEM_AC) rd_s16b(&o_ptr->ac); + else o_ptr->ac = 0; + + if (flags & SAVE_ITEM_DD) rd_byte(&o_ptr->dd); + else o_ptr->dd = 0; + if (flags & SAVE_ITEM_DS) rd_byte(&o_ptr->ds); + else o_ptr->ds = 0; + + if (flags & SAVE_ITEM_IDENT) rd_byte(&o_ptr->ident); + else o_ptr->ident = 0; + + if (flags & SAVE_ITEM_MARKED) rd_byte(&o_ptr->marked); + else o_ptr->marked = 0; + + /* Object flags */ + if (flags & SAVE_ITEM_ART_FLAGS0) rd_u32b(&o_ptr->art_flags[0]); + else o_ptr->art_flags[0] = 0; + if (flags & SAVE_ITEM_ART_FLAGS1) rd_u32b(&o_ptr->art_flags[1]); + else o_ptr->art_flags[1] = 0; + if (flags & SAVE_ITEM_ART_FLAGS2) rd_u32b(&o_ptr->art_flags[2]); + else o_ptr->art_flags[2] = 0; + if (flags & SAVE_ITEM_ART_FLAGS3) rd_u32b(&o_ptr->art_flags[3]); + else o_ptr->art_flags[3] = 0; + + if (flags & SAVE_ITEM_CURSE_FLAGS) rd_u32b(&o_ptr->curse_flags); + else o_ptr->curse_flags = 0; + + /* Monster holding object */ + if (flags & SAVE_ITEM_HELD_M_IDX) rd_s16b(&o_ptr->held_m_idx); + else o_ptr->held_m_idx = 0; + + /* Special powers */ + if (flags & SAVE_ITEM_XTRA1) rd_byte(&o_ptr->xtra1); + else o_ptr->xtra1 = 0; + if (flags & SAVE_ITEM_XTRA2) rd_byte(&o_ptr->xtra2); + else o_ptr->xtra2 = 0; + + if (flags & SAVE_ITEM_XTRA3) rd_byte(&o_ptr->xtra3); + else o_ptr->xtra3 = 0; + + if (flags & SAVE_ITEM_XTRA4) rd_s16b(&o_ptr->xtra4); + else o_ptr->xtra4 = 0; + if (flags & SAVE_ITEM_XTRA5) rd_s16b(&o_ptr->xtra5); + else o_ptr->xtra5 = 0; + + if (flags & SAVE_ITEM_FEELING) rd_byte(&o_ptr->feeling); + else o_ptr->feeling = 0; + + if (flags & SAVE_ITEM_INSCRIPTION) + { + rd_string(buf, sizeof(buf)); + o_ptr->inscription = quark_add(buf); + } + else o_ptr->inscription = 0; + + if (flags & SAVE_ITEM_ART_NAME) + { + rd_string(buf, sizeof(buf)); + o_ptr->art_name = quark_add(buf); + } + else o_ptr->art_name = 0; +} /* - * Read a monster + * Read a monster (Old method) */ -static void rd_monster(monster_type *m_ptr) +static void rd_monster_old(monster_type *m_ptr) { byte tmp8u; char buf[128]; @@ -546,7 +703,7 @@ static void rd_monster(monster_type *m_ptr) { rd_s16b(&m_ptr->max_maxhp); } - rd_s16b(&m_ptr->csleep); + rd_s16b(&m_ptr->mtimed[MTIMED_CSLEEP]); rd_byte(&m_ptr->mspeed); if (z_older_than(10, 4, 2)) { @@ -560,17 +717,22 @@ static void rd_monster(monster_type *m_ptr) if (z_older_than(10,0,7)) { - m_ptr->fast = 0; - m_ptr->slow = 0; + m_ptr->mtimed[MTIMED_FAST] = 0; + m_ptr->mtimed[MTIMED_SLOW] = 0; } else { - rd_byte(&m_ptr->fast); - rd_byte(&m_ptr->slow); + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_FAST] = (s16b)tmp8u; + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_SLOW] = (s16b)tmp8u; } - rd_byte(&m_ptr->stunned); - rd_byte(&m_ptr->confused); - rd_byte(&m_ptr->monfear); + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_STUNNED] = (s16b)tmp8u; + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_CONFUSED] = (s16b)tmp8u; + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_MONFEAR] = (s16b)tmp8u; if (z_older_than(10,0,10)) { @@ -588,11 +750,8 @@ 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(&tmp8u); + m_ptr->mtimed[MTIMED_INVULNER] = (s16b)tmp8u; if (!(z_major == 2 && z_minor == 0 && z_patch == 6)) rd_u32b(&m_ptr->smart); @@ -609,7 +768,7 @@ static void rd_monster(monster_type *m_ptr) if (m_ptr->r_idx < 0) { m_ptr->r_idx = (0-m_ptr->r_idx); - m_ptr->mflag2 |= MFLAG_KAGE; + m_ptr->mflag2 |= MFLAG2_KAGE; } } else @@ -619,7 +778,7 @@ static void rd_monster(monster_type *m_ptr) if (z_older_than(11, 0, 12)) { - if (m_ptr->mflag2 & MFLAG_KAGE) + if (m_ptr->mflag2 & MFLAG2_KAGE) m_ptr->ap_r_idx = MON_KAGE; } @@ -629,7 +788,7 @@ static void rd_monster(monster_type *m_ptr) } else { - rd_string(buf, 128); + rd_string(buf, sizeof(buf)); if (buf[0]) m_ptr->nickname = quark_add(buf); } @@ -637,9 +796,159 @@ static void rd_monster(monster_type *m_ptr) } +/* + * Read a monster (New method) + */ +static void rd_monster(monster_type *m_ptr) +{ + u32b flags; + char buf[128]; + byte tmp8u; + + if (h_older_than(1, 5, 0, 0)) + { + rd_monster_old(m_ptr); + return; + } + + /*** Monster save flags ***/ + rd_u32b(&flags); + + /*** Read un-obvious elements ***/ + + /* Read the monster race */ + rd_s16b(&m_ptr->r_idx); + + /* Read the other information */ + rd_byte(&m_ptr->fy); + rd_byte(&m_ptr->fx); + rd_s16b(&m_ptr->hp); + rd_s16b(&m_ptr->maxhp); + rd_s16b(&m_ptr->max_maxhp); + + /* Monster race index of its appearance */ + if (flags & SAVE_MON_AP_R_IDX) rd_s16b(&m_ptr->ap_r_idx); + else m_ptr->ap_r_idx = m_ptr->r_idx; + + if (flags & SAVE_MON_SUB_ALIGN) rd_byte(&m_ptr->sub_align); + else m_ptr->sub_align = 0; + + if (flags & SAVE_MON_CSLEEP) rd_s16b(&m_ptr->mtimed[MTIMED_CSLEEP]); + else m_ptr->mtimed[MTIMED_CSLEEP] = 0; + + rd_byte(&m_ptr->mspeed); + + rd_s16b(&m_ptr->energy_need); + + if (flags & SAVE_MON_FAST) + { + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_FAST] = (s16b)tmp8u; + } + else m_ptr->mtimed[MTIMED_FAST] = 0; + if (flags & SAVE_MON_SLOW) + { + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_SLOW] = (s16b)tmp8u; + } + else m_ptr->mtimed[MTIMED_SLOW] = 0; + if (flags & SAVE_MON_STUNNED) + { + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_STUNNED] = (s16b)tmp8u; + } + else m_ptr->mtimed[MTIMED_STUNNED] = 0; + if (flags & SAVE_MON_CONFUSED) + { + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_CONFUSED] = (s16b)tmp8u; + } + else m_ptr->mtimed[MTIMED_CONFUSED] = 0; + if (flags & SAVE_MON_MONFEAR) + { + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_MONFEAR] = (s16b)tmp8u; + } + else m_ptr->mtimed[MTIMED_MONFEAR] = 0; + + if (flags & SAVE_MON_TARGET_Y) rd_s16b(&m_ptr->target_y); + else m_ptr->target_y = 0; + if (flags & SAVE_MON_TARGET_X) rd_s16b(&m_ptr->target_x); + else m_ptr->target_x = 0; + + if (flags & SAVE_MON_INVULNER) + { + rd_byte(&tmp8u); + m_ptr->mtimed[MTIMED_INVULNER] = (s16b)tmp8u; + } + else m_ptr->mtimed[MTIMED_INVULNER] = 0; + + if (flags & SAVE_MON_SMART) rd_u32b(&m_ptr->smart); + else m_ptr->smart = 0; + + if (flags & SAVE_MON_EXP) rd_u32b(&m_ptr->exp); + else m_ptr->exp = 0; + + m_ptr->mflag = 0; /* Not saved */ + + if (flags & SAVE_MON_MFLAG2) rd_byte(&m_ptr->mflag2); + else m_ptr->mflag2 = 0; + + if (flags & SAVE_MON_NICKNAME) + { + rd_string(buf, sizeof(buf)); + m_ptr->nickname = quark_add(buf); + } + else m_ptr->nickname = 0; + + if (flags & SAVE_MON_PARENT) rd_s16b(&m_ptr->parent_m_idx); + else m_ptr->parent_m_idx = 0; +} + +/* + * Old monster bit flags of racial resistances + */ +#define RF3_IM_ACID 0x00010000 /* Resist acid a lot */ +#define RF3_IM_ELEC 0x00020000 /* Resist elec a lot */ +#define RF3_IM_FIRE 0x00040000 /* Resist fire a lot */ +#define RF3_IM_COLD 0x00080000 /* Resist cold a lot */ +#define RF3_IM_POIS 0x00100000 /* Resist poison a lot */ +#define RF3_RES_TELE 0x00200000 /* Resist teleportation */ +#define RF3_RES_NETH 0x00400000 /* Resist nether a lot */ +#define RF3_RES_WATE 0x00800000 /* Resist water */ +#define RF3_RES_PLAS 0x01000000 /* Resist plasma */ +#define RF3_RES_NEXU 0x02000000 /* Resist nexus */ +#define RF3_RES_DISE 0x04000000 /* Resist disenchantment */ +#define RF3_RES_ALL 0x08000000 /* Resist all */ + +#define MOVE_RF3_TO_RFR(R_PTR,RF3,RFR) \ +{\ + if ((R_PTR)->r_flags3 & (RF3)) \ + { \ + (R_PTR)->r_flags3 &= ~(RF3); \ + (R_PTR)->r_flagsr |= (RFR); \ + } \ +} +#define RF4_BR_TO_RFR(R_PTR,RF4_BR,RFR) \ +{\ + if ((R_PTR)->r_flags4 & (RF4_BR)) \ + { \ + (R_PTR)->r_flagsr |= (RFR); \ + } \ +} +#define RF4_BR_LITE 0x00004000 /* Breathe Lite */ +#define RF4_BR_DARK 0x00008000 /* Breathe Dark */ +#define RF4_BR_CONF 0x00010000 /* Breathe Confusion */ +#define RF4_BR_SOUN 0x00020000 /* Breathe Sound */ +#define RF4_BR_CHAO 0x00040000 /* Breathe Chaos */ +#define RF4_BR_TIME 0x00200000 /* Breathe Time */ +#define RF4_BR_INER 0x00400000 /* Breathe Inertia */ +#define RF4_BR_GRAV 0x00800000 /* Breathe Gravity */ +#define RF4_BR_SHAR 0x01000000 /* Breathe Shards */ +#define RF4_BR_WALL 0x04000000 /* Breathe Force */ /* * Read the monster lore */ @@ -653,6 +962,14 @@ static void rd_lore(int r_idx) rd_s16b(&r_ptr->r_sights); rd_s16b(&r_ptr->r_deaths); rd_s16b(&r_ptr->r_pkills); + if (h_older_than(1, 7, 0, 5)) + { + r_ptr->r_akills = r_ptr->r_pkills; + } + else + { + rd_s16b(&r_ptr->r_akills); + } rd_s16b(&r_ptr->r_tkills); /* Count wakes and ignores */ @@ -668,7 +985,7 @@ static void rd_lore(int r_idx) rd_byte(&r_ptr->r_drop_item); /* Count spells */ - rd_byte(&r_ptr->r_cast_inate); + rd_byte(&tmp8u); rd_byte(&r_ptr->r_cast_spell); /* Count blows of each type */ @@ -684,14 +1001,55 @@ static void rd_lore(int r_idx) rd_u32b(&r_ptr->r_flags4); rd_u32b(&r_ptr->r_flags5); rd_u32b(&r_ptr->r_flags6); + if (h_older_than(1, 5, 0, 3)) + { + r_ptr->r_flagsr = 0L; + + /* Move RF3 resistance flags to RFR */ + MOVE_RF3_TO_RFR(r_ptr, RF3_IM_ACID, RFR_IM_ACID); + MOVE_RF3_TO_RFR(r_ptr, RF3_IM_ELEC, RFR_IM_ELEC); + MOVE_RF3_TO_RFR(r_ptr, RF3_IM_FIRE, RFR_IM_FIRE); + MOVE_RF3_TO_RFR(r_ptr, RF3_IM_COLD, RFR_IM_COLD); + MOVE_RF3_TO_RFR(r_ptr, RF3_IM_POIS, RFR_IM_POIS); + MOVE_RF3_TO_RFR(r_ptr, RF3_RES_TELE, RFR_RES_TELE); + MOVE_RF3_TO_RFR(r_ptr, RF3_RES_NETH, RFR_RES_NETH); + MOVE_RF3_TO_RFR(r_ptr, RF3_RES_WATE, RFR_RES_WATE); + MOVE_RF3_TO_RFR(r_ptr, RF3_RES_PLAS, RFR_RES_PLAS); + MOVE_RF3_TO_RFR(r_ptr, RF3_RES_NEXU, RFR_RES_NEXU); + MOVE_RF3_TO_RFR(r_ptr, RF3_RES_DISE, RFR_RES_DISE); + MOVE_RF3_TO_RFR(r_ptr, RF3_RES_ALL, RFR_RES_ALL); + + /* Separate breathers resistance from RF4 to RFR */ + RF4_BR_TO_RFR(r_ptr, RF4_BR_LITE, RFR_RES_LITE); + RF4_BR_TO_RFR(r_ptr, RF4_BR_DARK, RFR_RES_DARK); + RF4_BR_TO_RFR(r_ptr, RF4_BR_SOUN, RFR_RES_SOUN); + RF4_BR_TO_RFR(r_ptr, RF4_BR_CHAO, RFR_RES_CHAO); + RF4_BR_TO_RFR(r_ptr, RF4_BR_TIME, RFR_RES_TIME); + RF4_BR_TO_RFR(r_ptr, RF4_BR_INER, RFR_RES_INER); + RF4_BR_TO_RFR(r_ptr, RF4_BR_GRAV, RFR_RES_GRAV); + RF4_BR_TO_RFR(r_ptr, RF4_BR_SHAR, RFR_RES_SHAR); + RF4_BR_TO_RFR(r_ptr, RF4_BR_WALL, RFR_RES_WALL); + + /* Resist confusion is merged to RF3_NO_CONF */ + if (r_ptr->r_flags4 & RF4_BR_CONF) r_ptr->r_flags3 |= RF3_NO_CONF; + + /* Misc resistance hack to RFR */ + if (r_idx == MON_STORMBRINGER) r_ptr->r_flagsr |= RFR_RES_CHAO; + if (r_ptr->r_flags3 & RF3_ORC) r_ptr->r_flagsr |= RFR_RES_DARK; + } + else + { + rd_u32b(&r_ptr->r_flagsr); + } /* Read the "Racial" monster limit per level */ rd_byte(&r_ptr->max_num); + /* Location in saved floor */ + rd_s16b(&r_ptr->floor_id); + /* Later (?) */ rd_byte(&tmp8u); - rd_byte(&tmp8u); - rd_byte(&tmp8u); /* Repair the lore flags */ r_ptr->r_flags1 &= r_ptr->flags1; @@ -700,6 +1058,7 @@ static void rd_lore(int r_idx) r_ptr->r_flags4 &= r_ptr->flags4; r_ptr->r_flags5 &= r_ptr->flags5; r_ptr->r_flags6 &= r_ptr->flags6; + r_ptr->r_flagsr &= r_ptr->flagsr; } @@ -718,7 +1077,7 @@ static void rd_lore(int r_idx) static void home_carry(store_type *st_ptr, object_type *o_ptr) { int slot; - s32b value, j_value; + s32b value; int i; object_type *j_ptr; @@ -751,45 +1110,7 @@ static void home_carry(store_type *st_ptr, object_type *o_ptr) /* Check existing slots to see if we must "slide" */ for (slot = 0; slot < st_ptr->stock_num; slot++) { - /* Get that item */ - j_ptr = &st_ptr->stock[slot]; - - /* Hack -- readable books always come first */ - if ((o_ptr->tval == mp_ptr->spell_book) && - (j_ptr->tval != mp_ptr->spell_book)) break; - if ((j_ptr->tval == mp_ptr->spell_book) && - (o_ptr->tval != mp_ptr->spell_book)) continue; - - /* Objects sort by decreasing type */ - if (o_ptr->tval > j_ptr->tval) break; - if (o_ptr->tval < j_ptr->tval) continue; - - /* Can happen in the home */ - if (!object_aware_p(o_ptr)) continue; - if (!object_aware_p(j_ptr)) break; - - /* Objects sort by increasing sval */ - if (o_ptr->sval < j_ptr->sval) break; - if (o_ptr->sval > j_ptr->sval) continue; - - /* Objects in the home can be unknown */ - if (!object_known_p(o_ptr)) continue; - if (!object_known_p(j_ptr)) break; - - /* - * Hack: otherwise identical rods sort by - * increasing recharge time --dsb - */ - if (o_ptr->tval == TV_ROD) - { - if (o_ptr->pval < j_ptr->pval) break; - if (o_ptr->pval > j_ptr->pval) continue; - } - - /* Objects sort by decreasing value */ - j_value = object_value(j_ptr); - if (value > j_value) break; - if (value < j_value) continue; + if (object_sort_comp(o_ptr, value, &st_ptr->stock[slot])) break; } /* Slide the others up */ @@ -964,12 +1285,23 @@ static void rd_options(void) rd_byte(&b); hitpoint_warn = b; + /* Read "mana_warn" */ + if(h_older_than(1, 7, 0, 0)) + { + mana_warn=2; + } + else + { + rd_byte(&b); + mana_warn = b; + } + /*** Cheating options ***/ 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; @@ -977,6 +1309,7 @@ static void rd_options(void) cheat_xtra = (c & 0x0800) ? TRUE : FALSE; cheat_know = (c & 0x1000) ? TRUE : FALSE; cheat_live = (c & 0x2000) ? TRUE : FALSE; + cheat_save = (c & 0x4000) ? TRUE : FALSE; rd_byte((byte *)&autosave_l); rd_byte((byte *)&autosave_t); @@ -1043,6 +1376,9 @@ static void rd_options(void) else option_flag[5] |= (0x00000001 << 3); } + /* Extract the options */ + extract_option_vars(); + /*** Window Options ***/ @@ -1097,7 +1433,7 @@ 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); @@ -1107,7 +1443,7 @@ static void rd_ghost(void) /* * Save quick start data */ -void load_quick_start() +static void load_quick_start(void) { byte tmp8u; int i; @@ -1140,9 +1476,10 @@ void load_quick_start() 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], 60); + for (i = 0; i < 4; i++) rd_string(previous_char.history[i], sizeof(previous_char.history[i])); - rd_byte(&previous_char.quests); + /* UNUSED : Was number of random quests */ + rd_byte(&tmp8u); rd_byte(&tmp8u); previous_char.quick_ok = (bool)tmp8u; @@ -1157,16 +1494,26 @@ static void rd_extra(void) byte tmp8u; s16b tmp16s; + u16b tmp16u; + + rd_string(player_name, sizeof(player_name)); - rd_string(player_name, 32); + rd_string(p_ptr->died_from, sizeof(p_ptr->died_from)); - rd_string(died_from, 80); + if (!h_older_than(1, 7, 0, 1)) + { + char buf[1024]; + + /* Read the message */ + rd_string(buf, sizeof buf); + if (buf[0]) p_ptr->last_message = string_make(buf); + } 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 */ @@ -1205,25 +1552,36 @@ static void rd_extra(void) rd_s32b(&p_ptr->au); rd_s32b(&p_ptr->max_exp); + if (h_older_than(1, 5, 4, 1)) p_ptr->max_max_exp = p_ptr->max_exp; + else rd_s32b(&p_ptr->max_max_exp); rd_s32b(&p_ptr->exp); - rd_u16b(&p_ptr->exp_frac); + + if (h_older_than(1, 7, 0, 3)) + { + rd_u16b(&tmp16u); + p_ptr->exp_frac = (u32b)tmp16u; + } + else + { + rd_u32b(&p_ptr->exp_frac); + } 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] = SPELL_EXP_MASTER; } 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)) { @@ -1234,8 +1592,18 @@ 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; + if (music_singing_any()) p_ptr->action = ACTION_SING; if (z_older_than(11, 0, 7)) { @@ -1256,10 +1624,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)) { @@ -1270,64 +1638,30 @@ 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)) { - get_mon_num_prep(NULL, NULL); - for (i = 0; i < MAX_KUBI; i++) - { - monster_race *r_ptr; - while (1) - { - int j; - - kubi_r_idx[i] = get_mon_num(MAX_DEPTH - 1); - r_ptr = &r_info[kubi_r_idx[i]]; - - if(!(r_ptr->flags1 & RF1_UNIQUE)) continue; - - if(!(r_ptr->flags9 & RF9_DROP_CORPSE)) continue; + determine_bounty_uniques(); - if(r_ptr->flags6 & RF6_SPECIAL) continue; - - for (j = 0; j < i; j++) - if (kubi_r_idx[i] == kubi_r_idx[j])break; - - if (j == i) break; - } - } - for (i = 0; i < MAX_KUBI -1; i++) - { - int j,tmp; - for (j = i; j < MAX_KUBI; j++) - { - if (r_info[kubi_r_idx[i]].level > r_info[kubi_r_idx[j]].level) - { - tmp = kubi_r_idx[i]; - kubi_r_idx[i] = kubi_r_idx[j]; - kubi_r_idx[j] = tmp; - } - } - } for (i = 0; i < MAX_KUBI; i++) { - if(!r_info[kubi_r_idx[i]].max_num) - kubi_r_idx[i] += 10000; + /* Is this bounty unique already dead? */ + if (!r_info[kubi_r_idx[i]].max_num) kubi_r_idx[i] += 10000; } } else @@ -1360,6 +1694,11 @@ static void rd_extra(void) /* Read arena and rewards information */ rd_s16b(&p_ptr->arena_number); + if (h_older_than(1, 5, 0, 1)) + { + /* Arena loser of previous version was marked number 99 */ + if (p_ptr->arena_number >= 99) p_ptr->arena_number = ARENA_DEFEATED_OLD_VER; + } rd_s16b(&tmp16s); p_ptr->inside_arena = (bool)tmp16s; rd_s16b(&p_ptr->inside_quest); @@ -1370,33 +1709,55 @@ static void rd_extra(void) p_ptr->inside_battle = (bool)tmp16s; } rd_byte(&p_ptr->exit_bldg); - rd_byte(&p_ptr->leftbldg); + rd_byte(&tmp8u); rd_s16b(&p_ptr->oldpx); rd_s16b(&p_ptr->oldpy); if (z_older_than(10, 3, 13) && !dun_level && !p_ptr->inside_arena) {p_ptr->oldpy = 33;p_ptr->oldpx = 131;} + /* Was p_ptr->rewards[MAX_BACT] */ rd_s16b(&tmp16s); + for (i = 0; i < tmp16s; i++) + { + s16b tmp16s2; + rd_s16b(&tmp16s2); + } - if (tmp16s > MAX_BACT) + if (h_older_than(1, 7, 0, 3)) { -#ifdef JP -note(format("¤ÎÃæ", tmp16s)); -#else - note(format("Too many (%d) building rewards!", tmp16s)); -#endif + rd_s16b(&tmp16s); + p_ptr->mhp = tmp16s; + + rd_s16b(&tmp16s); + p_ptr->chp = tmp16s; + rd_u16b(&tmp16u); + p_ptr->chp_frac = (u32b)tmp16u; + } + else + { + rd_s32b(&p_ptr->mhp); + rd_s32b(&p_ptr->chp); + rd_u32b(&p_ptr->chp_frac); } - for (i = 0; i < tmp16s; i++) rd_s16b(&p_ptr->rewards[i]); + if (h_older_than(1, 7, 0, 3)) + { + rd_s16b(&tmp16s); + p_ptr->msp = tmp16s; - rd_s16b(&p_ptr->mhp); - rd_s16b(&p_ptr->chp); - rd_u16b(&p_ptr->chp_frac); + rd_s16b(&tmp16s); + p_ptr->csp = tmp16s; - rd_s16b(&p_ptr->msp); - rd_s16b(&p_ptr->csp); - rd_u16b(&p_ptr->csp_frac); + rd_u16b(&tmp16u); + p_ptr->csp_frac = (u32b)tmp16u; + } + else + { + rd_s32b(&p_ptr->msp); + rd_s32b(&p_ptr->csp); + rd_u32b(&p_ptr->csp_frac); + } rd_s16b(&p_ptr->max_plv); if (z_older_than(10, 3, 8)) @@ -1405,16 +1766,16 @@ note(format(" } else { - byte max = (byte)max_d_idx; + byte max = (byte)max_d_idx; - rd_byte(&max); + rd_byte(&max); - for(i = 0; i < max; i++) + for(i = 0; i < max; i++) { - rd_s16b(&max_dlv[i]); + rd_s16b(&max_dlv[i]); if (max_dlv[i] > d_info[i].maxdepth) max_dlv[i] = d_info[i].maxdepth; } - } + } /* Repair maximum player level XXX XXX XXX */ if (p_ptr->max_plv < p_ptr->lev) p_ptr->max_plv = p_ptr->lev; @@ -1422,7 +1783,7 @@ note(format(" /* More info */ strip_bytes(8); rd_s16b(&p_ptr->sc); - strip_bytes(2); + rd_s16b(&p_ptr->concent); /* Read the flags */ strip_bytes(2); /* Old "rest" */ @@ -1435,6 +1796,10 @@ note(format(" rd_s16b(&p_ptr->energy_need); if (z_older_than(11, 0, 13)) p_ptr->energy_need = 100 - p_ptr->energy_need; + if (z_older_than(12, 1, 3)) + p_ptr->enchant_energy_need = 0; + else + rd_s16b(&p_ptr->enchant_energy_need); rd_s16b(&p_ptr->fast); rd_s16b(&p_ptr->slow); @@ -1462,6 +1827,12 @@ note(format(" rd_s16b(&tmp16s); p_ptr->recall_dungeon = (byte)tmp16s; } + + if (h_older_than(1, 5, 0, 0)) + p_ptr->alter_reality = 0; + else + rd_s16b(&p_ptr->alter_reality); + rd_s16b(&p_ptr->see_infra); rd_s16b(&p_ptr->tim_infra); rd_s16b(&p_ptr->oppose_fire); @@ -1481,7 +1852,7 @@ note(format(" p_ptr->tim_regen = 0; p_ptr->kabenuke = 0; p_ptr->tim_stealth = 0; - p_ptr->tim_ffall = 0; + p_ptr->tim_levitation = 0; p_ptr->tim_sh_touki = 0; p_ptr->lightspeed = 0; p_ptr->tsubureru = 0; @@ -1496,7 +1867,7 @@ note(format(" p_ptr->multishadow = 0; p_ptr->dustrobe = 0; - p_ptr->chaos_patron = get_chaos_patron(); + p_ptr->chaos_patron = ((p_ptr->age + p_ptr->sc) % MAX_PATRON); p_ptr->muta1 = 0; p_ptr->muta2 = 0; p_ptr->muta3 = 0; @@ -1510,7 +1881,7 @@ note(format(" rd_s16b(&p_ptr->tim_regen); rd_s16b(&p_ptr->kabenuke); rd_s16b(&p_ptr->tim_stealth); - rd_s16b(&p_ptr->tim_ffall); + rd_s16b(&p_ptr->tim_levitation); rd_s16b(&p_ptr->tim_sh_touki); rd_s16b(&p_ptr->lightspeed); rd_s16b(&p_ptr->tsubureru); @@ -1534,6 +1905,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; @@ -1584,7 +1966,10 @@ note(format(" rd_u32b(&p_ptr->special_defense); } rd_byte(&p_ptr->knowledge); - rd_byte(&tmp8u); /* oops */ + + rd_byte(&tmp8u); + p_ptr->autopick_autoregister = tmp8u ? TRUE : FALSE; + rd_byte(&tmp8u); /* oops */ rd_byte(&p_ptr->action); if (!z_older_than(10, 4, 3)) @@ -1593,7 +1978,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); @@ -1608,24 +1993,47 @@ 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); - feeling = tmp8u; + rd_byte(&p_ptr->feeling); + + switch (p_ptr->start_race) + { + case RACE_VAMPIRE: + case RACE_SKELETON: + case RACE_ZOMBIE: + case RACE_SPECTRE: + turn_limit = TURNS_PER_TICK * TOWN_DAWN * MAX_DAYS + TURNS_PER_TICK * TOWN_DAWN * 3 / 4; + break; + default: + turn_limit = TURNS_PER_TICK * TOWN_DAWN * (MAX_DAYS - 1) + TURNS_PER_TICK * TOWN_DAWN * 3 / 4; + break; + } + dungeon_turn_limit = TURNS_PER_TICK * TOWN_DAWN * (MAX_DAYS - 1) + TURNS_PER_TICK * TOWN_DAWN * 3 / 4; - /* Turn of last "feeling" */ + /* Turn when level began */ rd_s32b(&old_turn); - /* Current turn */ - rd_s32b(&turn); + if (h_older_than(1, 7, 0, 4)) + { + p_ptr->feeling_turn = old_turn; + } + else + { + /* Turn of last "feeling" */ + rd_s32b(&p_ptr->feeling_turn); + } + + /* Current turn */ + rd_s32b(&turn); if (z_older_than(10, 3, 12)) { @@ -1636,6 +2044,7 @@ note(format(" if (z_older_than(11, 0, 13)) { old_turn /= 2; + p_ptr->feeling_turn /= 2; turn /= 2; dungeon_turn /= 2; } @@ -1648,23 +2057,7 @@ note(format(" if (z_older_than(10,0,3)) { - monster_race *r_ptr; - - while (1) - { - today_mon = get_mon_num(MAX(max_dlv[DUNGEON_ANGBAND], 3)); - r_ptr = &r_info[today_mon]; - - if (r_ptr->flags1 & RF1_UNIQUE) continue; - if (r_ptr->flags2 & (RF2_MULTIPLY)) continue; - if (!(r_ptr->flags9 & RF9_DROP_CORPSE) || !(r_ptr->flags9 & RF9_DROP_SKELETON)) continue; - if (r_ptr->level < MIN(max_dlv[DUNGEON_ANGBAND], 40)) continue; - if (r_ptr->rarity > 10) continue; - if (r_ptr->level == 0) continue; - break; - } - - p_ptr->today_mon = 0; + determine_today_mon(TRUE); } else { @@ -1681,6 +2074,34 @@ note(format(" rd_s16b(&p_ptr->riding); } + /* Current floor_id */ + if (h_older_than(1, 5, 0, 0)) + { + p_ptr->floor_id = 0; + } + else + { + rd_s16b(&p_ptr->floor_id); + } + + if (h_older_than(1, 5, 0, 2)) + { + /* Nothing to do */ + } + else + { + /* Get number of party_mon array */ + rd_s16b(&tmp16s); + + /* Strip old temporary preserved pets */ + for (i = 0; i < tmp16s; i++) + { + monster_type dummy_mon; + + rd_monster(&dummy_mon); + } + } + if (z_older_than(10,1,2)) { playtime = 0; @@ -1764,6 +2185,9 @@ static errr rd_inventory(void) /* Wield equipment */ if (n >= INVEN_RARM) { + /* Player touches it */ + q_ptr->marked |= OM_TOUCHED; + /* Copy object */ object_copy(&inventory[n], q_ptr); @@ -1795,6 +2219,9 @@ note(" /* Get a slot */ n = slot++; + /* Player touches it */ + q_ptr->marked |= OM_TOUCHED; + /* Copy object */ object_copy(&inventory[n], q_ptr); @@ -1829,7 +2256,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); @@ -1838,13 +2265,32 @@ static void rd_messages(void) +/* Old hidden trap flag */ +#define CAVE_TRAP 0x8000 + +/*** Terrain Feature Indexes (see "lib/edit/f_info.txt") ***/ +#define OLD_FEAT_INVIS 0x02 +#define OLD_FEAT_GLYPH 0x03 +#define OLD_FEAT_QUEST_ENTER 0x08 +#define OLD_FEAT_QUEST_EXIT 0x09 +#define OLD_FEAT_MINOR_GLYPH 0x40 +#define OLD_FEAT_BLDG_1 0x81 +#define OLD_FEAT_MIRROR 0xc3 + +/* Old quests */ +#define OLD_QUEST_WATER_CAVE 18 + +/* Quest constants */ +#define QUEST_OLD_CASTLE 27 +#define QUEST_ROYAL_CRYPT 28 + /* - * Read the dungeon + * Read the dungeon (old method) * * The monsters/objects must be loaded in the same order * that they were stored, since the actual indexes matter. */ -static errr rd_dungeon(void) +static errr rd_dungeon_old(void) { int i, y, x; int ymax, xmax; @@ -1859,7 +2305,7 @@ static errr rd_dungeon(void) /* Header info */ rd_s16b(&dun_level); - if (z_older_than(10, 3, 8)) dungeon_type = DUNGEON_ANGBAND; + if (z_older_than(10, 3, 8)) dungeon_type = DUNGEON_ANGBAND; else rd_byte(&dungeon_type); /* Set the base level for old versions */ @@ -1892,12 +2338,22 @@ static errr rd_dungeon(void) /* Load the dungeon data */ for (x = y = 0; y < ymax; ) { + u16b info; + /* Grab RLE info */ rd_byte(&count); if (z_older_than(10,3,6)) + { rd_byte(&tmp8u); + info = (u16b)tmp8u; + } else - rd_s16b(&tmp16s); + { + rd_u16b(&info); + + /* Decline invalid flags */ + info &= ~(CAVE_LITE | CAVE_VIEW | CAVE_MNLT | CAVE_MNDK); + } /* Apply the RLE info */ for (i = count; i > 0; i--) @@ -1906,9 +2362,7 @@ static errr rd_dungeon(void) c_ptr = &cave[y][x]; /* Extract "info" */ - if (z_older_than(10,3,6)) - c_ptr->info = tmp8u; - else c_ptr->info = tmp16s; + c_ptr->info = info; /* Advance/Wrap */ if (++x >= xmax) @@ -1938,14 +2392,8 @@ 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; + c_ptr->feat = (s16b)tmp8u; /* Advance/Wrap */ if (++x >= xmax) @@ -1974,8 +2422,8 @@ static errr rd_dungeon(void) /* Access the cave */ c_ptr = &cave[y][x]; - /* Extract "feat" */ - c_ptr->mimic = tmp8u; + /* Extract "mimic" */ + c_ptr->mimic = (s16b)tmp8u; /* Advance/Wrap */ if (++x >= xmax) @@ -2019,13 +2467,114 @@ 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 == OLD_FEAT_INVIS) + { + c_ptr->feat = feat_floor; + c_ptr->info |= CAVE_TRAP; + } + + /* Older than 1.1.1 */ + if (c_ptr->feat == OLD_FEAT_MIRROR) + { + c_ptr->feat = feat_floor; + c_ptr->info |= CAVE_OBJECT; + } + } + } + + if (h_older_than(1, 3, 1, 0)) + { + for (y = 0; y < ymax; y++) for (x = 0; x < xmax; x++) + { + /* Access the cave */ + c_ptr = &cave[y][x]; + + /* Old CAVE_IN_MIRROR flag */ + if (c_ptr->info & CAVE_OBJECT) + { + c_ptr->mimic = feat_mirror; + } + + /* Runes will be mimics and flags */ + else if ((c_ptr->feat == OLD_FEAT_MINOR_GLYPH) || + (c_ptr->feat == OLD_FEAT_GLYPH)) + { + c_ptr->info |= CAVE_OBJECT; + c_ptr->mimic = c_ptr->feat; + c_ptr->feat = feat_floor; + } + + /* Hidden traps will be trap terrains mimicing floor */ + else if (c_ptr->info & CAVE_TRAP) + { + c_ptr->info &= ~CAVE_TRAP; + c_ptr->mimic = c_ptr->feat; + c_ptr->feat = choose_random_trap(); + } + + /* Another hidden trap */ + else if (c_ptr->feat == OLD_FEAT_INVIS) + { + c_ptr->mimic = feat_floor; + c_ptr->feat = feat_trap_open; + } + } + } + + /* Quest 18 was removed */ + if (h_older_than(1, 7, 0, 6) && !vanilla_town) + { + for (y = 0; y < ymax; y++) for (x = 0; x < xmax; x++) + { + /* Access the cave */ + c_ptr = &cave[y][x]; + + if ((c_ptr->special == OLD_QUEST_WATER_CAVE) && !dun_level) + { + if (c_ptr->feat == OLD_FEAT_QUEST_ENTER) + { + c_ptr->feat = feat_tree; + c_ptr->special = 0; + } + else if (c_ptr->feat == OLD_FEAT_BLDG_1) + { + c_ptr->special = lite_town ? QUEST_OLD_CASTLE : QUEST_ROYAL_CRYPT; + } + } + else if ((c_ptr->feat == OLD_FEAT_QUEST_EXIT) && + (p_ptr->inside_quest == OLD_QUEST_WATER_CAVE)) + { + c_ptr->feat = feat_up_stair; + c_ptr->special = 0; + } + } + } + /*** Objects ***/ /* Read the item count */ rd_u16b(&limit); /* Verify maximum */ - if (limit >= max_o_idx) + if (limit > max_o_idx) { #ifdef JP note(format("¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤¬Â礭¤¹¤®¤ë(%d)¡ª", limit)); @@ -2056,9 +2605,328 @@ note(format(" note(format("Object allocation error (%d <> %d)", i, o_idx)); #endif - return (152); - } + return (152); + } + + + /* Acquire place */ + o_ptr = &o_list[o_idx]; + + /* Read the item */ + rd_item(o_ptr); + + + /* XXX XXX XXX XXX XXX */ + + /* Monster */ + if (o_ptr->held_m_idx) + { + monster_type *m_ptr; + + /* Monster */ + m_ptr = &m_list[o_ptr->held_m_idx]; + + /* Build a stack */ + o_ptr->next_o_idx = m_ptr->hold_o_idx; + + /* Place the object */ + m_ptr->hold_o_idx = o_idx; + } + + /* Dungeon */ + else + { + /* Access the item location */ + c_ptr = &cave[o_ptr->iy][o_ptr->ix]; + + /* Build a stack */ + o_ptr->next_o_idx = c_ptr->o_idx; + + /* Place the object */ + c_ptr->o_idx = o_idx; + } + } + + + /*** Monsters ***/ + + /* Read the monster count */ + rd_u16b(&limit); + + /* Hack -- verify */ + if (limit > max_m_idx) + { +#ifdef JP +note(format("¥â¥ó¥¹¥¿¡¼¤ÎÇÛÎó¤¬Â礭¤¹¤®¤ë(%d)¡ª", limit)); +#else + note(format("Too many (%d) monster entries!", limit)); +#endif + + return (161); + } + + /* Read the monsters */ + for (i = 1; i < limit; i++) + { + int m_idx; + monster_type *m_ptr; + + /* Get a new record */ + m_idx = m_pop(); + + /* Oops */ + if (i != m_idx) + { +#ifdef JP +note(format("¥â¥ó¥¹¥¿¡¼ÇÛÃÖ¥¨¥é¡¼ (%d <> %d)", i, m_idx)); +#else + note(format("Monster allocation error (%d <> %d)", i, m_idx)); +#endif + + return (162); + } + + + /* Acquire monster */ + m_ptr = &m_list[m_idx]; + + /* Read the monster */ + rd_monster(m_ptr); + + + /* Access grid */ + c_ptr = &cave[m_ptr->fy][m_ptr->fx]; + + /* Mark the location */ + c_ptr->m_idx = m_idx; + + /* Count */ + real_r_ptr(m_ptr)->cur_num++; + } + + /*** Success ***/ + + /* The dungeon is ready */ + if (z_older_than(10, 3, 13) && !dun_level && !p_ptr->inside_arena) + character_dungeon = FALSE; + else + character_dungeon = TRUE; + + /* Success */ + return (0); +} + + + +/* + * Read the saved floor + * + * The monsters/objects must be loaded in the same order + * that they were stored, since the actual indexes matter. + */ +static errr rd_saved_floor(saved_floor_type *sf_ptr) +{ + int ymax, xmax; + int i, y, x; + byte count; + byte tmp8u; + s16b tmp16s; + u16b tmp16u; + s32b tmp32s; + u32b tmp32u; + u16b limit; + + cave_template_type *template; + + + /*** Wipe all cave ***/ + clear_cave(); + + + /*** Basic info ***/ + + /* Dungeon floor specific info follows */ + + if (!sf_ptr) + { + /*** Not a saved floor ***/ + + rd_s16b(&dun_level); + base_level = dun_level; + } + else + { + /*** The saved floor ***/ + + rd_s16b(&tmp16s); + if (tmp16s != sf_ptr->floor_id) return 171; + + rd_byte(&tmp8u); + if (tmp8u != sf_ptr->savefile_id) return 171; + + rd_s16b(&tmp16s); + if (tmp16s != sf_ptr->dun_level) return 171; + dun_level = sf_ptr->dun_level; + + rd_s32b(&tmp32s); + if (tmp32s != sf_ptr->last_visit) return 171; + + rd_u32b(&tmp32u); + if (tmp32u != sf_ptr->visit_mark) return 171; + + rd_s16b(&tmp16s); + if (tmp16s != sf_ptr->upper_floor_id) return 171; + + rd_s16b(&tmp16s); + if (tmp16s != sf_ptr->lower_floor_id) return 171; + } + + rd_s16b(&base_level); + rd_s16b(&num_repro); + + rd_u16b(&tmp16u); + py = (int)tmp16u; + + rd_u16b(&tmp16u); + px = (int)tmp16u; + + rd_s16b(&cur_hgt); + rd_s16b(&cur_wid); + + rd_byte(&p_ptr->feeling); + + + + /*** Read template for cave_type ***/ + + /* Read the template count */ + rd_u16b(&limit); + + /* Allocate the "template" array */ + C_MAKE(template, limit, cave_template_type); + + /* Read the templates */ + for (i = 0; i < limit; i++) + { + cave_template_type *ct_ptr = &template[i]; + + /* Read it */ + rd_u16b(&ct_ptr->info); + if (h_older_than(1, 7, 0, 2)) + { + rd_byte(&tmp8u); + ct_ptr->feat = (s16b)tmp8u; + rd_byte(&tmp8u); + ct_ptr->mimic = (s16b)tmp8u; + } + else + { + rd_s16b(&ct_ptr->feat); + rd_s16b(&ct_ptr->mimic); + } + rd_s16b(&ct_ptr->special); + } + + /* Maximal size */ + ymax = cur_hgt; + xmax = cur_wid; + + + /*** Run length decoding ***/ + + /* Load the dungeon data */ + for (x = y = 0; y < ymax; ) + { + u16b id; + + /* Grab RLE info */ + rd_byte(&count); + + id = 0; + do + { + rd_byte(&tmp8u); + id += tmp8u; + } while (tmp8u == MAX_UCHAR); + + /* Apply the RLE info */ + for (i = count; i > 0; i--) + { + /* Access the cave */ + cave_type *c_ptr = &cave[y][x]; + + /* Extract cave data */ + c_ptr->info = template[id].info; + c_ptr->feat = template[id].feat; + c_ptr->mimic = template[id].mimic; + c_ptr->special = template[id].special; + + /* Advance/Wrap */ + if (++x >= xmax) + { + /* Wrap */ + x = 0; + + /* Advance/Wrap */ + if (++y >= ymax) break; + } + } + } + + /* Quest 18 was removed */ + if (h_older_than(1, 7, 0, 6) && !vanilla_town) + { + for (y = 0; y < ymax; y++) for (x = 0; x < xmax; x++) + { + /* Access the cave */ + cave_type *c_ptr = &cave[y][x]; + + if ((c_ptr->special == OLD_QUEST_WATER_CAVE) && !dun_level) + { + if (c_ptr->feat == OLD_FEAT_QUEST_ENTER) + { + c_ptr->feat = feat_tree; + c_ptr->special = 0; + } + else if (c_ptr->feat == OLD_FEAT_BLDG_1) + { + c_ptr->special = lite_town ? QUEST_OLD_CASTLE : QUEST_ROYAL_CRYPT; + } + } + else if ((c_ptr->feat == OLD_FEAT_QUEST_EXIT) && + (p_ptr->inside_quest == OLD_QUEST_WATER_CAVE)) + { + c_ptr->feat = feat_up_stair; + c_ptr->special = 0; + } + } + } + + /* Free the "template" array */ + C_FREE(template, limit, cave_template_type); + + + /*** Objects ***/ + + /* Read the item count */ + rd_u16b(&limit); + + /* Verify maximum */ + if (limit > max_o_idx) return 151; + + + /* Read the dungeon items */ + for (i = 1; i < limit; i++) + { + int o_idx; + object_type *o_ptr; + + /* Get a new record */ + o_idx = o_pop(); + + /* Oops */ + if (i != o_idx) return 152; /* Acquire place */ o_ptr = &o_list[o_idx]; @@ -2067,8 +2935,6 @@ note(format(" rd_item(o_ptr); - /* XXX XXX XXX XXX XXX */ - /* Monster */ if (o_ptr->held_m_idx) { @@ -2088,7 +2954,7 @@ note(format(" else { /* Access the item location */ - c_ptr = &cave[o_ptr->iy][o_ptr->ix]; + cave_type *c_ptr = &cave[o_ptr->iy][o_ptr->ix]; /* Build a stack */ o_ptr->next_o_idx = c_ptr->o_idx; @@ -2105,41 +2971,20 @@ note(format(" rd_u16b(&limit); /* Hack -- verify */ - if (limit >= max_m_idx) - { -#ifdef JP -note(format("¥â¥ó¥¹¥¿¡¼¤ÎÇÛÎó¤¬Â礭¤¹¤®¤ë(%d)¡ª", limit)); -#else - note(format("Too many (%d) monster entries!", limit)); -#endif - - return (161); - } + if (limit > max_m_idx) return 161; /* Read the monsters */ for (i = 1; i < limit; i++) { + cave_type *c_ptr; int m_idx; - monster_type *m_ptr; - monster_race *r_ptr; - - /* Get a new record */ m_idx = m_pop(); /* Oops */ - if (i != m_idx) - { -#ifdef JP -note(format("¥â¥ó¥¹¥¿¡¼ÇÛÃÖ¥¨¥é¡¼ (%d <> %d)", i, m_idx)); -#else - note(format("Monster allocation error (%d <> %d)", i, m_idx)); -#endif - - return (162); - } + if (i != m_idx) return 162; /* Acquire monster */ @@ -2155,26 +3000,184 @@ note(format(" /* Mark the location */ c_ptr->m_idx = m_idx; + /* Count */ + real_r_ptr(m_ptr)->cur_num++; + } + + /* Success */ + return 0; +} + + +/* + * Read the dungeon (new method) + * + * The monsters/objects must be loaded in the same order + * that they were stored, since the actual indexes matter. + */ +static errr rd_dungeon(void) +{ + errr err = 0; + byte num; + int i; + + /* Initialize saved_floors array and temporal files */ + init_saved_floors(FALSE); - /* Access race */ - r_ptr = &r_info[m_ptr->r_idx]; + /* Older method */ + if (h_older_than(1, 5, 0, 0)) + { + err = rd_dungeon_old(); + + /* Prepare floor_id of current floor */ + if (dungeon_type) + { + p_ptr->floor_id = get_new_floor_id(); + get_sf_ptr(p_ptr->floor_id)->dun_level = dun_level; + } - /* Count XXX XXX XXX */ - r_ptr->cur_num++; + return err; } - /*** Success ***/ - /* The dungeon is ready */ - if (z_older_than(10, 3, 13) && !dun_level && !p_ptr->inside_arena) - character_dungeon = FALSE; + /*** Meta info ***/ + + /* Number of floor_id used from birth */ + rd_s16b(&max_floor_id); + + /* Current dungeon type */ + rd_byte(&dungeon_type); + + + /* Number of the saved_floors array elements */ + rd_byte(&num); + + /*** No saved floor (On the surface etc.) ***/ + if (!num) + { + /* Read the current floor data */ + err = rd_saved_floor(NULL); + } + + /*** In the dungeon ***/ else - character_dungeon = TRUE; + { - /* Success */ - return (0); -} + /* Read the saved_floors array */ + for (i = 0; i < num; i++) + { + saved_floor_type *sf_ptr = &saved_floors[i]; + + rd_s16b(&sf_ptr->floor_id); + rd_byte(&sf_ptr->savefile_id); + rd_s16b(&sf_ptr->dun_level); + rd_s32b(&sf_ptr->last_visit); + rd_u32b(&sf_ptr->visit_mark); + rd_s16b(&sf_ptr->upper_floor_id); + rd_s16b(&sf_ptr->lower_floor_id); + } + + + /* Move saved floors data to temporal files */ + for (i = 0; i < num; i++) + { + saved_floor_type *sf_ptr = &saved_floors[i]; + byte tmp8u; + + /* Unused element */ + if (!sf_ptr->floor_id) continue; + + /* Read the failure mark */ + rd_byte(&tmp8u); + if (tmp8u) continue; + + /* Read from the save file */ + err = rd_saved_floor(sf_ptr); + + /* Error? */ + if (err) break; + + /* Re-save as temporal saved floor file */ + if (!save_floor(sf_ptr, SLF_SECOND)) err = 182; + + /* Error? */ + if (err) break; + } + + /* Finally load current floor data from temporal file */ + if (!err) + { + if (!load_floor(get_sf_ptr(p_ptr->floor_id), SLF_SECOND)) err = 183; + } + } + + + /*** Error messages ***/ + switch (err) + { + case 151: +#ifdef JP + note("¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤¬Â礭¤¹¤®¤ë¡ª"); +#else + note("Too many object entries!"); +#endif + break; + + case 152: +#ifdef JP + note("¥¢¥¤¥Æ¥àÇÛÃÖ¥¨¥é¡¼"); +#else + note("Object allocation error"); +#endif + break; + case 161: +#ifdef JP + note("¥â¥ó¥¹¥¿¡¼¤ÎÇÛÎó¤¬Â礭¤¹¤®¤ë¡ª"); +#else + note("Too many monster entries!"); +#endif + break; + + case 162: +#ifdef JP + note("¥â¥ó¥¹¥¿¡¼ÇÛÃÖ¥¨¥é¡¼"); +#else + note("Monster allocation error"); +#endif + break; + + case 171: +#ifdef JP + note("Êݸ¤µ¤ì¤¿¥Õ¥í¥¢¤Î¥À¥ó¥¸¥ç¥ó¥Ç¡¼¥¿¤¬²õ¤ì¤Æ¤¤¤Þ¤¹¡ª"); +#else + note("Dungeon data of saved floors are broken!"); +#endif + break; + + case 182: +#ifdef JP + note("¥Æ¥ó¥Ý¥é¥ê¡¦¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¡ª"); +#else + note("Failed to make temporal files!"); +#endif + break; + + case 183: +#ifdef JP + note("Error 183"); +#else + note("Error 183"); +#endif + break; + } + + /* The dungeon is ready */ + character_dungeon = TRUE; + + /* Success or Error */ + return err; +} /* @@ -2199,13 +3202,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 */ @@ -2219,13 +3222,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); @@ -2241,8 +3246,13 @@ note(format(" rd_u32b(&tmp32u); /* Later use (always zero) */ - rd_u32b(&tmp32u); + rd_u16b(&tmp16u); + + /* Later use (always zero) */ + rd_byte(&tmp8u); + /* Kanji code */ + rd_byte(&kanji_code); /* Read RNG state */ rd_randomizer(); @@ -2262,18 +3272,6 @@ if (arg_fiddle) note(" if (arg_fiddle) note("Loaded Option Flags"); #endif - /* - * Munchkin players are marked - * - * XXX - should be replaced with a better method, - * after the new scorefile-handling is implemented. - */ - if (munchkin_death) - { - /* Mark savefile */ - noscore |= 0x0001; - } - /* Then the "messages" */ rd_messages(); #ifdef JP @@ -2286,14 +3284,16 @@ if (arg_fiddle) note(" for (i = 0; i < max_r_idx; i++) { - monster_race *r_ptr; /* Access that monster */ - r_ptr = &r_info[i]; + monster_race *r_ptr = &r_info[i]; /* Hack -- Reset the death counter */ r_ptr->max_num = 100; + if (r_ptr->flags1 & RF1_UNIQUE) r_ptr->max_num = 1; - if (r_ptr->flags7 & RF7_UNIQUE_7) r_ptr->max_num = 7; + + /* Hack -- Non-unique Nazguls are semi-unique */ + else if (r_ptr->flags7 & RF7_NAZGUL) r_ptr->max_num = MAX_NAZGUL_NUM; } /* Monster Memory */ @@ -2314,13 +3314,8 @@ note(format(" /* Read the available records */ for (i = 0; i < tmp16u; i++) { - monster_race *r_ptr; - /* Read the lore */ rd_lore(i); - - /* Access that monster */ - r_ptr = &r_info[i]; } #ifdef JP @@ -2364,24 +3359,6 @@ if (arg_fiddle) note(" #endif -#if 0 - /* - * Initialize arena and rewards information - */ - p_ptr->arena_number = 0; - p_ptr->inside_arena = 0; - p_ptr->inside_quest = 0; - p_ptr->leftbldg = FALSE; - p_ptr->exit_bldg = TRUE; - - /* Start in town 1 */ - p_ptr->town_num = 1; - - p_ptr->wilderness_x = 4; - p_ptr->wilderness_y = 4; - -#endif - /* Init the wilderness seeds */ for (i = 0; i < max_wild_x; i++) { @@ -2454,7 +3431,9 @@ note(format(" } /* Load quest status if quest is running */ - if (quest[i].status == QUEST_STATUS_TAKEN || (!z_older_than(10, 3, 14) && (quest[i].status == QUEST_STATUS_COMPLETED)) || (!z_older_than(11, 0, 7) && (i >= MIN_RANDOM_QUEST) && (i <= (MIN_RANDOM_QUEST+max_rquests_load)))) + if ((quest[i].status == QUEST_STATUS_TAKEN) || + (!z_older_than(10, 3, 14) && (quest[i].status == QUEST_STATUS_COMPLETED)) || + (!z_older_than(11, 0, 7) && (i >= MIN_RANDOM_QUEST) && (i <= (MIN_RANDOM_QUEST + max_rquests_load)))) { rd_s16b(&quest[i].cur_num); rd_s16b(&quest[i].max_num); @@ -2465,36 +3444,7 @@ note(format(" if ((quest[i].type == QUEST_TYPE_RANDOM) && (!quest[i].r_idx)) { - int r_idx; - while (1) - { - monster_race *r_ptr; - - /* - * Random monster 5 - 10 levels out of depth - * (depending on level) - */ - 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; - - if(r_ptr->flags6 & RF6_SPECIAL) continue; - - if(r_ptr->flags7 & RF7_FRIENDLY) continue; - - if(r_ptr->flags7 & RF7_AQUATIC) continue; - - if(r_ptr->flags8 & RF8_WILD_ONLY) continue; - - /* - * Accept monsters that are 2 - 6 levels - * out of depth depending on the quest level - */ - if (r_ptr->level > (quest[i].level + (quest[i].level / 20))) break; - } - - quest[i].r_idx = r_idx; + determine_random_questor(&quest[i]); } /* Load quest item index */ @@ -2516,7 +3466,7 @@ note(format(" init_flags = INIT_ASSIGN; p_ptr->inside_quest = i; - process_dungeon_file("q_info_j.txt", 0, 0, 0, 0); + process_dungeon_file("q_info.txt", 0, 0, 0, 0); p_ptr->inside_quest = old_inside_quest; } } @@ -2546,6 +3496,13 @@ note(format(" } } + /* Quest 18 was removed */ + if (h_older_than(1, 7, 0, 6)) + { + WIPE(&quest[OLD_QUEST_WATER_CAVE], quest_type); + quest[OLD_QUEST_WATER_CAVE].status = QUEST_STATUS_UNTAKEN; + } + /* Position in the wilderness */ rd_s32b(&p_ptr->wilderness_x); rd_s32b(&p_ptr->wilderness_y); @@ -2610,11 +3567,23 @@ note(format(" /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { + artifact_type *a_ptr = &a_info[i]; + rd_byte(&tmp8u); - a_info[i].cur_num = tmp8u; - rd_byte(&tmp8u); - rd_byte(&tmp8u); - rd_byte(&tmp8u); + a_ptr->cur_num = tmp8u; + + if (h_older_than(1, 5, 0, 0)) + { + a_ptr->floor_id = 0; + + rd_byte(&tmp8u); + rd_byte(&tmp8u); + rd_byte(&tmp8u); + } + else + { + rd_s16b(&a_ptr->floor_id); + } } #ifdef JP if (arg_fiddle) note("ÅÁÀâ¤Î¥¢¥¤¥Æ¥à¤ò¥í¡¼¥É¤·¤Þ¤·¤¿"); @@ -2653,7 +3622,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 */ @@ -2664,22 +3633,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); @@ -2690,12 +3659,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)) { @@ -2704,8 +3673,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++; } @@ -2722,7 +3691,7 @@ note(format(" for (i = 0; i < 64; i++) { - rd_byte(&spell_order[i]); + rd_byte(&p_ptr->spell_order[i]); } @@ -2796,11 +3765,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++) { @@ -2810,7 +3779,7 @@ note(" /* I'm not dead yet... */ - if (!death) + if (!p_ptr->is_dead) { /* Dead players have no dungeon */ #ifdef JP @@ -2841,6 +3810,17 @@ note(" } } + /* Quest 18 was removed */ + if (h_older_than(1, 7, 0, 6)) + { + if (p_ptr->inside_quest == OLD_QUEST_WATER_CAVE) + { + dungeon_type = lite_town ? DUNGEON_ANGBAND : DUNGEON_GALGALS; + dun_level = 1; + p_ptr->inside_quest = 0; + } + } + #ifdef VERIFY_CHECKSUMS @@ -2896,9 +3876,15 @@ errr rd_savefile_new(void) { errr err; + /* Grab permissions */ + safe_setuid_grab(); + /* The savefile is a binary file */ fff = my_fopen(savefile, "rb"); + /* Drop permissions */ + safe_setuid_drop(); + /* Paranoia */ if (!fff) return (-1); @@ -2916,3 +3902,173 @@ errr rd_savefile_new(void) } +/* + * Actually load and verify a floor save data + */ +static bool load_floor_aux(saved_floor_type *sf_ptr) +{ + byte tmp8u; + u32b tmp32u; + +#ifdef VERIFY_CHECKSUMS + u32b n_x_check, n_v_check; + u32b o_x_check, o_v_check; +#endif + + /* Hack -- decrypt (read xor_byte) */ + xor_byte = 0; + rd_byte(&tmp8u); + + /* Clear the checksums */ + v_check = 0L; + x_check = 0L; + + /* Set the version number to current version */ + /* Never load old temporal files */ + h_ver_extra = H_VER_EXTRA; + h_ver_patch = H_VER_PATCH; + h_ver_minor = H_VER_MINOR; + h_ver_major = H_VER_MAJOR; + + /* Verify the sign */ + rd_u32b(&tmp32u); + if (saved_floor_file_sign != tmp32u) return FALSE; + + /* Read -- have error? */ + if (rd_saved_floor(sf_ptr)) return FALSE; + + +#ifdef VERIFY_CHECKSUMS + /* Save the checksum */ + n_v_check = v_check; + + /* Read the old checksum */ + rd_u32b(&o_v_check); + + /* Verify */ + if (o_v_check != n_v_check) return FALSE; + + /* Save the encoded checksum */ + n_x_check = x_check; + + /* Read the checksum */ + rd_u32b(&o_x_check); + + /* Verify */ + if (o_x_check != n_x_check) return FALSE; +#endif + + /* Success */ + return TRUE; +} + + +/* + * Attempt to load the temporally saved-floor data + */ +bool load_floor(saved_floor_type *sf_ptr, u32b mode) +{ + FILE *old_fff = NULL; + byte old_xor_byte = 0; + u32b old_v_check = 0; + u32b old_x_check = 0; + byte old_h_ver_major = 0; + byte old_h_ver_minor = 0; + byte old_h_ver_patch = 0; + byte old_h_ver_extra = 0; + + bool ok = TRUE; + char floor_savefile[1024]; + + byte old_kanji_code = kanji_code; + + /* + * Temporal files are always written in system depended kanji + * code. + */ +#ifdef JP +# ifdef EUC + /* EUC kanji code */ + kanji_code = 2; +# endif +# ifdef SJIS + /* SJIS kanji code */ + kanji_code = 3; +# endif +#else + /* ASCII */ + kanji_code = 1; +#endif + + + /* We have one file already opened */ + if (mode & SLF_SECOND) + { + /* Backup original values */ + old_fff = fff; + old_xor_byte = xor_byte; + old_v_check = v_check; + old_x_check = x_check; + old_h_ver_major = h_ver_major; + old_h_ver_minor = h_ver_minor; + old_h_ver_patch = h_ver_patch; + old_h_ver_extra = h_ver_extra; + } + + /* floor savefile */ + sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id); + + /* Grab permissions */ + safe_setuid_grab(); + + /* The savefile is a binary file */ + fff = my_fopen(floor_savefile, "rb"); + + /* Drop permissions */ + safe_setuid_drop(); + + /* Couldn't read */ + if (!fff) ok = FALSE; + + /* Attempt to load */ + if (ok) + { + /* Load saved floor data from file */ + ok = load_floor_aux(sf_ptr); + + /* Check for errors */ + if (ferror(fff)) ok = FALSE; + + /* Close the file */ + my_fclose(fff); + + /* Grab permissions */ + safe_setuid_grab(); + + /* Delete the file */ + if (!(mode & SLF_NO_KILL)) (void)fd_kill(floor_savefile); + + /* Drop permissions */ + safe_setuid_drop(); + } + + /* We have one file already opened */ + if (mode & SLF_SECOND) + { + /* Restore original values */ + fff = old_fff; + xor_byte = old_xor_byte; + v_check = old_v_check; + x_check = old_x_check; + h_ver_major = old_h_ver_major; + h_ver_minor = old_h_ver_minor; + h_ver_patch = old_h_ver_patch; + h_ver_extra = old_h_ver_extra; + } + + /* Restore old knowledge */ + kanji_code = old_kanji_code; + + /* Result */ + return ok; +}