Exemplo n.º 1
0
/* skip entries until found search or dict end. skipped does not include the found key */
bool TorrentBase::try_next_dict_entry(BufferString search, BufferString prev, bool &error, BufferString *skipped) {
	size_t start = m_buffer.pos();
	error = true;
	if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict, found eof");

	BufferString cur;

	while (m_buffer.m_data[m_buffer.pos()] != 'e') {
		size_t curpos = m_buffer.pos();;
		if (!read_utf8(cur)) return errorcontext("parsing dict key failed");
		if (cur <= prev) return seterror("(previous) dict entries in wrong order");
		if (cur == search) {
			error = false;
			if (0 != skipped) *skipped = BufferString(m_buffer.data() + start, curpos - start);
			return true;
		}
		if (cur > search) {
			m_buffer.m_pos = curpos;
			error = false;
			if (0 != skipped) *skipped = BufferString(m_buffer.data() + start, m_buffer.pos() - start);
			return false;
		}
		prev = cur;
		if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict value, found eof");
		if (!skip_value()) return errorcontext("parsing dict value failed");
		if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict entry or 'e', found eof");
	}

	/* dict end found, don't skip the 'e' */
	error = false;
	if (0 != skipped) *skipped = BufferString(m_buffer.data() + start, m_buffer.pos() - start);
	return false;
}
Exemplo n.º 2
0
	void parse_array(const char* json, Array<const char*>& array)
	{
		CE_ASSERT_NOT_NULL(json);

		if (*json == '[')
		{
			json = next(json, '[');
			json = skip_spaces(json);

			if (*json == ']')
			{
				json = next(json, ']');
				return;
			}

			while (*json)
			{
				array::push_back(array, json);

				json = skip_value(json);
				json = skip_spaces(json);

				if (*json == ']')
				{
					json = next(json, ']');
					return;
				}

				json = next(json, ',');
				json = skip_spaces(json);
			}
		}

		CE_FATAL("Bad array");
	}
Exemplo n.º 3
0
	void parse_array(const char* json, JsonArray& array)
	{
		CE_ASSERT_NOT_NULL(json);

		if (*json == '[')
		{
			json = skip_spaces(++json);

			if (*json == ']')
				return;

			while (*json)
			{
				array::push_back(array, json);

				json = skip_value(json);
				json = skip_spaces(json);

				if (*json == ']')
					return;

				json = skip_spaces(json);
			}
		}

		CE_FATAL("Bad array");
	}
Exemplo n.º 4
0
static void rd_monster(monster_type *m_ptr)
{
	start_section_read("monster");

	/* Hack -- wipe */
	WIPE(m_ptr, monster_type);

	skip_value("name");

	/* Read the monster race */
	m_ptr->r_idx = read_int("r_idx");

	/* Read the other information */
	m_ptr->fy = read_int("fy");
	m_ptr->fx = read_int("fx");
	m_ptr->dun_depth = read_int("dun_depth");
	m_ptr->hp = read_int("hp");
	m_ptr->maxhp = read_int("maxhp");
	m_ptr->csleep = read_int("csleep");
	m_ptr->mspeed = read_int("mspeed");
	m_ptr->energy = read_uint("energy");
	m_ptr->stunned = read_int("stunned");
	m_ptr->confused = read_int("confused");
	m_ptr->monfear = read_int("afraid");

	end_section_read("monster");
}
Exemplo n.º 5
0
void JsonIn::skip_member()
{
    skip_string();
    skip_pair_separator();
    skip_value();
    skip_separator();
}
Exemplo n.º 6
0
bool JsonIn::skip_member()
{
    skip_string();
    skip_pair_separator();
    skip_value();
    return skip_separator();
}
Exemplo n.º 7
0
void JsonIn::skip_array()
{
    start_array();
    while (!end_array()) {
        skip_value();
    }
    // end_value called by end_array
}
Exemplo n.º 8
0
bool TorrentBase::skip_list() {
	if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected list, found eof");
	if (m_buffer.m_data[m_buffer.pos()] != 'l') return seterror("expected 'l' for list");

	m_buffer.next();
	if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected list entry or 'e', found eof");

	while (m_buffer.m_data[m_buffer.pos()] != 'e') {
		if (!skip_value()) return errorcontext("parsing list entry failed");;
		if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected list entry or 'e', found eof");
	}
	m_buffer.next();

	return true;
}
Exemplo n.º 9
0
	void parse_object(const char* json, Map<DynamicString, const char*>& object)
	{
		CE_ASSERT_NOT_NULL(json);

		if (*json == '{')
		{
			json = next(json, '{');

			json = skip_spaces(json);

			if (*json == '}')
			{
				next(json, '}');
				return;
			}

			while (*json)
			{
				TempAllocator256 ta;
				DynamicString key(ta);
				parse_string(json, key);

				json = skip_string(json);
				json = skip_spaces(json);
				json = next(json, ':');
				json = skip_spaces(json);

				map::set(object, key, json);

				json = skip_value(json);
				json = skip_spaces(json);

				if (*json == '}')
				{
					next(json, '}');
					return;
				}

				json = next(json, ',');
				json = skip_spaces(json);
			}
		}

		CE_FATAL("Bad object");
	}
Exemplo n.º 10
0
bool TorrentBase::skip_dict() {
	if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict, found eof");
	if (m_buffer.m_data[m_buffer.pos()] != 'd') return seterror("expected 'd' for dict");

	m_buffer.next();
	if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict entry or 'e', found eof");

	BufferString last, cur;

	while (m_buffer.m_data[m_buffer.pos()] != 'e') {
		if (!read_utf8(cur)) return errorcontext("parsing dict key failed");
		if (cur <= last) return seterror("(previous) dict entries in wrong order");
		last = cur;
		if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict value, found eof");
		if (!skip_value()) return errorcontext("parsing dict value failed");
		if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict entry or 'e', found eof");
	}
	m_buffer.next();

	return true;
}
Exemplo n.º 11
0
	void parse_object(const char* json, JsonObject& object)
	{
		CE_ASSERT_NOT_NULL(json);

		if (*json == '{')
		{
			json = skip_spaces(++json);

			if (*json == '}')
				return;

			while (*json)
			{
				const char* key_begin = *json == '"' ? (json + 1) : json;

				TempAllocator256 ta;
				DynamicString key(ta);
				json = parse_key(json, key);

				FixedString fs_key(key_begin, key.length());

				json = skip_spaces(json);
				json = next(json, (*json == '=') ? '=' : ':');
				json = skip_spaces(json);

				map::set(object, fs_key, json);

				json = skip_value(json);
				json = skip_spaces(json);

				if (*json == '}')
					return;

				json = skip_spaces(json);
			}
		}

		CE_FATAL("Bad object");
	}
Exemplo n.º 12
0
/* skip entries until dict end */
bool TorrentBase::goto_dict_end(BufferString prev, BufferString *skipped) {
	size_t start = m_buffer.pos();
	if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict entry or 'e', found eof");

	BufferString cur;

	while (m_buffer.m_data[m_buffer.pos()] != 'e') {
		if (!read_utf8(cur)) return errorcontext("parsing dict key failed");
		if (cur <= prev) {
			std::cerr << "dict entries wrong order: '" << cur << "' <= '" << prev << "'\n";
		}
		if (cur <= prev) return seterror("(previous) dict entries in wrong order");
		prev = cur;
		if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict value, found eof");
		if (!skip_value()) return errorcontext("parsing dict value failed");
		if (m_buffer.pos() >= m_buffer.m_len) return seterror("expected dict entry or 'e', found eof");
	}
	m_buffer.next();

	if (0 != skipped) *skipped = BufferString(m_buffer.data() + start, m_buffer.pos() - start);

	return true;
}
Exemplo n.º 13
0
	static void parse_root_object(const char* json, JsonObject& object)
	{
		CE_ENSURE(NULL != json);

		while (*json)
		{
			const char* key_begin = *json == '"' ? (json + 1) : json;

			TempAllocator256 ta;
			DynamicString key(ta);
			json = parse_key(json, key);

			FixedString fs_key(key_begin, key.length());

			json = skip_spaces(json);
			json = next(json, (*json == '=') ? '=' : ':');
			json = skip_spaces(json);

			map::set(object._map, fs_key, json);

			json = skip_value(json);
			json = skip_spaces(json);
		}
	}
Exemplo n.º 14
0
static errr rd_dungeon(bool ext, int Depth)
{
	s32b depth;
	u16b max_y, max_x;

	int y, x;
	cave_type *c_ptr;
	char cave_row[MAX_WID+1];

	start_section_read("dungeon_level");

	/*** Depth info ***/

	/* Level info */
	depth = read_int("depth");
	max_y = read_int("max_height");
	max_x = read_int("max_width");
	if (ext) depth = Depth;

	/* players on this depth */
	players_on_depth[depth] = read_int("players_on_depth");

	/* Hack -- only read in staircase information for non-wilderness
	 * levels
	 */

	if (depth >= 0)
	{

		level_up_y[depth] = read_int("level_up_y");
		level_up_x[depth] = read_int("level_up_x");
		level_down_y[depth] = read_int("level_down_y");
		level_down_x[depth] = read_int("level_down_x");
		level_rand_y[depth] = read_int("level_rand_y");
		level_rand_x[depth] = read_int("level_rand_x");
		
	}
	/* HACK */
	else if (value_exists("level_up_y"))
	{
		skip_value("level_up_y");
		skip_value("level_up_x");
		skip_value("level_down_y");
		skip_value("level_down_x");
		skip_value("level_rand_y");
		skip_value("level_rand_x");	
	}

	/* allocate the memory for the dungoen if it has not already */
	/* been allocated - which it might have been if we are loading */
	/* a special static level file */
	if(!cave[depth])
		alloc_dungeon_level(depth);

	/* Load features */
	start_section_read("features");

		for (y = 0; y < max_y; y++)
		{
			read_binary("row",cave_row,MAX_WID);
			for(x = 0; x < max_x; x++)
			{
				/* Access the cave */
				c_ptr = &cave[depth][y][x];

				/* set the feature */
				c_ptr->feat = cave_row[x];
			}			
		}

	end_section_read("features");

	/* Load info */
	start_section_read("info");

		for (y = 0; y < max_y; y++)
		{
			read_binary("row",cave_row,MAX_WID);
			for(x = 0; x < max_x; x++)
			{
				/* Access the cave */
				c_ptr = &cave[depth][y][x];

				/* set the feature */
				c_ptr->info = cave_row[x];
			}			
		}

	end_section_read("info");

	end_section_read("dungeon_level");
	/* Success */
	return (0);
}
Exemplo n.º 15
0
 /* For wilderness levels, dun_depth has been changed from 1 to 4 bytes. */
static void rd_item(object_type *o_ptr)
{
	byte old_dd;
	byte old_ds;

	u32b f1, f2, f3;

	object_kind *k_ptr;

	char note[128];

	start_section_read("item");
	
	/* Hack -- wipe */
	WIPE(o_ptr, object_type);

	/* Skip name */
	skip_value("name");

	/* Kind */
	o_ptr->k_idx = read_int("k_idx");

	/* Location */
	o_ptr->iy = read_int("iy");
	o_ptr->ix = read_int("ix");
	
	o_ptr->dun_depth = read_int("dun_depth");

	/* Type/Subtype */
	o_ptr->tval = read_int("tval");
	o_ptr->sval = read_int("sval");

	/* Base pval */
	o_ptr->bpval = read_int("bpval");

	/* Special pval */
	o_ptr->pval = read_int("pval");


	o_ptr->discount = read_int("discount");
	o_ptr->number = read_int("number");
	o_ptr->weight = read_int("weight");

	o_ptr->name1 = read_int("name1");
	o_ptr->name2 = read_int("name2");
	o_ptr->name3 = read_int("name3");
	o_ptr->timeout = read_int("timeout");

	o_ptr->to_h = read_int("to_h");
	o_ptr->to_d = read_int("to_d");
	o_ptr->to_a = read_int("to_a");

	o_ptr->ac = read_int("ac");

	old_dd = read_int("dd");
	old_ds = read_int("ds");

	o_ptr->ident = read_int("ident");

	/* Special powers */
	o_ptr->xtra1 = read_int("xtra1");
	o_ptr->xtra2 = read_int("xtra2");

	/* Inscription */
	read_str("inscription",note); 
 
	/* Save the inscription */
	if (note[0]) o_ptr->note = quark_add(note);

	/* Owner information */
	if (value_exists("owner_name"))
	{
		/* Name */
		read_str("owner_name",note);
		/* Save */
		if (!STRZERO(note)) o_ptr->owner_name = quark_add(note); 
		/* Id */
		o_ptr->owner_id = read_int("owner_id");
	}

	/* Monster holding object */ 
   o_ptr->held_m_idx = read_int("held_m_idx");

	end_section_read("item");

	/* Mega-Hack -- handle "dungeon objects" later */
	if ((o_ptr->k_idx >= 445) && (o_ptr->k_idx <= 479)) return;


	/* 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 |= ID_BROKEN;


	/* Repair non "wearable" items */
	if (!wearable_p(o_ptr))
	{
		/* Acquire correct fields */
		o_ptr->to_h = k_ptr->to_h;
		o_ptr->to_d = k_ptr->to_d;
		o_ptr->to_a = k_ptr->to_a;

		/* Acquire correct fields */
		o_ptr->ac = k_ptr->ac;
		o_ptr->dd = k_ptr->dd;
		o_ptr->ds = k_ptr->ds;

		/* Acquire correct weight */
		o_ptr->weight = k_ptr->weight;

		/* Paranoia */
		o_ptr->name1 = o_ptr->name2 = 0;

		/* All done */
		return;
	}


	/* Extract the flags */
	object_flags(o_ptr, &f1, &f2, &f3);


	/* Paranoia */
	if (true_artifact_p(o_ptr))
	{
		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;
	}


	/* Acquire standard fields */
	o_ptr->ac = k_ptr->ac;
	o_ptr->dd = k_ptr->dd;
	o_ptr->ds = k_ptr->ds;

	/* Acquire standard weight */
	o_ptr->weight = k_ptr->weight;

	/* Hack -- extract the "broken" flag */
	if (o_ptr->pval < 0) o_ptr->ident |= ID_BROKEN;


	/* Artifacts */
	if (artifact_p(o_ptr))
	{
		artifact_type *a_ptr;

		/* Obtain the artifact info */
#if defined(RANDART)
		if (o_ptr->name1 == ART_RANDART)
		{
			a_ptr = randart_make(o_ptr);
		}
		else
		{
#endif
		a_ptr = &a_info[o_ptr->name1];
#if defined(RANDART)
		}
#endif
		/* Acquire new artifact "pval" */
		o_ptr->pval = a_ptr->pval;

		/* Acquire new artifact fields */
		o_ptr->ac = a_ptr->ac;
		o_ptr->dd = a_ptr->dd;
		o_ptr->ds = a_ptr->ds;

		/* Acquire new artifact weight */
		o_ptr->weight = a_ptr->weight;

		/* Hack -- extract the "broken" flag */
		if (!a_ptr->cost) o_ptr->ident |= ID_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 |= ID_BROKEN;

		/* 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;
		}
	}
}
Exemplo n.º 16
0
/*
 * Read the uniques lore
 */
static void rd_u_lore(int r_idx)
{
	monster_race *r_ptr = &r_info[r_idx];

	start_section_read("lore");

	skip_value("name");

	/* Count sights/deaths/kills */
	r_ptr->r_sights = read_int("sights");
	if (value_exists("deaths")) skip_value("deaths");
	if (value_exists("pkills")) skip_value("pkills");
	r_ptr->r_tkills = read_int("tkills");
	
	if (value_exists("wake")) skip_value("wake");
	if (value_exists("ignore")) skip_value("ignore");
	if (value_exists("respawn_timer")) skip_value("respawn_timer");
	if (value_exists("drop_gold")) skip_value("drop_gold");
	if (value_exists("drop_item")) skip_value("drop_item");
	if (value_exists("cast_innate")) skip_value("cast_innate");
	if (value_exists("cast_spell")) skip_value("cast_spell");
	
	if (section_exists("blows")) 
	{
		start_section_read("blows");
		while(value_exists("blow")) skip_value("blow");
		end_section_read("blows");
	}
	if (section_exists("flags")) 
	{
		start_section_read("flags");
		while(value_exists("flag")) skip_value("flag");
		end_section_read("flags");
	}
	
	/* Read the "Racial" monster limit per level */
	r_ptr->max_num = read_int("max_num");

	if (value_exists("killer")) skip_value("killer");
	
	end_section_read("lore");

}
Exemplo n.º 17
0
static bool rd_extra(player_type *p_ptr, bool had_header)
{
	int i = 0;

	start_section_read("player");

	if (!had_header)
	{
		read_str("playername",p_ptr->name); /* 32 */
		skip_value("pass");
	}

	read_str("died_from",p_ptr->died_from); /* 80 */

	read_str("died_from_list",p_ptr->died_from_list); /* 80 */
	p_ptr->died_from_depth = read_int("died_from_depth");

	start_section_read("history");
	for (i = 0; i < 4; i++)
	{
		read_str("history",p_ptr->history[i]); /* 60 */
	}
	if (value_exists("descrip"))
	read_str("descrip",p_ptr->descrip); /* 240?! */
	end_section_read("history");

	/* Class/Race/Gender/Party */
	if (!had_header)
	{
		p_ptr->prace = read_int("prace");
		p_ptr->pclass = read_int("pclass");
		p_ptr->male = read_int("male");
	}
	p_ptr->party = read_int("party");

	/* Special Race/Class info */
	p_ptr->hitdie = read_int("hitdie");
	p_ptr->expfact = read_int("expfact");

	/* Age/Height/Weight */
	p_ptr->age = read_int("age");
	p_ptr->ht = read_int("ht");
	p_ptr->wt = read_int("wt");

	/* Read the stat info */
	start_section_read("stats");
	for (i = 0; i < 6; i++) p_ptr->stat_max[i] = read_int("stat_max");
	for (i = 0; i < 6; i++) p_ptr->stat_cur[i] = read_int("stat_cur");
	end_section_read("stats");

	p_ptr->id = read_int("id");

	/* If he was created in the pre-ID days, give him one */
	if (!p_ptr->id)
		p_ptr->id = player_id++;

	p_ptr->au = read_int("au");

	p_ptr->max_exp = read_int("max_exp");
	p_ptr->exp = read_int("exp");
	p_ptr->exp_frac = read_int("exp_frac");

	p_ptr->lev = read_int("lev");

	p_ptr->mhp = read_int("mhp");
	p_ptr->chp = read_int("chp");
	p_ptr->chp_frac = read_int("chp_frac");

	p_ptr->msp = read_int("msp");
	p_ptr->csp = read_int("csp");
	p_ptr->csp_frac = read_int("csp_frac");

	if(value_exists("no_ghost"))
	{
		(void)read_int("no_ghost");
	}
	
	p_ptr->max_plv = read_int("max_plv");
	p_ptr->max_dlv = read_int("max_dlv");
	
	p_ptr->recall_depth = p_ptr->max_dlv;

	p_ptr->py = read_int("py");
	p_ptr->px = read_int("px");
	p_ptr->dun_depth = read_int("dun_depth");

	p_ptr->world_x = read_int("world_x");
	p_ptr->world_y = read_int("world_y");

	/* More info */
	
	p_ptr->ghost = read_int("ghost");
	p_ptr->sc = read_int("sc");
	p_ptr->fruit_bat = read_int("fruit_bat");

	/* Read the flags */
	p_ptr->lives = read_int("lives");

	/* hack */
	p_ptr->blind = read_int("blind");
	p_ptr->paralyzed = read_int("paralyzed");
	p_ptr->confused = read_int("confused");
	p_ptr->food = read_int("food");
	p_ptr->energy = read_uint("energy");
	p_ptr->fast = read_int("fast");
	p_ptr->slow = read_int("slow");
	p_ptr->afraid = read_int("afraid");
	p_ptr->cut = read_int("cut");
	p_ptr->stun = read_int("stun");
	p_ptr->poisoned = read_int("poisoned");
	p_ptr->image = read_int("image");
	p_ptr->protevil = read_int("protevil");
	p_ptr->invuln = read_int("invuln");
	p_ptr->hero = read_int("hero");
	p_ptr->shero = read_int("shero");
	p_ptr->shield = read_int("shield");
	p_ptr->blessed = read_int("blessed");
	p_ptr->tim_invis = read_int("tim_invis");
	p_ptr->word_recall = read_int("word_recall");
	p_ptr->see_infra = read_int("see_infra");
	p_ptr->tim_infra = read_int("tim_infra");
	
	p_ptr->oppose_fire = read_int("oppose_fire");
	p_ptr->oppose_cold = read_int("oppose_cold");
	p_ptr->oppose_acid = read_int("oppose_acid");
	p_ptr->oppose_elec = read_int("oppose_elec");
	p_ptr->oppose_pois = read_int("oppose_pois");

	p_ptr->confusing = read_int("confusing");
	p_ptr->searching = read_int("searching");
	p_ptr->maximize = read_int("maximize");
	p_ptr->preserve = read_int("preserve");

	/* Read the unique list info */
	start_section_read("uniques");
	for (i = 0; i < z_info->r_max; i++) p_ptr->r_killed[i] = read_int("unique");
	end_section_read("uniques");

	/* Special stuff */
	panic_save = read_int("panic_save");
	p_ptr->total_winner = read_int("total_winner");
	p_ptr->retire_timer = read_int("retire_timer");
	p_ptr->noscore = read_int("noscore");

	/* Read "death" */
	p_ptr->death = read_int("death");

	end_section_read("player");

	/* Success */
	return FALSE;
}
Exemplo n.º 18
0
/*
 * Actually read the savefile
 *
 */
static errr rd_savefile_new_aux(player_type *p_ptr)
{
	int i;

	u16b tmp16u;
	u32b tmp32u;
	bool clear = FALSE;
	bool had_header = FALSE;
	char stat_order_hack[6];

	start_section_read("mangband_player_save");
	start_section_read("version");
	read_int("major"); 
	read_int("minor");
	read_int("patch");
	end_section_read("version");
	
	if (section_exists("header")) 
	{
		start_section_read("header");
		had_header = TRUE;

		read_str("playername",p_ptr->name); /* 32 */

		skip_value("pass");

		p_ptr->prace = read_int("prace");
		p_ptr->pclass = read_int("pclass");
		p_ptr->male = read_int("male");

		read_binary("stat_order", stat_order_hack, 6);
		for (i = 0; i < 6; i++)
			p_ptr->stat_order[i] = stat_order_hack[i];

		end_section_read("header");
	}

	/* Operating system info */
	sf_xtra = read_uint("sf_xtra");

	/* Time of savefile creation */
	sf_when = read_uint("sf_when");

	/* Number of resurrections */
	sf_lives = read_int("sf_lives");

	/* Number of times played */
	sf_saves = read_int("sf_saves");

	/* Skip the turn info - if present */
	skip_value("turn");
	
	/* Turn this character was born on */
	if(value_exists("birth_turn"))
		read_hturn("birth_turn", &p_ptr->birth_turn);
	else
		/* Disable character event logging if no birth turn */
		ht_clr(&p_ptr->birth_turn);

	/* Player turns (actually time spent playing) */
	if(value_exists("player_turn"))
		read_hturn("player_turn", &p_ptr->turn);
	else
		ht_clr(&p_ptr->turn);

	/* Read birth options */
	if (rd_birthoptions(p_ptr))
	{
		return (28);
	}

	/* Monster Memory */
	if (section_exists("monster_lore")) {
	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++)
	{
		/* Read the lore */
		rd_lore(p_ptr, i);
	}
	end_section_read("monster_lore");
	}
	
	/* Object Memory */
	start_section_read("object_memory");
	tmp16u = read_int("max_k_idx");

	/* Incompatible save files */
	if (tmp16u > z_info->k_max)
	{
		note(format("Too many (%u) object kinds!", tmp16u));
		return (22);
	}

	/* Read the object memory */
	for (i = 0; i < tmp16u; i++)
	{
		byte tmp8u;

		tmp8u = read_int("flags");

		p_ptr->obj_aware[i] = (tmp8u & 0x01) ? TRUE : FALSE;
		p_ptr->obj_tried[i] = (tmp8u & 0x02) ? TRUE : FALSE;
	}
	end_section_read("object_memory");

	/*if (arg_fiddle) note("Loaded Object Memory");*/

	/* Read the extra stuff */
	rd_extra(p_ptr, had_header);

	/*if (arg_fiddle) note("Loaded extra information");*/


	/* Read the player_hp array */
	start_section_read("hp");
	tmp16u = read_int("py_max_level");

	/* Read the player_hp array */
	for (i = 0; i < tmp16u; i++)
	{
		p_ptr->player_hp[i] = read_int("hp");
	}
	end_section_read("hp");


	/* Important -- Initialize the race/class */
	p_ptr->rp_ptr = &p_info[p_ptr->prace];
	p_ptr->cp_ptr = &c_info[p_ptr->pclass];
	

	/* Important -- Choose the magic info */
	p_ptr->mp_ptr = &c_info[p_ptr->pclass].spells;


	/* Read spell info */
	if (section_exists("spell_flags"))
	{
		start_section_read("spell_flags");
		for (i = 0; i < PY_MAX_SPELLS; i++)
		{
			p_ptr->spell_flags[i] = read_int("flag");
		}
		end_section_read("spell_flags");
	}
	else
	{
		/* Port spell flags from old format */
		u32b spell_learned1, spell_learned2;
		u32b spell_worked1, spell_worked2;
		u32b spell_forgotten1, spell_forgotten2;
		spell_learned1 = read_uint("spell_learned1");
		spell_learned2 = read_uint("spell_learned2");
		spell_worked1 = read_uint("spell_worked1");
		spell_worked2 = read_uint("spell_worked2");
		spell_forgotten1 = read_uint("spell_forgotten1");
		spell_forgotten2 = read_uint("spell_forgotten2");
		for (i = 0; i < PY_MAX_SPELLS; i++)
		{
			if ((i < 32) ?
				(spell_forgotten1 & (1L << i)) :
				(spell_forgotten2 & (1L << (i - 32))))
			{
				p_ptr->spell_flags[i] |= PY_SPELL_FORGOTTEN;
			} 
			if ((i < 32) ?
				(spell_learned1 & (1L << i)) :
				(spell_learned2 & (1L << (i - 32))))
			{
				p_ptr->spell_flags[i] |= PY_SPELL_LEARNED;
			}
			if ((i < 32) ?
				(spell_worked1 & (1L << i)) :
				(spell_worked2 & (1L << (i - 32))))
			{
				p_ptr->spell_flags[i] |= PY_SPELL_WORKED;
			}			
		}
	}

	start_section_read("spell_order");
	for (i = 0; i < PY_MAX_SPELLS; i++)
	{
		p_ptr->spell_order[i] = read_int("order");
	}
	end_section_read("spell_order");

	/* Read the inventory */
	if (rd_inventory(p_ptr))
	{
		/*note("Unable to read inventory");*/
		return (21);
	}

	/* Read hostility information if new enough */
	if (rd_hostilities(p_ptr))
	{
		return (22);
	}
	rd_cave_memory(p_ptr);
	
	/* read the wilderness map */
	start_section_read("wilderness");
	/* get the map size */
	tmp32u = read_int("max_wild");
		
	/* if too many map entries */
	if (tmp32u > MAX_WILD)
	{
		return 23;
	}
		
	/* read in the map */
	for (i = 0; i < tmp32u; i++)
	{
		p_ptr->wild_map[i] = read_int("wild_map");
	}
	end_section_read("wilderness");
	
	/* Read the character event history */
	if(section_exists("event_history"))
	{
		char buf[160];
		cptr msg;
		history_event evt;
		history_event *last = NULL;
		start_section_read("event_history");
		while(value_exists("hist"))
		{
			int depth, level;
			history_event *n_evt = NULL;
			read_str("hist", buf);
			if (sscanf(buf, "%02i:%02i:%02i   %4ift   %2i   ", &evt.days, &evt.hours, &evt.mins,
				&depth, &level) == 5)
			{
				msg = &buf[25];/* skip 25 characters ^ */
				evt.depth = depth / 50;
				evt.message = quark_add(msg);
			}
			/* Allocate */
			MAKE(n_evt, history_event);
			n_evt->days = evt.days; n_evt->hours = evt.hours; n_evt->mins = evt.mins;
			n_evt->depth = evt.depth; n_evt->level = level;
			n_evt->message = evt.message;
			/* Add to chain */
			if (!last)
			{
				p_ptr->charhist = n_evt;
				last = n_evt;
			}
			else
			{
				last->next = n_evt;
				last = n_evt;
			}
		}
		end_section_read("event_history");
	}

	/* Read the characters quest list */
	if(section_exists("quests"))
	{
		start_section_read("quests");
		tmp16u = read_int("max_q_idx");
		for(i = 0; i < MAX_Q_IDX; i++)
		{
			tmp16u = read_int("level");
			p_ptr->q_list[i].level = tmp16u;
		}
		end_section_read("quests");
	}

	/* Read the characters sold artifact list */
	if(section_exists("found_artifacts"))
	{
		start_section_read("found_artifacts");
		tmp16u = read_int("max_a_idx");
		tmp32u = tmp16u;
		/* If we have an unexpected number of arts, just reset our list
		 * of sold artifacts. It's not so important we want to break
		 * save file compatability for it. */
		if( tmp16u != z_info->a_max )
		{
			clear = TRUE;
			tmp16u = 0;
		}
		for(i = 0; i < z_info->a_max; i++)
		{
			if(i < tmp32u)
			{
				if(!clear) tmp16u = read_int("a_info");
			}
			p_ptr->a_info[i] = tmp16u;
		}
		end_section_read("found_artifacts");
	}

	/* Hack -- no ghosts */
	/* r_info[z_info->r_max - 1].max_num = 0; */

  end_section_read("mangband_player_save");
  
	/* Success */
	return (0);
}