/* * Read a monster */ static void rd_monster(monster_type *m_ptr) { byte tmp8u; /* 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->csleep); rd_byte(&m_ptr->mspeed); rd_s16b(&m_ptr->energy_need); rd_byte(&m_ptr->hasted); rd_byte(&m_ptr->slowed); rd_byte(&m_ptr->stunned); rd_byte(&m_ptr->confused); rd_byte(&m_ptr->monfear); rd_byte(&m_ptr->invulner); rd_u32b(&m_ptr->smart); rd_s16b(&m_ptr->target_y); rd_s16b(&m_ptr->target_x); rd_u32b(&m_ptr->flags); rd_byte(&tmp8u); }
/* * Read terrain lore */ static errr rd_feature_lore(int f_idx) { /* Get the feature */ feature_type *f_ptr = &f_info[f_idx]; feature_lore *f_l_ptr = &f_l_list[f_idx]; byte tmp8u; int i; rd_byte(&tmp8u); /* Activate the "everseen" flag, if needed */ f_ptr->f_everseen = (tmp8u & 0x01); /*Success, for older savefiles*/ if (older_than(0, 4, 3)) return (0); /* Write the terrain_lore memory*/ rd_byte(&f_l_ptr->f_l_sights); /*Write the lore flags*/ rd_u32b(&f_l_ptr->f_l_flags1); rd_u32b(&f_l_ptr->f_l_flags2); rd_u32b(&f_l_ptr->f_l_flags3); /* Repair the lore flags */ f_l_ptr->f_l_flags1 &= f_ptr->f_flags1; f_l_ptr->f_l_flags2 &= f_ptr->f_flags2; f_l_ptr->f_l_flags3 &= f_ptr->f_flags3; rd_byte(&f_l_ptr->f_l_defaults); /*record the max amount of feat states*/ rd_byte(&tmp8u); /*Failure, if the # of MAX FEAT STATES is desceased*/ if (tmp8u > MAX_FEAT_STATES) return (-1); for (i = 0; i < tmp8u; i++) { rd_byte(&f_l_ptr->f_l_state[i]); } rd_byte(&f_l_ptr->f_l_power); rd_byte(&f_l_ptr->f_l_dam_non_native); rd_byte(&f_l_ptr->f_l_native_moves); rd_byte(&f_l_ptr->f_l_non_native_moves); rd_byte(&f_l_ptr->f_l_native_to_hit_adj); rd_byte(&f_l_ptr->f_l_non_native_to_hit_adj); rd_byte(&f_l_ptr->f_l_stealth_adj); /* Success */ return (0); }
static int rd_history(void) { u32b tmp32u; size_t i; history_clear(); rd_u32b(&tmp32u); for (i = 0; i < tmp32u; i++) { s32b turn; s16b dlev, clev; u16b type; byte art_name; char text[80]; rd_u16b(&type); rd_s32b(&turn); rd_s16b(&dlev); rd_s16b(&clev); rd_byte(&art_name); rd_string(text, sizeof(text)); history_add_full(type, art_name, dlev, clev, turn, text); } return 0; }
/* * Read and discard all fields of an unknown extension. */ static errr rd_unknown_extension(void) { byte tmp8u; u16b tmp16u; s16b tmp16s; u32b tmp32u; s32b tmp32s; char string[1024]; while (TRUE) { /* Read field type */ rd_byte(&tmp8u); /* End mark? */ if (tmp8u == EXTENSION_TYPE_END) break; /* Discard field depending on type */ switch(tmp8u) { case EXTENSION_TYPE_U32B: rd_u32b(&tmp32u); break; case EXTENSION_TYPE_S32B: rd_s32b(&tmp32s); break; case EXTENSION_TYPE_U16B: rd_u16b(&tmp16u); break; case EXTENSION_TYPE_S16B: rd_s16b(&tmp16s); break; case EXTENSION_TYPE_STRING: rd_string(string, sizeof(string)); break; case EXTENSION_TYPE_BYTE: rd_byte(&tmp8u); break; /* Garbage? */ default: return (-1); } } /* Success */ return (0); }
/* * Read a monster */ static void rd_monster(monster_type *m_ptr) { /* Read the monster race */ rd_s16b(&m_ptr->r_idx); /* Read the other information */ rd_s16b(&m_ptr->image_r_idx); rd_byte(&m_ptr->fy); rd_byte(&m_ptr->fx); rd_s16b(&m_ptr->hp); rd_s16b(&m_ptr->maxhp); rd_s16b(&m_ptr->alertness); rd_byte(&m_ptr->skip_next_turn); rd_byte(&m_ptr->mspeed); rd_byte(&m_ptr->energy); rd_byte(&m_ptr->stunned); rd_byte(&m_ptr->confused); rd_s16b(&m_ptr->hasted); rd_s16b(&m_ptr->slowed); rd_byte(&m_ptr->stance); rd_s16b(&m_ptr->morale); rd_s16b(&m_ptr->tmp_morale); rd_byte(&m_ptr->noise); rd_byte(&m_ptr->encountered); rd_byte(&m_ptr->target_y); rd_byte(&m_ptr->target_x); rd_byte(&m_ptr->wandering_idx); rd_byte(&m_ptr->wandering_dist); rd_byte(&m_ptr->mana); rd_s16b(&m_ptr->mimic_k_idx); rd_u32b(&m_ptr->mflag); // 8 spare bytes strip_bytes(8); }
/* * Read RNG state */ static int rd_randomizer(void) { int i; u32b noop; /* current value for the simple RNG */ rd_u32b(&Rand_value); /* state index */ rd_u32b(&state_i); /* for safety, make sure state_i < RAND_DEG */ state_i = state_i % RAND_DEG; /* RNG variables */ rd_u32b(&z0); rd_u32b(&z1); rd_u32b(&z2); /* RNG state */ for (i = 0; i < RAND_DEG; i++) rd_u32b(&STATE[i]); /* NULL padding */ for (i = 0; i < 59 - RAND_DEG; i++) rd_u32b(&noop); Rand_quick = FALSE; return 0; }
/* * Read the monster lore */ static void rd_lore(int r_idx) { int i; monster_race *r_ptr = &r_info[r_idx]; monster_lore *l_ptr = &l_list[r_idx]; /* Count deaths/sights/kills */ rd_s16b(&l_ptr->deaths); rd_s16b(&l_ptr->psights); rd_s16b(&l_ptr->tsights); rd_s16b(&l_ptr->pkills); rd_s16b(&l_ptr->tkills); /* Count notices and ignores */ rd_byte(&l_ptr->notice); rd_byte(&l_ptr->ignore); rd_byte(&l_ptr->drop_item); rd_byte(&l_ptr->ranged); /* Count blows of each type */ for (i = 0; i < MONSTER_BLOW_MAX; i++) rd_byte(&l_ptr->blows[i]); /* Memorize flags */ rd_u32b(&l_ptr->flags1); rd_u32b(&l_ptr->flags2); rd_u32b(&l_ptr->flags3); rd_u32b(&l_ptr->flags4); /* Read the "Racial" monster limit per level */ rd_byte(&r_ptr->max_num); // 8 spare bytes strip_bytes(8); /* Repair the lore flags */ l_ptr->flags1 &= r_ptr->flags1; l_ptr->flags2 &= r_ptr->flags2; l_ptr->flags3 &= r_ptr->flags3; l_ptr->flags4 &= r_ptr->flags4; }
/* * Read a monster */ static void rd_monster(monster_type *m_ptr) { byte num; int i; /* 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_byte(&m_ptr->m_speed); rd_s16b(&m_ptr->m_energy); /* Find the number of monster timed effects */ rd_byte(&num); if (num == MON_TMD_MAX) { /* Read all the effects */ for (i = 0; i < num; i++) rd_s16b(&m_ptr->m_timed[i]); } else { s16b dummy; /* Probably in trouble anyway */ for (i = 0; i < num; i++) rd_s16b(&dummy); note("Discarding unsupported monster timed effects"); } rd_u32b(&m_ptr->mflag); rd_u32b(&m_ptr->smart); rd_byte(&m_ptr->target_y); rd_byte(&m_ptr->target_x); rd_byte(&m_ptr->mana); strip_bytes(1); }
static int rd_misc(void) { byte tmp8u; /* Read the randart version */ rd_u32b(&randart_version); /* Read the randart seed */ rd_u32b(&seed_randart); /* Skip the flags */ strip_bytes(12); /* Hack -- the two "special seeds" */ rd_u32b(&seed_flavor); rd_u32b(&seed_town); /* Special stuff */ rd_u16b(&p_ptr->panic_save); rd_u16b(&p_ptr->total_winner); rd_u16b(&p_ptr->noscore); /* Read "death" */ rd_byte(&tmp8u); p_ptr->is_dead = tmp8u; /* Read "feeling" */ rd_byte(&tmp8u); feeling = tmp8u; /* Turn of last "feeling" */ rd_s32b(&old_turn); /* Current turn */ rd_s32b(&turn); return 0; }
/* * Read the monster lore */ static void rd_lore(int r_idx) { byte tmp8u; monster_race *r_ptr = &r_info[r_idx]; /* Count sights/deaths/kills */ rd_s16b(&r_ptr->r_sights); rd_s16b(&r_ptr->r_deaths); rd_s16b(&r_ptr->r_pkills); rd_s16b(&r_ptr->r_tkills); /* Count wakes and ignores */ rd_byte(&r_ptr->r_wake); rd_byte(&r_ptr->r_ignore); /* Extra stuff */ rd_byte(&r_ptr->r_xtra1); rd_byte(&r_ptr->r_xtra2); /* Count drops */ rd_byte(&r_ptr->r_drop_gold); rd_byte(&r_ptr->r_drop_item); /* Count spells */ rd_byte(&r_ptr->r_cast_inate); rd_byte(&r_ptr->r_cast_spell); /* Count blows of each type */ rd_byte(&r_ptr->r_blows[0]); rd_byte(&r_ptr->r_blows[1]); rd_byte(&r_ptr->r_blows[2]); rd_byte(&r_ptr->r_blows[3]); /* Memorize flags */ rd_u32b(&r_ptr->r_flags1); rd_u32b(&r_ptr->r_flags2); rd_u32b(&r_ptr->r_flags3); rd_u32b(&r_ptr->r_flags4); rd_u32b(&r_ptr->r_flags5); rd_u32b(&r_ptr->r_flags6); /* Read the "Racial" monster limit per level */ rd_byte(&r_ptr->max_num); /* Later (?) */ rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); /* Repair the lore flags */ r_ptr->r_flags1 &= r_ptr->flags1; r_ptr->r_flags2 &= r_ptr->flags2; r_ptr->r_flags3 &= r_ptr->flags3; r_ptr->r_flags4 &= r_ptr->flags4; r_ptr->r_flags5 &= r_ptr->flags5; r_ptr->r_flags6 &= r_ptr->flags6; }
/* * Read RNG state */ static void rd_randomizer(void) { int i; // 8 spare bytes strip_bytes(8); /* Place */ rd_u16b(&Rand_place); /* State */ for (i = 0; i < RAND_DEG; i++) { rd_u32b(&Rand_state[i]); } /* Accept */ Rand_quick = FALSE; }
/* * Read RNG state (added in 2.8.0) */ static void rd_randomizer(void) { int i; u16b tmp16u; /* Tmp */ rd_u16b(&tmp16u); /* Place */ rd_u16b(&Rand_place); /* State */ for (i = 0; i < RAND_DEG; i++) { rd_u32b(&Rand_state[i]); } /* Accept */ Rand_quick = FALSE; }
/* * Read the monster lore */ static void rd_monster_lore(int r_idx) { byte tmp8u; int i; monster_race *r_ptr = &r_info[r_idx]; monster_lore *l_ptr = &l_list[r_idx]; /* Count sights/deaths/kills */ rd_s16b(&l_ptr->sights); rd_s16b(&l_ptr->deaths); rd_s16b(&l_ptr->pkills); rd_s16b(&l_ptr->tkills); /* Count wakes and ignores */ rd_byte(&l_ptr->wake); rd_byte(&l_ptr->ignore); /* Extra stuff */ rd_byte(&l_ptr->xtra1); rd_byte(&l_ptr->xtra2); /* Count drops */ rd_byte(&l_ptr->drop_gold); rd_byte(&l_ptr->drop_item); rd_byte(&l_ptr->ranged); /* Count blows of each type */ for (i = 0; i < MONSTER_BLOW_MAX; i++) rd_byte(&l_ptr->blows[i]); /* Memorize flags */ rd_u32b(&l_ptr->r_l_flags1); rd_u32b(&l_ptr->r_l_flags2); rd_u32b(&l_ptr->r_l_flags3); rd_u32b(&l_ptr->r_l_flags4); rd_u32b(&l_ptr->r_l_flags5); rd_u32b(&l_ptr->r_l_flags6); rd_u32b(&l_ptr->r_l_flags7); rd_u32b(&l_ptr->r_l_native); /* Read the "Racial" monster limit per level */ rd_byte(&r_ptr->max_num); /* Hack - allow for new monsters from a modified monster list to appear in a current game. */ /* In case of a monster entry that wasn't a unique is now made a unique.*/ if (r_ptr->flags1 & (RF1_UNIQUE)) { if (r_ptr->max_num > 1) r_ptr->max_num = 1; } /* Not a unique, but a new monster entry in the current game. */ else if (r_ptr->max_num == 0) r_ptr->max_num = 100; /* Later (?) */ rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); /* Repair the lore flags */ l_ptr->r_l_flags1 &= r_ptr->flags1; l_ptr->r_l_flags2 &= r_ptr->flags2; l_ptr->r_l_flags3 &= r_ptr->flags3; l_ptr->r_l_flags4 &= r_ptr->flags4; l_ptr->r_l_flags5 &= r_ptr->flags5; l_ptr->r_l_flags6 &= r_ptr->flags6; l_ptr->r_l_flags7 &= r_ptr->flags7; l_ptr->r_l_native &= r_ptr->r_native; }
/* * Read the random artifacts */ static int rd_randarts(void) { size_t i; byte tmp8u; s16b tmp16s; u16b tmp16u; u16b artifact_count; s32b tmp32s; u32b tmp32u; if (!OPT(adult_randarts)) return 0; if (older_than(3, 0, 14)) { /* * XXX XXX XXX * Importing old savefiles with random artifacts is dangerous * since the randart-generators differ and produce different * artifacts from the same random seed. * * Switching off the check for incompatible randart versions * allows to import such a savefile - do it at your own risk. */ /* Check for incompatible randart version */ if (randart_version != RANDART_VERSION) { note(format("Incompatible random artifacts version!")); return (-1); } /* Initialize randarts */ do_randart(seed_randart, TRUE); } else { /* Read the number of artifacts */ rd_u16b(&artifact_count); /* Alive or cheating death */ if (!p_ptr->is_dead || arg_wizard) { /* Incompatible save files */ if (artifact_count > z_info->a_max) { note(format("Too many (%u) random artifacts!", artifact_count)); return (-1); } /* Mark the old artifacts as "empty" */ for (i = 0; i < z_info->a_max; i++) { artifact_type *a_ptr = &a_info[i]; a_ptr->name = 0; a_ptr->tval = 0; a_ptr->sval = 0; } /* Read the artifacts */ for (i = 0; i < artifact_count; i++) { artifact_type *a_ptr = &a_info[i]; u16b time_base, time_dice, time_sides; rd_byte(&a_ptr->tval); rd_byte(&a_ptr->sval); rd_s16b(&a_ptr->pval); rd_s16b(&a_ptr->to_h); rd_s16b(&a_ptr->to_d); rd_s16b(&a_ptr->to_a); rd_s16b(&a_ptr->ac); rd_byte(&a_ptr->dd); rd_byte(&a_ptr->ds); rd_s16b(&a_ptr->weight); rd_s32b(&a_ptr->cost); /* Hack - XXX - MarbleDice - Maximum saveable flags = 96 */ for (i = 0; i < 12 && i < OF_SIZE; i++) rd_byte(&a_ptr->flags[i]); if (i < 12) strip_bytes(OF_SIZE - i); rd_byte(&a_ptr->level); rd_byte(&a_ptr->rarity); rd_byte(&a_ptr->alloc_prob); rd_byte(&a_ptr->alloc_min); rd_byte(&a_ptr->alloc_max); rd_u16b(&a_ptr->effect); rd_u16b(&time_base); rd_u16b(&time_dice); rd_u16b(&time_sides); a_ptr->time.base = time_base; a_ptr->time.dice = time_dice; a_ptr->time.sides = time_sides; } /* Initialize only the randart names */ do_randart(seed_randart, FALSE); } else { /* Read the artifacts */ for (i = 0; i < artifact_count; i++) { rd_byte(&tmp8u); /* a_ptr->tval */ rd_byte(&tmp8u); /* a_ptr->sval */ rd_s16b(&tmp16s); /* a_ptr->pval */ rd_s16b(&tmp16s); /* a_ptr->to_h */ rd_s16b(&tmp16s); /* a_ptr->to_d */ rd_s16b(&tmp16s); /* a_ptr->to_a */ rd_s16b(&tmp16s); /* a_ptr->ac */ rd_byte(&tmp8u); /* a_ptr->dd */ rd_byte(&tmp8u); /* a_ptr->ds */ rd_s16b(&tmp16s); /* a_ptr->weight */ rd_s32b(&tmp32s); /* a_ptr->cost */ rd_u32b(&tmp32u); /* a_ptr->flags1 */ rd_u32b(&tmp32u); /* a_ptr->flags2 */ rd_u32b(&tmp32u); /* a_ptr->flags3 */ rd_byte(&tmp8u); /* a_ptr->level */ rd_byte(&tmp8u); /* a_ptr->rarity */ rd_byte(&tmp8u); /* a_ptr->alloc_prob */ rd_byte(&tmp8u); /* a_ptr->alloc_min */ rd_byte(&tmp8u); /* a_ptr->alloc_max */ rd_u16b(&tmp16u); /* a_ptr->effect */ rd_u16b(&tmp16u); /* a_ptr->time_base */ rd_u16b(&tmp16u); /* a_ptr->time_dice */ rd_u16b(&tmp16u); /* a_ptr->time_sides */ } } } return (0); }
/* * Read the "extra" information */ static errr rd_extra(void) { int i; byte tmp8u; u16b tmp16u; int max_spells = PY_MAX_SPELLS; if (!variant_more_spells) max_spells = 64; rd_string(op_ptr->full_name, 32); rd_string(p_ptr->died_from, 80); if (older_than(3, 0, 1)) { char *hist = p_ptr->history; for (i = 0; i < 4; i++) { /* Read a part of the history */ rd_string(hist, 60); /* Advance */ hist += strlen(hist); /* Separate by spaces */ hist[0] = ' '; hist++; } /* Make sure it is terminated */ hist[0] = '\0'; } else { rd_string(p_ptr->history, 250); } /* Player race */ rd_byte(&p_ptr->prace); /* Verify player race */ if (p_ptr->prace >= z_info->p_max) { note(format("Invalid player race (%d).", p_ptr->prace)); return (-1); } /* Player class */ rd_byte(&p_ptr->pclass); /* Verify player class */ if (p_ptr->pclass >= z_info->c_max) { note(format("Invalid player class (%d).", p_ptr->pclass)); return (-1); } /* Player gender */ rd_byte(&p_ptr->psex); /* Hack -- record style in stripped bytes */ rd_byte(&tmp8u); /* Oops */ /* Ignore old redundant info */ p_ptr->pstyle=tmp8u; /* Special Race/Class info */ rd_byte(&p_ptr->hitdie); rd_byte(&p_ptr->expfact); /* Age/Height/Weight */ rd_s16b(&p_ptr->age); rd_s16b(&p_ptr->ht); rd_s16b(&p_ptr->wt); /* Read the stat info */ for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_max[i]); for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_cur[i]); strip_bytes(24); /* oops */ rd_s32b(&p_ptr->au); rd_s32b(&p_ptr->max_exp); rd_s32b(&p_ptr->exp); rd_u16b(&p_ptr->exp_frac); rd_s16b(&p_ptr->lev); /* Verify player level */ if ((p_ptr->lev < 1) || (p_ptr->lev > PY_MAX_LEVEL)) { note(format("Invalid player level (%d).", p_ptr->lev)); return (-1); } rd_s16b(&p_ptr->mhp); rd_s16b(&p_ptr->chp); rd_u16b(&p_ptr->chp_frac); rd_s16b(&p_ptr->msp); rd_s16b(&p_ptr->csp); rd_u16b(&p_ptr->csp_frac); rd_s16b(&p_ptr->max_lev); rd_s16b(&p_ptr->max_depth); /* Hack -- Repair maximum player level */ if (p_ptr->max_lev < p_ptr->lev) p_ptr->max_lev = p_ptr->lev; /* Hack -- Repair maximum dungeon level */ if (p_ptr->max_depth < 0) p_ptr->max_depth = 1; /* More info */ /* Hack --- Get psval information. */ rd_byte(&tmp8u); /* Oops */ /* Ignore old redundant info */ p_ptr->psval=tmp8u; /* Hack -- set styles for vanilla characters */ /* Mega Hack -- use psval == 1 to indicate we have applied this hack */ if ((!p_ptr->pstyle) && (!p_ptr->psval)) { switch(p_ptr->pclass) { case 2: /* CLASS_PRIEST */ p_ptr->pstyle = WS_HAFTED; break; case 4: /* CLASS_RANGER */ p_ptr->pstyle = WS_BOW; break; default: p_ptr->psval = 1; break; } } /* Hack --- Get held_song information. */ rd_byte(&tmp8u); /* Oops */ /* Ignore old redundant info */ p_ptr->held_song=tmp8u; strip_bytes(6); /* Was strip bytes(8) */ rd_s16b(&p_ptr->sc); strip_bytes(2); /* Read the flags */ strip_bytes(2); /* Old "rest" */ rd_s16b(&p_ptr->blind); rd_s16b(&p_ptr->paralyzed); rd_s16b(&p_ptr->confused); rd_s16b(&p_ptr->food); /* Read in 'rest' */ if (variant_fast_moves) rd_s16b(&p_ptr->rest); else { strip_bytes(2); p_ptr->rest = PY_REST_FULL; } strip_bytes(2); /* Old "food_digested" / "protection" */ /* Read more flags */ rd_s16b(&p_ptr->energy); rd_s16b(&p_ptr->fast); rd_s16b(&p_ptr->slow); rd_s16b(&p_ptr->afraid); rd_s16b(&p_ptr->cut); rd_s16b(&p_ptr->stun); rd_s16b(&p_ptr->poisoned); rd_s16b(&p_ptr->image); rd_s16b(&p_ptr->protevil); rd_s16b(&p_ptr->invuln); rd_s16b(&p_ptr->hero); rd_s16b(&p_ptr->shero); rd_s16b(&p_ptr->shield); rd_s16b(&p_ptr->blessed); rd_s16b(&p_ptr->tim_invis); rd_s16b(&p_ptr->word_recall); rd_s16b(&p_ptr->see_infra); rd_s16b(&p_ptr->tim_infra); rd_s16b(&p_ptr->oppose_fire); rd_s16b(&p_ptr->oppose_cold); rd_s16b(&p_ptr->oppose_acid); rd_s16b(&p_ptr->oppose_elec); rd_s16b(&p_ptr->oppose_pois); rd_byte(&tmp8u); /* Was p_ptr->confusing */ rd_byte(&tmp8u); /* oops */ rd_byte(&tmp8u); /* oops */ rd_byte(&tmp8u); /* oops */ rd_byte(&p_ptr->searching); rd_byte(&tmp8u); /* oops */ rd_byte(&tmp8u); /* oops */ rd_byte(&tmp8u); /* oops */ /* Future use */ strip_bytes(40); /* Read the randart version */ rd_u32b(&randart_version); /* Read the randart seed */ rd_u32b(&seed_randart); /* Skip the flags */ strip_bytes(12); /* Hack -- the two "special seeds" */ rd_u32b(&seed_flavor); rd_u32b(&seed_town); /* Special stuff */ rd_u16b(&p_ptr->panic_save); rd_u16b(&p_ptr->total_winner); rd_u16b(&p_ptr->noscore); /* Read "death" */ rd_byte(&tmp8u); p_ptr->is_dead = tmp8u; /* Read "feeling" */ rd_byte(&tmp8u); feeling = tmp8u; /* Turn of last "feeling" */ rd_s32b(&old_turn); /* Current turn */ rd_s32b(&turn); /* Read the player_hp array */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > PY_MAX_LEVEL) { note(format("Too many (%u) hitpoint entries!", tmp16u)); return (-1); } /* Read the player_hp array */ for (i = 0; i < tmp16u; i++) { rd_s16b(&p_ptr->player_hp[i]); } /* Read spell info */ rd_u32b(&p_ptr->spell_learned1); rd_u32b(&p_ptr->spell_learned2); if (variant_more_spells) rd_u32b(&p_ptr->spell_learned3); if (variant_more_spells) rd_u32b(&p_ptr->spell_learned4); rd_u32b(&p_ptr->spell_worked1); rd_u32b(&p_ptr->spell_worked2); if (variant_more_spells) rd_u32b(&p_ptr->spell_worked3); if (variant_more_spells) rd_u32b(&p_ptr->spell_worked4); rd_u32b(&p_ptr->spell_forgotten1); rd_u32b(&p_ptr->spell_forgotten2); if (variant_more_spells) rd_u32b(&p_ptr->spell_forgotten3); if (variant_more_spells) rd_u32b(&p_ptr->spell_forgotten4); /* Read in the spells */ for (i = 0; i < max_spells; i++) { if (variant_more_spells) rd_s16b(&p_ptr->spell_order[i]); else { rd_byte(&tmp8u); p_ptr->spell_order[i] = tmp8u; } } return (0); }
/* * Read options * * Note that the normal options are stored as a set of 256 bit flags, * plus a set of 256 bit masks to indicate which bit flags were defined * at the time the savefile was created. This will allow new options * to be added, and old options to be removed, at any time, without * hurting old savefiles. * * The window options are stored in the same way, but note that each * window gets 32 options, and their order is fixed by certain defines. */ static void rd_options(void) { int i, n; byte b; u16b tmp16u; u32b flag[8]; u32b mask[8]; u32b window_flag[ANGBAND_TERM_MAX]; u32b window_mask[ANGBAND_TERM_MAX]; /* Hack -- unset all Save File Options for compatibility */ for (i = 0; i < OPT_PAGE_PER; i++) { /* Collect options on this "page" */ if (option_page[8][i] != 255) { op_ptr->opt[option_page[8][i]] = FALSE; } } /*** Oops ***/ /* Ignore old options */ strip_bytes(16); /*** Special info */ /* Read "delay_factor" */ rd_byte(&b); op_ptr->delay_factor = b; /* Read "hitpoint_warn" */ rd_byte(&b); op_ptr->hitpoint_warn = b; /* Old cheating options */ rd_u16b(&tmp16u); /*** Normal Options ***/ /* Read the option flags */ for (n = 0; n < 8; n++) rd_u32b(&flag[n]); /* Read the option masks */ for (n = 0; n < 8; n++) rd_u32b(&mask[n]); /* Analyze the options */ for (i = 0; i < OPT_MAX; i++) { int os = i / 32; int ob = i % 32; /* Process real entries */ if (option_text[i]) { /* Process saved entries */ if (mask[os] & (1L << ob)) { /* Set flag */ if (flag[os] & (1L << ob)) { /* Set */ op_ptr->opt[i] = TRUE; } /* Clear flag */ else { /* Set */ op_ptr->opt[i] = FALSE; } } } } /*** Window Options ***/ /* Read the window flags */ for (n = 0; n < ANGBAND_TERM_MAX; n++) { rd_u32b(&window_flag[n]); } /* Read the window masks */ for (n = 0; n < ANGBAND_TERM_MAX; n++) { rd_u32b(&window_mask[n]); } /* Analyze the options */ for (n = 0; n < ANGBAND_TERM_MAX; n++) { /* Analyze the options */ for (i = 0; i < 32; i++) { /* Process valid flags */ if (window_flag_desc[i]) { /* Process valid flags */ if (window_mask[n] & (1L << i)) { /* Set */ if (window_flag[n] & (1L << i)) { /* Set */ op_ptr->window_flag[n] |= (1L << i); } } } } } }
/* * Read the monster lore */ static void rd_lore(int r_idx) { byte tmp8u; monster_race *r_ptr = &r_info[r_idx]; monster_lore *l_ptr = &l_list[r_idx]; /* Count sights/deaths/kills */ rd_s16b(&l_ptr->sights); rd_s16b(&l_ptr->deaths); rd_s16b(&l_ptr->pkills); rd_s16b(&l_ptr->tkills); /* Count wakes and ignores */ rd_byte(&l_ptr->wake); rd_byte(&l_ptr->ignore); /* Extra stuff */ rd_byte(&l_ptr->xtra1); rd_byte(&l_ptr->xtra2); /* Count drops */ rd_byte(&l_ptr->drop_gold); rd_byte(&l_ptr->drop_item); /* Count spells */ rd_byte(&l_ptr->cast_innate); rd_byte(&l_ptr->cast_spell); /* Count blows of each type */ rd_byte(&l_ptr->blows[0]); rd_byte(&l_ptr->blows[1]); rd_byte(&l_ptr->blows[2]); rd_byte(&l_ptr->blows[3]); /* Memorize flags */ rd_u32b(&l_ptr->flags1); rd_u32b(&l_ptr->flags2); rd_u32b(&l_ptr->flags3); rd_u32b(&l_ptr->flags4); rd_u32b(&l_ptr->flags5); rd_u32b(&l_ptr->flags6); if (variant_drop_body && !(older_than(2,9,6))) rd_u32b(&l_ptr->flags7); /* Read the "Racial" monster limit per level */ rd_byte(&r_ptr->max_num); /* Later (?) */ rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); /* Repair the lore flags */ l_ptr->flags1 &= r_ptr->flags1; l_ptr->flags2 &= r_ptr->flags2; l_ptr->flags3 &= r_ptr->flags3; l_ptr->flags4 &= r_ptr->flags4; l_ptr->flags5 &= r_ptr->flags5; l_ptr->flags6 &= r_ptr->flags6; }
/* * Read an object * * This function attempts to "repair" old savefiles, and to extract * the most up to date values for various object fields. * * Note that Angband 2.7.9 introduced a new method for object "flags" * in which the "flags" on an object are actually extracted when they * are needed from the object kind, artifact index, ego-item index, * and two special "xtra" fields which are used to encode any "extra" * power of certain ego-items. This had the side effect that items * imported from pre-2.7.9 savefiles will lose any "extra" powers they * may have had, and also, all "uncursed" items will become "cursed" * again, including Calris, even if it is being worn at the time. As * 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) { char buf[128]; /* Kind */ rd_s16b(&o_ptr->k_idx); /* Location */ rd_byte(&o_ptr->iy); rd_byte(&o_ptr->ix); /* Type/Subtype */ rd_byte(&o_ptr->tval); rd_byte(&o_ptr->sval); rd_s32b(&o_ptr->pval); rd_byte(&o_ptr->discount); rd_byte(&o_ptr->number); rd_s16b(&o_ptr->weight); rd_byte(&o_ptr->name1); rd_byte(&o_ptr->name2); rd_s32b(&o_ptr->timeout); rd_s16b(&o_ptr->to_h); rd_s16b(&o_ptr->to_d); rd_s16b(&o_ptr->to_a); rd_s16b(&o_ptr->ac); 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); /* Monster holding object */ rd_s16b(&o_ptr->held_m_idx); /* Special powers */ rd_byte(&o_ptr->xtra1); rd_byte(&o_ptr->xtra2); rd_s16b(&o_ptr->xtra3); /* Feeling - from 2.3.1, "savefile version 1" */ rd_byte(&o_ptr->feeling); /* Inscription */ rd_string(buf, sizeof(buf)); /* 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; } } } /* Save the inscription */ if (buf[0]) o_ptr->inscription = quark_add(buf); /* Random artifact */ rd_string(buf, sizeof(buf)); if (buf[0]) o_ptr->art_name = quark_add(buf); /* Named ego */ rd_string(buf, sizeof(buf)); if (buf[0]) o_ptr->ego_name = quark_add(buf); /* The Python object - old */ { s32b tmp32s; rd_s32b(&tmp32s); strip_bytes(tmp32s); } #if 0 /* Mega-Hack -- handle "dungeon objects" later */ if ((o_ptr->k_idx >= 445) && (o_ptr->k_idx <= 479)) return; #endif /* Paranoia */ if (o_ptr->name1) { artifact_type *a_ptr; /* Obtain the artifact info */ a_ptr = &a_info[o_ptr->name1]; /* Verify that artifact */ if (!a_ptr->name) o_ptr->name1 = 0; } /* Paranoia */ if (o_ptr->name2) { ego_item_type *e_ptr; /* Obtain the ego-item info */ e_ptr = &e_info[o_ptr->name2]; /* Verify that ego-item */ if (!e_ptr->name) o_ptr->name2 = 0; } }
/* * Read options * * Note that the normal options are stored as a set of 256 bit flags, * plus a set of 256 bit masks to indicate which bit flags were defined * at the time the savefile was created. This will allow new options * to be added, and old options to be removed, at any time, without * hurting old savefiles. * * The window options are stored in the same way, but note that each * window gets 32 options, and their order is fixed by certain defines. */ static int rd_options(void) { int i, n; byte b; u16b tmp16u; u32b flag[8]; u32b mask[8]; u32b window_flag[REPOSBAND_TERM_MAX]; u32b window_mask[REPOSBAND_TERM_MAX]; /*** Oops ***/ /* Ignore old options */ strip_bytes(16); /*** Special info */ /* Read "delay_factor" */ rd_byte(&b); op_ptr->delay_factor = b; /* Read "hitpoint_warn" */ rd_byte(&b); op_ptr->hitpoint_warn = b; /* Read lazy movement delay */ rd_u16b(&tmp16u); lazymove_delay = (tmp16u < 1000) ? tmp16u : 0; /*** Normal Options ***/ /* Read the option flags */ for (n = 0; n < 8; n++) rd_u32b(&flag[n]); /* Read the option masks */ for (n = 0; n < 8; n++) rd_u32b(&mask[n]); /* Analyze the options */ for (i = 0; i < OPT_MAX; i++) { int os = i / 32; int ob = i % 32; /* Process saved entries */ if (mask[os] & (1L << ob)) { /* Set flag */ if (flag[os] & (1L << ob)) op_ptr->opt[i] = TRUE; /* Clear flag */ else op_ptr->opt[i] = FALSE; } } /*** Window Options ***/ /* Read the window flags */ for (n = 0; n < REPOSBAND_TERM_MAX; n++) { rd_u32b(&window_flag[n]); } /* Read the window masks */ for (n = 0; n < REPOSBAND_TERM_MAX; n++) { rd_u32b(&window_mask[n]); } /* Analyze the options */ for (n = 0; n < REPOSBAND_TERM_MAX; n++) { /* Analyze the options */ for (i = 0; i < 32; i++) { /* Process valid flags */ if (window_flag_desc[i]) { /* Blank invalid flags */ if (!(window_mask[n] & (1L << i))) { window_flag[n] &= ~(1L << i); } } } } /* Set up the subwindows */ subwindows_set_flags(window_flag, REPOSBAND_TERM_MAX); return 0; }
/* * Read the random artifacts */ static errr rd_randarts(void) { #ifdef GJW_RANDART int i; byte tmp8u; s16b tmp16s; u16b tmp16u; u16b artifact_count; s32b tmp32s; u32b tmp32u; if (older_than(2, 9, 3)) { /* * XXX XXX XXX * Importing old savefiles with random artifacts is dangerous * since the randart-generators differ and produce different * artifacts from the same random seed. * * Switching off the check for incompatible randart versions * allows to import such a savefile - do it at your own risk. */ /* Check for incompatible randart version */ if (randart_version != RANDART_VERSION) { note(format("Incompatible random artifacts version!")); return (-1); } /* Alive or cheating death */ if (!p_ptr->is_dead || arg_wizard) { /* Initialize randarts */ do_randart(seed_randart, TRUE); } } else { /* Read the number of artifacts */ rd_u16b(&artifact_count); /* Alive or cheating death */ if (!p_ptr->is_dead || arg_wizard) { /* Initialize randarts */ do_randart(seed_randart, TRUE); /* Incompatible save files */ if (artifact_count > z_info->a_max) { note(format("Too many (%u) random artifacts!", artifact_count)); return (-1); } /* Read the artifacts */ for (i = 0; i < artifact_count; i++) { artifact_type *a_ptr = &a_info[i]; rd_byte(&a_ptr->tval); rd_byte(&a_ptr->sval); rd_s16b(&a_ptr->pval); rd_s16b(&a_ptr->to_h); rd_s16b(&a_ptr->to_d); rd_s16b(&a_ptr->to_a); rd_s16b(&a_ptr->ac); rd_byte(&a_ptr->dd); rd_byte(&a_ptr->ds); rd_s16b(&a_ptr->weight); rd_s32b(&a_ptr->cost); rd_u32b(&a_ptr->flags1); rd_u32b(&a_ptr->flags2); rd_u32b(&a_ptr->flags3); rd_byte(&a_ptr->level); rd_byte(&a_ptr->rarity); /* Hack -- Unangband requires 2 bytes to store activation */ if (z_info->a_max == 256) rd_s16b(&a_ptr->activation); else rd_byte(&tmp8u); rd_u16b(&a_ptr->time); rd_u16b(&a_ptr->randtime); } } else { /* Read the artifacts */ for (i = 0; i < artifact_count; i++) { rd_byte(&tmp8u); /* a_ptr->tval */ rd_byte(&tmp8u); /* a_ptr->sval */ rd_s16b(&tmp16s); /* a_ptr->pval */ rd_s16b(&tmp16s); /* a_ptr->to_h */ rd_s16b(&tmp16s); /* a_ptr->to_d */ rd_s16b(&tmp16s); /* a_ptr->to_a */ rd_s16b(&tmp16s); /* a_ptr->ac */ rd_byte(&tmp8u); /* a_ptr->dd */ rd_byte(&tmp8u); /* a_ptr->ds */ rd_s16b(&tmp16s); /* a_ptr->weight */ rd_s32b(&tmp32s); /* a_ptr->cost */ rd_u32b(&tmp32u); /* a_ptr->flags1 */ rd_u32b(&tmp32u); /* a_ptr->flags2 */ rd_u32b(&tmp32u); /* a_ptr->flags3 */ rd_byte(&tmp8u); /* a_ptr->level */ rd_byte(&tmp8u); /* a_ptr->rarity */ /* Hack -- Unangband requires 2 bytes to store activation */ if (artifact_count == 256) rd_u16b(&tmp16u); else rd_byte(&tmp8u); rd_u16b(&tmp16u); /* a_ptr->time */ rd_u16b(&tmp16u); /* a_ptr->randtime */ } } } return (0); #else /* GJW_RANDART */ note("Random artifacts are disabled in this binary."); return (-1); #endif /* GJW_RANDART */ }
/* * Read a store */ static errr rd_store(int n) { store_type *st_ptr = &store[n]; int j; byte own, num; u32b extra32; s16b extra16; /* Read the basic info */ rd_u32b(&extra32); rd_s16b(&extra16); rd_byte(&own); rd_byte(&num); rd_s16b(&extra16); rd_s16b(&extra16); /* Paranoia */ if (own >= z_info->b_max) { note("Illegal store owner!"); return (-1); } st_ptr->owner = own; /* Read the items */ for (j = 0; j < num; j++) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Wipe the object */ object_wipe(i_ptr); /* Read the item */ if (rd_item(i_ptr)) { note("Error reading item"); return (-1); } /* Accept any valid items */ if (st_ptr->stock_num < STORE_INVEN_MAX) { int k = st_ptr->stock_num++; /* Accept the item */ object_copy(&st_ptr->stock[k], i_ptr); } } /* Success */ return (0); }
/* * Read a Win32 BMP file. * * Assumes that the bitmap has a size such that no padding is needed in * various places. Currently only handles bitmaps with 3 to 256 colors. */ static byte *ReadBMP(char *Name, int *bw, int *bh) { FILE *f; BITMAPFILEHEADER fileheader; BITMAPINFOHEADER infoheader; byte *Data; int ncol; int total; int i; u16b x, y; /* Open the BMP file */ f = fopen(Name, "r"); /* No such file */ if (!f) { quit ("No bitmap to load!"); } /* Read the "BITMAPFILEHEADER" */ rd_u16b(f, &(fileheader.bfType)); rd_u32b(f, &(fileheader.bfSize)); rd_u16b(f, &(fileheader.bfReserved1)); rd_u16b(f, &(fileheader.bfReserved2)); rd_u32b(f, &(fileheader.bfOffBits)); /* Read the "BITMAPINFOHEADER" */ rd_u32b(f, &(infoheader.biSize)); rd_u32b(f, &(infoheader.biWidth)); rd_u32b(f, &(infoheader.biHeight)); rd_u16b(f, &(infoheader.biPlanes)); rd_u16b(f, &(infoheader.biBitCount)); rd_u32b(f, &(infoheader.biCompresion)); rd_u32b(f, &(infoheader.biSizeImage)); rd_u32b(f, &(infoheader.biXPelsPerMeter)); rd_u32b(f, &(infoheader.biYPelsPerMeter)); rd_u32b(f, &(infoheader.biClrUsed)); rd_u32b(f, &(infoheader.biClrImportand)); /* Verify the header */ if (feof(f) || (fileheader.bfType != 19778) || (infoheader.biSize != 40)) { quit_fmt("Incorrect BMP file format %s", Name); } /* The two headers above occupy 54 bytes total */ /* The "bfOffBits" field says where the data starts */ /* The "biClrUsed" field does not seem to be reliable */ /* Compute number of colors recorded */ ncol = (fileheader.bfOffBits - 54) / 4; for (i = 0; i < ncol; i++) { RGBQUAD clrg; /* Read an "RGBQUAD" */ rd_byte(f, &(clrg.b)); rd_byte(f, &(clrg.g)); rd_byte(f, &(clrg.r)); rd_byte(f, &(clrg.filler)); /* Analyze the color */ pal[i * 3] = clrg.b; pal[i * 3 + 1] = clrg.g; pal[i * 3 + 2] = clrg.r; } /* Look for illegal bitdepths. */ if ((infoheader.biBitCount == 1) || (infoheader.biBitCount == 24)) { quit_fmt("Illegal biBitCount %d in %s", infoheader.biBitCount, Name); } /* Determine total bytes needed for image */ total = infoheader.biWidth * (infoheader.biHeight + 2); /* Allocate image memory */ C_MAKE(Data, total, byte); for (y = 0; y < infoheader.biHeight; y++) { int y2 = infoheader.biHeight - y - 1; for (x = 0; x < infoheader.biWidth; x++) { int ch = getc(f); /* Verify not at end of file XXX XXX */ if (feof(f)) quit_fmt("Unexpected end of file in %s", Name); if (infoheader.biBitCount == 8) { Data[x + y2 * infoheader.biWidth] = ch; } else if (infoheader.biBitCount == 4) { Data[x + y2 * infoheader.biWidth] = ch / 16; x++; Data[x + y2 * infoheader.biWidth] = ch % 16; } } } fclose(f); /* Save the size for later */ *bw = infoheader.biWidth; *bh = infoheader.biHeight; return (Data); }
/* * Read options * * Note that the normal options are stored as a set of 256 bit flags, * plus a set of 256 bit masks to indicate which bit flags were defined * at the time the savefile was created. This will allow new options * to be added, and old options to be removed, at any time, without * hurting old savefiles. * * The window options are stored in the same way, but note that each * window gets 32 options, and their order is fixed by certain defines. */ static void rd_options(void) { int i, n; byte b; u16b tmp16u; u32b flag[8]; u32b mask[8]; u32b window_flag[ANGBAND_TERM_MAX]; u32b window_mask[ANGBAND_TERM_MAX]; /*** Oops ***/ /* Ignore old options */ strip_bytes(16); /*** Special info */ /* Read "delay_factor" */ rd_byte(&b); op_ptr->delay_factor = b; /* Read "hitpoint_warn" */ rd_byte(&b); op_ptr->hitpoint_warn = b; /* Old cheating options */ rd_u16b(&tmp16u); /*** Normal Options ***/ /* Read the option flags */ for (n = 0; n < 8; n++) rd_u32b(&flag[n]); /* Read the option masks */ for (n = 0; n < 8; n++) rd_u32b(&mask[n]); /* Analyze the options */ for (i = 0; i < OPT_MAX; i++) { int os = i / 32; int ob = i % 32; /* Process real entries */ if (!options[i].name) continue; /* Process saved entries */ if (mask[os] & (1L << ob)) { /* Set flag */ if (flag[os] & (1L << ob)) { /* Set */ op_ptr->opt[i] = TRUE; } /* Clear flag */ else { /* Set */ op_ptr->opt[i] = FALSE; } } } /*** Window Options ***/ /* Read the window flags */ for (n = 0; n < ANGBAND_TERM_MAX; n++) { rd_u32b(&window_flag[n]); } /* Read the window masks */ for (n = 0; n < ANGBAND_TERM_MAX; n++) { rd_u32b(&window_mask[n]); } /* Analyze the options */ for (n = 0; n < ANGBAND_TERM_MAX; n++) { /* Analyze the options */ for (i = 0; i < 32; i++) { /* Process valid flags */ if (window_flag_desc[i]) { /* Blank invalid flags */ if (!(window_mask[n] & (1L << i))) { window_flag[n] &= ~(1L << i); } } } } /* Set up the subwindows */ subwindows_set_flags(window_flag, ANGBAND_TERM_MAX); }
/* * Actually read the savefile */ static int rd_savefile_new_aux(void) { u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; /* Mention the savefile version */ note(format("Loading a %d.%d.%d savefile...", sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; /* Strip old data */ strip_bytes(20); if (!get_check("If you import this savefile, object memory will be lost. Is that OK? [y/n]")) return -1; if (rd_randomizer()) return -1; if (rd_options()) return -1; if (rd_messages()) return -1; if (rd_monster_memory()) return -1; if (rd_object_memory()) return -1; if (rd_quests()) return -1; if (rd_artifacts()) return -1; if (rd_player()) return -1; if (rd_squelch()) return -1; if (rd_misc()) return -1; if (rd_player_hp()) return -1; if (rd_player_spells()) return -1; if (rd_randarts()) return -1; if (rd_inventory()) return -1; if (rd_stores()) return -1; if (rd_dungeon()) return -1; if (rd_objects()) return -1; if (rd_monsters()) return -1; if (rd_ghost()) return -1; if (rd_history()) return -1; /* 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) { note("Invalid checksum"); return (-1); } /* 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) { note("Invalid encoded checksum"); return (-1); } /* Hack -- no ghosts */ r_info[z_info->r_max-1].max_num = 0; /* Success */ return (0); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i; byte tmp8u; u16b tmp16u; u32b tmp32u; int a_max; artifact_type *a_info_new; object_lore *a_list_new; #ifdef VERIFY_CHECKSUMS u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; #endif /* Mention the savefile version */ note(format("Loading a %d.%d.%d savefile...", sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; /* Operating system info */ rd_u32b(&sf_xtra); /* Time of savefile creation */ rd_u32b(&sf_when); /* Number of resurrections */ rd_u16b(&sf_lives); /* Number of times played */ rd_u16b(&sf_saves); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Read RNG state */ rd_randomizer(); if (arg_fiddle) note("Loaded Randomizer Info"); /* Then the options */ rd_options(); if (arg_fiddle) note("Loaded Option Flags"); /* Then the "messages" */ rd_messages(); if (arg_fiddle) note("Loaded Messages"); /* Monster Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->r_max) { note(format("Too many (%u) monster races!", tmp16u)); return (-1); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_lore(i); } if (arg_fiddle) note("Loaded Monster Memory"); /* Object Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->k_max) { note(format("Too many (%u) object kinds!", tmp16u)); return (-1); } /* Read the object memory */ for (i = 0; i < tmp16u; i++) { byte tmp8u; object_kind *k_ptr = &k_info[i]; rd_byte(&tmp8u); k_ptr->aware = (tmp8u == 1) ? TRUE: FALSE; k_ptr->tried = (tmp8u >= 2) ? TRUE: FALSE; if ((variant_guess_id) && (tmp8u > 2)) k_ptr->guess = (tmp8u - 2); /* Activations */ if ((variant_usage_id) && !(older_than(2,9,6))) rd_s16b(&k_ptr->used); } if (arg_fiddle) note("Loaded Object Memory"); /* Load the Quests */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > MAX_Q_IDX) { note(format("Too many (%u) quests!", tmp16u)); return (-1); } /* Load the Quests */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); q_list[i].level = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } if (arg_fiddle) note("Loaded Quests"); /* Load the Artifacts */ rd_u16b(&tmp16u); a_max = tmp16u; /* Incompatible save files */ if (a_max > 256) { note(format("Too many (%u) artifacts!", tmp16u)); return (-1); } /* Allocate the new artifact range */ C_MAKE(a_info_new, a_max, artifact_type); /* Allocate the new artifact range */ C_MAKE(a_list_new, a_max, object_lore); /* Read the artifact flags */ for (i = 0; i < a_max; i++) { object_lore *n_ptr = &a_list_new[i]; rd_byte(&tmp8u); a_info_new[i].cur_num = (tmp8u != 0); rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); if (variant_learn_id) { /* Knowledge */ rd_u32b(&n_ptr->can_flags1); rd_u32b(&n_ptr->can_flags2); rd_u32b(&n_ptr->can_flags3); rd_u32b(&n_ptr->not_flags1); rd_u32b(&n_ptr->not_flags2); rd_u32b(&n_ptr->not_flags3); } /* Activations */ if (variant_usage_id) rd_s16b(&a_info_new[i].activated); /* Oops */ if (variant_learn_id) rd_byte(&tmp8u); if (variant_learn_id) rd_byte(&tmp8u); } if (arg_fiddle) note("Loaded Artifacts"); if (variant_learn_id || variant_usage_id) { /* Load the Ego items */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->e_max) { note(format("Too many (%u) ego items!", tmp16u)); return (24); } /* Read the ego item flags */ for (i = 0; i < tmp16u; i++) { object_lore *n_ptr = &e_list[i]; /* Knowledge */ if (variant_learn_id) { rd_u32b(&n_ptr->can_flags1); rd_u32b(&n_ptr->can_flags2); rd_u32b(&n_ptr->can_flags3); rd_u32b(&n_ptr->may_flags1); rd_u32b(&n_ptr->may_flags2); rd_u32b(&n_ptr->may_flags3); rd_u32b(&n_ptr->not_flags1); rd_u32b(&n_ptr->not_flags2); rd_u32b(&n_ptr->not_flags3); } /* Oops */ if (variant_usage_id) rd_byte(&e_info[i].aware); if (variant_usage_id) rd_byte(&tmp8u); /* Oops */ if (variant_learn_id) rd_byte(&tmp8u); if (variant_learn_id) rd_byte(&tmp8u); } } if (arg_fiddle) note("Loaded Ego Items"); /* Read the extra stuff */ if (rd_extra()) return (-1); if (arg_fiddle) note("Loaded extra information"); /* Read random artifacts */ if ((adult_rand_artifacts) || (a_max == 256)) { if (rd_randarts()) return (-1); if (arg_fiddle) note("Loaded Random Artifacts"); } /* Only restore fixed arts if dead */ if (a_max > z_info->a_max) a_max = z_info->a_max; /* Don't restore fixed art knowledge if all random */ else if (p_ptr->is_dead) a_max = 0; /* Copy over the artifact flags */ for (i = 0; i < a_max; i++) { object_lore *n_ptr = &a_list[i]; object_lore *n2_ptr = &a_list_new[i]; a_info[i].cur_num = a_info_new[i].cur_num; if (variant_learn_id) { /* Knowledge */ n_ptr->can_flags1 = n2_ptr->can_flags1; n_ptr->can_flags2 = n2_ptr->can_flags2; n_ptr->can_flags3 = n2_ptr->can_flags3; n_ptr->not_flags1 = n2_ptr->not_flags1; n_ptr->not_flags2 = n2_ptr->not_flags2; n_ptr->not_flags3 = n2_ptr->not_flags3; } /* Activations */ if (variant_usage_id) a_info[i].activated = a_info_new[i].activated; } FREE(a_info_new); FREE(a_list_new); /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/class */ rp_ptr = &p_info[p_ptr->prace]; cp_ptr = &c_info[p_ptr->pclass]; /* Read the inventory */ if (rd_inventory()) { note("Unable to read inventory"); return (-1); } /* Read the stores */ rd_u16b(&tmp16u); for (i = 0; i < tmp16u; i++) { if (rd_store(i)) return (-1); } /* I'm not dead yet... */ if (!p_ptr->is_dead) { /* Dead players have no dungeon */ note("Restoring Dungeon..."); if (rd_dungeon()) { note("Error reading dungeon data"); return (-1); } /* Read the ghost info */ rd_ghost(); } #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) { note("Invalid checksum"); return (-1); } /* 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) { note("Invalid encoded checksum"); return (-1); } #endif /* Hack -- no ghosts */ r_info[z_info->r_max-1].max_num = 0; /* Set important Save-File Option */ variant_save_feats = TRUE; /* Success */ return (0); }
/* * Read an object * * This function attempts to "repair" old savefiles, and to extract * the most up to date values for various object fields. */ static errr rd_item(object_type *o_ptr) { byte old_dd; byte old_ds; u32b f1, f2, f3; object_kind *k_ptr; char buf[128]; /* Kind */ rd_s16b(&o_ptr->k_idx); /* Paranoia */ if ((o_ptr->k_idx < 0) || (o_ptr->k_idx >= z_info->k_max)) return (-1); /* Location */ rd_byte(&o_ptr->iy); rd_byte(&o_ptr->ix); /* Type/Subtype */ rd_byte(&o_ptr->tval); rd_byte(&o_ptr->sval); /* Special pval */ rd_s16b(&o_ptr->pval); /* Special stack counter */ if ((variant_pval_stacks)||(variant_time_stacks)) rd_byte(&o_ptr->stackc); rd_byte(&o_ptr->discount); rd_byte(&o_ptr->number); rd_s16b(&o_ptr->weight); rd_byte(&o_ptr->name1); rd_byte(&o_ptr->name2); rd_s16b(&o_ptr->timeout); rd_s16b(&o_ptr->to_h); rd_s16b(&o_ptr->to_d); rd_s16b(&o_ptr->to_a); rd_s16b(&o_ptr->ac); rd_byte(&old_dd); rd_byte(&old_ds); rd_byte(&o_ptr->ident); rd_byte(&o_ptr->marked); /* Hack -- fix rod/ring/dragon armor pval so that timeout set correctly in future */ if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_DRAG_ARMOR) || ((o_ptr->tval == TV_RING) && ((o_ptr->sval == SV_RING_FLAMES) || (o_ptr->sval == SV_RING_ACID) || (o_ptr->sval == SV_RING_ICE) || (o_ptr->sval == SV_RING_LIGHTNING)))) { o_ptr->pval = k_info[o_ptr->k_idx].pval; } /* Hack -- remove chests */ if (o_ptr->tval == TV_CHEST) o_ptr->k_idx = 0; /* Old flags */ strip_bytes(12); /* Monster holding object */ rd_s16b(&o_ptr->held_m_idx); /* Special powers */ rd_byte(&o_ptr->xtra1); rd_byte(&o_ptr->xtra2); /* Flags we have learnt about an item */ if (variant_learn_id) { /* Knowledge */ rd_u32b(&o_ptr->can_flags1); rd_u32b(&o_ptr->can_flags2); rd_u32b(&o_ptr->can_flags3); rd_u32b(&o_ptr->may_flags1); rd_u32b(&o_ptr->may_flags2); rd_u32b(&o_ptr->may_flags3); rd_u32b(&o_ptr->not_flags1); rd_u32b(&o_ptr->not_flags2); rd_u32b(&o_ptr->not_flags3); } /* Times we have used an item */ if (variant_usage_id) rd_s16b(&o_ptr->usage); /* Guessed an item as */ if (variant_guess_id) { rd_byte(&o_ptr->guess1); rd_byte(&o_ptr->guess2); } /* Item has a monster 'flavor' */ if (variant_drop_body) { rd_s16b(&o_ptr->name3); } /* Inscription */ rd_string(buf, 128); /* Save the inscription */ if (buf[0]) o_ptr->note = quark_add(buf); /* 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)) { /* Get the 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; /* Get the correct fields */ o_ptr->ac = k_ptr->ac; o_ptr->dd = k_ptr->dd; o_ptr->ds = k_ptr->ds; /* Get the correct weight */ o_ptr->weight = k_ptr->weight; /* Paranoia */ o_ptr->name1 = o_ptr->name2 = 0; /* All done */ return (0); } /* Extract the flags */ object_flags(o_ptr, &f1, &f2, &f3); /* Paranoia */ if (o_ptr->name1) { artifact_type *a_ptr; /* Paranoia */ if (o_ptr->name1 >= 256) return (-1); /* Obtain the artifact info */ a_ptr = &a_info[o_ptr->name1]; /* Verify that artifact */ if (!a_ptr->name) o_ptr->name1 = 0; } /* Paranoia */ if (o_ptr->name2) { ego_item_type *e_ptr; /* Paranoia */ if (o_ptr->name2 >= z_info->e_max) return (-1); /* Obtain the ego-item info */ e_ptr = &e_info[o_ptr->name2]; /* Verify that ego-item */ if (!e_ptr->name) o_ptr->name2 = 0; } /* Get the standard fields */ o_ptr->ac = k_ptr->ac; o_ptr->dd = k_ptr->dd; o_ptr->ds = k_ptr->ds; /* Get the 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]; /* Get the new artifact "pval" */ o_ptr->pval = a_ptr->pval; /* Get the new artifact fields */ o_ptr->ac = a_ptr->ac; o_ptr->dd = a_ptr->dd; o_ptr->ds = a_ptr->ds; /* Get the 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]; /* Hack -- keep some old fields */ if ((o_ptr->dd < old_dd) && (o_ptr->ds == old_ds)) { /* Keep old boosted damage dice */ o_ptr->dd = old_dd; } /* Hack -- extract the "broken" flag */ if (!e_ptr->cost) o_ptr->ident |= (IDENT_BROKEN); /* Hack -- enforce legal pval */ if (e_ptr->flags1 & (TR1_PVAL_MASK)) { /* Force a meaningful pval */ if (!o_ptr->pval) o_ptr->pval = 1; } /* Mega-Hack - Enforce the special broken items */ if ((o_ptr->name2 == EGO_BLASTED) || (o_ptr->name2 == EGO_SHATTERED)) { /* These were set to k_info values by preceding code */ o_ptr->ac = 0; o_ptr->dd = 0; o_ptr->ds = 0; } } /* Success */ return (0); }
/* * Read options (ignore most pre-2.8.0 options) * * Note that the normal options are now stored as a set of 256 bit flags, * plus a set of 256 bit masks to indicate which bit flags were defined * at the time the savefile was created. This will allow new options * to be added, and old options to be removed, at any time, without * hurting old savefiles. * * The window options are stored in the same way, but note that each * window gets 32 options, and their order is fixed by certain defines. */ static void rd_options(void) { int i, n; byte b; u16b c; u32b flag[8]; u32b mask[8]; /*** Oops ***/ /* Ignore old options */ strip_bytes(16); /*** Special info */ /* Read "delay_factor" */ rd_byte(&b); delay_factor = b; /* Read "hitpoint_warn" */ rd_byte(&b); hitpoint_warn = b; /* Read "spellpoint_warn" */ rd_byte(&b); spellpoint_warn = b; /*** Cheating options ***/ rd_u16b(&c); if (c & 0x0002) wizard = TRUE; cheat_peek = (c & 0x0100) ? TRUE : FALSE; cheat_hear = (c & 0x0200) ? TRUE : FALSE; cheat_room = (c & 0x0400) ? TRUE : FALSE; cheat_xtra = (c & 0x0800) ? TRUE : FALSE; cheat_know = (c & 0x1000) ? TRUE : FALSE; cheat_live = (c & 0x2000) ? TRUE : FALSE; rd_byte(&autosave_l); rd_byte(&autosave_t); rd_s16b(&autosave_freq); /*** Normal Options ***/ /* Read the option flags */ for (n = 0; n < 8; n++) rd_u32b(&flag[n]); /* Read the option masks */ for (n = 0; n < 8; n++) rd_u32b(&mask[n]); /* Analyze the options */ for (n = 0; n < 8; n++) { /* Analyze the options */ for (i = 0; i < 32; i++) { /* Process valid flags */ if (mask[n] & (1L << i)) { /* Process valid flags */ if (option_mask[n] & (1L << i)) { /* Set */ if (flag[n] & (1L << i)) { /* Set */ option_flag[n] |= (1L << i); } /* Clear */ else { /* Clear */ option_flag[n] &= ~(1L << i); } } } } } /*** Window Options ***/ /* Read the window flags */ for (n = 0; n < 8; n++) rd_u32b(&flag[n]); /* Read the window masks */ for (n = 0; n < 8; n++) rd_u32b(&mask[n]); /* Analyze the options */ for (n = 0; n < 8; n++) { /* Analyze the options */ for (i = 0; i < 32; i++) { /* Process valid flags */ if (mask[n] & (1L << i)) { /* Process valid flags */ if (window_mask[n] & (1L << i)) { /* Set */ if (flag[n] & (1L << i)) { /* Set */ window_flag[n] |= (1L << i); } /* Clear */ else { /* Clear */ window_flag[n] &= ~(1L << i); } } } } } }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i, j; int town_count; s32b wild_x_size; s32b wild_y_size; byte tmp8u; u16b tmp16u; u32b tmp32u; u16b tmp_k_idx; #ifdef VERIFY_CHECKSUMS u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; #endif /* Mention the savefile version */ #ifdef JP note(format("バージョン %d.%d.%d のセーブ・ファイルをロード中...", #else note(format("Loading a %d.%d.%d savefile...", #endif sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; #if SAVEFILE_VERSION /* Read the version number of the savefile */ rd_u32b(&sf_version); #endif /* SAVEFILE_VERSION */ /* Operating system info */ rd_u32b(&sf_xtra); /* Time of savefile creation */ rd_u32b(&sf_when); /* Number of resurrections */ rd_u16b(&sf_lives); /* Number of times played */ rd_u16b(&sf_saves); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Later use (always zero) */ rd_u16b(&tmp16u); /* Later use (always zero) */ rd_byte(&tmp8u); /* Kanji code */ rd_byte(&kanji_code); /* Read RNG state */ rd_randomizer(); #ifdef JP if (arg_fiddle) note("乱数情報をロードしました"); #else if (arg_fiddle) note("Loaded Randomizer Info"); #endif /* Then the options */ rd_options(); #ifdef JP if (arg_fiddle) note("オプションをロードしました"); #else 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 if (arg_fiddle) note("メッセージをロードしました"); #else if (arg_fiddle) note("Loaded Messages"); #endif /* Monster Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > max_r_idx) { #ifdef JP note(format("モンスターの種族が多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) monster races!", tmp16u)); #endif return (21); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_lore(i); } #ifdef JP if (arg_fiddle) note("モンスターの思い出をロードしました"); #else if (arg_fiddle) note("Loaded Monster Memory"); #endif /* Object Memory */ rd_u16b(&tmp_k_idx); /* Incompatible save files */ if (tmp_k_idx > max_k_idx) { #ifdef JP note(format("アイテムの種類が多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) object kinds!", tmp16u)); #endif return (22); } /* Make array for object memory */ C_MAKE(obj_mem, tmp_k_idx, byte); /* Read the object memory */ for (i = 0; i < tmp_k_idx; i++) { #if 0 byte tmp8u; object_kind *k_ptr = &k_info[i]; rd_byte(&tmp8u); k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; #else rd_byte(&obj_mem[i]); #endif } #ifdef JP if (arg_fiddle) note("アイテムの記録をロードしました"); #else if (arg_fiddle) note("Loaded Object Memory"); #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->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++) { for (j = 0; j < max_wild_y; j++) { wilderness[j][i].seed = randint0(0x10000000); } } /* 2.1.3 or newer version */ { u16b max_towns_load; u16b max_quests_load; byte max_rquests_load; /* Number of towns */ rd_u16b(&max_towns_load); /* Incompatible save files */ if (max_towns_load > max_towns) { #ifdef JP note(format("町が多すぎる(%u)!", max_towns_load)); #else note(format("Too many (%u) towns!", max_towns_load)); #endif return (23); } /* Number of quests */ rd_u16b(&max_quests_load); rd_byte(&max_rquests_load); /* Incompatible save files */ if (max_quests_load > max_quests) { #ifdef JP note(format("クエストが多すぎる(%u)!", max_quests_load)); #else note(format("Too many (%u) quests!", max_quests_load)); #endif return (23); } for (i = 0; i < max_quests_load; i++) { if (i < max_quests) { rd_s16b(&quest[i].status); rd_s16b(&quest[i].level); rd_byte(&quest[i].complev); /* Load quest status if quest is running */ if ((quest[i].status == QUEST_STATUS_TAKEN) || (quest[i].status == QUEST_STATUS_COMPLETED) || ((i >= MIN_RANDOM_QUEST) && (i <= (MIN_RANDOM_QUEST + max_rquests_load)))) { rd_s16b(&quest[i].cur_num); rd_s16b(&quest[i].max_num); rd_s16b(&quest[i].type); /* Load quest monster index */ rd_s16b(&quest[i].r_idx); 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 + 10); r_ptr = &r_info[r_idx]; if(!(r_ptr->flags1 & RF1_UNIQUE)) continue; if (r_ptr->flags1 & RF1_QUESTOR) continue; if (r_ptr->level >= quest[i].level + 5) continue; if (r_ptr->level >= quest[i].level) break; } quest[i].r_idx = r_idx; } /* Load quest item index */ rd_s16b(&quest[i].k_idx); if (quest[i].k_idx) a_info[quest[i].k_idx].gen_flags |= TRG_QUESTITEM; /* Load quest flags */ rd_byte(&quest[i].flags); } } /* Ignore the empty quests from old versions */ else { /* Ignore quest status */ strip_bytes(2); /* Ignore quest level */ strip_bytes(2); /* * We don't have to care about the other info, * since status should be 0 for these quests anyway */ } } /* Position in the wilderness */ rd_s32b(&p_ptr->wilderness_x); rd_s32b(&p_ptr->wilderness_y); /* Size of the wilderness */ rd_s32b(&wild_x_size); rd_s32b(&wild_y_size); /* Incompatible save files */ if ((wild_x_size > max_wild_x) || (wild_y_size > max_wild_y)) { #ifdef JP note(format("荒野が大きすぎる(%u/%u)!", wild_x_size, wild_y_size)); #else note(format("Wilderness is too big (%u/%u)!", wild_x_size, wild_y_size)); #endif return (23); } /* Load the wilderness seeds */ for (i = 0; i < wild_x_size; i++) { for (j = 0; j < wild_y_size; j++) { rd_u32b(&wilderness[j][i].seed); } } } #ifdef JP if (arg_fiddle) note("クエスト情報をロードしました"); #else if (arg_fiddle) note("Loaded Quests"); #endif /* Load the Artifacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > max_a_idx) { #ifdef JP note(format("伝説のアイテムが多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) artifacts!", tmp16u)); #endif return (24); } /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); a_info[i].cur_num = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } #ifdef JP if (arg_fiddle) note("伝説のアイテムをロードしました"); #else if (arg_fiddle) note("Loaded Artifacts"); #endif /* Read the extra stuff */ rd_extra(); #ifdef JP if (arg_fiddle) note("特別情報をロードしました"); #else if (arg_fiddle) note("Loaded extra information"); #endif /* Read the player_hp array */ rd_u16b(&tmp16u); /* Remark questor flag on random quester */ if (!death) { for (i = MIN_RANDOM_QUEST; i <= MAX_RANDOM_QUEST; i++) { r_info[quest[i].r_idx].flags1 |= RF1_QUESTOR; } } /* Incompatible save files */ if (tmp16u > PY_MAX_LEVEL) { #ifdef JP note(format("ヒットポイント配列が大きすぎる(%u)!", tmp16u)); #else note(format("Too many (%u) hitpoint entries!", tmp16u)); #endif return (25); } /* Read the player_hp array */ for (i = 0; i < tmp16u; i++) { rd_s16b(&player_hp[i]); } /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/class */ rp_ptr = &race_info[p_ptr->prace]; cp_ptr = &class_info[p_ptr->pclass]; /* Important -- Initialize the magic */ mp_ptr = &m_info[p_ptr->pclass]; /* 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); for (i = 0; i < 64; i++) { rd_byte(&spell_order[i]); } /* Read the inventory */ if (rd_inventory()) { #ifdef JP note("持ち物情報を読み込むことができません"); #else note("Unable to read inventory"); #endif return (21); } /* Read number of towns */ rd_u16b(&tmp16u); town_count = tmp16u; /* Read the stores */ rd_u16b(&tmp16u); for (i = 1; i < town_count; i++) { for (j = 0; j < tmp16u; j++) { if (rd_store(i, j)) return (22); } } for (i = 0; i < tmp_k_idx; i++) { byte tmp8u = obj_mem[i]; object_kind *k_ptr = &k_info[i]; k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; } /* Free array for object memories */ C_KILL(obj_mem, tmp_k_idx, byte); /* Read the pet command settings */ if (sf_version > 2) { rd_s16b(&p_ptr->pet_follow_distance); rd_byte(&p_ptr->pet_open_doors); rd_byte(&p_ptr->pet_pickup_items); } else { rd_byte(&tmp8u); p_ptr->pet_follow_distance = tmp8u; rd_byte(&p_ptr->pet_open_doors); rd_byte(&p_ptr->pet_pickup_items); } /* I'm not dead yet... */ if (!death) { /* Dead players have no dungeon */ #ifdef JP note("ダンジョン復元中..."); #else note("Restoring Dungeon..."); #endif if (rd_dungeon()) { #ifdef JP note("ダンジョンデータ読み込み失敗"); #else note("Error reading dungeon data"); #endif return (34); } /* Read the ghost info */ rd_ghost(); { s32b tmp32s; rd_s32b(&tmp32s); strip_bytes(tmp32s); } } #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) { #ifdef JP note("チェックサムがおかしい"); #else note("Invalid checksum"); #endif return (11); } /* 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) { #ifdef JP note("エンコードされたチェックサムがおかしい"); #else note("Invalid encoded checksum"); #endif return (11); } #endif /* Success */ return (0); }
void rd_s32b(s32b *ip) { rd_u32b((u32b*)ip); }
/* * Read the "extra" information */ static void rd_extra(void) { int i; byte tmp8u; s16b tmp16s; rd_string(player_name, sizeof(player_name)); rd_string(died_from, sizeof(died_from)); load_quick_start(); for (i = 0; i < 4; i++) { rd_string(history[i], sizeof(history[i])); } /* Class/Race/Gender/Spells */ rd_byte(&p_ptr->prace); rd_byte(&p_ptr->pclass); rd_byte(&p_ptr->psex); rd_byte(&p_ptr->realm1); rd_byte(&p_ptr->realm2); rd_byte(&tmp8u); /* oops */ /* Special Race/Class info */ rd_byte(&p_ptr->hitdie); rd_u16b(&p_ptr->expfact); /* Age/Height/Weight */ rd_s16b(&p_ptr->age); rd_s16b(&p_ptr->ht); rd_s16b(&p_ptr->wt); /* Read the stat info */ for (i = 0; i < 6; i++) rd_s16b(&p_ptr->stat_max[i]); for (i = 0; i < 6; i++) rd_s16b(&p_ptr->stat_cur[i]); strip_bytes(24); /* oops */ rd_s32b(&p_ptr->au); rd_s32b(&p_ptr->max_exp); rd_s32b(&p_ptr->exp); rd_u16b(&p_ptr->exp_frac); rd_s16b(&p_ptr->lev); rd_s16b(&p_ptr->town_num); /* Read arena and rewards information */ rd_s16b(&p_ptr->arena_number); rd_s16b(&p_ptr->inside_arena); rd_s16b(&p_ptr->inside_quest); rd_byte(&p_ptr->exit_bldg); rd_byte(&tmp8u); rd_s16b(&p_ptr->oldpx); rd_s16b(&p_ptr->oldpy); rd_s16b(&tmp16s); if (tmp16s > MAX_BACT) { #ifdef JP note(format("の中", tmp16s)); #else note(format("Too many (%d) building rewards!", tmp16s)); #endif } for (i = 0; i < tmp16s; i++) rd_s16b(&p_ptr->rewards[i]) ; rd_s16b(&p_ptr->mhp); rd_s16b(&p_ptr->chp); rd_u16b(&p_ptr->chp_frac); rd_s16b(&p_ptr->msp); rd_s16b(&p_ptr->csp); rd_u16b(&p_ptr->csp_frac); rd_s16b(&p_ptr->max_plv); rd_s16b(&p_ptr->max_dlv); /* Repair maximum player level XXX XXX XXX */ if (p_ptr->max_plv < p_ptr->lev) p_ptr->max_plv = p_ptr->lev; /* Repair maximum dungeon level */ if (p_ptr->max_dlv < 0) p_ptr->max_dlv = 1; /* More info */ strip_bytes(8); rd_s16b(&p_ptr->sc); strip_bytes(2); /* Read the flags */ strip_bytes(2); /* Old "rest" */ rd_s16b(&p_ptr->blind); rd_s16b(&p_ptr->paralyzed); rd_s16b(&p_ptr->confused); rd_s16b(&p_ptr->food); strip_bytes(4); /* Old "food_digested" / "protection" */ rd_s16b(&p_ptr->energy_need); rd_s16b(&p_ptr->fast); rd_s16b(&p_ptr->slow); rd_s16b(&p_ptr->afraid); rd_s16b(&p_ptr->cut); rd_s16b(&p_ptr->stun); rd_s16b(&p_ptr->poisoned); rd_s16b(&p_ptr->image); rd_s16b(&p_ptr->protevil); rd_s16b(&p_ptr->invuln); rd_s16b(&p_ptr->hero); rd_s16b(&p_ptr->shero); rd_s16b(&p_ptr->shield); rd_s16b(&p_ptr->magicdef); rd_s16b(&p_ptr->musou); rd_s16b(&p_ptr->blessed); rd_s16b(&p_ptr->tim_invis); rd_s16b(&p_ptr->word_recall); rd_s16b(&p_ptr->see_infra); rd_s16b(&p_ptr->tim_infra); rd_s16b(&p_ptr->tim_regen); rd_s16b(&p_ptr->tim_sh_fire); rd_s16b(&p_ptr->tim_sh_elec); rd_s16b(&p_ptr->tim_sh_cold); rd_s16b(&p_ptr->oppose_fire); rd_s16b(&p_ptr->oppose_cold); rd_s16b(&p_ptr->oppose_acid); rd_s16b(&p_ptr->oppose_elec); rd_s16b(&p_ptr->oppose_pois); rd_s16b(&p_ptr->tim_esp); rd_s16b(&p_ptr->tim_wraith); rd_s16b(&p_ptr->resist_magic); rd_s16b(&p_ptr->tim_radar); rd_s16b(&p_ptr->tim_might); rd_s16b(&p_ptr->tim_xtra2); rd_s16b(&p_ptr->tim_xtra3); rd_s16b(&p_ptr->tim_brand); rd_u32b(&p_ptr->xtra_brand); rd_s16b(&p_ptr->valar_patron); rd_u32b(&p_ptr->muta); /* Calc the regeneration modifier for mutations */ mutant_regenerate_mod = calc_mutant_regenerate_mod(); rd_byte(&p_ptr->confusing); rd_byte(&tmp8u); /* oops */ rd_byte(&tmp8u); p_ptr->autopick_autoregister = tmp8u ? TRUE : FALSE; rd_byte(&tmp8u); /* oops */ rd_byte(&p_ptr->searching); rd_byte(&tmp8u); /* maximize_mode was deleted */ rd_byte(&preserve_mode); rd_byte(&tmp8u); /* Future use */ for (i = 0; i < 48; i++) rd_byte(&tmp8u); /* Skip the flags */ strip_bytes(12); /* Hack -- the two "special seeds" */ rd_u32b(&seed_flavor); rd_u32b(&seed_town); /* Special stuff */ rd_u16b(&panic_save); rd_u16b(&total_winner); rd_u16b(&noscore); /* Read "death" */ rd_byte(&tmp8u); death = tmp8u; /* Read "feeling" */ rd_byte(&p_ptr->feeling); /* Turn when level began */ rd_s32b(&old_turn); /* Turn of last "feeling" */ rd_s32b(&p_ptr->feeling_turn); /* Current turn */ rd_s32b(&turn); /* Current total playtime */ rd_u32b(&playtime); }