int read_device_file(char *filename) { FILE *f; int i, j, n; if ((f = fopen(filename, "rb")) == NULL) return -1; /* read file header */ memset(&hdr, 0, sizeof(dat_hdr_t)); fread(&hdr, sizeof(int), 3, f); rd_string(f, &hdr.notes[0]); fread(&hdr.num_families, sizeof(dat_hdr_t) - offsetof(dat_hdr_t, num_families), 1, f); /* read family entries */ families = (family_ent_t *) malloc(sizeof(family_ent_t) * hdr.num_families); memset(families, 0, sizeof(family_ent_t) * hdr.num_families); for (i = 0; i < hdr.num_families; i++) { fread(&families[i], offsetof(family_ent_t, name), 1, f); rd_string(f, &families[i].name[0]); fread(&families[i].prg_entry_script, sizeof(family_ent_t) - offsetof(family_ent_t, prg_entry_script), 1, f); } /* read device entries */ devices = (device_ent_t *) malloc(sizeof(device_ent_t) * hdr.num_devices); memset(devices, 0, sizeof(device_ent_t) * hdr.num_devices); for (i = 0; i < hdr.num_devices; i++) { rd_string(f, &devices[i].part_name[0]); fread(&devices[i].family, sizeof(device_ent_t) - offsetof(device_ent_t, family), 1, f); } /* read script entries */ scripts = (script_ent_t *) malloc(sizeof(script_ent_t) * hdr.num_scripts); memset(scripts, 0, sizeof(script_ent_t) * hdr.num_scripts); for (i = 0; i < hdr.num_scripts; i++) { fread(&scripts[i], sizeof(uint16_t), 1, f); rd_string(f, &scripts[i].name[0]); fread(&scripts[i].version, offsetof(script_ent_t, script) - offsetof(script_ent_t, version), 1, f); fread(&scripts[i].script, scripts[i].script_length, sizeof(uint16_t), f); rd_string(f, &scripts[i].comment[0]); /* check if name already exists */ n = 0; scripts[i].org_name[0] = 0; for (j = 0; j < i; j++) if (strcmp(scripts[j].name, scripts[i].name) == 0) n++; if (n > 0) { /* if there are more scripts that share the same name * rename them, and store there orginal name in "org_name" * member */ strcpy(scripts[i].org_name, scripts[i].name); sprintf(scripts[i].name, "%s_%d", scripts[i].org_name, n); printf("%d scripts with name \"%s\" -> renaming to \"%s\"\n", n, scripts[i].org_name, scripts[i].name); } } fclose(f); return 0; }
/* * Read the notes. Every new savefile has at least NOTES_MARK. */ static bool rd_notes(void) { int alive = (!p_ptr->is_dead || arg_wizard); char tmpstr[100]; if (alive && adult_take_notes) { /* Create the tempfile (notes_file & notes_fname are global) */ create_notes_file(); if (!notes_file) { note("Can't create a temporary file for notes"); return (TRUE); } /* Append the notes in the savefile to the tempfile*/ while (TRUE) { rd_string(tmpstr, sizeof(tmpstr)); /* Found the end? */ if (strstr(tmpstr, NOTES_MARK)) break; file_putf(notes_file, "%s\n", tmpstr); } /* Paranoia. Remove the notes from memory */ file_flush(notes_file); } /* Ignore the notes */ else { while (TRUE) { rd_string(tmpstr, sizeof(tmpstr)); /* Found the end? */ if (strstr(tmpstr, NOTES_MARK)) { break; } } } return (FALSE); }
/* * 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); }
/* * Save quick start data */ static void load_quick_start(void) { byte tmp8u; int i; rd_byte(&previous_char.psex); rd_byte(&previous_char.prace); rd_byte(&previous_char.pclass); rd_byte(&previous_char.realm1); rd_byte(&previous_char.realm2); rd_s16b(&previous_char.age); rd_s16b(&previous_char.ht); rd_s16b(&previous_char.wt); rd_s16b(&previous_char.sc); rd_s32b(&previous_char.au); for (i = 0; i < 6; i++) rd_s16b(&previous_char.stat_max[i]); for (i = 0; i < PY_MAX_LEVEL; i++) rd_s16b(&previous_char.player_hp[i]); rd_s16b(&previous_char.valar_patron); for (i = 0; i < 4; i++) rd_string(previous_char.history[i], sizeof(previous_char.history[i])); rd_byte(&previous_char.quests); rd_byte(&tmp8u); previous_char.quick_ok = (bool)tmp8u; }
/* * Read the saved messages */ static void rd_messages(void) { int i; char buf[128]; u16b tmp16u; s16b num; /* Total */ rd_s16b(&num); /* Read the messages */ for (i = 0; i < num; i++) { /* Read the message */ rd_string(buf, 128); /* Read the message type */ if (!older_than(2, 9, 1)) rd_u16b(&tmp16u); else tmp16u = MSG_GENERIC; /* Save the message */ message_add(buf, tmp16u); } }
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 the saved messages */ static int rd_messages(void) { int i; char buf[128]; u16b tmp16u; s16b num; /* Total */ rd_s16b(&num); /* Read the messages */ for (i = 0; i < num; i++) { /* Read the message */ rd_string(buf, sizeof(buf)); /* Read the message type */ rd_u16b(&tmp16u); /* Save the message */ message_add(buf, tmp16u); } return 0; }
/* * Read squelch and autoinscription submenu for all known objects */ static int rd_squelch(void) { size_t i; byte tmp8u = 24; /* Read how many squelch bytes we have */ rd_byte(&tmp8u); /* Check against current number */ if (tmp8u != squelch_size) { strip_bytes(tmp8u); } else { for (i = 0; i < squelch_size; i++) rd_byte(&squelch_level[i]); } /* Handle ego-item squelch */ if ((sf_major == 3) && (sf_minor == 0) && (sf_patch != 9)) { u16b file_e_max; /* Read the number of saved ego-item */ rd_u16b(&file_e_max); for (i = 0; i < file_e_max; i++) { if (i < z_info->e_max) { byte flags; /* Read and extract the flag */ rd_byte(&flags); e_info[i].everseen |= (flags & 0x02); } } } else { } /* Read the current number of auto-inscriptions */ rd_u16b(&inscriptions_count); /* Write the autoinscriptions array*/ for (i = 0; i < inscriptions_count; i++) { char tmp[80]; rd_s16b(&inscriptions[i].kind_idx); rd_string(tmp, sizeof(tmp)); inscriptions[i].inscription_idx = quark_add(tmp); } return 0; }
/* * Hack -- strip the "ghost" info * * XXX XXX XXX This is such a nasty hack it hurts. */ static void rd_ghost(void) { char buf[64]; /* Strip name */ rd_string(buf, 64); /* Strip old data */ strip_bytes(60); }
/** * Read monster memory. */ int rd_monster_memory(void) { u16b tmp16u; char buf[128]; int i; /* Monster temporary flags */ rd_byte(&mflag_size); /* Incompatible save files */ if (mflag_size > MFLAG_SIZE) { note(format("Too many (%u) monster temporary flags!", mflag_size)); return (-1); } /* Reset maximum numbers per level */ for (i = 1; z_info && i < z_info->r_max; i++) { struct monster_race *race = &r_info[i]; race->max_num = 100; if (rf_has(race->flags, RF_UNIQUE)) race->max_num = 1; } rd_string(buf, sizeof(buf)); while (!streq(buf, "No more monsters")) { struct monster_race *race = lookup_monster(buf); /* Get the kill count, skip if monster invalid */ rd_u16b(&tmp16u); if (!race) continue; /* Store the kill count, ensure dead uniques stay dead */ l_list[race->ridx].pkills = tmp16u; if (rf_has(race->flags, RF_UNIQUE) && tmp16u) race->max_num = 0; /* Look for the next monster */ rd_string(buf, sizeof(buf)); } return 0; }
/* * Read the notes. Every new savefile has at least NOTES_MARK. */ static bool rd_notes(void) { int alive = (!p_ptr->is_dead || arg_wizard); char tmpstr[100]; int i; // reset the notes buffer for (i = 0; i < NOTES_LENGTH; i++) { notes_buffer[i] = '\0'; } if (alive) { /* Append the notes in the savefile to the buffer */ while (TRUE) { rd_string(tmpstr, sizeof(tmpstr)); /* Found the end? */ if (strstr(tmpstr, NOTES_MARK)) break; my_strcat(notes_buffer, format("%s\n", tmpstr), sizeof(notes_buffer)); } } /* Ignore the notes */ else { while (TRUE) { rd_string(tmpstr, sizeof(tmpstr)); /* Found the end? */ if (strstr(tmpstr, NOTES_MARK)) { break; } } } return 0; }
/** * Read the player information */ int rd_player(void) { int i; byte num; byte stat_max = 0; char buf[80]; struct player_race *r; struct player_class *c; rd_string(player->full_name, sizeof(player->full_name)); rd_string(player->died_from, 80); player->history = mem_zalloc(250); rd_string(player->history, 250); /* Player race */ rd_string(buf, sizeof(buf)); for (r = races; r; r = r->next) { if (streq(r->name, buf)) { player->race = r; break; } } /* Verify player race */ if (!player->race) { note(format("Invalid player race (%s).", buf)); return -1; } /* Player class */ rd_string(buf, sizeof(buf)); for (c = classes; c; c = c->next) { if (streq(c->name, buf)) { player->class = c; break; } }
static int rd_ghost(void) { char buf[64]; /* Only if the player's alive */ if (p_ptr->is_dead) return 0; /* XXX */ /* Strip name */ rd_string(buf, 64); /* Strip old data */ strip_bytes(60); return 0; }
/** * Read a trap record */ static void rd_trap(struct trap *trap) { int i; char buf[80]; rd_string(buf, sizeof(buf)); if (buf[0]) { trap->kind = lookup_trap(buf); trap->t_idx = trap->kind->tidx; } rd_byte(&trap->fy); rd_byte(&trap->fx); rd_byte(&trap->power); rd_byte(&trap->timeout); for (i = 0; i < trf_size; i++) rd_byte(&trap->flags[i]); }
/* * Read the saved messages */ static void rd_messages(void) { int i; char buf[128]; s16b num; /* Total */ rd_s16b(&num); /* Read the messages */ for (i = 0; i < num; i++) { /* Read the message */ rd_string(buf, sizeof(buf)); /* Save the message */ message_add(buf); } }
/** * Read options. */ int rd_options(void) { byte b; u16b tmp16u; /*** Special info */ /* Read "delay_factor" */ rd_byte(&b); player->opts.delay_factor = b; /* Read "hitpoint_warn" */ rd_byte(&b); player->opts.hitpoint_warn = b; /* Read lazy movement delay */ rd_u16b(&tmp16u); player->opts.lazymove_delay = (tmp16u < 1000) ? tmp16u : 0; /* Read options */ while (1) { byte value; char name[40]; rd_string(name, sizeof name); if (!name[0]) break; rd_byte(&value); option_set(name, !!value); } return 0; }
/** * Read a monster */ static bool rd_monster(struct chunk *c, struct monster *mon) { byte tmp8u; u16b tmp16u; char race_name[80]; size_t j; /* Read the monster race */ rd_string(race_name, sizeof(race_name)); mon->race = lookup_monster(race_name); if (!mon->race) { note(format("Monster race %s no longer exists!", race_name)); return (-1); } /* Read the other information */ rd_byte(&mon->fy); rd_byte(&mon->fx); rd_s16b(&mon->hp); rd_s16b(&mon->maxhp); rd_byte(&mon->mspeed); rd_byte(&mon->energy); rd_byte(&tmp8u); for (j = 0; j < tmp8u; j++) rd_s16b(&mon->m_timed[j]); /* Read and extract the flag */ for (j = 0; j < mflag_size; j++) rd_byte(&mon->mflag[j]); for (j = 0; j < of_size; j++) rd_byte(&mon->known_pstate.flags[j]); for (j = 0; j < elem_max; j++) rd_s16b(&mon->known_pstate.el_info[j].res_level); rd_u16b(&tmp16u); if (tmp16u) { /* Find and set the mimicked object */ struct object *square_obj = square_object(c, mon->fy, mon->fx); /* Try and find the mimicked object; if we fail, create a new one */ while (square_obj) { if (square_obj->mimicking_m_idx == tmp16u) break; square_obj = square_obj->next; } if (square_obj) { mon->mimicked_obj = square_obj; } else { mon_create_mimicked_object(c, mon, tmp16u); } } /* Read all the held objects (order is unimportant) */ while (true) { struct object *obj = rd_item(); if (!obj) break; pile_insert(&mon->held_obj, obj); assert(obj->oidx); assert(c->objects[obj->oidx] == NULL); c->objects[obj->oidx] = obj; } return true; }
/* * Read the "extra" information */ static int rd_player(void) { int i; byte num; rd_string(op_ptr->full_name, sizeof(op_ptr->full_name)); rd_string(p_ptr->died_from, 80); 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); } rp_ptr = &p_info[p_ptr->prace]; /* 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); } cp_ptr = &c_info[p_ptr->pclass]; mp_ptr = &cp_ptr->spells; /* Player gender */ rd_byte(&p_ptr->psex); sp_ptr = &sex_info[p_ptr->psex]; /* Numeric name suffix */ rd_byte(&op_ptr->name_suffix); /* 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]); for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_birth[i]); rd_s16b(&p_ptr->ht_birth); rd_s16b(&p_ptr->wt_birth); rd_s32b(&p_ptr->au_birth); strip_bytes(4); 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 */ strip_bytes(8); rd_s16b(&p_ptr->sc); strip_bytes(2); /* Read the flags */ rd_s16b(&p_ptr->food); rd_s16b(&p_ptr->energy); rd_s16b(&p_ptr->word_recall); rd_s16b(&p_ptr->state.see_infra); rd_byte(&p_ptr->confusing); rd_byte(&p_ptr->searching); /* Find the number of timed effects */ rd_byte(&num); if (num <= TMD_MAX) { /* Read all the effects */ for (i = 0; i < num; i++) rd_s16b(&p_ptr->timed[i]); /* Initialize any entries not read */ if (num < TMD_MAX) C_WIPE(p_ptr->timed + num, TMD_MAX - num, s16b); } else { /* Probably in trouble anyway */ for (i = 0; i < TMD_MAX; i++) rd_s16b(&p_ptr->timed[i]); /* Discard unused entries */ strip_bytes(2 * (num - TMD_MAX)); note("Discarded unsupported timed effects"); } /* Future use */ strip_bytes(40); 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 int rd_item(object_type *o_ptr) { byte old_dd; byte old_ds; byte tmp8u; size_t i; 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); rd_s16b(&o_ptr->pval); /* Pseudo-ID bit */ rd_byte(&tmp8u); 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(&tmp8u); rd_byte(&o_ptr->marked); rd_byte(&o_ptr->origin); rd_byte(&o_ptr->origin_depth); rd_u16b(&o_ptr->origin_xtra); /* Hack - XXX - MarbleDice - Maximum saveable flags = 96 */ for (i = 0; i < 12 && i < OF_SIZE; i++) rd_byte(&o_ptr->flags[i]); if (i < 12) strip_bytes(OF_SIZE - i); /* Monster holding object */ rd_s16b(&o_ptr->held_m_idx); rd_string(buf, sizeof(buf)); /* Save the inscription */ if (buf[0]) o_ptr->note = quark_add(buf); /* Lookup item kind */ o_ptr->k_idx = lookup_kind(o_ptr->tval, o_ptr->sval); k_ptr = &k_info[o_ptr->k_idx]; /* Return now in case of "blank" or "empty" objects */ if (!k_ptr->name || !o_ptr->k_idx) { o_ptr->k_idx = 0; return 0; } /* Repair non "wearable" items */ if (!wearable_p(o_ptr)) { /* Get the correct fields */ if (!randcalc_valid(k_ptr->to_h, o_ptr->to_h)) o_ptr->to_h = randcalc(k_ptr->to_h, o_ptr->origin_depth, RANDOMISE); if (!randcalc_valid(k_ptr->to_d, o_ptr->to_d)) o_ptr->to_d = randcalc(k_ptr->to_d, o_ptr->origin_depth, RANDOMISE); if (!randcalc_valid(k_ptr->to_a, o_ptr->to_a)) o_ptr->to_a = randcalc(k_ptr->to_a, o_ptr->origin_depth, RANDOMISE); /* 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); } /* Paranoia */ if (o_ptr->name1) { artifact_type *a_ptr; /* Paranoia */ if (o_ptr->name1 >= z_info->a_max) 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; /* 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; } /* 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 -- enforce legal pval */ if (flags_test(e_ptr->flags, OF_SIZE, OF_PVAL_MASK, FLAG_END)) { /* Force a meaningful pval */ if (!o_ptr->pval) o_ptr->pval = 1; } } /* 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) { u32b f1, f2, f3; object_kind *k_ptr; char buf[128]; int i; /* Kind */ rd_s16b(&o_ptr->k_idx); /* Paranoia */ if ((o_ptr->k_idx < 0) || (o_ptr->k_idx >= z_info->k_max)) { return (-1); } /* Hallucinatory Kind */ rd_s16b(&o_ptr->image_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); /* Special pval */ rd_s16b(&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_s16b(&o_ptr->timeout); rd_s16b(&o_ptr->att); rd_byte(&o_ptr->dd); rd_byte(&o_ptr->ds); rd_s16b(&o_ptr->evn); rd_byte(&o_ptr->pd); rd_byte(&o_ptr->ps); rd_byte(&o_ptr->pickup); rd_u32b(&o_ptr->ident); rd_byte(&o_ptr->marked); /* Monster holding object */ rd_s16b(&o_ptr->held_m_idx); /* Special powers */ rd_byte(&o_ptr->xtra1); // granted abilities rd_byte(&o_ptr->abilities); for (i = 0; i < 8; i++) { rd_byte(&o_ptr->skilltype[i]); rd_byte(&o_ptr->abilitynum[i]); } // 8 spare bytes strip_bytes(8); /* Inscription */ rd_string(buf, sizeof(buf)); /* Save the inscription */ if (buf[0]) o_ptr->obj_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->att = k_ptr->att; o_ptr->evn = k_ptr->evn; /* Get the correct fields */ o_ptr->dd = k_ptr->dd; o_ptr->ds = k_ptr->ds; o_ptr->pd = k_ptr->pd; o_ptr->ps = k_ptr->ps; /* 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) { artefact_type *a_ptr; /*hack - adjust if new artefact*/ if (o_ptr->name1 >= art_norm_count) { o_ptr->name1 += new_artefacts; } /* Paranoia */ if (o_ptr->name1 >= z_info->art_max) { return (-1); } /* Obtain the artefact info */ a_ptr = &a_info[o_ptr->name1]; /* Verify that artefact */ if (a_ptr->tval + a_ptr->sval == 0) { 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 special item info */ e_ptr = &e_info[o_ptr->name2]; /* Verify that special item */ if (!e_ptr->name) o_ptr->name2 = 0; } /* Hack -- extract the "broken" flag */ if (o_ptr->pval < 0) o_ptr->ident |= (IDENT_BROKEN); /* Artefacts */ if (o_ptr->name1) { artefact_type *a_ptr; /* Obtain the artefact info */ a_ptr = &a_info[o_ptr->name1]; /* Get the new artefact "pval" */ o_ptr->pval = a_ptr->pval; /* Get the new artefact fields */ o_ptr->dd = a_ptr->dd; o_ptr->ds = a_ptr->ds; o_ptr->pd = a_ptr->pd; o_ptr->ps = a_ptr->ps; o_ptr->evn = a_ptr->evn; /* Get the new artefact 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 special item info */ e_ptr = &e_info[o_ptr->name2]; /* 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; } } /* Used to add back boosted damage dice and sides */ /* No longer needed as we don't repair non-artefacts anymore */ /* Success */ return (0); }
/** * Read an object. */ static struct object *rd_item(void) { struct object *obj = object_new(); byte tmp8u; u16b tmp16u; byte effect; size_t i; char buf[128]; byte ver = 1; rd_u16b(&tmp16u); rd_byte(&ver); if (tmp16u != 0xffff) return NULL; rd_u16b(&obj->oidx); /* Location */ rd_byte(&obj->iy); rd_byte(&obj->ix); /* Type/Subtype */ rd_string(buf, sizeof(buf)); if (buf[0]) { obj->tval = tval_find_idx(buf); } rd_string(buf, sizeof(buf)); if (buf[0]) { obj->sval = lookup_sval(obj->tval, buf); } rd_s16b(&obj->pval); rd_byte(&obj->number); rd_s16b(&obj->weight); rd_string(buf, sizeof(buf)); if (buf[0]) { obj->artifact = lookup_artifact_name(buf); if (!obj->artifact) { note(format("Couldn't find artifact %s!", buf)); return NULL; } } rd_string(buf, sizeof(buf)); if (buf[0]) { obj->ego = lookup_ego_item(buf, obj->tval, obj->sval); if (!obj->ego) { note(format("Couldn't find ego item %s!", buf)); return NULL; } } rd_byte(&effect); rd_s16b(&obj->timeout); rd_s16b(&obj->to_h); rd_s16b(&obj->to_d); rd_s16b(&obj->to_a); rd_s16b(&obj->ac); rd_byte(&obj->dd); rd_byte(&obj->ds); rd_byte(&obj->origin); rd_byte(&obj->origin_depth); rd_string(buf, sizeof(buf)); if (buf[0]) { obj->origin_race = lookup_monster(buf); } rd_byte(&obj->notice); for (i = 0; i < of_size; i++) rd_byte(&obj->flags[i]); for (i = 0; i < obj_mod_max; i++) { rd_s16b(&obj->modifiers[i]); } /* Read brands */ rd_byte(&tmp8u); if (tmp8u) { obj->brands = mem_zalloc(z_info->brand_max * sizeof(bool)); for (i = 0; i < brand_max; i++) { rd_byte(&tmp8u); obj->brands[i] = tmp8u ? true : false; } } /* Read slays */ rd_byte(&tmp8u); if (tmp8u) { obj->slays = mem_zalloc(z_info->slay_max * sizeof(bool)); for (i = 0; i < slay_max; i++) { rd_byte(&tmp8u); obj->slays[i] = tmp8u ? true : false; } } /* Read curses */ rd_byte(&tmp8u); if (tmp8u) { obj->curses = mem_zalloc(z_info->curse_max * sizeof(struct curse_data)); for (i = 0; i < curse_max; i++) { rd_byte(&tmp8u); obj->curses[i].power = tmp8u; rd_u16b(&tmp16u); obj->curses[i].timeout = tmp16u; } } for (i = 0; i < elem_max; i++) { rd_s16b(&obj->el_info[i].res_level); rd_byte(&obj->el_info[i].flags); } /* Monster holding object */ rd_s16b(&obj->held_m_idx); rd_s16b(&obj->mimicking_m_idx); /* Activation */ rd_u16b(&tmp16u); if (tmp16u) obj->activation = &activations[tmp16u]; rd_u16b(&tmp16u); obj->time.base = tmp16u; rd_u16b(&tmp16u); obj->time.dice = tmp16u; rd_u16b(&tmp16u); obj->time.sides = tmp16u; /* Save the inscription */ rd_string(buf, sizeof(buf)); if (buf[0]) obj->note = quark_add(buf); /* Lookup item kind */ obj->kind = lookup_kind(obj->tval, obj->sval); /* Check we have a kind */ if ((!obj->tval && !obj->sval) || !obj->kind) { object_delete(&obj); return NULL; } /* Set effect */ if (effect && obj->ego) obj->effect = obj->ego->effect; if (effect && !obj->effect) obj->effect = obj->kind->effect; /* Success */ return obj; }
/* * Read the "extra" information */ static errr rd_extra(void) { int i, j; byte tmp8u; u16b file_e_max; rd_string(op_ptr->full_name, sizeof(op_ptr->full_name)); rd_string(p_ptr->died_from, 80); 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 house */ rd_byte(&p_ptr->phouse); /* Verify player house */ if (p_ptr->phouse >= z_info->c_max) { note(format("Invalid player house (%d).", p_ptr->phouse)); return (-1); } /* Player sex */ rd_byte(&p_ptr->psex); /* Tutorial? */ rd_s16b(&p_ptr->game_type); /* 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_base[i]); for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_drain[i]); /* Read the skill info */ for (i = 0; i < S_MAX; i++) rd_s16b(&p_ptr->skill_base[i]); /* Read the abilities info */ for (i = 0; i < S_MAX; i++) { for (j = 0; j < ABILITIES_MAX; j++) { rd_byte(&p_ptr->innate_ability[i][j]); rd_byte(&p_ptr->active_ability[i][j]); } } rd_s16b(&p_ptr->last_attack_m_idx); rd_s16b(&p_ptr->consecutive_attacks); rd_s16b(&p_ptr->bane_type); for (i = 0; i < ACTION_MAX; ++i) { rd_byte(&(p_ptr->previous_action[i])); } rd_byte(&p_ptr->focused); rd_s32b(&p_ptr->new_exp); rd_s32b(&p_ptr->exp); rd_s32b(&p_ptr->encounter_exp); rd_s32b(&p_ptr->kill_exp); rd_s32b(&p_ptr->descent_exp); rd_s32b(&p_ptr->ident_exp); 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_depth); /* Hack -- Repair maximum dungeon level */ if (p_ptr->max_depth < 0) p_ptr->max_depth = 1; rd_u16b(&p_ptr->staircasiness); /* More info */ rd_s16b(&p_ptr->sc); /* Read the flags */ rd_byte(&p_ptr->song1); rd_byte(&p_ptr->song2); rd_s16b(&p_ptr->song_duration); rd_s16b(&p_ptr->wrath); rd_s16b(&p_ptr->blind); rd_s16b(&p_ptr->entranced); rd_s16b(&p_ptr->confused); rd_s16b(&p_ptr->food); rd_u16b(&p_ptr->stairs_taken); rd_u16b(&p_ptr->forge_drought); rd_u16b(&p_ptr->forge_count); 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->rage); rd_s16b(&p_ptr->tmp_str); rd_s16b(&p_ptr->tmp_dex); rd_s16b(&p_ptr->tmp_con); rd_s16b(&p_ptr->tmp_gra); rd_s16b(&p_ptr->tim_invis); rd_s16b(&p_ptr->word_recall); rd_s16b(&p_ptr->darkened); rd_s16b(&p_ptr->oppose_fire); rd_s16b(&p_ptr->oppose_cold); rd_s16b(&p_ptr->oppose_pois); rd_byte(&p_ptr->stealth_mode); rd_byte(&p_ptr->self_made_arts); // 20 spare bytes strip_bytes(20); /* Read item-quality squelch sub-menu */ for (i = 0; i < SQUELCH_BYTES; i++) rd_byte(&squelch_level[i]); /* Load the name of the current greater vault */ rd_string(g_vault_name, sizeof(g_vault_name)); /* Read the number of saved special item types */ rd_u16b(&file_e_max); /* Read special item squelch settings */ for (i = 0; i < z_info->e_max; i++) { ego_item_type *e_ptr = &e_info[i]; tmp8u = 0; if (i < file_e_max) rd_byte(&tmp8u); e_ptr->squelch |= (tmp8u & 0x01); e_ptr->everseen |= (tmp8u & 0x02); e_ptr->aware |= (tmp8u & 0x04); /* Hack - Repair the savefile */ if (!e_ptr->everseen) e_ptr->squelch = FALSE; } /* Read possible extra elements */ while (i < file_e_max) { rd_byte(&tmp8u); i++; } /*Write the current number of auto-inscriptions*/ rd_u16b(&inscriptionsCount); /*Write the autoinscriptions array*/ for(i = 0; i < inscriptionsCount; i++) { char tmp[80]; rd_s16b(&inscriptions[i].kindIdx); rd_string(tmp, 80); inscriptions[i].inscriptionIdx = quark_add(tmp); } for (i = 0; i < MAX_GREATER_VAULTS; i++) { s16b n; rd_s16b(&n); p_ptr->greater_vaults[i] = n; } /* Read the randart version */ rd_u32b(&randart_version); /* Read the randart seed */ rd_u32b(&seed_randart); /* Hack -- the two "special seeds" */ rd_u32b(&seed_flavor); /* Special stuff */ rd_u16b(&p_ptr->panic_save); rd_byte(&p_ptr->truce); rd_byte(&p_ptr->morgoth_hits); rd_byte(&p_ptr->crown_hint); rd_byte(&p_ptr->crown_shatter); rd_byte(&p_ptr->cursed); rd_byte(&p_ptr->on_the_run); rd_byte(&p_ptr->morgoth_slain); rd_u16b(&p_ptr->escaped); rd_u16b(&p_ptr->noscore); rd_s16b(&p_ptr->smithing_leftover); rd_byte(&tmp8u); p_ptr->unique_forge_made = tmp8u; rd_byte(&tmp8u); p_ptr->unique_forge_seen = tmp8u; /* Read "death" */ rd_byte(&tmp8u); p_ptr->is_dead = tmp8u; /* Read "feeling" */ rd_byte(&tmp8u); feeling = tmp8u; /*read the level feeling*/ rd_byte(&tmp8u); do_feeling = tmp8u; /* Current turn */ rd_s32b(&turn); /* Current player turn */ rd_s32b(&playerturn); 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 the "extra" information */ static errr rd_extra(void) { int i; byte tmp8u; u16b tmp16u; u16b file_e_max; byte num; rd_string(op_ptr->full_name, sizeof(op_ptr->full_name)); rd_string(p_ptr->died_from, 80); 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); strip_bytes(1); /* 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]); for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_birth[i]); for (i = 0; i < A_MAX; ++i) rd_s16b(&p_ptr->stat_quest_add[i]); rd_s16b(&p_ptr->ht_birth); rd_s16b(&p_ptr->wt_birth); rd_s16b(&p_ptr->sc_birth); rd_s32b(&p_ptr->au_birth); strip_bytes(24); /* oops */ rd_u16b(&p_ptr->q_fame); rd_u16b(&p_ptr->deferred_rewards); 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 > z_info->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); rd_s16b(&p_ptr->recall_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; /* Hack -- Repair recall dungeon level */ if (p_ptr->recall_depth < 0) p_ptr->recall_depth = 1; rd_s16b(&p_ptr->quest_depth); /* Hack -- Repair max quest level */ if ((p_ptr->max_depth > 1) && (p_ptr->max_depth > p_ptr->quest_depth)) { p_ptr->quest_depth = p_ptr->max_depth; } /* More info */ strip_bytes(6); rd_s16b(&p_ptr->sc); strip_bytes(2); /* Read the flags */ strip_bytes(2); /* Old "rest" */ rd_s16b(&p_ptr->food); strip_bytes(4); /* Old "food_digested" / "protection" */ rd_s16b(&p_ptr->p_energy); rd_s16b(&p_ptr->word_recall); rd_s16b(&p_ptr->state.see_infra); rd_byte(&p_ptr->confusing); rd_byte(&tmp8u); rd_byte(&p_ptr->searching); rd_byte(&tmp8u); /* oops */ rd_byte(&tmp8u); /* oops */ rd_byte(&tmp8u); /* oops */ /* Find the number of timed effects */ rd_byte(&num); if (num == TMD_MAX) { /* Read all the effects */ for (i = 0; i < num; i++) rd_s16b(&p_ptr->timed[i]); } else { s16b dummy2; /* Probably in trouble anyway */ for (i = 0; i < TMD_MAX; i++) rd_s16b(&dummy2); /* Discard unused entries */ note("Discarding unsupported timed effects"); } rd_s16b(&p_ptr->base_wakeup_chance); rd_s16b(&total_wakeup_chance); /* Read item-quality squelch sub-menu */ for (i = 0; i < SQUELCH_BYTES; i++) rd_byte(&squelch_level[i]); /* Load the name of the current greater vault */ rd_string(g_vault_name, sizeof(g_vault_name)); /* Read the number of saved ego-item types */ rd_u16b(&file_e_max); /* Read ego-item squelch settings */ for (i = 0; i < z_info->e_max; i++) { ego_item_type *e_ptr = &e_info[i]; tmp8u = 0; if (i < file_e_max) rd_byte(&tmp8u); e_ptr->squelch |= (tmp8u & 0x01); e_ptr->everseen |= (tmp8u & 0x02); /* Hack - Repair the savefile */ if (!e_ptr->everseen) e_ptr->squelch = FALSE; } /* Read possible extra elements */ while (i < file_e_max) { rd_byte(&tmp8u); i++; } /*Read the current number of auto-inscriptions*/ rd_u16b(&inscriptionsCount); /*Read the autoinscriptions array*/ for(i = 0; i < inscriptionsCount; i++) { char tmp[80]; rd_s16b(&inscriptions[i].kindIdx); rd_string(tmp, 80); inscriptions[i].inscriptionIdx = quark_add(tmp); } /* * The number of the bone file (if any) that player ghosts should use to * derive the ghost name, sex, class, race, and level. */ rd_s16b(&player_ghost_num); /* Find out how many thefts have recently occurred. */ strip_bytes(1); /* Read number of monster traps on level. */ rd_byte(&num_trap_on_level); /* Future use */ strip_bytes(13); /* Read the summon spells that have already failed on the level */ rd_u32b(&dungeon_summon_mask_f7); /* Read the randart seed */ rd_u32b(&seed_randart); /* Skip the flags */ strip_bytes(12); /* Hack -- the three "special seeds" */ rd_u32b(&seed_flavor); rd_u32b(&seed_town); rd_u32b(&seed_ghost); /* 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; /*read the level feeling*/ rd_byte(&tmp8u); do_feeling = tmp8u; /* Current turn */ rd_s32b(&turn); /*Current Player Turn*/ rd_s32b(&p_ptr->p_turn); /* Turn count for quest indicator */ rd_u16b(&quest_indicator_timer); /* Check if the quest indicator must flash the victory sign */ if (quest_indicator_timer & (QUEST_INDICATOR_COMPLETE_BIT)) { /* We won the quest */ quest_indicator_complete = TRUE; /* Clear the mark from the timer */ quest_indicator_timer &= ~(QUEST_INDICATOR_COMPLETE_BIT); } /* Panel change offsets */ rd_u16b(&panel_change_offset_y); rd_u16b(&panel_change_offset_x); /* Check bounds */ if (panel_change_offset_y < MIN_PANEL_CHANGE_OFFSET_Y) { panel_change_offset_y = MIN_PANEL_CHANGE_OFFSET_Y; } if (panel_change_offset_x < MIN_PANEL_CHANGE_OFFSET_X) { panel_change_offset_x = MIN_PANEL_CHANGE_OFFSET_X; } /* Read the player_hp array */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->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 the player spells */ if (rd_player_spells()) return (-1); 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 the random artifacts */ static errr rd_randarts(void) { int i; byte tmp8u; s16b tmp16s; u16b tmp16u; u16b artifact_count, begin; s32b tmp32s; u32b tmp32u; /* Read the number of artifacts */ rd_u16b(&begin); rd_u16b(&artifact_count); rd_u16b(&art_norm_count); /* Alive or cheating death */ if (!p_ptr->is_dead || arg_wizard) { /* Incompatible save files */ if ((artifact_count > z_info->art_max) || (art_norm_count > z_info->art_norm_max)) { note(format("Too many (%u) artifacts!", artifact_count)); return (-1); } /*Mark any new added artifacts*/ if (art_norm_count < z_info->art_norm_max) { new_artifacts = z_info->art_norm_max - art_norm_count; } else new_artifacts = 0; /* Mark the old artifacts as "empty" */ for (i = begin; i < z_info->art_max; i++) { artifact_type *a_ptr = &a_info[i]; /*hack - if a new "normal artifact has been added in mid-game, don't erase it*/ if ((i >= art_norm_count) && (i < z_info->art_norm_max)) continue; a_ptr->tval = 0; a_ptr->sval = 0; a_ptr->name[0] = '\0'; } /* Read the artifacts */ for (i = begin; i < artifact_count; i++) { artifact_type *a_ptr = &a_info[i]; /*hack - if a new "normal artifact has been added in mid-game, don't erase it*/ if ((i >= art_norm_count) && (i < z_info->art_norm_max)) continue; rd_string (a_ptr->name, MAX_LEN_ART_NAME); 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->a_flags1); rd_u32b(&a_ptr->a_flags2); rd_u32b(&a_ptr->a_flags3); rd_u32b(&a_ptr->a_native); rd_byte(&a_ptr->a_level); rd_byte(&a_ptr->a_rarity); rd_byte(&a_ptr->activation); rd_u16b(&a_ptr->time); rd_u16b(&a_ptr->randtime); } } else { /* Strip the the artifacts for a dead/new character*/ for (i = begin; i < artifact_count; i++) { char tmpstr[MAX_LEN_ART_NAME]; rd_string (tmpstr, sizeof (tmpstr)); /*a_ptr->name*/ 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_u32b(&tmp32u); /* a_ptr->a_native */ rd_byte(&tmp8u); /* a_ptr->level */ rd_byte(&tmp8u); /* a_ptr->rarity */ rd_byte(&tmp8u); /* a_ptr->activation */ rd_u16b(&tmp16u); /* a_ptr->time */ rd_u16b(&tmp16u); /* a_ptr->randtime */ } } return (0); }
/* * 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); }
/* * 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, fn; 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); rd_byte(&o_ptr->discount); rd_byte(&o_ptr->number); rd_s16b(&o_ptr->weight); rd_byte(&o_ptr->art_num); rd_byte(&o_ptr->ego_num); 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_u32b(&o_ptr->ident); rd_byte(&o_ptr->marked); rd_s16b(&o_ptr->mimic_r_idx); /* Old flags */ strip_bytes(12); /* Monster holding object */ rd_s16b(&o_ptr->held_m_idx); /* Special powers */ rd_byte(&o_ptr->xtra1); rd_u32b(&o_ptr->xtra2); /* Inscription */ rd_string(buf, sizeof(buf)); /* Save the inscription */ if (buf[0]) o_ptr->obj_note = quark_add(buf); /* Object history */ rd_byte(&o_ptr->origin_nature); rd_s16b(&o_ptr->origin_dlvl); rd_s16b(&o_ptr->origin_r_idx); rd_string(buf, sizeof(buf)); if (buf[0]) o_ptr->origin_m_name = 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); /* Ensure that rods and wands get the appropriate pvals, * and transfer rod charges to timeout. * this test should only be passed once, the first * time the file is open with ROD/WAND stacking code * It could change the timeout improperly if the PVAL (time a rod * takes to charge after use) is changed in object.txt. * But this is nothing a little resting won't solve. * * -JG- */ if ((o_ptr->tval == TV_ROD) && (o_ptr->pval - (k_ptr->pval * o_ptr->number) != 0)) { o_ptr->timeout = o_ptr->pval; o_ptr->pval = k_ptr->pval * o_ptr->number; } /* 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; if ((o_ptr->tval != TV_MAGIC_BOOK) && (o_ptr->tval != TV_PRAYER_BOOK) && (o_ptr->tval != TV_DRUID_BOOK)) { /* Paranoia */ o_ptr->art_num = o_ptr->ego_num = 0; /* All done */ return (0); } /*spellbooks can now have an ego-item*/ else o_ptr->art_num = 0; } /* Extract the flags */ object_flags(o_ptr, &f1, &f2, &f3, &fn); /* Paranoia */ if (o_ptr->art_num) { artifact_type *a_ptr; /*hack - adjust if new artifact*/ if (o_ptr->art_num >= art_norm_count) { o_ptr->art_num += new_artifacts; } /* Paranoia */ if (o_ptr->art_num >= z_info->art_max) { return (-1); } /* Obtain the artifact info */ a_ptr = &a_info[o_ptr->art_num]; /* Verify that artifact */ if (a_ptr->tval + a_ptr->sval == 0) { o_ptr->art_num = 0; } } /* Paranoia */ if (o_ptr->ego_num) { ego_item_type *e_ptr; /* Paranoia */ if (o_ptr->ego_num >= z_info->e_max) { return (-1); } /* Obtain the ego-item info */ e_ptr = &e_info[o_ptr->ego_num]; /* Verify that ego-item */ if (!e_ptr->name) o_ptr->ego_num = 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->art_num) { artifact_type *a_ptr; /* Obtain the artifact info */ a_ptr = &a_info[o_ptr->art_num]; /* 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->ego_num) { ego_item_type *e_ptr; /* Obtain the ego-item info */ e_ptr = &e_info[o_ptr->ego_num]; /* 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->ego_num == EGO_BLASTED) || (o_ptr->ego_num == EGO_SHATTERED)) { /* These were set to k_info values by preceding code */ o_ptr->ac = 0; o_ptr->dd = 0; o_ptr->ds = 0; } } /* Hack -- keep boosted damage dice and sides */ if (o_ptr->dd < old_dd) o_ptr->dd = old_dd; if (o_ptr->ds < old_ds) o_ptr->ds = old_ds; /* Hack -- *Identified* artifacts are known in future games */ if ((o_ptr->ident & (IDENT_MENTAL)) && ARTIFACT_EASY_MENTAL(o_ptr)) { /* Mark as *identified* */ a_l_list[o_ptr->art_num].was_fully_identified = 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. * * 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; } }
static int get_desc(void) { rd_string(savefile_desc, sizeof savefile_desc); return 0; }