Beispiel #1
0
/*
 * Read the dungeon
 *
 * The monsters/objects must be loaded in the same order
 * that they were stored, since the actual indexes matter.
 *
 * Note that the size of the dungeon is now hard-coded to
 * DUNGEON_HGT by DUNGEON_WID, and any dungeon with another
 * size will be silently discarded by this routine.
 *
 * Note that dungeon objects, including objects held by monsters, are
 * placed directly into the dungeon, using "object_copy()", which will
 * copy "iy", "ix", and "held_m_idx", leaving "next_o_idx" blank for
 * objects held by monsters, since it is not saved in the savefile.
 *
 * After loading the monsters, the objects being held by monsters are
 * linked directly into those monsters.
 */
static errr rd_dungeon(void)
{
	int i, y, x;
int by, bx;

	s16b town;
	s16b dungeon;
	s16b depth;
	s16b py, px;
	s16b ymax, xmax;

	byte count;
	byte tmp8u;
	u16b tmp16u;

u16b limit;

	/*** Basic info ***/

	/* Header info */
	rd_s16b(&depth);
	rd_s16b(&dungeon);
	rd_s16b(&py);
	rd_s16b(&px);
	rd_s16b(&ymax);
	rd_s16b(&xmax);
	rd_s16b(&town);
	rd_u16b(&tmp16u);


	/* Ignore illegal dungeons */
	if (town>=z_info->t_max)
	{
		note(format("Ignoring illegal dungeon (%d)", dungeon));
		return (0);
	}

	/* Ignore illegal dungeons */
	if ((depth < 0) || (depth > max_depth(dungeon)))
	{
		note(format("Ignoring illegal dungeon depth (%d)", depth));
		return (0);
	}

	/* Ignore illegal dungeons */
	if ((ymax != DUNGEON_HGT) || (xmax != DUNGEON_WID))
	{
		/* XXX XXX XXX */
		note(format("Ignoring illegal dungeon size (%d,%d).", ymax, xmax));
		return (0);
	}

	/* Ignore illegal dungeons */
	if ((px < 0) || (px >= DUNGEON_WID) ||
	    (py < 0) || (py >= DUNGEON_HGT))
	{
		note(format("Ignoring illegal player location (%d,%d).", py, px));
		return (1);
	}


	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < DUNGEON_HGT; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Extract "info" */
			cave_info[y][x] = tmp8u;

			/* Advance/Wrap */
			if (++x >= DUNGEON_WID)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= DUNGEON_HGT) break;
			}
		}
	}

	/* Hack -- not fully dynamic */
	dyna_full = FALSE;

	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < DUNGEON_HGT; )
	{
		/* Grab RLE info */
		rd_byte(&count);

		if (variant_save_feats) rd_u16b(&tmp16u);
		else rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Save the feat */
			if (variant_save_feats) cave_feat[y][x] = tmp16u;
			else cave_feat[y][x] = tmp8u;

			/* Check for los flag set*/
			if (f_info[cave_feat[y][x]].flags1 & (FF1_LOS))
			{
				cave_info[y][x] &= ~(CAVE_WALL);
			}

			/* Handle wall grids */
			else
			{
				cave_info[y][x] |= (CAVE_WALL);
			}

			/* Handle dynamic grids */
			if (f_info[cave_feat[y][x]].flags3 & (FF3_DYNAMIC_MASK))
			{
				if (dyna_n < (DYNA_MAX-1))
				{
					dyna_g[dyna_n++] = GRID(y,x);
				}
				else
				{
					dyna_full = TRUE;
					dyna_cent_y = 255;
					dyna_cent_x = 255;
				}
			}

			/* Advance/Wrap */
			if (++x >= DUNGEON_WID)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= DUNGEON_HGT) break;
			}
		}
	}

	/*** Player ***/

	/* Fix depth */
	if (depth < 1) depth = min_depth(dungeon);

	/* Fix depth */
	if (depth > max_depth(dungeon)) depth = max_depth(dungeon);

	/* Load depth */
	p_ptr->depth = depth;
	p_ptr->dungeon = dungeon;
	p_ptr->town = town;


	/* Place player in dungeon */
	if (!player_place(py, px))
	{
		note(format("Cannot place player (%d,%d)!", py, px));
		return (-1);
	}


	/*** Room descriptions ***/
   
	if (!variant_room_info)
	{
		/* Initialize the room table */
		for (by = 0; by < MAX_ROOMS_ROW; by++)
		{
			for (bx = 0; bx < MAX_ROOMS_COL; bx++)
			{
				dun_room[by][bx] = 0;
			}
		}

		/* Initialise 'zeroeth' room description */
		room_info[0].flags = 0;
	}
	else
	{

		for (bx = 0; bx < MAX_ROOMS_ROW; bx++)
		{
			for (by = 0; by < MAX_ROOMS_COL; by++)
			{
				rd_byte(&dun_room[bx][by]);
			}
		}

		for (i = 1; i < DUN_ROOMS; i++)
		{
			int j;

			rd_byte(&room_info[i].type);
			rd_byte(&room_info[i].flags);

			if (room_info[i].type == ROOM_NORMAL)
			{
				for (j = 0; j < ROOM_DESC_SECTIONS; j++)
				{
					rd_s16b(&room_info[i].section[j]);

					if (room_info[i].section[j] == -1) break;
				}
			}
		}
	}

	/*** Objects ***/

	/* Read the item count */
	rd_u16b(&limit);

	/* Verify maximum */
	if (limit > z_info->o_max)
	{
		note(format("Too many (%d) object entries!", limit));
		return (-1);
	}

	/* Read the dungeon items */
	for (i = 1; i < limit; i++)
	{
		object_type *i_ptr;
		object_type object_type_body;

		s16b o_idx;
		object_type *o_ptr;


		/* Get the object */
		i_ptr = &object_type_body;

		/* Wipe the object */
		object_wipe(i_ptr);

		/* Read the item */
		if (rd_item(i_ptr))
		{
			note("Error reading item");
			return (-1);
		}

		/* Make an object */
		o_idx = o_pop();

		/* Paranoia */
		if (o_idx != i)
		{
			note(format("Cannot place object %d!", i));
			return (-1);
		}

		/* Get the object */
		o_ptr = &o_list[o_idx];

		/* Structure Copy */
		object_copy(o_ptr, i_ptr);

		/* Dungeon floor */
		if (!i_ptr->held_m_idx)
		{
			int x = i_ptr->ix;
			int y = i_ptr->iy;

			/* ToDo: Verify coordinates */

			/* Link the object to the pile */
			o_ptr->next_o_idx = cave_o_idx[y][x];

			/* Link the floor to the object */
			cave_o_idx[y][x] = o_idx;
		}
	}


	/*** Monsters ***/

	/* Read the monster count */
	rd_u16b(&limit);

	/* Hack -- verify */
	if (limit > z_info->m_max)
	{
		note(format("Too many (%d) monster entries!", limit));
		return (-1);
	}

	/* Read the monsters */
	for (i = 1; i < limit; i++)
	{
		monster_type *n_ptr;
		monster_type monster_type_body;


		/* Get local monster */
		n_ptr = &monster_type_body;

		/* Clear the monster */
		(void)WIPE(n_ptr, monster_type);

		/* Read the monster */
		rd_monster(n_ptr);


		/* Place monster in dungeon */
		if (monster_place(n_ptr->fy, n_ptr->fx, n_ptr) != i)
		{
			note(format("Cannot place monster %d", i));
			return (-1);
		}
	}


	/*** Holding ***/

	/* 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;
	}


	/*** Success ***/

	/* The dungeon is ready */
	character_dungeon = TRUE;

	/* Regenerate town in post 2.9.3 versions */
	if (older_than(2, 9, 4) && (p_ptr->depth == 0))
		character_dungeon = FALSE;

	/* Success */
	return (0);
}
Beispiel #2
0
/*
 * Read the dungeon
 *
 * The monsters/objects must be loaded in the same order
 * that they were stored, since the actual indexes matter.
 */
static errr rd_dungeon(void)
{
	int i, y, x;
	int ymax, xmax;
	byte count;
	byte tmp8u;
	s16b tmp16s;
	u16b limit;
	cave_type *c_ptr;


	/*** Basic info ***/

	/* Header info */
	rd_s16b(&dun_level);

	/* Set the base level for old versions */
	base_level = dun_level;

	/* Read the base level */
	rd_s16b(&base_level);

	rd_s16b(&num_repro);
	rd_s16b(&py);
	rd_s16b(&px);
	rd_s16b(&cur_hgt);
	rd_s16b(&cur_wid);
	rd_s16b(&tmp16s); /* max_panel_rows */
	rd_s16b(&tmp16s); /* max_panel_cols */

	/* Maximal size */
	ymax = cur_hgt;
	xmax = cur_wid;

	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < ymax; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_s16b(&tmp16s);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Access the cave */
			c_ptr = &cave[y][x];

			/* Extract "info" */
			c_ptr->info = tmp16s;

			/* Decline invalid flags */
			c_ptr->info &= ~(CAVE_LITE | CAVE_VIEW | CAVE_MNLT);

			/* Advance/Wrap */
			if (++x >= xmax)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= ymax) break;
			}
		}
	}


	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < ymax; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Access the cave */
			c_ptr = &cave[y][x];

			/* Extract "feat" */
			c_ptr->feat = tmp8u;

			/* Advance/Wrap */
			if (++x >= xmax)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= ymax) break;
			}
		}
	}

	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < ymax; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Access the cave */
			c_ptr = &cave[y][x];

			/* Extract "feat" */
			c_ptr->mimic = tmp8u;

			/* Advance/Wrap */
			if (++x >= xmax)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= ymax) break;
			}
		}
	}

	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < ymax; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_s16b(&tmp16s);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Access the cave */
			c_ptr = &cave[y][x];

			/* Extract "feat" */
			c_ptr->special = tmp16s;

			/* Advance/Wrap */
			if (++x >= xmax)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= ymax) break;
			}
		}
	}

	/*** Objects ***/

	/* Read the item count */
	rd_u16b(&limit);

	/* Verify maximum */
	if (limit > max_o_idx)
	{
#ifdef JP
		note(format("アイテムの配列が大きすぎる(%d)!", limit));
#else
		note(format("Too many (%d) object entries!", limit));
#endif
		return (151);
	}

	/* Read the dungeon items */
	for (i = 1; i < limit; i++)
	{
		int o_idx;

		object_type *o_ptr;


		/* Get a new record */
		o_idx = o_pop();

		/* Oops */
		if (i != o_idx)
		{
#ifdef JP
note(format("アイテム配置エラー (%d <> %d)", i, o_idx));
#else
			note(format("Object allocation error (%d <> %d)", i, o_idx));
#endif

			return (152);
		}


		/* Acquire place */
		o_ptr = &o_list[o_idx];

		/* Read the item */
		rd_item(o_ptr);


		/* XXX XXX XXX XXX XXX */

		/* Monster */
		if (o_ptr->held_m_idx)
		{
			monster_type *m_ptr;

			/* Monster */
			m_ptr = &m_list[o_ptr->held_m_idx];

			/* Build a stack */
			o_ptr->next_o_idx = m_ptr->hold_o_idx;

			/* Place the object */
			m_ptr->hold_o_idx = o_idx;
		}

		/* Dungeon */
		else
		{
			/* Access the item location */
			c_ptr = &cave[o_ptr->iy][o_ptr->ix];

			/* Build a stack */
			o_ptr->next_o_idx = c_ptr->o_idx;

			/* Place the object */
			c_ptr->o_idx = o_idx;
		}
	}


	/*** Monsters ***/

	/* Read the monster count */
	rd_u16b(&limit);

	/* Hack -- verify */
	if (limit > max_m_idx)
	{
#ifdef JP
		note(format("モンスターの配列が大きすぎる(%d)!", limit));
#else
		note(format("Too many (%d) monster entries!", limit));
#endif
		return (161);
	}

	/* Read the monsters */
	for (i = 1; i < limit; i++)
	{
		int m_idx;

		monster_type *m_ptr;

		monster_race *r_ptr;


		/* Get a new record */
		m_idx = m_pop();

		/* Oops */
		if (i != m_idx)
		{
#ifdef JP
note(format("モンスター配置エラー (%d <> %d)", i, m_idx));
#else
			note(format("Monster allocation error (%d <> %d)", i, m_idx));
#endif

			return (162);
		}


		/* Acquire monster */
		m_ptr = &m_list[m_idx];

		/* Read the monster */
		rd_monster(m_ptr);


		/* Access grid */
		c_ptr = &cave[m_ptr->fy][m_ptr->fx];

		/* Mark the location */
		c_ptr->m_idx = m_idx;


		/* Access race */
		r_ptr = &r_info[m_ptr->r_idx];

		/* Count XXX XXX XXX */
		r_ptr->cur_num++;
	}

	/*** Success ***/

	/* Regenerate the dungeon for corrupted panic-saves */
	if ((py == 0) || (px == 0))
	{
		character_dungeon = FALSE;
	}
	else
	{
		/* The dungeon is ready */
		character_dungeon = TRUE;
	}

	/* Success */
	return (0);
}
Beispiel #3
0
/*
 * Read the dungeon
 *
 * The monsters/objects must be loaded in the same order
 * that they were stored, since the actual indexes matter.
 *
 * Note that the size of the dungeon is now hard-coded to
 * DUNGEON_HGT by DUNGEON_WID, and any dungeon with another
 * size will be silently discarded by this routine.
 *
 * Note that dungeon objects, including objects held by monsters, are
 * placed directly into the dungeon, using "object_copy()", which will
 * copy "iy", "ix", and "held_m_idx", leaving "next_o_idx" blank for
 * objects held by monsters, since it is not saved in the savefile.
 *
 * After loading the monsters, the objects being held by monsters are
 * linked directly into those monsters.
 */
static errr rd_dungeon(void)
{
	int i, y, x;

	s16b depth;
	s16b py, px;

	byte count;
	byte tmp8u;

	u16b limit;


	/*** Basic info ***/

	/* Header info */
	rd_s16b(&depth);
	rd_s16b(&py);
	rd_s16b(&px);
	rd_byte(&p_ptr->cur_map_hgt);
	rd_byte(&p_ptr->cur_map_wid);

	/* Ignore illegal dungeons */
	if ((depth < 0) || (depth > MORGOTH_DEPTH))
	{
		note(format("Ignoring illegal dungeon depth (%d)", depth));
		return (0);
	}

	/* Ignore illegal dungeons */
	if ((p_ptr->cur_map_hgt > MAX_DUNGEON_HGT) || (p_ptr->cur_map_wid > MAX_DUNGEON_WID))
	{
		/* XXX XXX XXX */
		note(format("Ignoring illegal dungeon size (%d,%d).", p_ptr->cur_map_hgt, p_ptr->cur_map_wid));
		return (0);
	}

	/* Ignore illegal dungeons */
	if ((px < 0) || (px >= p_ptr->cur_map_wid) ||
		(py < 0) || (py >= p_ptr->cur_map_hgt))
	{
		note(format("Ignoring illegal player location (%d,%d).", py, px));
		return (1);
	}


	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < p_ptr->cur_map_hgt; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Extract "info" */
			cave_info[y][x] = tmp8u;

			/* Advance/Wrap */
			if (++x >= p_ptr->cur_map_wid)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= p_ptr->cur_map_hgt) break;
			}
		}
	}


	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < p_ptr->cur_map_hgt; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Extract "feat" */
			cave_set_feat(y, x, tmp8u);

			/* Advance/Wrap */
			if (++x >= p_ptr->cur_map_wid)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= p_ptr->cur_map_hgt) break;
			}
		}
	}


	/*** Player ***/

	/* Load depth */
	p_ptr->depth = depth;

	/* Place player in dungeon */
	if (!player_place(py, px))
	{
		note(format("Cannot place player (%d,%d)!", py, px));
		return (-1);
	}


	/*** Objects ***/

	/* Read the item count */
	rd_u16b(&limit);

	/* Verify maximum */
	if (limit > z_info->o_max)
	{
		note(format("Too many (%d) object entries!", limit));
		return (-1);
	}

	/* Read the dungeon items */
	for (i = 1; i < limit; i++)
	{
		object_type *i_ptr;
		object_type object_type_body;

		s16b o_idx;
		object_type *o_ptr;


		/* Get the object */
		i_ptr = &object_type_body;

		/* Wipe the object */
		object_wipe(i_ptr);

		/* Read the item */
		if (rd_item(i_ptr))
		{
			note("Error reading item");
			return (-1);
		}

		/* Make an object */
		o_idx = o_pop();

		/* Paranoia */
		if (o_idx != i)
		{
			note(format("Cannot place object %d!", i));
			return (-1);
		}

		/* Get the object */
		o_ptr = &o_list[o_idx];

		/* Structure Copy */
		object_copy(o_ptr, i_ptr);

		/* Dungeon floor */
		if (!i_ptr->held_m_idx)
		{
			int x = i_ptr->ix;
			int y = i_ptr->iy;

			/* ToDo: Verify coordinates */

			/* Link the object to the pile */
			o_ptr->next_o_idx = cave_o_idx[y][x];

			/* Link the floor to the object */
			cave_o_idx[y][x] = o_idx;

			/* Rearrange stack if needed */
			rearrange_stack(y, x);
		}
	}


	/*** Monsters ***/

	/* Read the monster count */
	rd_u16b(&limit);

	/* Hack -- verify */
	if (limit > z_info->m_max)
	{
		note(format("Too many (%d) monster entries!", limit));
		return (-1);
	}

	/* Read the monsters */
	for (i = 1; i < limit; i++)
	{
		monster_type *n_ptr;
		monster_type monster_type_body;
		monster_race *r_ptr;

		int r_idx;

		/* Get local monster */
		n_ptr = &monster_type_body;

		/* Clear the monster */
		(void)WIPE(n_ptr, monster_type);

		/* Read the monster */
		rd_monster(n_ptr);

		/* Access the "r_idx" of the chosen monster */
		r_idx = n_ptr->r_idx;

		/* Access the actual race */
		r_ptr = &r_info[r_idx];

		/* Place monster in dungeon */
		if (monster_place(n_ptr->fy, n_ptr->fx, n_ptr) != i)
		{
			note(format("Cannot place monster %d", i));
			return (-1);
		}
	}

	/*** Holding ***/

	/* 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 = &mon_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;
	}

	// dump the wandering monster information
	for (i = FLOW_WANDERING_HEAD; i < MAX_FLOWS; i++)
	{
		rd_byte(&flow_center_y[i]);
		rd_byte(&flow_center_x[i]);
		rd_s16b(&wandering_pause[i]);
		
		update_noise(flow_center_y[i], flow_center_x[i], i);
	}
	
		
	/*** Success ***/

	/* The dungeon is ready */
	character_dungeon = TRUE;

	/* Success */
	return (0);
}
Beispiel #4
0
/*
 * Read the dungeon
 *
 * The monsters/objects must be loaded in the same order
 * that they were stored, since the actual indexes matter.
 *
 * Note that the size of the dungeon is now hard-coded to
 * DUNGEON_HGT by DUNGEON_WID, and any dungeon with another
 * size will be silently discarded by this routine.
 *
 * Note that dungeon objects, including objects held by monsters, are
 * placed directly into the dungeon, using "object_copy()", which will
 * copy "iy", "ix", and "held_m_idx", leaving "next_o_idx" blank for
 * objects held by monsters, since it is not saved in the savefile.
 *
 * After loading the monsters, the objects being held by monsters are
 * linked directly into those monsters.
 */
static errr rd_dungeon(void)
{
	int i, y, x;

	s16b depth;
	s16b py, px;

	byte count;
	byte tmp8u;
	u16b tmp16u;

	u16b limit;


	/*** Basic info ***/

	/* Header info */
	rd_s16b(&depth);
	rd_u16b(&p_ptr->dungeon_type);
	/* Get dungeon capabilities */
	set_dungeon_type(p_ptr->dungeon_type);

	rd_s16b(&py);
	rd_s16b(&px);
	rd_byte(&p_ptr->cur_map_hgt);
	rd_byte(&p_ptr->cur_map_wid);
	rd_u16b(&altered_inventory_counter);
	/* Paranoia */
	allow_altered_inventory = FALSE;

	rd_u16b(&tmp16u);


	/* Ignore illegal dungeons */
	if ((depth < 0) || (depth >= MAX_DEPTH))
	{
		note(format("Ignoring illegal dungeon depth (%d)", depth));
		return (0);
	}

	/* Ignore illegal dungeons */
	if ((p_ptr->cur_map_hgt > MAX_DUNGEON_HGT) || (p_ptr->cur_map_wid > MAX_DUNGEON_WID))
	{
		/* XXX XXX XXX */
		note(format("Ignoring illegal dungeon size (%d,%d).", p_ptr->cur_map_hgt, p_ptr->cur_map_wid));
		return (0);
	}

	/* Ignore illegal dungeons */
	if ((px < 0) || (px >= p_ptr->cur_map_wid) ||
		(py < 0) || (py >= p_ptr->cur_map_hgt))
	{
		note(format("Ignoring illegal player location (%d,%d).", py, px));
		return (1);
	}


	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < p_ptr->cur_map_hgt; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			/* Extract "info" */
			cave_info[y][x] = tmp8u;

			/* Advance/Wrap */
			if (++x >= p_ptr->cur_map_wid)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= p_ptr->cur_map_hgt) break;
			}
		}
	}


	/*** Run length decoding ***/

	/* Load the dungeon data */
	for (x = y = 0; y < p_ptr->cur_map_hgt; )
	{
		/* Grab RLE info */
		rd_byte(&count);
		rd_byte(&tmp8u);

		/* Apply the RLE info */
		for (i = count; i > 0; i--)
		{
			feature_type *f_ptr;

			/* Extract "feat" */
			cave_feat[y][x] = tmp8u;

			update_los_proj_move(y, x);

			/* Get fast access to feature */
			f_ptr = &f_info[tmp8u];

			/* Handle glowing grids */
			if (_feat_ff2_match(f_ptr, FF2_GLOW))
			{
				int d;

				/* Turn on super glow */
				cave_info[y][x] |= (CAVE_HALO);

				/* Spread super glow through adjacent grids */
				for (d = 0; d < 8; d++)
				{
					/* Get coordinates */
					int yy = y + ddy_ddd[d];
					int xx = x + ddx_ddd[d];

					/* Ignore annoying locations */
					if (!in_bounds_fully(yy, xx))
					{
						continue;
					}

					/* Turn on super glow */
					cave_info[yy][xx] |= (CAVE_HALO);
				}
			}

			/* Register dynamic features */
			if (_feat_ff3_match(f_ptr, FF3_DYNAMIC))
			{
				(void)add_dynamic_terrain(y, x);
			}

			/* Update the flags of the current level */
			if (_feat_ff3_match(f_ptr, TERRAIN_MASK))
			{
				level_flag |= get_level_flag((u16b)(f_ptr - f_info));
			}

			/* Advance/Wrap */
			if (++x >= p_ptr->cur_map_wid)
			{
				/* Wrap */
				x = 0;

				/* Advance/Wrap */
				if (++y >= p_ptr->cur_map_hgt) break;
			}
		}
	}


	/*** Player ***/

	/* Load depth */
	p_ptr->depth = depth;


	/* Place player in dungeon */
	if (!player_place(py, px))
	{
		note(format("Cannot place player (%d,%d)!", py, px));
		return (-1);
	}


	/*** Objects ***/

	/* Read the item count */
	rd_u16b(&limit);

	/* Verify maximum */
	if (limit > z_info->o_max)
	{
		note(format("Too many (%d) object entries!", limit));
		return (-1);
	}

	/* Read the dungeon items */
	for (i = 1; i < limit; i++)
	{
		object_type *i_ptr;
		object_type object_type_body;

		s16b o_idx;
		object_type *o_ptr;


		/* Get the object */
		i_ptr = &object_type_body;

		/* Wipe the object */
		object_wipe(i_ptr);

		/* Read the item */
		if (rd_item(i_ptr))
		{
			note("Error reading item");
			return (-1);
		}

		/* Make an object */
		o_idx = o_pop();

		/* Paranoia */
		if (o_idx != i)
		{
			note(format("Cannot place object %d!", i));
			return (-1);
		}

		/* Get the object */
		o_ptr = &o_list[o_idx];

		/* Structure Copy */
		object_copy(o_ptr, i_ptr);

		/* Dungeon floor */
		if (!i_ptr->held_m_idx)
		{
			int x = i_ptr->ix;
			int y = i_ptr->iy;

			/* ToDo: Verify coordinates */

			/* Link the object to the pile */
			o_ptr->next_o_idx = cave_o_idx[y][x];

			/* Link the floor to the object */
			cave_o_idx[y][x] = o_idx;

			/* Rearrange stack if needed */
			rearrange_stack(y, x);
		}
	}


	/*** Monsters ***/

	/* Read the monster count */
	rd_u16b(&limit);

	/* Hack -- verify */
	if (limit > z_info->m_max)
	{
		note(format("Too many (%d) monster entries!", limit));
		return (-1);
	}

	/* Read the monsters */
	for (i = 1; i < limit; i++)
	{
		monster_type *n_ptr;
		monster_type monster_type_body;
		monster_race *r_ptr;

		int r_idx;

		/* Get local monster */
		n_ptr = &monster_type_body;

		/* Clear the monster */
		(void)WIPE(n_ptr, monster_type);

		/* Read the monster */
		rd_monster(n_ptr);

		/* Access the "r_idx" of the chosen monster */
		r_idx = n_ptr->r_idx;

		/* Access the actual race */
		r_ptr = &r_info[r_idx];

		/* If a player ghost, some special features need to be added. */
		if (r_ptr->flags2 & (RF2_PLAYER_GHOST))
		{
			(void)prepare_ghost(n_ptr->r_idx);
		}

		/* Place monster in dungeon */
		if (monster_place(n_ptr->fy, n_ptr->fx, n_ptr) != i)
		{
			note(format("Cannot place monster %d", i));
			return (-1);
		}
	}


	/*** Holding ***/

	/* 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 = &mon_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;
	}

	/*** Effects ***/
	/* Read the effect count */
	rd_u16b(&limit);

	/* Verify maximum */
	if (limit > z_info->x_max)
	{
		note(format("Too many (%d) effect entries!", limit));
		return (-1);
	}

	/* Read the dungeon items */
	for (i = 1; i < limit; i++)
	{

		/* Read the item */
		if (rd_effect())
		{
			note("Error reading effect");
			return (-1);
		}
	}


	/*** Success ***/

	/* The dungeon is ready */
	character_dungeon = TRUE;

	/* Success */
	return (0);
}
Beispiel #5
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);
}