/* * 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); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i; byte tmp8u; u16b tmp16u; 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; /* 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); // 8 spare bytes strip_bytes(8); /* 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 & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; k_ptr->everseen = (tmp8u & 0x08) ? TRUE: FALSE; rd_byte(&k_ptr->squelch); } if (arg_fiddle) note("Loaded Object Memory"); /* Load the Artefacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->art_max) { note(format("Too many (%u) artefacts!", tmp16u)); return (-1); } /* Read the artefact flags */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); a_info[i].cur_num = tmp8u; rd_byte(&tmp8u); a_info[i].found_num = tmp8u; } if (arg_fiddle) note("Loaded Artefacts"); /* Read the extra stuff */ if (rd_extra()) return (-1); if (arg_fiddle) note("Loaded extra information"); if (rd_randarts()) return (-1); if (arg_fiddle) note("Loaded Random Artefacts"); if (rd_notes()) return (-1); if (arg_fiddle) note("Loaded Notes"); /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/house */ rp_ptr = &p_info[p_ptr->prace]; hp_ptr = &c_info[p_ptr->phouse]; /* Read the inventory */ if (rd_inventory()) { note("Unable to read inventory"); 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); } } /* 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); } /* Success */ return (0); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i; byte tmp8u; u16b tmp16u; u32b tmp32u; 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, and the game_mode byte */ strip_bytes(5); /* 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_monster_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 & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; k_ptr->everseen = (tmp8u & 0x08) ? TRUE: FALSE; rd_byte(&k_ptr->squelch); /* Hack - Repair the savefile */ if (!k_ptr->everseen) k_ptr->squelch = SQUELCH_NEVER; } if (arg_fiddle) note("Loaded Object Memory"); /* Load the Quests */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->q_max) { note(format("Too many (%u) quests!", tmp16u)); return (23); } /* Load the Quests */ for (i = 0; i < tmp16u; i++) { quest_type *q_ptr = &q_info[i]; rd_byte(&q_ptr->q_type); /* Only limited info for permanent quests. The rest is detailed in quest.txt */ if (q_ptr->q_type == QUEST_PERMANENT) { rd_byte(&q_ptr->q_flags); rd_s16b(&q_ptr->q_num_killed); continue; } rd_u16b(&q_ptr->q_reward); rd_u16b(&q_ptr->q_fame_inc); rd_byte(&q_ptr->base_level); rd_byte(&q_ptr->q_theme); rd_s16b(&q_ptr->mon_idx); rd_s32b(&q_ptr->turn_counter); rd_s16b(&q_ptr->q_num_killed); rd_s16b(&q_ptr->q_max_num); rd_byte(&q_ptr->q_flags); } if (arg_fiddle) note("Loaded Quests"); /* Load the Artifacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->art_max) { note(format("Too many (%u) artifacts!", tmp16u)); return (-1); } /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); a_info[i].a_cur_num = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } if (arg_fiddle) note("Loaded Artifacts"); /* Read the extra stuff */ if (rd_extra()) return (-1); if (arg_fiddle) note("Loaded extra information"); if (rd_randarts()) return (-1); if (arg_fiddle) note("Loaded Random Artifacts"); if (rd_notes()) return (-1); if (arg_fiddle) note("Loaded Notes"); if (rd_extensions()) return (-1); if (arg_fiddle) note("Loaded Extensions"); /* 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]; /* Important -- Initialize the magic */ mp_ptr = &cp_ptr->spells; /* Hack - In NPP 050, we moved a spell out of ironman book.*/ if (cp_ptr->spell_book == TV_MAGIC_BOOK) p_ptr->spell_flags[SPELL_FLIGHT] &= ~(PY_SPELL_IRONMAN); /* 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); } /* Read the stored number of terrain features */ rd_u16b(&tmp16u); /* Check bounds */ if (tmp16u > z_info->f_max) { note(format("Too many (%u) terrain features!", tmp16u)); return (-1); } /* Read terrain lore */ for (i = 0; i < tmp16u; i++) { if (rd_feature_lore(i)) return (-1); } /* Artifact lore */ /* Read the stored number of artifacts (normal + special) */ rd_u16b(&tmp16u); /* Check bounds */ if (tmp16u > z_info->art_norm_max) { note(format("Too many (%u) artifacts!", tmp16u)); return (-1); } /* Read artifact lore */ for (i = 0; i < tmp16u; i++) { if (rd_artifact_lore(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); } } /* 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); } /* Success */ return (0); }
errr rd_server_savefile() { int i; errr err = 0; char savefile[1024]; byte tmp8u; u16b tmp16u; u32b tmp32u; s32b tmp32s; int major; char name[80]; /* Savefile name */ path_build(savefile, 1024, ANGBAND_DIR_SAVE, "server"); /* The server savefile is a binary file */ file_handle = my_fopen(savefile, "r"); line_counter = 0; start_section_read("mangband_server_save"); start_section_read("version"); major = read_int("major"); major = read_int("minor"); major = read_int("patch"); end_section_read("version"); /* Paranoia */ if (!file_handle) return (-1); /* Clear the checksums */ v_check = 0L; x_check = 0L; /* Operating system info */ sf_xtra = read_uint("xtra"); /* Time of savefile creation */ sf_when = read_uint("timestamp"); /* Number of lives */ sf_lives = read_int("sf_lives"); /* Number of times played */ sf_saves = read_int("sf_saves"); /* Monster Memory */ start_section_read("monster_lore"); tmp16u = read_int("max_r_idx"); /* Incompatible save files */ if (tmp16u > z_info->r_max) { note(format("Too many (%u) monster races!", tmp16u)); return (21); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { monster_race *r_ptr; /* Read the lore */ rd_u_lore(i); /* Access the monster race */ r_ptr = &r_info[i]; } end_section_read("monster_lore"); /* Load the Artifacts */ start_section_read("artifacts"); tmp16u = read_int("max_a_idx"); /* Incompatible save files */ if (tmp16u > z_info->a_max) { note(format("Too many (%u) artifacts!", tmp16u)); return (24); } /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { tmp8u = read_int("artifact"); a_info[i].cur_num = tmp8u; } end_section_read("artifacts"); /* Read the stores */ start_section_read("stores"); tmp16u = read_int("max_stores"); for (i = 0; i < tmp16u; i++) { if (rd_store(i)) return (22); } end_section_read("stores"); /* Read party info if savefile is new enough */ start_section_read("parties"); tmp16u = read_int("max_parties"); /* Incompatible save files */ if (tmp16u > MAX_PARTIES) { note(format("Too many (%u) parties!", tmp16u)); return (25); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { rd_party(i); } end_section_read("parties"); /* XXX If new enough, read in the saved levels and monsters. */ start_section_read("dungeon_levels"); /* read the number of levels to be loaded */ tmp32u = read_uint("num_levels"); /* load the levels */ for (i = 0; i < tmp32u; i++) rd_dungeon(FALSE, 0); /* load any special static levels */ rd_dungeon_special(); end_section_read("dungeon_levels"); start_section_read("monsters"); /* get the number of monsters to be loaded */ tmp32u = read_int("max_monsters"); if (tmp32u > MAX_M_IDX) { note(format("Too many (%u) monsters!", tmp16u)); return (29); } /* load the monsters */ for (i = 1; i < tmp32u; i++) { rd_monster(&m_list[m_pop()]); } end_section_read("monsters"); /* Read object info */ start_section_read("objects"); tmp16u = read_int("max_objects"); /* Incompatible save files */ if (tmp16u > MAX_O_IDX) { note(format("Too many (%u) objects!", tmp16u)); return (26); } /* Read the available records */ for (i = 1; i < tmp16u; i++) { rd_item(&o_list[i]); } /* Set the maximum object number */ o_max = tmp16u; end_section_read("objects"); /* Read holding info */ /* Reacquire objects */ for (i = 1; i < o_max; ++i) { object_type *o_ptr; monster_type *m_ptr; /* Get the object */ o_ptr = &o_list[i]; /* Ignore dungeon objects */ if (!o_ptr->held_m_idx) continue; /* Verify monster index */ if (o_ptr->held_m_idx > z_info->m_max) { note("Invalid monster index"); return (-1); } /* Get the monster */ m_ptr = &m_list[o_ptr->held_m_idx]; /* Link the object to the pile */ o_ptr->next_o_idx = m_ptr->hold_o_idx; /* Link the monster to the object */ m_ptr->hold_o_idx = i; } /* Read house info */ start_section_read("houses"); tmp16u = read_int("num_houses"); /* Incompatible save files */ if (tmp16u > MAX_HOUSES) { note(format("Too many (%u) houses!", tmp16u)); return (27); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { rd_house(i); } num_houses = tmp16u; end_section_read("houses"); /* Read arenas info */ if (section_exists("arenas")) { start_section_read("arenas"); tmp16u = read_int("num_arenas"); /* Incompatible save files */ if (tmp16u > MAX_ARENAS) { note(format("Too many (%u) arenas!", tmp16u)); return (27); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { rd_arena(i); } num_arenas = tmp16u; end_section_read("arenas"); } /* Read wilderness info */ start_section_read("wilderness"); /* read how many wilderness levels */ tmp32u = read_int("max_wild"); if (tmp32u > MAX_WILD) { note("Too many wilderness levels"); return 28; } for (i = 1; i < tmp32u; i++) { rd_wild(i); } end_section_read("wilderness"); /* Read the player name database */ start_section_read("player_names"); tmp32u = read_int("num_players"); /* Read the available records */ for (i = 0; i < tmp32u; i++) { start_section_read("player"); /* Read the ID */ tmp32s = read_int("id"); /* Read the player name */ read_str("name",name); /* Store the player name */ add_player_name(name, tmp32s); end_section_read("player"); } end_section_read("player_names"); seed_flavor = read_uint("seed_flavor"); seed_town = read_uint("seed_town"); player_id = read_int("player_id"); read_hturn("turn", &turn); /* Hack -- no ghosts */ /*r_info[z_info->r_max - 1].max_num = 0;*/ end_section_read("mangband_server_save"); /* Check for errors */ if (ferror(file_handle)) err = -1; /* Close the file */ my_fclose(file_handle); /* Result */ return (err); }